]> git.mxchange.org Git - flightgear.git/commitdiff
FGCom integrated into FlightGear.
authorf-jjth <clemaez@hotmail.fr>
Sun, 19 May 2013 14:29:49 +0000 (16:29 +0200)
committerJames Turner <zakalawe@mac.com>
Fri, 16 Aug 2013 16:02:47 +0000 (17:02 +0100)
Disabled by default at build time.

448 files changed:
CMakeLists.txt
package/IRIX/FlightGear.idb [deleted file]
src/Include/config_cmake.h.in
src/Main/CMakeLists.txt
src/Main/fg_init.cxx
src/Main/options.cxx
src/Network/CMakeLists.txt
src/Network/fgcom.cxx [new file with mode: 0644]
src/Network/fgcom.hxx [new file with mode: 0644]
utils/CMakeLists.txt
utils/iaxclient/COPYING.LIB [new file with mode: 0644]
utils/iaxclient/README [new file with mode: 0644]
utils/iaxclient/lib/CMakeLists.txt [new file with mode: 0644]
utils/iaxclient/lib/TODO [new file with mode: 0644]
utils/iaxclient/lib/audio_alsa.c [new file with mode: 0644]
utils/iaxclient/lib/audio_alsa.h [new file with mode: 0644]
utils/iaxclient/lib/audio_encode.c [new file with mode: 0644]
utils/iaxclient/lib/audio_encode.h [new file with mode: 0644]
utils/iaxclient/lib/audio_file.c [new file with mode: 0644]
utils/iaxclient/lib/audio_file.h [new file with mode: 0644]
utils/iaxclient/lib/audio_openal.c [new file with mode: 0644]
utils/iaxclient/lib/audio_openal.h [new file with mode: 0644]
utils/iaxclient/lib/audio_portaudio.c [new file with mode: 0644]
utils/iaxclient/lib/audio_portaudio.h [new file with mode: 0644]
utils/iaxclient/lib/codec_alaw.c [new file with mode: 0644]
utils/iaxclient/lib/codec_alaw.h [new file with mode: 0644]
utils/iaxclient/lib/codec_ffmpeg.c [new file with mode: 0644]
utils/iaxclient/lib/codec_ffmpeg.h [new file with mode: 0644]
utils/iaxclient/lib/codec_gsm.c [new file with mode: 0644]
utils/iaxclient/lib/codec_gsm.h [new file with mode: 0644]
utils/iaxclient/lib/codec_ilbc.c [new file with mode: 0644]
utils/iaxclient/lib/codec_ilbc.h [new file with mode: 0644]
utils/iaxclient/lib/codec_speex.c [new file with mode: 0644]
utils/iaxclient/lib/codec_speex.h [new file with mode: 0644]
utils/iaxclient/lib/codec_theora.c [new file with mode: 0644]
utils/iaxclient/lib/codec_theora.h [new file with mode: 0644]
utils/iaxclient/lib/codec_ulaw.c [new file with mode: 0644]
utils/iaxclient/lib/codec_ulaw.h [new file with mode: 0644]
utils/iaxclient/lib/gsm/copyright [new file with mode: 0644]
utils/iaxclient/lib/gsm/inc/config.h [new file with mode: 0644]
utils/iaxclient/lib/gsm/inc/gsm.h [new file with mode: 0644]
utils/iaxclient/lib/gsm/inc/private.h [new file with mode: 0644]
utils/iaxclient/lib/gsm/inc/proto.h [new file with mode: 0644]
utils/iaxclient/lib/gsm/inc/unproto.h [new file with mode: 0644]
utils/iaxclient/lib/gsm/libgsm.prj [new file with mode: 0644]
utils/iaxclient/lib/gsm/readme [new file with mode: 0644]
utils/iaxclient/lib/gsm/src/add.c [new file with mode: 0644]
utils/iaxclient/lib/gsm/src/code.c [new file with mode: 0644]
utils/iaxclient/lib/gsm/src/debug.c [new file with mode: 0644]
utils/iaxclient/lib/gsm/src/decode.c [new file with mode: 0644]
utils/iaxclient/lib/gsm/src/gsm_create.c [new file with mode: 0644]
utils/iaxclient/lib/gsm/src/gsm_decode.c [new file with mode: 0644]
utils/iaxclient/lib/gsm/src/gsm_destroy.c [new file with mode: 0644]
utils/iaxclient/lib/gsm/src/gsm_encode.c [new file with mode: 0644]
utils/iaxclient/lib/gsm/src/gsm_explode.c [new file with mode: 0644]
utils/iaxclient/lib/gsm/src/gsm_implode.c [new file with mode: 0644]
utils/iaxclient/lib/gsm/src/gsm_option.c [new file with mode: 0644]
utils/iaxclient/lib/gsm/src/gsm_print.c [new file with mode: 0644]
utils/iaxclient/lib/gsm/src/k6opt.h [new file with mode: 0644]
utils/iaxclient/lib/gsm/src/k6opt.s [new file with mode: 0644]
utils/iaxclient/lib/gsm/src/long_term.c [new file with mode: 0644]
utils/iaxclient/lib/gsm/src/lpc.c [new file with mode: 0644]
utils/iaxclient/lib/gsm/src/preprocess.c [new file with mode: 0644]
utils/iaxclient/lib/gsm/src/rpe.c [new file with mode: 0644]
utils/iaxclient/lib/gsm/src/short_term.c [new file with mode: 0644]
utils/iaxclient/lib/gsm/src/table.c [new file with mode: 0644]
utils/iaxclient/lib/iaxclient.h [new file with mode: 0644]
utils/iaxclient/lib/iaxclient_lib.c [new file with mode: 0644]
utils/iaxclient/lib/iaxclient_lib.h [new file with mode: 0644]
utils/iaxclient/lib/libiax2/AUTHORS [new file with mode: 0644]
utils/iaxclient/lib/libiax2/COPYING [new file with mode: 0644]
utils/iaxclient/lib/libiax2/COPYING.LIB [new file with mode: 0644]
utils/iaxclient/lib/libiax2/ChangeLog [new file with mode: 0644]
utils/iaxclient/lib/libiax2/INSTALL [new file with mode: 0644]
utils/iaxclient/lib/libiax2/Makefile.am [new file with mode: 0644]
utils/iaxclient/lib/libiax2/NEWS [new file with mode: 0644]
utils/iaxclient/lib/libiax2/README [new file with mode: 0644]
utils/iaxclient/lib/libiax2/bootstrap.sh [new file with mode: 0755]
utils/iaxclient/lib/libiax2/build.sh [new file with mode: 0755]
utils/iaxclient/lib/libiax2/configure.in [new file with mode: 0644]
utils/iaxclient/lib/libiax2/depcomp [new file with mode: 0755]
utils/iaxclient/lib/libiax2/gen.sh [new file with mode: 0755]
utils/iaxclient/lib/libiax2/iax-config.in [new file with mode: 0755]
utils/iaxclient/lib/libiax2/iax.spec.in [new file with mode: 0644]
utils/iaxclient/lib/libiax2/install-sh [new file with mode: 0755]
utils/iaxclient/lib/libiax2/libiax2.vcproj [new file with mode: 0644]
utils/iaxclient/lib/libiax2/missing [new file with mode: 0755]
utils/iaxclient/lib/libiax2/mkinstalldirs [new file with mode: 0755]
utils/iaxclient/lib/libiax2/src/Makefile.am [new file with mode: 0644]
utils/iaxclient/lib/libiax2/src/answer.h [new file with mode: 0644]
utils/iaxclient/lib/libiax2/src/busy.h [new file with mode: 0644]
utils/iaxclient/lib/libiax2/src/dialtone.h [new file with mode: 0644]
utils/iaxclient/lib/libiax2/src/frame.h [new file with mode: 0644]
utils/iaxclient/lib/libiax2/src/iax-client.h [new file with mode: 0644]
utils/iaxclient/lib/libiax2/src/iax.c [new file with mode: 0644]
utils/iaxclient/lib/libiax2/src/iax.h [new file with mode: 0644]
utils/iaxclient/lib/libiax2/src/iax2-parser.c [new file with mode: 0644]
utils/iaxclient/lib/libiax2/src/iax2-parser.h [new file with mode: 0644]
utils/iaxclient/lib/libiax2/src/iax2.h [new file with mode: 0644]
utils/iaxclient/lib/libiax2/src/jitterbuf.c [new file with mode: 0644]
utils/iaxclient/lib/libiax2/src/jitterbuf.h [new file with mode: 0644]
utils/iaxclient/lib/libiax2/src/md5.c [new file with mode: 0644]
utils/iaxclient/lib/libiax2/src/md5.h [new file with mode: 0644]
utils/iaxclient/lib/libiax2/src/miniphone.c [new file with mode: 0644]
utils/iaxclient/lib/libiax2/src/miniphone.h [new file with mode: 0644]
utils/iaxclient/lib/libiax2/src/options.c [new file with mode: 0644]
utils/iaxclient/lib/libiax2/src/options.h [new file with mode: 0644]
utils/iaxclient/lib/libiax2/src/ring10.h [new file with mode: 0644]
utils/iaxclient/lib/libiax2/src/ringtone.h [new file with mode: 0644]
utils/iaxclient/lib/libiax2/src/winiphone.c [new file with mode: 0644]
utils/iaxclient/lib/libiax2/src/winpoop.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/ChangeLog [new file with mode: 0644]
utils/iaxclient/lib/libspeex/arch.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/bits.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/cb_search.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/cb_search.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/cb_search_arm4.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/cb_search_sse.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/exc_10_16_table.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/exc_10_32_table.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/exc_20_32_table.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/exc_5_256_table.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/exc_5_64_table.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/exc_8_128_table.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/filters.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/filters.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/filters_arm4.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/filters_sse.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/fixed_arm4.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/fixed_arm5e.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/fixed_debug.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/fixed_generic.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/gain_table.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/gain_table_lbr.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/hexc_10_32_table.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/hexc_table.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/high_lsp_tables.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/include/speex/speex.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/include/speex/speex_bits.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/include/speex/speex_callbacks.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/include/speex/speex_config_types.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/include/speex/speex_echo.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/include/speex/speex_header.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/include/speex/speex_jitter.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/include/speex/speex_noglobals.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/include/speex/speex_preprocess.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/include/speex/speex_stereo.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/include/speex/speex_types.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/jitter.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/lbr_48k_tables.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/lpc.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/lpc.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/lsp.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/lsp.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/lsp_tables_nb.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/ltp.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/ltp.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/ltp_arm4.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/ltp_sse.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/math_approx.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/math_approx.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/mdf.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/medfilter.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/medfilter.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/misc.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/misc.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/modes.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/modes.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/modes_noglobals.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/nb_celp.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/nb_celp.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/preprocess.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/quant_lsp.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/quant_lsp.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/sb_celp.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/sb_celp.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/smallft.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/smallft.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/speex.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/speex_callbacks.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/speex_header.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/stack_alloc.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/stereo.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/testdenoise.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/testecho.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/testenc.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/testenc_uwb.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/testenc_wb.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/vbr.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/vbr.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/vq.c [new file with mode: 0644]
utils/iaxclient/lib/libspeex/vq.h [new file with mode: 0644]
utils/iaxclient/lib/libspeex/vq_arm4.h [new file with mode: 0644]
utils/iaxclient/lib/macosx/Prefixes.h [new file with mode: 0644]
utils/iaxclient/lib/macosx/README [new file with mode: 0644]
utils/iaxclient/lib/macosx/iaxclientlib.pbproj/project.pbxproj [new file with mode: 0644]
utils/iaxclient/lib/portaudio/LICENSE.txt [new file with mode: 0644]
utils/iaxclient/lib/portaudio/Makefile.darwin [new file with mode: 0644]
utils/iaxclient/lib/portaudio/Makefile.in [new file with mode: 0644]
utils/iaxclient/lib/portaudio/README.txt [new file with mode: 0644]
utils/iaxclient/lib/portaudio/SConstruct [new file with mode: 0644]
utils/iaxclient/lib/portaudio/V19-devel-readme.txt [new file with mode: 0644]
utils/iaxclient/lib/portaudio/aclocal.m4 [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/CHANGELOG [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/SConscript [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/doc/README [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/doc/config.doxy [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/doc/config.doxy.linux [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/example/devs.cxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/example/sine.cxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/AsioDeviceAdapter.hxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/AutoSystem.hxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/BlockingStream.hxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/CFunCallbackStream.hxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/CallbackInterface.hxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/CallbackStream.hxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/CppFunCallbackStream.hxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/Device.hxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/DirectionSpecificStreamParameters.hxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/Exception.hxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/HostApi.hxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/InterfaceCallbackStream.hxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/MemFunCallbackStream.hxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/PortAudioCpp.hxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/SampleDataFormat.hxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/Stream.hxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/StreamParameters.hxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/System.hxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/SystemDeviceIterator.hxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/SystemHostApiIterator.hxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/AsioDeviceAdapter.cxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/BlockingStream.cxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/CFunCallbackStream.cxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/CallbackInterface.cxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/CallbackStream.cxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/CppFunCallbackStream.cxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/Device.cxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/DirectionSpecificStreamParameters.cxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/Exception.cxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/HostApi.cxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/InterfaceCallbackStream.cxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/MemFunCallbackStream.cxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/Stream.cxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/StreamParameters.cxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/System.cxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/SystemDeviceIterator.cxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/SystemHostApiIterator.cxx [new file with mode: 0644]
utils/iaxclient/lib/portaudio/config.doxy [new file with mode: 0644]
utils/iaxclient/lib/portaudio/config.guess [new file with mode: 0755]
utils/iaxclient/lib/portaudio/config.sub [new file with mode: 0755]
utils/iaxclient/lib/portaudio/configure [new file with mode: 0755]
utils/iaxclient/lib/portaudio/configure.in [new file with mode: 0644]
utils/iaxclient/lib/portaudio/docs/index.html [new file with mode: 0644]
utils/iaxclient/lib/portaudio/docs/latency.html [new file with mode: 0644]
utils/iaxclient/lib/portaudio/docs/pa_impl_guide.html [new file with mode: 0644]
utils/iaxclient/lib/portaudio/docs/pa_impl_startstop.html [new file with mode: 0644]
utils/iaxclient/lib/portaudio/docs/pa_tut_asio.html [new file with mode: 0644]
utils/iaxclient/lib/portaudio/docs/pa_tut_callback.html [new file with mode: 0644]
utils/iaxclient/lib/portaudio/docs/pa_tut_devs.html [new file with mode: 0644]
utils/iaxclient/lib/portaudio/docs/pa_tut_explore.html [new file with mode: 0644]
utils/iaxclient/lib/portaudio/docs/pa_tut_init.html [new file with mode: 0644]
utils/iaxclient/lib/portaudio/docs/pa_tut_mac.html [new file with mode: 0644]
utils/iaxclient/lib/portaudio/docs/pa_tut_mac_osx.html [new file with mode: 0644]
utils/iaxclient/lib/portaudio/docs/pa_tut_open.html [new file with mode: 0644]
utils/iaxclient/lib/portaudio/docs/pa_tut_oss.html [new file with mode: 0644]
utils/iaxclient/lib/portaudio/docs/pa_tut_over.html [new file with mode: 0644]
utils/iaxclient/lib/portaudio/docs/pa_tut_pc.html [new file with mode: 0644]
utils/iaxclient/lib/portaudio/docs/pa_tut_run.html [new file with mode: 0644]
utils/iaxclient/lib/portaudio/docs/pa_tut_rw.html [new file with mode: 0644]
utils/iaxclient/lib/portaudio/docs/pa_tut_term.html [new file with mode: 0644]
utils/iaxclient/lib/portaudio/docs/pa_tut_util.html [new file with mode: 0644]
utils/iaxclient/lib/portaudio/docs/pa_tutorial.html [new file with mode: 0644]
utils/iaxclient/lib/portaudio/docs/portaudio_h.txt [new file with mode: 0644]
utils/iaxclient/lib/portaudio/docs/portaudio_icmc2001.pdf [new file with mode: 0644]
utils/iaxclient/lib/portaudio/docs/proposals.html [new file with mode: 0644]
utils/iaxclient/lib/portaudio/docs/releases.html [new file with mode: 0644]
utils/iaxclient/lib/portaudio/fixdir.bat [new file with mode: 0755]
utils/iaxclient/lib/portaudio/fixfile.bat [new file with mode: 0755]
utils/iaxclient/lib/portaudio/include/pa_asio.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/include/pa_linux_alsa.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/include/pa_mac_core.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/include/pa_win_wmme.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/include/portaudio.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/index.html [new file with mode: 0644]
utils/iaxclient/lib/portaudio/install-sh [new file with mode: 0755]
utils/iaxclient/lib/portaudio/libtool [new file with mode: 0755]
utils/iaxclient/lib/portaudio/ltmain.sh [new file with mode: 0644]
utils/iaxclient/lib/portaudio/pa_tests/patest_in_overflow.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/pablio/README.txt [new file with mode: 0644]
utils/iaxclient/lib/portaudio/pablio/pablio.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/pablio/pablio.def [new file with mode: 0644]
utils/iaxclient/lib/portaudio/pablio/pablio.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/pablio/ringbuffer.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/pablio/ringbuffer.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/pablio/test_rw.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/pablio/test_rw_echo.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/pablio/test_w_saw.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/pablio/test_w_saw8.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/portaudio-2.0.pc [new file with mode: 0644]
utils/iaxclient/lib/portaudio/portaudio-2.0.pc.in [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/SConscript [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/common/pa_allocation.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/common/pa_allocation.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/common/pa_converters.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/common/pa_converters.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/common/pa_cpuload.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/common/pa_cpuload.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/common/pa_dither.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/common/pa_dither.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/common/pa_endianness.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/common/pa_front.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/common/pa_hostapi.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/common/pa_process.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/common/pa_process.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/common/pa_skeleton.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/common/pa_stream.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/common/pa_stream.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/common/pa_trace.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/common/pa_trace.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/common/pa_types.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/common/pa_util.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/alsa/pa_linux_alsa.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/asio/ASIO-README.txt [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/asio/Callback_adaptation_.pdf [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/asio/Pa_ASIO.pdf [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/asio/iasiothiscallresolver.cpp [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/asio/iasiothiscallresolver.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/asio/pa_asio.cpp [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/notes.txt [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/pa_mac_core.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/pa_mac_core_internal.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/pa_mac_core_utilities.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/pa_mac_core_utilities.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/ringbuffer.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/ringbuffer.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/dsound/pa_win_ds.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/dsound/pa_win_ds_dynlink.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/dsound/pa_win_ds_dynlink.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/jack/pa_jack.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/oss/low_latency_tip.txt [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/oss/pa_unix_oss.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/oss/recplay.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/wasapi/pa_win_wasapi.cpp [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/wdmks/pa_win_wdmks.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/wdmks/readme.txt [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/hostapi/wmme/pa_win_wmme.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/os/mac_osx/pa_mac_hostapis.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/os/unix/pa_unix_hostapis.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/os/unix/pa_unix_util.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/os/unix/pa_unix_util.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/os/win/pa_win_hostapis.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/os/win/pa_win_util.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/os/win/pa_x86_plain_converters.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/src/os/win/pa_x86_plain_converters.h [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/README.txt [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/debug_convert.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/debug_dither_calc.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/debug_dual.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/debug_multi_in.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/debug_multi_out.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/debug_record.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/debug_record_reuse.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/debug_sine.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/debug_sine_amp.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/debug_sine_formats.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/debug_srate.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/debug_test1.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/pa_devs.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/pa_fuzz.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/pa_minlat.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/paqa_devs.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/paqa_errs.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest1.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_buffer.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_callbackstop.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_clip.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_dither.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_hang.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_in_overflow.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_latency.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_leftright.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_longsine.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_many.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_maxsines.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_mono.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_mono_asio_channel_select.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_multi_sine.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_out_underflow.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_pink.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_prime.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_read_record.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_read_write_wire.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_record.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_ringmix.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_saw.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_sine.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_sine8.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_sine_formats.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_sine_time.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_start_stop.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_stop.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_stop_playout.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_sync.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_toomanysines.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_two_rates.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_underflow.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_wire.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_write_sine.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/test/patest_write_stop.c [new file with mode: 0644]
utils/iaxclient/lib/portaudio/testcvs/changeme.txt [new file with mode: 0644]
utils/iaxclient/lib/portmixer/LICENSE.txt [new file with mode: 0644]
utils/iaxclient/lib/portmixer/macproj/portmixer.mcp [new file with mode: 0755]
utils/iaxclient/lib/portmixer/px_common/portmixer.h [new file with mode: 0755]
utils/iaxclient/lib/portmixer/px_mac/px_mac.c [new file with mode: 0755]
utils/iaxclient/lib/portmixer/px_mac_core/px_mac_core.c [new file with mode: 0755]
utils/iaxclient/lib/portmixer/px_none/px_none.c [new file with mode: 0755]
utils/iaxclient/lib/portmixer/px_tests/px_test.c [new file with mode: 0755]
utils/iaxclient/lib/portmixer/px_unix_oss/px_unix_oss.c [new file with mode: 0755]
utils/iaxclient/lib/portmixer/px_win_wmme/px_win_wmme.c [new file with mode: 0755]
utils/iaxclient/lib/portmixer/winproj/portmixer.vcproj [new file with mode: 0644]
utils/iaxclient/lib/sound2c.pl [new file with mode: 0755]
utils/iaxclient/lib/sox/README.sox [new file with mode: 0644]
utils/iaxclient/lib/sox/compand.c [new file with mode: 0644]
utils/iaxclient/lib/sox/resample.c [new file with mode: 0644]
utils/iaxclient/lib/sox/sox.h [new file with mode: 0644]
utils/iaxclient/lib/sox/soxcompat.c [new file with mode: 0644]
utils/iaxclient/lib/spandsp/plc.c [new file with mode: 0644]
utils/iaxclient/lib/spandsp/plc.h [new file with mode: 0644]
utils/iaxclient/lib/unixfuncs.c [new file with mode: 0644]
utils/iaxclient/lib/video.c [new file with mode: 0644]
utils/iaxclient/lib/video_portvideo.cpp [new file with mode: 0644]
utils/iaxclient/lib/video_portvideo.h [new file with mode: 0644]
utils/iaxclient/lib/win/devcpp/iaxclient.dev [new file with mode: 0644]
utils/iaxclient/lib/win/iaxclient.def [new file with mode: 0644]
utils/iaxclient/lib/win/iaxclient_dll.c [new file with mode: 0644]
utils/iaxclient/lib/win/iaxclient_dll.def [new file with mode: 0644]
utils/iaxclient/lib/win/vc6/all.dsp [new file with mode: 0644]
utils/iaxclient/lib/win/vc6/iaxclient_lib.dsw [new file with mode: 0644]
utils/iaxclient/lib/win/vs2003/iaxclient_dll.vcproj [new file with mode: 0644]
utils/iaxclient/lib/win/vs2003/iaxclient_lib.sln [new file with mode: 0644]
utils/iaxclient/lib/win/vs2003/iaxclient_lib.vcproj [new file with mode: 0644]
utils/iaxclient/lib/win/vs2005/iaxclient_dll.vcproj [new file with mode: 0644]
utils/iaxclient/lib/win/vs2005/iaxclient_lib.sln [new file with mode: 0644]
utils/iaxclient/lib/win/vs2005/iaxclient_lib.vcproj [new file with mode: 0644]
utils/iaxclient/lib/wince/inttypes.h [new file with mode: 0644]
utils/iaxclient/lib/winfuncs.c [new file with mode: 0644]

index 7088f0ec5aeb3842284d3c5b7cf6506711ad498d..2e3fbf522b3d17ef8d6e52a56ce174480d0db991 100644 (file)
@@ -149,6 +149,7 @@ option(WITH_FGPANEL      "Set to ON to build the fgpanel application (default)"
 option(ENABLE_FGVIEWER   "Set to ON to build the fgviewer application (default)" ON)
 option(ENABLE_GPSSMOOTH  "Set to ON to build the GPSsmooth application (default)" ON)
 option(ENABLE_TERRASYNC  "Set to ON to build the terrasync application (default)" ON)
+option(ENABLE_IAX        "Set to ON to build the IAXClient library (default)" ON)
 
 option(ENABLE_FGJS       "Set to ON to build the fgjs application (default)" ON)
 option(ENABLE_JS_DEMO    "Set to ON to build the js_demo application (default)" ON)
@@ -347,8 +348,14 @@ include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS}
     ${SIMGEAR_INCLUDE_DIR}
     ${PLIB_INCLUDE_DIR} )
 
+include_directories(${PROJECT_SOURCE_DIR})
 include_directories(${PROJECT_SOURCE_DIR}/src)
-
+if(ENABLE_IAX)
+    include_directories(${PROJECT_SOURCE_DIR}/utils/fgcom/iaxclient/lib)
+    if(WIN32)
+        include_directories(${PROJECT_SOURCE_DIR}/utils/fgcom/iaxclient/lib/libiax2/src)
+    endif()
+endif()
 # following is needed, because config.h is include 'bare', whereas
 # version.h is included as <Include/version.h> - this should be cleaned up
 include_directories(${PROJECT_BINARY_DIR}/src)
@@ -379,8 +386,8 @@ if (EMBEDDED_SIMGEAR)
     include_directories(${PROJECT_BINARY_DIR}/simgear)
 endif(EMBEDDED_SIMGEAR)
 
-add_subdirectory(src)
 add_subdirectory(utils)
+add_subdirectory(src)
 add_subdirectory(man)
 
 #-----------------------------------------------------------------------------
diff --git a/package/IRIX/FlightGear.idb b/package/IRIX/FlightGear.idb
deleted file mode 100644 (file)
index 2fba90c..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-d 0755 erik user opt/FlightGear-0.9.4/bin opt/FlightGear-0.9.4/bin FlightGear.sw.base_R10k
-d 0755 erik user opt/FlightGear-0.9.4/bin opt/FlightGear-0.9.4/bin FlightGear.sw.base_R4k
-f 0755 erik user opt/FlightGear-0.9.4/bin/est-epsilon opt/FlightGear-0.9.4/bin/est-epsilon FlightGear.sw.optional
-f 0755 erik user opt/FlightGear-0.9.4/bin/fgadmin opt/FlightGear-0.9.4/bin/fgadmin FlightGear.sw.admin removeop("if [ -x $rbase/usr/sbin/iconcatalogedit ]; then chroot $rbase /usr/sbin/iconcatalogedit -remove 'Category:File Name:/opt/FlightGear-0.9.4/bin/fgadmin'  -syspage Freeware;  fi;") exitop("if [ -x $rbase/usr/sbin/iconcatalogedit ]; then chroot $rbase /usr/sbin/iconcatalogedit -add 'Category:File Name:/opt/FlightGear-0.9.4/bin/fgadmin'  -syspage Freeware;  fi;")
-f 0755 erik user opt/FlightGear-0.9.4/bin/fgfs opt/FlightGear-0.9.4/bin/fgfs FlightGear.sw.base_R4k
-f 0755 erik user opt/FlightGear-0.9.4/bin/fgfs opt/FlightGear-0.9.4/bin/fgfs.10k FlightGear.sw.base_R10k
-f 0755 erik user opt/FlightGear-0.9.4/bin/fgjs opt/FlightGear-0.9.4/bin/fgjs FlightGear.sw.optional
-f 0755 erik user opt/FlightGear-0.9.4/bin/fgrun opt/FlightGear-0.9.4/bin/fgrun FlightGear.sw.admin removeop("if [ -x $rbase/usr/sbin/iconcatalogedit ]; then chroot $rbase /usr/sbin/iconcatalogedit -remove 'Category:File Name:/opt/FlightGear-0.9.4/bin/fgrun'  -syspage Freeware;  fi;") exitop("if [ -x $rbase/usr/sbin/iconcatalogedit ]; then chroot $rbase /usr/sbin/iconcatalogedit -add 'Category:File Name:/opt/FlightGear-0.9.4/bin/fgrun'  -syspage Freeware;  fi;")
-f 0755 erik user opt/FlightGear-0.9.4/bin/gl-info opt/FlightGear-0.9.4/bin/gl-info FlightGear.sw.optional
-f 0755 erik user opt/FlightGear-0.9.4/bin/js_demo opt/FlightGear-0.9.4/bin/js_demo FlightGear.sw.optional
-f 0755 erik user opt/FlightGear-0.9.4/bin/metar opt/FlightGear-0.9.4/bin/metar FlightGear.sw.optional
-f 0755 erik user opt/FlightGear-0.9.4/bin/terrasync opt/FlightGear-0.9.4/bin/terrasync FlightGear.sw.terrasync
-f 0755 erik user opt/FlightGear-0.9.4/bin/yasim opt/FlightGear-0.9.4/bin/yasim FlightGear.sw.optional
-d 0755 erik user opt/FlightGear-0.9.4/man opt/FlightGear-0.9.4/man FlightGear.man.manpages
-d 0755 erik user opt/FlightGear-0.9.4/man/man1 opt/FlightGear-0.9.4/man/man1 FlightGear.man.manpages
-f 0644 erik user opt/FlightGear-0.9.4/man/man1/est-epsilon.1 opt/FlightGear-0.9.4/man/man1/est-epsilon.1 FlightGear.man.manpages
-f 0644 erik user opt/FlightGear-0.9.4/man/man1/fgfs.1 opt/FlightGear-0.9.4/man/man1/fgfs.1 FlightGear.man.manpages
-f 0644 erik user opt/FlightGear-0.9.4/man/man1/fgjs.1 opt/FlightGear-0.9.4/man/man1/fgjs.1 FlightGear.man.manpages
-f 0644 erik user opt/FlightGear-0.9.4/man/man1/gl-info.1 opt/FlightGear-0.9.4/man/man1/gl-info.1 FlightGear.man.manpages
-f 0644 erik user opt/FlightGear-0.9.4/man/man1/js_demo.1 opt/FlightGear-0.9.4/man/man1/js_demo.1 FlightGear.man.manpages
-f 0644 erik user opt/FlightGear-0.9.4/man/man1/pstest.1 opt/FlightGear-0.9.4/man/man1/pstest.1 FlightGear.man.manpages
-d 0755 erik user opt/FlightGear-0.9.4/sbin opt/FlightGear-0.9.4/sbin FlightGear.sw.servers
-f 0755 erik user opt/FlightGear-0.9.4/sbin/js_server opt/FlightGear-0.9.4/sbin/js_server FlightGear.sw.servers
index 3963d71e9e68f4c86a67207f8e05872b6b6034ec..af5115d74610b1494c1451ab9655762ba8a89cff 100644 (file)
@@ -40,3 +40,5 @@
 #cmakedefine FG_JPEG_SERVER
 
 #cmakedefine SYSTEM_SQLITE
+
+#cmakedefine ENABLE_IAX
index dceb3db3c7527510cf18a274bcacd3633e34b2b9..bb996cad3eede7749d585a610a0a924dc97cd3d2 100644 (file)
@@ -91,7 +91,9 @@ if(ENABLE_JSBSIM)
     
     target_link_libraries(fgfs JSBSim)
 endif()
-
+if(ENABLE_IAX)
+    target_link_libraries(fgfs iaxclient_lib ${OPENAL_LIBRARY})
+endif()
 if(FG_HAVE_GPERFTOOLS)
     include_directories(${GooglePerfTools_INCLUDE_DIR})
     target_link_libraries(fgfs ${GooglePerfTools_LIBRARIES})
index 632998d5652ae4c2f5ca4d417c41f5bf5048a3da..76e14cd67ba15bc0c46c87e2b688005b8804c429 100644 (file)
 #include <Instrumentation/HUD/HUD.hxx>
 #include <Cockpit/cockpitDisplayManager.hxx>
 #include <Network/HTTPClient.hxx>
+#include <Network/fgcom.hxx>
 
 #include "fg_init.hxx"
 #include "fg_io.hxx"
@@ -741,6 +742,13 @@ void fgCreateSubsystems() {
     globals->add_subsystem("voice", new FGVoiceMgr, SGSubsystemMgr::DISPLAY);
 #endif
 
+#ifdef ENABLE_IAX
+    ////////////////////////////////////////////////////////////////////
+    // Initialize the FGCom subsystem.
+    ////////////////////////////////////////////////////////////////////
+    globals->add_subsystem("fgcom", new FGCom);
+#endif
+
     ////////////////////////////////////////////////////////////////////
     // Initialize the lighting subsystem.
     ////////////////////////////////////////////////////////////////////
index 2e7b02f550b1b8cddcc00d67aef4896db380285a..b85ef26b0b87aa0ea74f977d6eef0557e442d46f 100644 (file)
@@ -185,6 +185,7 @@ fgSetDefaults ()
     fgSetBool("/sim/panel/visibility", true);
     fgSetBool("/sim/sound/enabled", true);
     fgSetBool("/sim/sound/working", true);
+    fgSetBool("/sim/fgcom/enabled", false);
 
                                // Flight Model options
     fgSetString("/sim/flight-model", "jsb");
@@ -1490,6 +1491,10 @@ struct OptionDesc {
     {"aircraft",                     true,  OPTION_STRING, "/sim/aircraft", false, "", 0 },
     {"vehicle",                      true,  OPTION_STRING, "/sim/aircraft", false, "", 0 },
     {"failure",                      true,  OPTION_FUNC | OPTION_MULTI,   "", false, "", fgOptFailure },
+#ifdef ENABLE_IAX
+    {"enable-fgcom",                 false, OPTION_BOOL,   "/sim/fgcom/enabled", true, "", 0 },
+    {"disable-fgcom",                false, OPTION_BOOL,   "/sim/fgcom/enabled", false, "", 0 },
+#endif
     {"com1",                         true,  OPTION_DOUBLE, "/instrumentation/comm[0]/frequencies/selected-mhz", false, "", 0 },
     {"com2",                         true,  OPTION_DOUBLE, "/instrumentation/comm[1]/frequencies/selected-mhz", false, "", 0 },
     {"nav1",                         true,  OPTION_FUNC,   "", false, "", fgOptNAV1 },
index 2d2bc2c5b11201afbe57e258792ba7e83a177947..27d2e1b074f8ea85a15bbdee3a129b82a7d10313 100644 (file)
@@ -55,6 +55,11 @@ set(HEADERS
        ray.hxx
        rul.hxx
        )
+
+if(ENABLE_IAX)
+    list(APPEND SOURCES fgcom.cxx)
+    list(APPEND HEADERS fgcom.hxx)
+endif()
        
 if(FG_JPEG_SERVER)
     list(APPEND SOURCES jpg-httpd.cxx)
diff --git a/src/Network/fgcom.cxx b/src/Network/fgcom.cxx
new file mode 100644 (file)
index 0000000..e3cb98f
--- /dev/null
@@ -0,0 +1,585 @@
+// fgcom.cxx -- FGCom: Voice communication
+//
+// Written by Clement de l'Hamaide, started Mai 2013.
+//
+// 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include "fgcom.hxx"
+
+// standard library includes
+#include <cstdio>
+
+// simgear includes
+#include <simgear/compiler.h>
+#include <simgear/sg_inlines.h>
+#include <simgear/debug/logstream.hxx>
+#include <simgear/math/sg_geodesy.hxx>
+#include <simgear/timing/timestamp.hxx>
+
+// flightgear includes
+#include <Main/fg_props.hxx>
+#include <Main/globals.hxx>
+#include <ATC/CommStation.hxx>
+#include <Airports/airport.hxx>
+#include <Navaids/navlist.hxx>
+
+#include <utils/iaxclient/lib/iaxclient.h>
+
+
+#define NUM_CALLS 4
+#define MAX_RANGE 100.0
+#define MIN_RANGE  20.0
+#define DEFAULT_SERVER "fgcom.flightgear.org"
+#define IAX_DELAY 300  // delay between calls in milliseconds
+#define TEST_FREQ 910.00
+#define NULL_ICAO "ZZZZ"
+
+const int special_freq[] = { // Define some freq who need to be used with NULL_ICAO
+       911000,
+       700000,
+       123450,
+       122750,
+       121500,
+       123500,
+       121000,
+       723340 };
+
+
+FGCom::FGCom() :
+    _register(true)
+{
+  _listener_active = 0;
+}
+
+
+
+FGCom::~FGCom()
+{
+}
+
+
+
+void FGCom::bind()
+{
+  SGPropertyNode *node     = fgGetNode("/sim/fgcom", 0, true);
+  _test_node               = node->getChild( "test", 0, true );
+  _server_node             = node->getChild( "server", 0, true );
+  _enabled_node            = node->getChild( "enabled", 0, true );
+  _micBoost_node           = node->getChild( "mic-boost", 0, true );
+  _micLevel_node           = node->getChild( "mic-level", 0, true );
+  _speakerLevel_node       = node->getChild( "speaker-level", 0, true );
+  _selectedInput_node      = node->getChild( "device-input", 0, true );
+  _selectedOutput_node     = node->getChild( "device-output", 0, true );
+
+  SGPropertyNode *reg_node = node->getChild("register", 0, true);
+  _register_node           = reg_node->getChild( "enabled", 0, true );
+  _username_node           = reg_node->getChild( "username", 0, true );
+  _password_node           = reg_node->getChild( "password", 0, true );
+
+  //_nav0_node               = fgGetNode("/instrumentation/nav[0]/frequencies/selected-mhz", true);
+  //_nav1_node               = fgGetNode("/instrumentation/nav[1]/frequencies/selected-mhz", true);
+  _comm0_node              = fgGetNode("/instrumentation/comm[0]/frequencies/selected-mhz", true);
+  //_comm1_node              = fgGetNode("/instrumentation/comm[1]/frequencies/selected-mhz", true);
+  _ptt0_node               = fgGetNode("/instrumentation/comm[0]/ptt", true); //FIXME: what about /instrumentation/comm[1]/ptt ?
+  _callsign_node           = fgGetNode("/sim/multiplay/callsign", true);
+
+  // Set default values if not provided
+  if ( !_enabled_node->hasValue() )
+      _enabled_node->setBoolValue(true);
+
+  if ( !_test_node->hasValue() )
+      _test_node->setBoolValue(false);
+
+  if ( !_micBoost_node->hasValue() )
+      _micBoost_node->setIntValue(1);
+
+  if ( !_server_node->hasValue() )
+      _server_node->setStringValue(DEFAULT_SERVER);
+
+  if ( !_speakerLevel_node->hasValue() )
+      _speakerLevel_node->setFloatValue(1.0);
+
+  if ( !_micLevel_node->hasValue() )
+      _micLevel_node->setFloatValue(1.0);
+
+  if ( !_register_node->hasValue() )
+      _register_node->setBoolValue(false);
+
+  if ( !_username_node->hasValue() )
+      _username_node->setStringValue("guest");
+
+  if ( !_password_node->hasValue() )
+      _password_node->setStringValue("guest");
+
+  _selectedOutput_node->addChangeListener(this);
+  _selectedInput_node->addChangeListener(this);
+  _speakerLevel_node->addChangeListener(this);
+  _micBoost_node->addChangeListener(this);
+  _micLevel_node->addChangeListener(this);
+  _enabled_node->addChangeListener(this);
+  _comm0_node->addChangeListener(this);
+  //_comm1_node->addChangeListener(this);
+  //_nav0_node->addChangeListener(this);
+  //_nav1_node->addChangeListener(this);
+  _ptt0_node->addChangeListener(this);
+  _test_node->addChangeListener(this);
+}
+
+
+
+void FGCom::unbind()
+{
+}
+
+
+
+void FGCom::init()
+{
+  _enabled          = _enabled_node->getBoolValue();
+  _server           = _server_node->getStringValue();
+  _register         = _register_node->getBoolValue();
+  _username         = _username_node->getStringValue();
+  _password         = _password_node->getStringValue();
+
+  _currentComm0     = _comm0_node->getDoubleValue();
+  //_currentComm1     = _comm1_node->getDoubleValue();
+  //_currentNav0      = _nav0_node->getDoubleValue();
+  //_currentNav1      = _nav1_node->getDoubleValue();
+
+  _comm0Changed     = false;
+  //_comm1Changed     = false;
+  //_nav0Changed      = false;
+  //_nav1Changed      = false;
+}
+
+
+
+void FGCom::postinit()
+{
+    if( !_enabled ) {
+        return;
+    }
+    
+    //WARNING: this _must_ be executed after sound system is totally initialized !
+    if( iaxc_initialize(NUM_CALLS) ) {
+        SG_LOG(SG_IO, SG_ALERT, "FGCom: cannot initialize iaxclient!");
+        _enabled = false;
+        return;
+    }
+    
+    // FIXME: To be implemented in IAX audio driver
+    //iaxc_mic_boost_set( _micBoost_node->getIntValue() );
+    iaxc_set_formats( IAXC_FORMAT_GSM, IAXC_FORMAT_GSM );
+    iaxc_start_processing_thread ();
+    
+    if ( _register ) {
+      _regId = iaxc_register( const_cast<char*>(_username.c_str()),
+                              const_cast<char*>(_password.c_str()),
+                              const_cast<char*>(_server.c_str()) );
+        if( _regId == -1 ) {
+            SG_LOG(SG_IO, SG_INFO, "FGCom: cannot register iaxclient!");
+            return;
+        }
+    }
+
+    /*
+      Here we will create the list of available audio devices
+      Each audio device has a name, an ID, and a list of capabilities
+      If an audio device can output sound, available-output=true 
+      If an audio device can input sound, available-input=true 
+
+      /sim/fgcom/selected-input (int)
+      /sim/fgcom/selected-output (int)
+
+      /sim/fgcom/device[n]/id (int)
+      /sim/fgcom/device[n]/name (string)
+      /sim/fgcom/device[n]/available-input (bool)
+      /sim/fgcom/device[n]/available-output (bool)
+    */
+
+    //FIXME: OpenAL driver use an hard-coded device
+    //       so all following is unused finally until someone
+    //       implement "multi-device" support in IAX audio driver
+    SGPropertyNode *node     = fgGetNode("/sim/fgcom", 0, true);
+
+    struct iaxc_audio_device *devs;
+    int nDevs, input, output, ring;
+
+    iaxc_audio_devices_get(&devs,&nDevs, &input, &output, &ring);
+
+    for(int i=0; i<nDevs; i++ ) {
+      SGPropertyNode *in_node = node->getChild("device", i, true);
+
+      // devID
+      _deviceID_node[i] = in_node->getChild("id", 0, true);
+      _deviceID_node[i]->setIntValue(devs[i].devID);
+
+      // name
+      _deviceName_node[i] = in_node->getChild("name", 0, true);
+      _deviceName_node[i]->setStringValue(devs[i].name);
+
+      // input capability
+      _deviceInput_node[i] = in_node->getChild("available-input", 0, true);
+      if( devs[i].capabilities & IAXC_AD_INPUT )
+        _deviceInput_node[i]->setBoolValue(true);
+      else 
+        _deviceInput_node[i]->setBoolValue(false);
+
+      // output capability
+      _deviceOutput_node[i] = in_node->getChild("available-output", 0, true);
+      if( devs[i].capabilities & IAXC_AD_OUTPUT )
+        _deviceOutput_node[i]->setBoolValue(true);
+      else 
+        _deviceOutput_node[i]->setBoolValue(false);
+
+      // use default device at start
+      if( devs[i].capabilities & IAXC_AD_INPUT_DEFAULT )
+        _selectedInput_node->setIntValue(devs[i].devID);
+      if( devs[i].capabilities & IAXC_AD_OUTPUT_DEFAULT )
+        _selectedOutput_node->setIntValue(devs[i].devID);
+    }
+
+    iaxc_millisleep(50);
+
+    // Do the first call at start
+    const double freq = _comm0_node->getDoubleValue();
+    std::string num = computePhoneNumber(freq, getAirportCode(freq));
+    if( num.size() > 0 ) {
+      SG_LOG( SG_IO, SG_INFO, "FGCom comm[0] number=" << num );
+      _callComm0 = iaxc_call(num.c_str());
+    }
+    if( _callComm0 == -1 )
+      SG_LOG( SG_IO, SG_ALERT, "FGCom cannot call selected freq" );
+}
+
+
+
+void FGCom::updateCall(bool& changed, int& callNo, double freqMHz)
+{
+    if (!changed) {
+        if( !isInRange(freqMHz) ) {
+            iaxc_dump_call_number(callNo);
+            callNo = -1;
+            return;
+        } else {
+            if(callNo != -1)
+                return;
+        }
+    }
+    
+    SG_LOG( SG_IO, SG_INFO, "FGCom manage change" );
+    changed = false; // FIXME, out-params are confusing
+
+    if( callNo != -1 ) {
+        iaxc_dump_call_number( callNo );
+        callNo = -1;
+    }
+
+    if(_p.elapsedMSec() > IAX_DELAY) {
+        std::string num = computePhoneNumber(freqMHz, getAirportCode(freqMHz));
+        if( !isInRange(freqMHz) )
+            return;
+        if( !num.empty() ) {
+            SG_LOG( SG_IO, SG_INFO, "FGCom number=" << num );
+            callNo = iaxc_call_ex(num.c_str(), _callsign.c_str(), NULL, 0 /* no video */);
+
+            if( callNo == -1 )
+                SG_LOG( SG_IO, SG_ALERT, "FGCom cannot call selected freq" );
+        }
+    } else {
+        changed = true;
+    }
+}
+
+
+
+void FGCom::update(double dt)
+{
+    if ( !_enabled ) {
+        return;
+    }
+    // For now we manage FGCom for only one freq because IAXClient
+    // is not able to handle multiple calls at same time.
+    updateCall(_comm0Changed, _callComm0, _comm0_node->getDoubleValue());
+    // updateCall(_comm1Changed, _callComm1, _comm1_node->getDoubleValue());
+    // updateCall(_nav0Changed, _callNav0, _nav0_node->getDoubleValue());
+    // updateCall(_nav1Changed, _callNav1, _nav1_node->getDoubleValue());
+}
+
+
+
+void FGCom::shutdown()
+{
+  SG_LOG( SG_IO, SG_INFO, "FGCom shutdown()" );
+  _enabled = false;
+
+  iaxc_unregister(_regId);
+  iaxc_stop_processing_thread();
+  iaxc_shutdown();
+}
+
+
+
+void FGCom::valueChanged(SGPropertyNode *prop)
+{
+  if (prop == _enabled_node) {
+    SG_LOG( SG_IO, SG_INFO, "FGCom enabled= " << prop->getBoolValue() );
+    if( prop->getBoolValue() ) {
+      init();
+      postinit();
+    } else {
+      shutdown();
+    }
+    return;
+  }
+
+  if (prop == _ptt0_node && _enabled) {
+    if( _ptt0_node->getBoolValue() ) {
+      iaxc_input_level_set( _micLevel_node->getFloatValue() ); //0.0 = min , 1.0 = max
+      iaxc_output_level_set( 0.0 );
+    } else {
+      iaxc_input_level_set( 0.0 );
+      iaxc_output_level_set( _speakerLevel_node->getFloatValue() );
+    }
+  }
+
+  if (prop == _test_node) {
+    SG_LOG( SG_IO, SG_INFO, "FGCom test= " << prop->getBoolValue() );
+    testMode( prop->getBoolValue() );
+    return;
+  }
+
+  //FIXME: not implemented in IAX audio driver (audio_openal.c)
+  if (prop == _micBoost_node && _enabled) {
+    int micBoost = prop->getIntValue();
+    SG_LOG( SG_IO, SG_INFO, "FGCom mic-boost= " << micBoost );
+    SG_CLAMP_RANGE<int>( micBoost, 0, 1 );
+    iaxc_mic_boost_set( micBoost ) ; // 0 = enabled , 1 = disabled
+    return;
+  }
+
+  //FIXME: not implemented in IAX audio driver (audio_openal.c)
+  if ((prop == _selectedInput_node || prop == _selectedOutput_node) && _enabled) {
+    int selectedInput = _selectedInput_node->getIntValue();
+    int selectedOutput = _selectedOutput_node->getIntValue();
+    SG_LOG( SG_IO, SG_INFO, "FGCom selected-input= " << selectedInput );
+    SG_LOG( SG_IO, SG_INFO, "FGCom selected-output= " << selectedOutput );
+    iaxc_audio_devices_set(selectedInput, selectedOutput, 0);
+    return;
+  }
+
+  if (_listener_active)
+    return;
+
+  _listener_active++;
+
+  if (prop == _speakerLevel_node && _enabled) {
+    float speakerLevel = prop->getFloatValue();
+    SG_LOG( SG_IO, SG_INFO, "FGCom speaker-level= " << speakerLevel );
+    SG_CLAMP_RANGE<float>( speakerLevel, 0.0, 1.0 );
+    _speakerLevel_node->setFloatValue(speakerLevel);
+    iaxc_output_level_set(speakerLevel);
+  }
+
+  if (prop == _micLevel_node && _enabled) {
+    float micLevel = prop->getFloatValue();
+    SG_LOG( SG_IO, SG_INFO, "FGCom mic-level= " << micLevel );
+    SG_CLAMP_RANGE<float>( micLevel, 0.0, 1.0 );
+    _micLevel_node->setFloatValue(micLevel);
+    iaxc_input_level_set(micLevel);
+  }
+
+  if (prop == _comm0_node) {
+    if( _currentComm0 != prop->getDoubleValue() ) {
+      SG_LOG( SG_IO, SG_INFO, "FGCom comm[0]/freq= " << prop->getDoubleValue() );
+      _currentComm0 = prop->getDoubleValue();
+      _p.stamp();
+      _comm0Changed = true;
+    }
+  }
+/*
+  if (prop == _comm1_node) {
+    if( _currentComm1 != prop->getDoubleValue() ) {
+      SG_LOG( SG_IO, SG_INFO, "FGCom comm[1]/freq= " << prop->getDoubleValue() );
+      _currentComm1 = prop->getDoubleValue();
+      _p.stamp();
+      _comm1Changed = true;
+    }
+  }
+
+  if (prop == _nav0_node) {
+    if( _currentNav0 != prop->getDoubleValue() ) {
+      SG_LOG( SG_IO, SG_INFO, "FGCom nav[0]/freq= " << prop->getDoubleValue() );
+      _currentNav0 = prop->getDoubleValue();
+      _nav0Changed = true;
+    }
+  }
+
+  if (prop == _nav1_node) {
+    if( _currentNav1 != prop->getDoubleValue() ) {
+      SG_LOG( SG_IO, SG_INFO, "FGCom nav[1]/freq= " << prop->getDoubleValue() );
+      _currentNav1 = prop->getDoubleValue();
+      _nav1Changed = true;
+    }
+  }
+*/
+
+  _listener_active--;
+}
+
+
+
+void FGCom::testMode(bool testMode)
+{
+  if(testMode) {
+    _enabled = false;
+    iaxc_dump_call_number(_callComm0);
+    iaxc_input_level_set( _micLevel_node->getFloatValue() );
+    iaxc_output_level_set( _speakerLevel_node->getFloatValue() );
+    std::string num = computePhoneNumber(TEST_FREQ, NULL_ICAO);
+    if( num.size() > 0 ) {
+      SG_LOG( SG_IO, SG_INFO, "FGCom test mode =" << num );
+      iaxc_millisleep(IAX_DELAY);
+      _callComm0 = iaxc_call(num.c_str());
+    }
+    if( _callComm0 == -1 )
+      SG_LOG( SG_IO, SG_ALERT, "FGCom cannot call selected freq (test mode)" );
+  } else {
+    iaxc_dump_call_number(_callComm0);
+    iaxc_millisleep(IAX_DELAY);
+    _callComm0 = -1;
+    _enabled = true;
+  }
+}
+
+
+
+/*
+  \param freq The requested frequency e.g 120.825
+  \return The ICAO code as string e.g LFMV
+*/
+
+std::string FGCom::getAirportCode(const double& freq)
+{
+  SGGeod aircraftPos = globals->get_aircraft_position();
+
+  int freqKhz = 10 * static_cast<int>(freq * 100 + 0.25);
+
+  for(size_t i=0; i<sizeof(special_freq)/sizeof(special_freq[0]); i++) { // Check if it's a special freq
+    if(special_freq[i] == freqKhz) {
+      SG_LOG( SG_IO, SG_INFO, "FGCom getAirportCode: " << freqKhz << " is specially associated to " << NULL_ICAO );
+      return NULL_ICAO;
+    }
+  }
+
+  flightgear::CommStation* apt = flightgear::CommStation::findByFreq(freqKhz, aircraftPos);
+  if( !apt ) {
+    SG_LOG( SG_IO, SG_INFO, "FGCom getAirportCode: not found" );
+    return std::string();
+  }
+  SG_LOG( SG_IO, SG_INFO, "FGCom getAirportCode: found " << apt->airport()->ident() );
+
+  _aptPos = apt->geod();
+  return apt->airport()->ident();
+}
+
+
+
+/*
+  \param freq The requested frequency e.g 112.7
+  \return The ICAO code as string e.g ITS
+*/
+/*
+std::string FGCom::getVorCode(const double& freq) const
+{
+  SGGeod aircraftPos = globals->get_aircraft_position();
+  FGNavList::TypeFilter filter(FGPositioned::VOR);
+
+  FGNavRecord* vor = FGNavList::findByFreq( freq, aircraftPos, &filter);
+  if( !vor ) {
+    SG_LOG( SG_IO, SG_INFO, "FGCom getVorCode: not found" );
+    return std::string();
+  }
+  SG_LOG( SG_IO, SG_INFO, "FGCom getVorCode: found " << vor->get_ident(); );
+
+  return vor->get_ident();
+}
+*/
+
+
+/*
+  \param freq The requested frequency e.g 120.825
+  \param iaco The associated ICAO code e.g LFMV
+  \return The phone number as string i.e username:password@fgcom.flightgear.org/0176707786120825
+*/
+
+std::string FGCom::computePhoneNumber(const double& freq, const std::string& icao) const
+{
+  if( icao.empty() )
+    return std::string(); 
+
+  char phoneNumber[256];
+  char exten[32];
+  char tmp[5];
+
+  /*Convert ICAO to ASCII */
+  sprintf( tmp, "%4s", icao.c_str() );
+
+  /*Built the phone number */
+  sprintf( exten,
+           "%02d%02d%02d%02d%02d%06d",
+           01,
+           tmp[0],
+          tmp[1],
+           tmp[2],
+           tmp[3],
+          (int) (freq * 1000 + 0.5) );
+  exten[16] = '\0';
+
+  snprintf( phoneNumber,
+            sizeof (phoneNumber),
+            "%s:%s@%s/%s",
+            _username.c_str(),
+            _password.c_str(),
+           _server.c_str(),
+            exten);
+
+  return phoneNumber;
+}
+
+
+
+/*
+  \return A boolean value, 1=in range, 0=out of range
+*/
+
+bool FGCom::isInRange(const double &freq) const
+{
+    SGGeod acftPos = globals->get_aircraft_position();
+    double distNm = SGGeodesy::distanceNm(_aptPos, acftPos);
+    double delta_elevation_ft = fabs(acftPos.getElevationFt() - _aptPos.getElevationFt());
+    double rangeNm = 1.23 * sqrt(delta_elevation_ft);
+
+    if (rangeNm > MAX_RANGE) rangeNm = MAX_RANGE;
+    if (rangeNm < MIN_RANGE) rangeNm = MIN_RANGE;
+    if( distNm > rangeNm )   return 0;
+    return 1;
+}
+
+
diff --git a/src/Network/fgcom.hxx b/src/Network/fgcom.hxx
new file mode 100644 (file)
index 0000000..0025d3f
--- /dev/null
@@ -0,0 +1,102 @@
+#ifndef FG_FGCOM_HXX
+#define FG_FGCOM_HXX
+
+// fgcom.hxx -- FGCom: Voice communication
+//
+// Written by Clement de l'Hamaide, started Mai 2013.
+//
+// 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+#include <simgear/structure/subsystem_mgr.hxx>
+#include <simgear/props/props.hxx>
+#include <simgear/math/sg_geodesy.hxx>
+
+class FGCom : public SGSubsystem, public SGPropertyChangeListener
+{
+  public:
+    FGCom();
+    virtual ~FGCom();
+
+    virtual void bind();
+    virtual void unbind();
+    virtual void init();
+    virtual void postinit();
+    virtual void update(double dt);
+    virtual void valueChanged(SGPropertyNode *prop);
+    virtual void shutdown();
+
+  private:
+
+    SGPropertyNode_ptr _ptt0_node;                            // instrumentation/nav[0]/ptt
+    //SGPropertyNode_ptr _nav0_node;                          // instrumentation/nav[0]/frequencies/selected-mhz
+    //SGPropertyNode_ptr _nav1_node;                          // instrumentation/nav[1]/frequencies/selected-mhz
+    SGPropertyNode_ptr _comm0_node;                           // instrumentation/comm[0]/frequencies/selected-mhz
+    //SGPropertyNode_ptr _comm1_node;                         // instrumentation/comm[1]/frequencies/selected-mhz
+    SGPropertyNode_ptr _test_node;                            // sim/fgcom/test
+    SGPropertyNode_ptr _server_node;                          // sim/fgcom/server
+    SGPropertyNode_ptr _enabled_node;                         // sim/fgcom/enabled
+    SGPropertyNode_ptr _micBoost_node;                        // sim/fgcom/mic-boost
+    SGPropertyNode_ptr _callsign_node;                        // sim/multiplay/callsign
+    SGPropertyNode_ptr _register_node;                        // sim/fgcom/register/enabled
+    SGPropertyNode_ptr _username_node;                        // sim/fgcom/register/username
+    SGPropertyNode_ptr _password_node;                        // sim/fgcom/register/password
+    SGPropertyNode_ptr _micLevel_node;                        // sim/fgcom/mic-level
+    SGPropertyNode_ptr _speakerLevel_node;                    // sim/fgcom/speaker-level
+    SGPropertyNode_ptr _deviceID_node[4];                     // sim/fgcom/device[n]/id
+    SGPropertyNode_ptr _deviceName_node[4];                   // sim/fgcom/device[n]/name
+    SGPropertyNode_ptr _deviceInput_node[4];                  // sim/fgcom/device[n]/available-input
+    SGPropertyNode_ptr _deviceOutput_node[4];                 // sim/fgcom/device[n]/available-output
+    SGPropertyNode_ptr _selectedInput_node;                   // sim/fgcom/device-input
+    SGPropertyNode_ptr _selectedOutput_node;                  // sim/fgcom/device-output
+
+
+
+    double   _currentComm0;
+    //double   _currentComm1;
+    //double   _currentNav0;
+    //double   _currentNav1;
+    //bool     _nav0Changed;
+    //bool     _nav1Changed;
+    bool     _comm0Changed;
+    //bool     _comm1Changed;
+    bool     _register;
+    bool     _enabled;
+    int      _regId;
+    //int      _callNav0;
+    //int      _callNav1;
+    int      _callComm0;
+    //int      _callComm1;
+    int      _listener_active;
+    std::string   _server;
+    std::string   _callsign;
+    std::string   _username;
+    std::string   _password;
+    SGTimeStamp   _p;
+    SGGeod        _aptPos;
+
+    std::string   computePhoneNumber(const double& freq, const std::string& icao) const;
+    std::string   getAirportCode(const double& freq);
+    //std::string   getVorCode(const double& freq) const;
+    SGGeod        getAirportPos(const double& freq) const;
+    bool          isInRange(const double& freq) const;
+    
+    void updateCall(bool& changed, int& callNo, double freqMHz);
+    void testMode(bool testMode);
+
+};
+
+#endif // of FG_FGCOM_HXX
+
+
index 0775c2719fa535b2e2ecd4581e75a2ad0f3209ba..d920d1fcfae0393b6da6f4db13b32ea1fe89b9c7 100644 (file)
@@ -29,4 +29,10 @@ endif()
 
 if(ENABLE_TERRASYNC)
     add_subdirectory(TerraSync)
-endif()
\ No newline at end of file
+endif()
+
+if(ENABLE_IAX)
+    add_subdirectory(iaxclient/lib)
+#    add_subdirectory(iaxclient)
+    message(STATUS "IAXClient: ENABLED")
+endif()
diff --git a/utils/iaxclient/COPYING.LIB b/utils/iaxclient/COPYING.LIB
new file mode 100644 (file)
index 0000000..c4792dd
--- /dev/null
@@ -0,0 +1,515 @@
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations
+below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+^L
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it
+becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+^L
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control
+compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+^L
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+^L
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+^L
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+^L
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply, and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License
+may add an explicit geographical distribution limitation excluding those
+countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+^L
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+^L
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms
+of the ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.
+It is safest to attach them to the start of each source file to most
+effectively convey the exclusion of warranty; and each file should
+have at least the "copyright" line and a pointer to where the full
+notice is found.
+
+
+    <one line to give the library's name and a brief idea of what it
+does.>
+    Copyright (C) <year>  <name of author>
+
+    This library 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 of the License, or (at your option) any later version.
+
+    This library 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 library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+
+Also add information on how to contact you by electronic and paper
+mail.
+
+You should also get your employer (if you work as a programmer) or
+your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James
+Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/utils/iaxclient/README b/utils/iaxclient/README
new file mode 100644 (file)
index 0000000..c84ccec
--- /dev/null
@@ -0,0 +1,259 @@
+=======================================================================
+INTRODUCTION
+
+This is iaxclient, a portable IAX/IAX2 protocol telephony client library.
+
+The library itself is in the directory "lib", located in the same
+directory as this README file.
+
+The library is designed to build for multiple platforms, and currently
+supports Linux, MacOSX, Solaris, and Win32 platforms.  It is designed to handle
+the "backend" of IAX telephony operations, including call handling,
+network protocols, audio encoding/decoding, and audio capture/playback.
+In it's future, it may be extended to also handle video encode, decode,
+capture and playback.
+
+There are also sample clients, which use the library, included here.
+
+Currently, these are all stored under the "simpleclient" directory, and
+there are three of them:
+
+simpleclient/testcall:  A simple command-line oriented test program,
+                       useful for testing and debugging.   It supports 
+                       all of the same platforms as the library itself.
+
+simpleclient/wx:       A wxWindows (see wxwindows.org) based GUI
+                       client.  This client also supports all of the
+                       same platforms as the library itself.
+
+simpleclient/WinIAX:   A MSVC/Win32 client.  This only works with
+                       Win32, obviously, and was contributed by
+                       Faizan "Tili" Naqvi <faizan@tilizone.com>
+
+simpleclient/tkiaxphone        A command-line client, with a Tcl/Tk GUI
+                       client that drives it.  It should work on
+                       all the platforms
+
+
+The home page for iaxclient is "http://iaxclient.sourceforge.net/"
+
+Up-to-date versions of iaxclient are available from a sourceforge SVN
+repository.
+
+CVS tarballs are also available as a link from the home page.
+
+
+=======================================================================
+LICENSES
+
+
+The iaxclient library itself, is provided under the terms of the LGPL:
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+    MA 02111-1307, USA
+
+The iaxclient library may also include, when compiled, works distributed
+under other licenses.  See those directories and source files for
+specifics.  These include:
+
+    libiax:            (c) 2001 Mark Spencer under the LGPL.
+    libiax2:           (c) 2001 Mark Spencer under the LGPL.
+    gsm encoder:       Copyright 1992, 1993, 1994 by Jutta Degener 
+                       and Carsten Bormann, Technische Universitaet Berlin
+                       (free license, terms in gsm/copyright)
+    portaudio:         Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+                       Modified BSD style license, in portaudio/LICENSE.txt
+
+    sox tools:                 compand.c: Copyright 1999 Chris Bagwell And 
+                                       Nick Bailey
+                       resample.c: (not currently used) Copyright 1991
+                       Lance Norskog And Sundry Contributors, 
+                       free licenses in source files.
+    libspeex:          (c) various authors
+                       BSD-like license.
+
+
+=======================================================================
+CONTRIBUTORS:
+
+IAXCLIENT itself was contributed to by:
+
+Steve Kann <stevek@stevek.com>
+Shawn Lawrence <shawn.lawrence@terracecomm.com>
+Faizan "Tili" Naqvi <faizan@tilizone.com> [Win32 VC++ build/client]
+Scott Lambert <lambert@lambertfam.org> [FreeBSD build changes]
+Michael Van Donselaar <mvand@vandonselaar.org> [Win32/MinGW build directions, UI changes, IAXComm phone ]
+Steven Sokol <ssokol@sokol-associates.com> [ Debugging, Blind Transfer ]
+Stephan Kauss <Stephan@kauss.org> [ 32-bit alignment for IAX2 ]
+Stephen Uhler <suhler@sun.com> [Solaris build, tkiaxphone]
+Steve Underwood <steveu@coppice.org> [PLC implementation from spandsp]
+Jean-Denis Girard <jd.girard@sysnux.pf> [URL Receive implementation]
+Panfilov Dmitry <dima@bdpu.org> [Basic ALSA-native audio driver]
+Mihai Balea <mihai at hates dot ms>
+Bill Welch <welch1820 at gmail dot com> [Project files for several MS development environments]
+
+
+In addition to including libiax, IAXCLIENT is also based in part on code
+included in test clients within libiax itself.
+
+The included sub-libraries, including libiax, libiax2, gsm, portaudio,
+and the sox-derived filters, were developed by others, as noted in above
+and in their sources.  We couldn't have built IAXCLIENT (or, it would
+have been much more difficult!) without the great work from these
+projects.
+
+=======================================================================
+BUILDING THE LIBRARY:
+
+From the "lib" directory:
+       Linux: type "make" using standard gnu make/gcc
+       FreeBSD: type "gmake" using standard gnu make/gcc
+       MacOSX: type "make" using Apple Dev Tools (gnu make/gcc)
+       Win32: type "make" using Cygwin or Cygwin and MinGW (see below)
+       Solaris: type "gmake" using standard gnu make/gcc
+
+For a shared library, make clean, then make shared.
+You should receive a shared library (.dll, .so, .dylib, depending on your platform).
+
+Win32 Cygwin/MinGW; General:
+The Win32 build has been tested using the Cygwin Environment, and the
+MinGW port of the GCC compiler suite.   Previously, we only supported
+compilation with the cygwin _and_ mingw environments installed.  We are
+moving (4/20/2005) to support having the cygwin environment alone, with
+cygwin's own mingw packages, instead.   Compilation of the basic sample
+clients (but not iaxcomm), works fine with cygwin alone.
+
+Cygwin Alone:
+To install cygwin, download and run http://www.cygwin.com/setup.exe
+You will need to install, in addition to the defaults, these packages:
+gcc-mingw, gcc-mingw-core, (and for C++ clients, gcc-mingw-g++).
+[please let the maintainers know if other non-default packages are
+required].
+
+There's lots of goodies available from cygwin.
+
+Once you have this installed, open the cygwin shell, and build.  The
+library makefiles use the -mno-cygwin option, to create native Win32
+binaries which do _not_ require cygwin.dll, or any special runtimes.
+
+Cygwin and MinGW:
+Previously, we advocated installing cygwin environment (for Gnu Make and
+such), alongside the MinGW distribution itself, as outlined here.  This
+may still be necessary for the Wx-Windows based clients like iaxcomm.
+
+http://www.mingw.org/mingwfaq.shtml#faq-usingwithcygwin for the
+MinGW FAQ entry on using MinGW with Cygwin.  You do need to make sure
+that you install the Gnu "make" utility when you install cygwin.
+
+It should probably also work if you use the MSYS environment and the
+MinGW compiler, but this configuration is not as well tested.
+
+=======================================================================
+LIBRARY ORGANIZATION/DESIGN/CODING CONVENTION NOTES
+
+The iaxclient library is designed to be a small, simple library that
+encapsulates all that you need in order to make IAX protocol telephony
+programs.
+
+All exported symbols should be prefixed with "iaxc_", to avoid namespace
+collisions/pollution in programs using this library.
+
+The header file "iaxclient.h" should contain those declarations needed
+by client programs, but not rely on other headers (i.e. those from
+included libraries).  The "iaxclient-lib.h" header file is the main
+header file for the library's internal declarations.
+
+
+=======================================================================
+
+SAMPLE CLIENTS
+
+The "testcall" sample program, provided in the simpleclient/testcall
+directory (above this "lib" directory) is a simple client program which
+should also be portable.  
+
+The Makefile for "testcall" will automatically build or update the
+library when it it built, and the requirements for building testcall are
+the same as for the library itself.
+
+
+See README files in the other sample clients for directions for building
+these.
+
+=========================================================================
+
+CODECS
+
+The codec API is pretty straightforward; just use any of the existing
+available codecs as a guide.  The only place in the main code they
+interface is the switch in audio_encode.c:create_codec
+
+ILBC
+
+Lots of people are enamored with iLBC lately, so I put this together for
+them.  Personally, I prefer speex, because it seems to sound just as
+good, but has no license restrictions.  With proper compilation options
+(i.e. use it's SSE optimizations), it can be made even faster than the
+iLBC reference.
+
+There is glue to build iaxclient with iLBC available in the source, but
+the source to iLBC itself is _not_ included.  This is primarily because
+of the licensing issues.
+
+I'm not a lawyer, but it appears that iLBC's license would make it
+impossible to build iaxclient and link it with a GPL front-end, meaning
+a library built this way is no longer something that could be considered
+LGPL.  However, you could probably build a client using iLBC and
+distribute it legally, if you follow the rules in the LGPL.  So, this is
+an issue for you and your legal counsel to figure out.
+
+To actually build iaxclient with iLBC, though is very easy.  Just make a
+directory under lib named iLBC, and drop the iLBC reference sources into
+it, then change CODEC_ILBC=0 to CODEC_ILBC=1 in the Makefile, and away
+you go.
+
+The source presently is set up for the draft-5 version.
+
+The iLBC license and software can be found here 
+http://www.ilbcfreeware.org/software.html
+(sources are also in asterisk).  
+
+=========================================================================
+
+AUDIO DRIVERS
+
+The supported audio driver for iaxclient is audio_portaudio; which uses
+a snapshot of the portaudio v19 library (included, with some minor 
+modifications) to access native audio services on each platform.  
+It includes support for Windows (WMME), Linux (OSS, ALSA, JACK) and
+MacOS X (CoreAudio). 
+
+There is a (presently broken) WMME-native audio driver which was used
+during early development, and is no longer maintained.  You probably
+don't want to use this.
+
+All three Linux PortAudio drivers are enabled by default and supporting
+libraries need to be present on the system in order to build. If you
+prefer to disable one or more of the drivers, use the USE_PA_* options
+in the main Makefile.  
+
+Dmitry Panfilov has contributed a basic native ALSA driver for Linux.
+Not all features are supported with this driver.  It is not compiled in
+by default, because this would add alsa libraries to the build and link
+dependencies -- and we don't have a good way of communicating that to
+applications (like pkg-config stuff, etc). To use it, though, you just
+need to change AUDIO_ALSA=0 to AUDIO_ALSA=1 in the Makefile.
+
+
diff --git a/utils/iaxclient/lib/CMakeLists.txt b/utils/iaxclient/lib/CMakeLists.txt
new file mode 100644 (file)
index 0000000..25936f2
--- /dev/null
@@ -0,0 +1,124 @@
+
+# even if we don't select the codec, speex is used for pre-processing audio
+set(ENABLE_SPEXX 1)
+
+set(IAXCLIENT_BASE_SOURCES
+    audio_encode.c
+    audio_file.c
+    audio_openal.c
+    codec_alaw.c
+    codec_gsm.c
+    codec_ulaw.c
+    iaxclient_lib.c
+)
+
+set(LIBIAX2_SOURCES
+    libiax2/src/iax.c
+    libiax2/src/iax2-parser.c
+    libiax2/src/jitterbuf.c
+    libiax2/src/md5.c
+)
+
+set(GSM_SOURCES
+    gsm/src/add.c
+    gsm/src/code.c
+    gsm/src/debug.c
+    gsm/src/decode.c
+    gsm/src/gsm_create.c
+    gsm/src/gsm_decode.c
+    gsm/src/gsm_destroy.c
+    gsm/src/gsm_encode.c
+    gsm/src/gsm_explode.c
+    gsm/src/gsm_implode.c
+    gsm/src/gsm_option.c
+    gsm/src/gsm_print.c
+    gsm/src/long_term.c
+    gsm/src/lpc.c
+    gsm/src/preprocess.c
+    gsm/src/rpe.c
+    gsm/src/short_term.c
+    gsm/src/table.c
+)
+
+if (WIN32)
+    list(APPEND IAXCLIENT_BASE_SOURCES winfuncs.c)
+else()
+    list(APPEND IAXCLIENT_BASE_SOURCES unixfuncs.c)
+endif(WIN32)
+
+if (ENABLE_SPEXX)
+    list(APPEND IAXCLIENT_BASE_SOURCES codec_speex.c)
+    
+    set(SPEEX_SOURCES 
+        libspeex/bits.c
+        libspeex/cb_search.c
+        libspeex/exc_10_16_table.c
+        libspeex/exc_10_32_table.c
+        libspeex/exc_20_32_table.c
+        libspeex/exc_5_256_table.c
+        libspeex/exc_5_64_table.c
+        libspeex/exc_8_128_table.c
+        libspeex/filters.c
+        libspeex/gain_table.c
+        libspeex/gain_table_lbr.c
+        libspeex/hexc_10_32_table.c
+        libspeex/hexc_table.c
+        libspeex/high_lsp_tables.c
+        libspeex/jitter.c
+        libspeex/lbr_48k_tables.c
+        libspeex/lpc.c
+        libspeex/lsp.c
+        libspeex/lsp_tables_nb.c
+        libspeex/ltp.c
+        libspeex/math_approx.c
+        libspeex/mdf.c
+        libspeex/medfilter.c
+        libspeex/misc.c
+        libspeex/modes.c
+        libspeex/nb_celp.c
+        libspeex/preprocess.c
+        libspeex/quant_lsp.c
+        libspeex/sb_celp.c
+        libspeex/smallft.c
+        libspeex/speex.c
+        libspeex/speex_callbacks.c
+        libspeex/speex_header.c
+        libspeex/stereo.c
+        libspeex/vbr.c
+        libspeex/vq.c
+        )
+    
+    include_directories(${PROJECT_SOURCE_DIR}/utils/iaxclient/lib/libspeex/include)
+endif(ENABLE_SPEXX)
+
+if (ENABLE_ALSA)
+    list(APPEND IAXCLIENT_BASE_SOURCES audio_alsa.c)
+endif(ENABLE_ALSA)
+
+if (ENABLE_PORTAUDIO)
+    list(APPEND IAXCLIENT_BASE_SOURCES audio_portaudio.c)
+endif(ENABLE_PORTAUDIO)
+
+if (APPLE)
+    add_definitions(-DMACOSX)
+endif(APPLE)
+
+list(APPEND IAXCLIENT_BASE_SOURCES spandsp/plc.c)
+
+add_definitions(-DAUDIO_OPENAL=1)
+add_definitions(-DLIBIAX)
+
+# for GSM
+add_definitions(-DHAS_STRING_H -DHAS_STDLIB_H)
+add_definitions(-DCODEC_GSM)
+
+include_directories(${PROJECT_SOURCE_DIR}/utils/iaxclient/lib)
+include_directories(${PROJECT_SOURCE_DIR}/utils/iaxclient/lib/libiax2/src)
+include_directories(${PROJECT_SOURCE_DIR}/utils/iaxclient/lib/gsm/inc)
+
+add_library(iaxclient_lib STATIC 
+    ${IAXCLIENT_BASE_SOURCES} 
+    ${GSM_SOURCES} 
+    ${SPEEX_SOURCES}
+    ${LIBIAX2_SOURCES})
+
diff --git a/utils/iaxclient/lib/TODO b/utils/iaxclient/lib/TODO
new file mode 100644 (file)
index 0000000..efdcd9f
--- /dev/null
@@ -0,0 +1,101 @@
+TODO items:
+
+
+1) Audio driver work:
+       Properly abstract audio drivers (currently, we use only
+               portaudio, but we may also want to support others.
+               The most likely candidate here would be zaptel devices.
+
+       Instead of the "switch" statements in the code, define an audio
+       driver structure, with 
+       
+       - function pointers for actual driver entry points.     
+               initialization: (scans available devices, sets up data
+                               structures)
+               destruction: (stops everything, cleans up)
+               "start":  starts audio for a particular call?
+               "stop": stops audio for a particular call?
+               "playsound": plays a particular sound: can be used for
+                       incoming call notification, ringback, dialtone etc?
+               "select": select input and output devices to use?       
+               [maybe extend this for zap devices to have "ring", etc
+               functions?]
+
+               
+       - Common audio driver data members:
+               a) perhaps an array of devices the driver has found,
+                       with for each device, a device name, an
+                       indication of whether this device is the default
+                       input or output, and whether this device
+                       supports input, output, or both.
+
+       For portaudio, we probably want to switch to the "standard"
+       portaudio callback interface, and away from pablio, which isn't
+       really robust enough for our needs once we do this stuff.
+
+
+
+2) Codecs:  (I think that someone is working on this)
+
+       Currently, the library assumes that all calls will be GSM only,
+       and further assumes that all frames will be 20ms.  It can
+       control the frame size (within reason) for frames it sends out,
+       but should deal gracefully with incoming frames that aren't
+       20ms.
+
+       Codecs should probably be implemented via a similar set of
+       structure abstractions as audio drivers, above.  They also need
+       to handle incoming packets which may switch formats abruptly(?).
+
+DONE (or, at least, mostly done):
+==============================================================
+Call handling 
+       currently, the library really only supports one call, and not
+       very well.  It should have a collection of calls (either an
+       array, or a linked list), and keep track of the current state of
+       each call.
+
+       An array might be easiest to manage, and would map well to a
+       softphone client.  We would then just refer to calls by their
+       index, and a GUI client might present these like call
+       appearances on their display.
+
+       Incoming calls might come in on the first free call appearance,
+       and outgoing calls by default would do the same.
+
+       The state of each call might be similar to phonecore
+       (incoming_incomplete, incoming, outgoing_incomplete, outgoing),
+       but we'd also have to keep track of which call, if any, we
+       currenly have "selected" -- i.e. which one we should connect to
+       the audio system.
+
+       We'd need to send events to the client whenever a call changed
+       "state" in any way.
+
+       We can make the number of calls in the array defined at runtime
+       when the library is initialized.  A very simple client like
+       testcall would just ask for a single call, so it wouldn't have
+       to worry about a lot of this.
+
+Events:
+       We might want to consolidate the (currently three) callbacks
+       that the library makes to clients, into a single callback, that
+       passes back a structure with event info.  I was thinking of a
+       structure with an event type, and then a union of different
+       structures depending on the event type.
+
+       The only thing is that we might want to decide whether or not,
+       or how clients will "register" for different event types, even
+       if they're handled through the same callback mechanism.
+
+       Ideally, the library would handle all of the events itself, via
+       some "default" handlers.  (I.e. for messages, it might just print
+       them to stdout or stderr.  For incoming calls, it might accept
+       them by default).
+
+       So, the choices then are whether the client should register for
+       individual events, or perhaps it can just decline events as they
+       happen, and then the library could handle them. 
+
+
+       
diff --git a/utils/iaxclient/lib/audio_alsa.c b/utils/iaxclient/lib/audio_alsa.c
new file mode 100644 (file)
index 0000000..600fe85
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2006 Panfilov Dmitry
+ *
+ * Contributors:
+ * Panfilov Dmitry
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ *
+ */
+
+#include "iaxclient_lib.h"
+#include <alsa/asoundlib.h>
+
+static snd_pcm_t *stream_out;
+static snd_pcm_t *stream_in;
+
+#define FRAMES_PER_BUFFER 80 /* 80 frames == 10ms */
+
+
+static int alsa_play_sound(struct iaxc_sound *inSound, int ring) {
+  return 0;
+}
+
+int alsa_stop_sound(int soundID) {
+  return 0;
+}
+
+
+int alsa_start (struct iaxc_audio_driver *d ) {
+    return 0;
+}
+
+int alsa_stop (struct iaxc_audio_driver *d ) {
+    return 0;
+}
+
+void alsa_shutdown_audio()
+{
+    return;
+}
+
+
+int alsa_input(struct iaxc_audio_driver *d, void *samples, int *nSamples) {
+
+    /* we don't return partial buffers */
+    long r;
+    long byteread=*nSamples;
+    static int h;
+    *nSamples=0;
+    snd_pcm_start(stream_in);
+    if(h==1) { h=0; return 0;}
+    do{
+       r = snd_pcm_readi(stream_in, samples, byteread);
+        if (r == -EAGAIN){
+            continue;
+       }
+       if (r == - EPIPE) {
+           snd_pcm_prepare(stream_in);
+           continue;
+       }
+        samples += (r * 2);
+        byteread -= r;
+        *nSamples += r;
+    }while(r >=0 && byteread >0);
+    h=1;
+    return 0;
+}
+
+int alsa_output(struct iaxc_audio_driver *d, void *samples, int nSamples) {
+
+        long r;
+       snd_pcm_start(stream_out);
+        while (nSamples > 0) {
+                r = snd_pcm_writei(stream_out, samples, nSamples);
+                if (r == -EAGAIN){
+                    continue;
+               }
+               if (r == - EPIPE) {
+                   snd_pcm_prepare(stream_out);
+                   continue;
+               }
+                if (r < 0) {
+                   fprintf(stderr, "r=%d\n",r);
+               }
+                samples += r * 2;
+                nSamples -= r;
+        }
+        return 0;
+}
+
+int alsa_select_devices (struct iaxc_audio_driver *d, int input, int output, int ring) {
+    return 0;
+}
+
+int alsa_selected_devices (struct iaxc_audio_driver *d, int *input, int *output, int *ring) {
+    *input = 0;
+    *output = 0;
+    *ring = 0;
+    return 0;
+}
+
+int alsa_destroy (struct iaxc_audio_driver *d )
+{
+       /* TODO: something should happen here */
+    return 0;
+}
+
+double alsa_input_level_get(struct iaxc_audio_driver *d){
+    return -1;
+}
+
+double alsa_output_level_get(struct iaxc_audio_driver *d){
+    return -1;
+}
+
+int alsa_input_level_set(struct iaxc_audio_driver *d, double level){
+    return -1;
+}
+
+int alsa_output_level_set(struct iaxc_audio_driver *d, double level){
+    return -1;
+}
+
+
+/* initialize audio driver */
+int alsa_initialize (struct iaxc_audio_driver *d ,int sample_rate) {
+    int i;
+    int err;
+    short buf[128];
+    snd_pcm_hw_params_t *hw_params;
+    snd_pcm_sw_params_t *sw_params;
+
+    if ((err = snd_pcm_open (&stream_out, "default", SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
+        fprintf (stderr, "cannot open audio device default (%s)\n",
+        snd_strerror (err));
+       exit (1);
+    }
+    if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
+        fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n",
+       snd_strerror (err));
+       exit (1);
+    }
+    if ((err = snd_pcm_hw_params_any (stream_out, hw_params)) < 0) {
+       fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
+       snd_strerror (err));
+       exit (1);
+    }
+    if ((err = snd_pcm_hw_params_set_access (stream_out, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
+       fprintf (stderr, "cannot set access type (%s)\n",
+       snd_strerror (err));
+       exit (1);
+    }
+    if ((err = snd_pcm_hw_params_set_format (stream_out, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
+       fprintf (stderr, "cannot set sample format (%s)\n",
+       snd_strerror (err));
+       exit (1);
+    }
+    if ((err = snd_pcm_hw_params_set_rate (stream_out, hw_params, sample_rate, 0)) < 0) {
+        fprintf (stderr, "cannot set sample rate (%s)\n",
+       snd_strerror (err));
+       exit (1);
+    }
+    if ((err = snd_pcm_hw_params_set_channels (stream_out, hw_params, 1)) < 0) {
+       fprintf (stderr, "cannot set channel count (%s)\n",
+       snd_strerror (err));
+       exit (1);
+    }
+    if ((err = snd_pcm_hw_params (stream_out, hw_params)) < 0) {
+       fprintf (stderr, "cannot set parameters (%s)\n",
+       snd_strerror (err));
+       exit (1);
+    }
+
+    snd_pcm_sw_params_malloc(&sw_params);
+
+    err = snd_pcm_sw_params_current(stream_out, sw_params);
+    if (err < 0) {
+       printf("Unable to determine current swparams for playback: %s\n", snd_strerror(err));
+        return err;
+    }
+    err = snd_pcm_sw_params_set_start_threshold(stream_out, sw_params, 80);
+    if (err < 0) {
+        fprintf(stderr, "Unable to set start threshold mode for playback: %s\n", snd_strerror(err));
+        return err;
+    }
+    err = snd_pcm_sw_params(stream_out, sw_params);
+    if (err < 0) {
+        fprintf(stderr, "Unable to set sw params for playback: %s\n", snd_strerror(err));
+        return err;
+    }
+
+    if ((err = snd_pcm_open (&stream_in, "default", SND_PCM_STREAM_CAPTURE, 0)) < 0) {
+        fprintf (stderr, "cannot open audio device default (%s)\n",
+        snd_strerror (err));
+       exit (1);
+    }
+    if ((err = snd_pcm_hw_params_any (stream_in, hw_params)) < 0) {
+       fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n",
+       snd_strerror (err));
+       exit (1);
+    }
+    if ((err = snd_pcm_hw_params_set_access (stream_in, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
+       fprintf (stderr, "cannot set access type (%s)\n",
+       snd_strerror (err));
+       exit (1);
+    }
+    if ((err = snd_pcm_hw_params_set_format (stream_in, hw_params, SND_PCM_FORMAT_S16_LE)) < 0) {
+       fprintf (stderr, "cannot set sample format (%s)\n",
+       snd_strerror (err));
+       exit (1);
+    }
+    if ((err = snd_pcm_hw_params_set_rate (stream_in, hw_params, sample_rate, 0)) < 0) {
+        fprintf (stderr, "cannot set sample rate (%s)\n",
+       snd_strerror (err));
+       exit (1);
+    }
+    if ((err = snd_pcm_hw_params_set_channels (stream_in, hw_params, 1)) < 0) {
+       fprintf (stderr, "cannot set channel count (%s)\n",
+       snd_strerror (err));
+       exit (1);
+    }
+    if ((err = snd_pcm_hw_params (stream_in, hw_params)) < 0) {
+       fprintf (stderr, "cannot set parameters (%s)\n",
+       snd_strerror (err));
+       exit (1);
+    }
+
+    err = snd_pcm_sw_params_current(stream_in, sw_params);
+    if (err < 0) {
+       printf("Unable to determine current swparams for playback: %s\n", snd_strerror(err));
+        return err;
+    }
+    err = snd_pcm_sw_params_set_start_threshold(stream_in, sw_params, 80);
+    if (err < 0) {
+        fprintf(stderr, "Unable to set start threshold mode for playback: %s\n", snd_strerror(err));
+        return err;
+    }
+    err = snd_pcm_sw_params(stream_in, sw_params);
+    if (err < 0) {
+        fprintf(stderr, "Unable to set sw params for playback: %s\n", snd_strerror(err));
+        return err;
+    }
+
+
+    if ((err = snd_pcm_prepare (stream_in)) < 0) {
+        fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
+       snd_strerror (err));
+        exit (1);
+    }
+
+    if ((err = snd_pcm_prepare (stream_out)) < 0) {
+        fprintf (stderr, "cannot prepare audio interface for use (%s)\n",
+       snd_strerror (err));
+        exit (1);
+    }
+
+    d->initialize = alsa_initialize;
+    d->destroy = alsa_destroy;
+    d->select_devices = alsa_select_devices;
+    d->selected_devices = alsa_selected_devices;
+    d->start = alsa_start;
+    d->stop = alsa_stop;
+    d->output = alsa_output;
+    d->input = alsa_input;
+    d->input_level_get = alsa_input_level_get;
+    d->input_level_set = alsa_input_level_set;
+    d->output_level_get = alsa_output_level_get;
+    d->output_level_set = alsa_output_level_set;
+    d->play_sound = alsa_play_sound;
+    d->stop_sound = alsa_stop_sound;
+
+    return 0;
+}
diff --git a/utils/iaxclient/lib/audio_alsa.h b/utils/iaxclient/lib/audio_alsa.h
new file mode 100644 (file)
index 0000000..77f1e84
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003-2006, Horizon Wimba, Inc.
+ * Copyright (C) 2007, Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ */
+
+#ifndef _AUDIO_ALSA_H
+#define _AUDIO_ALSA_H
+
+int alsa_initialize();
+
+#endif
diff --git a/utils/iaxclient/lib/audio_encode.c b/utils/iaxclient/lib/audio_encode.c
new file mode 100644 (file)
index 0000000..e30757c
--- /dev/null
@@ -0,0 +1,410 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003-2006, Horizon Wimba, Inc.
+ * Copyright (C) 2007, Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ * Michael Van Donselaar <mvand@vandonselaar.org>
+ * Shawn Lawrence <shawn.lawrence@terracecomm.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ */
+
+#include "audio_encode.h"
+#include "iaxclient_lib.h"
+#include "iax-client.h"
+#ifdef CODEC_GSM
+#include "codec_gsm.h"
+#endif
+#include "codec_ulaw.h"
+#include "codec_alaw.h"
+
+#include "codec_speex.h"
+#include <speex/speex_preprocess.h>
+
+#ifdef CODEC_ILBC
+#include "codec_ilbc.h"
+#endif
+
+float iaxci_silence_threshold = AUDIO_ENCODE_SILENCE_DB;
+
+static float input_level = 0.0f;
+static float output_level = 0.0f;
+
+static SpeexPreprocessState *st = NULL;
+static int speex_state_size = 0;
+static int speex_state_rate = 0;
+
+int iaxci_filters = IAXC_FILTER_AGC|IAXC_FILTER_DENOISE|IAXC_FILTER_AAGC|IAXC_FILTER_CN;
+
+/* use to measure time since last audio was processed */
+static struct timeval timeLastInput ;
+static struct timeval timeLastOutput ;
+
+static struct iaxc_speex_settings speex_settings =
+{
+       1,    /* decode_enhance */
+       -1,   /* float quality */
+       -1,   /* bitrate */
+       0,    /* vbr */
+       0,    /* abr */
+       3     /* complexity */
+};
+
+
+static float vol_to_db(float vol)
+{
+       /* avoid calling log10() on zero which yields inf or
+        * negative numbers which yield nan */
+       if ( vol <= 0.0f )
+               return AUDIO_ENCODE_SILENCE_DB;
+       else
+               return log10f(vol) * 20.0f;
+}
+
+static int do_level_callback()
+{
+       static struct timeval last = {0,0};
+       struct timeval now;
+       float input_db;
+       float output_db;
+
+       now = iax_tvnow();
+
+       if ( last.tv_sec != 0 && iaxci_usecdiff(&now, &last) < 100000 )
+               return 0;
+
+       last = now;
+
+       /* if input has not been processed in the last second, set to silent */
+       input_db = iaxci_usecdiff(&now, &timeLastInput) < 1000000 ?
+                       vol_to_db(input_level) : AUDIO_ENCODE_SILENCE_DB;
+
+       /* if output has not been processed in the last second, set to silent */
+       output_db = iaxci_usecdiff(&now, &timeLastOutput) < 1000000 ?
+               vol_to_db(output_level) : AUDIO_ENCODE_SILENCE_DB;
+
+       iaxci_do_levels_callback(input_db, output_db);
+
+       return 0;
+}
+
+static void set_speex_filters()
+{
+       int i;
+
+       if ( !st )
+               return;
+
+       i = 1; /* always make VAD decision */
+       speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_VAD, &i);
+       i = (iaxci_filters & IAXC_FILTER_AGC) ? 1 : 0;
+       speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC, &i);
+       i = (iaxci_filters & IAXC_FILTER_DENOISE) ? 1 : 0;
+       speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DENOISE, &i);
+
+       /*
+       * We can tweak these parameters to play with VAD sensitivity.
+       * For now, we use the default values since it seems they are a good starting point.
+       * However, if need be, this is the code that needs to change
+       */
+       i = 35;
+       speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_PROB_START, &i);
+       i = 20;
+       speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_PROB_CONTINUE, &i);
+}
+
+static void calculate_level(short *audio, int len, float *level)
+{
+       int big_sample = 0;
+       int i;
+
+       for ( i = 0; i < len; i++ )
+       {
+               const int sample = abs(audio[i]);
+               big_sample = sample > big_sample ?
+                       sample : big_sample;
+       }
+
+       *level += ((float)big_sample / 32767.0f - *level) / 5.0f;
+}
+
+
+static int input_postprocess(void *audio, int len, int rate)
+{
+       static float lowest_volume = 1.0f;
+       float volume;
+       int silent = 0;
+
+       if ( !st || speex_state_size != len || speex_state_rate != rate )
+       {
+               if (st)
+                       speex_preprocess_state_destroy(st);
+               st = speex_preprocess_state_init(len,rate);
+               speex_state_size = len;
+               speex_state_rate = rate;
+               set_speex_filters();
+       }
+
+       calculate_level((short *)audio, len, &input_level);
+
+       /* only preprocess if we're interested in VAD, AGC, or DENOISE */
+       if ( (iaxci_filters & (IAXC_FILTER_DENOISE | IAXC_FILTER_AGC)) ||
+                       iaxci_silence_threshold > 0.0f )
+               silent = !speex_preprocess(st, (spx_int16_t *)audio, NULL);
+
+       /* Analog AGC: Bring speex AGC gain out to mixer, with lots of hysteresis */
+       /* use a higher continuation threshold for AAGC than for VAD itself */
+       if ( !silent &&
+            iaxci_silence_threshold != 0.0f &&
+            (iaxci_filters & IAXC_FILTER_AGC) &&
+            (iaxci_filters & IAXC_FILTER_AAGC)
+          )
+       {
+               static int i = 0;
+
+               i++;
+
+               if ( (i & 0x3f) == 0 )
+               {
+                       float loudness = st->loudness2;
+                       // speex_preprocess_ctl(st, SPEEX_PREPROCESS_GET_AGC_LOUDNESS, &loudness);
+                       if ( loudness > 8000.0f || loudness < 4000.0f )
+                       {
+                               const float level = iaxc_input_level_get();
+
+                               if ( loudness > 16000.0f && level > 0.5f )
+                               {
+                                       /* lower quickly if we're really too hot */
+                                       iaxc_input_level_set(level - 0.2f);
+                               }
+                               else if ( loudness > 8000.0f && level >= 0.15f )
+                               {
+                                       /* lower less quickly if we're a bit too hot */
+                                       iaxc_input_level_set(level - 0.1f);
+                               }
+                               else if ( loudness < 4000.0f && level <= 0.9f )
+                               {
+                                       /* raise slowly if we're cold */
+                                       iaxc_input_level_set(level + 0.1f);
+                               }
+                       }
+               }
+       }
+
+       /* This is ugly. Basically just don't get volume level if speex thought
+        * we were silent. Just set it to 0 in that case */
+       if ( iaxci_silence_threshold > 0.0f && silent )
+               input_level = 0.0f;
+
+       do_level_callback();
+
+       volume = vol_to_db(input_level);
+
+       if ( volume < lowest_volume )
+               lowest_volume = volume;
+
+       if ( iaxci_silence_threshold > 0.0f )
+               return silent;
+       else
+               return volume < iaxci_silence_threshold;
+}
+
+static int output_postprocess(void *audio, int len)
+{
+       calculate_level((short *)audio, len, &output_level);
+
+       do_level_callback();
+
+       return 0;
+}
+
+static struct iaxc_audio_codec *create_codec(int format)
+{
+       switch (format & IAXC_AUDIO_FORMAT_MASK)
+       {
+#ifdef CODEC_GSM
+       case IAXC_FORMAT_GSM:
+               return codec_audio_gsm_new();
+#endif
+       case IAXC_FORMAT_ULAW:
+               return codec_audio_ulaw_new();
+       case IAXC_FORMAT_ALAW:
+               return codec_audio_alaw_new();
+       case IAXC_FORMAT_SPEEX:
+               return codec_audio_speex_new(&speex_settings);
+#ifdef CODEC_ILBC
+       case IAXC_FORMAT_ILBC:
+               return codec_audio_ilbc_new();
+#endif
+       default:
+               /* ERROR: codec not supported */
+               fprintf(stderr, "ERROR: Codec not supported: %d\n", format);
+               return NULL;
+       }
+}
+
+EXPORT void iaxc_set_speex_settings(int decode_enhance, float quality,
+               int bitrate, int vbr, int abr, int complexity)
+{
+       speex_settings.decode_enhance = decode_enhance;
+       speex_settings.quality = quality;
+       speex_settings.bitrate = bitrate;
+       speex_settings.vbr = vbr;
+       speex_settings.abr = abr;
+       speex_settings.complexity = complexity;
+}
+
+int audio_send_encoded_audio(struct iaxc_call *call, int callNo, void *data,
+               int format, int samples)
+{
+       unsigned char outbuf[1024];
+       int outsize = 1024;
+       int silent;
+       int insize = samples;
+
+       /* update last input timestamp */
+       timeLastInput = iax_tvnow();
+
+       silent = input_postprocess(data, insize, 8000);
+
+       if(silent)
+       {
+               if(!call->tx_silent)
+               {  /* send a Comfort Noise Frame */
+                       call->tx_silent = 1;
+                       if ( iaxci_filters & IAXC_FILTER_CN )
+                               iax_send_cng(call->session, 10, NULL, 0);
+               }
+               return 0;  /* poof! no encoding! */
+       }
+
+       /* we're going to send voice now */
+       call->tx_silent = 0;
+
+       /* destroy encoder if it is incorrect type */
+       if(call->encoder && call->encoder->format != format)
+       {
+               call->encoder->destroy(call->encoder);
+               call->encoder = NULL;
+       }
+
+       /* just break early if there's no format defined: this happens for the
+        * first couple of frames of new calls */
+       if(format == 0) return 0;
+
+       /* create encoder if necessary */
+       if(!call->encoder)
+       {
+               call->encoder = create_codec(format);
+       }
+
+       if(!call->encoder)
+       {
+               /* ERROR: no codec */
+               fprintf(stderr, "ERROR: Codec could not be created: %d\n", format);
+               return 0;
+       }
+
+       if(call->encoder->encode(call->encoder, &insize, (short *)data,
+                               &outsize, outbuf))
+       {
+               /* ERROR: codec error */
+               fprintf(stderr, "ERROR: encode error: %d\n", format);
+               return 0;
+       }
+
+       if(samples-insize == 0)
+       {
+               fprintf(stderr, "ERROR encoding (no samples output (samples=%d)\n", samples);
+               return -1;
+       }
+
+       // Send the encoded audio data back to the app if required
+       // TODO: fix the stupid way in which the encoded audio size is returned
+       if ( iaxc_get_audio_prefs() & IAXC_AUDIO_PREF_RECV_LOCAL_ENCODED )
+               iaxci_do_audio_callback(callNo, 0, IAXC_SOURCE_LOCAL, 1,
+                               call->encoder->format & IAXC_AUDIO_FORMAT_MASK,
+                               sizeof(outbuf) - outsize, outbuf);
+
+       if(iax_send_voice(call->session,format, outbuf,
+                               sizeof(outbuf) - outsize, samples-insize) == -1)
+       {
+               fprintf(stderr, "Failed to send voice! %s\n", iax_errstr);
+               return -1;
+       }
+
+       return 0;
+}
+
+/* decode encoded audio; return the number of bytes decoded
+ * negative indicates error */
+int audio_decode_audio(struct iaxc_call * call, void * out, void * data, int len,
+               int format, int * samples)
+{
+       int insize = len;
+       int outsize = *samples;
+
+       timeLastOutput = iax_tvnow();
+
+       if ( format == 0 )
+       {
+               fprintf(stderr, "audio_decode_audio: Format is zero (should't happen)!\n");
+               return -1;
+       }
+
+       /* destroy decoder if it is incorrect type */
+       if ( call->decoder && call->decoder->format != format )
+       {
+               call->decoder->destroy(call->decoder);
+               call->decoder = NULL;
+       }
+
+       /* create decoder if necessary */
+       if ( !call->decoder )
+       {
+               call->decoder = create_codec(format);
+       }
+
+       if ( !call->decoder )
+       {
+               fprintf(stderr, "ERROR: Codec could not be created: %d\n",
+                               format);
+               return -1;
+       }
+
+       if ( call->decoder->decode(call->decoder,
+                               &insize, (unsigned char *)data,
+                               &outsize, (short *)out) )
+       {
+               fprintf(stderr, "ERROR: decode error: %d\n", format);
+               return -1;
+       }
+
+       output_postprocess(out, *samples - outsize);
+
+       *samples = outsize;
+       return len - insize;
+}
+
+EXPORT int iaxc_get_filters(void)
+{
+       return iaxci_filters;
+}
+
+EXPORT void iaxc_set_filters(int filters)
+{
+       iaxci_filters = filters;
+       set_speex_filters();
+}
+
+EXPORT void iaxc_set_silence_threshold(float thr)
+{
+       iaxci_silence_threshold = thr;
+       set_speex_filters();
+}
+
diff --git a/utils/iaxclient/lib/audio_encode.h b/utils/iaxclient/lib/audio_encode.h
new file mode 100644 (file)
index 0000000..d3dc561
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003-2006, Horizon Wimba, Inc.
+ * Copyright (C) 2007, Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ */
+
+#ifndef _AUDIO_ENCODE_H
+#define _AUDIO_ENCODE_H
+
+/* Minimum dB possible in the iaxclient world. This level
+ * is intended to represent silence.
+ */
+#define AUDIO_ENCODE_SILENCE_DB -99.0f
+
+struct iaxc_call;
+struct iax_event;
+
+int audio_send_encoded_audio(struct iaxc_call * most_recent_answer, int callNo,
+               void * data, int iEncodeType, int samples);
+
+int audio_decode_audio(struct iaxc_call * p, void * out, void * data, int len,
+               int iEncodeType, int * samples);
+
+#endif
+
diff --git a/utils/iaxclient/lib/audio_file.c b/utils/iaxclient/lib/audio_file.c
new file mode 100644 (file)
index 0000000..90c5e04
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * iaxclient_lib: An Inter-Asterisk eXchange communication library
+ *
+ * Module: audio_file
+ * Purpose: Audio code to read/write to files
+ * based on audio_portaudio, originally Developed by: Shawn Lawrence, Terrace Communications Inc.
+ * Developed by: Steve Kann
+ * Creation Date: October 30, 2003
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License
+ *
+ * IAX library Copyright (c) 2001 Linux Support Services
+ * IAXlib is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License
+ *
+ * This library uses the PortAudio Portable Audio Library
+ * For more information see: http://www.portaudio.com
+ * PortAudio Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ */
+
+#include "iaxclient_lib.h"
+
+typedef short SAMPLE;
+
+static FILE *inFile=NULL, *outFile=NULL;
+
+#define FRAMES_PER_BUFFER 80 /* 80 frames == 10ms */
+
+
+static int file_play_sound(struct iaxc_sound *inSound, int ring) {
+  return 0;
+}
+
+static int file_stop_sound(int soundID) {
+  return 0; 
+}
+
+
+static int file_start (struct iaxc_audio_driver *d ) {
+    return 0;
+}
+
+static int file_stop (struct iaxc_audio_driver *d ) {
+    return 0;
+}
+
+/* not used
+static void file_shutdown_audio() {
+    return;
+}
+*/
+
+static int file_input(struct iaxc_audio_driver *d, void *samples, int *nSamples) {
+       *nSamples = 0;
+       return 0;
+}
+
+static int file_output(struct iaxc_audio_driver *d, void *samples, int nSamples) {
+       
+       if(outFile) {
+           fwrite(samples, sizeof(SAMPLE), nSamples, outFile);
+       }
+       return 0;
+}
+
+static int file_select_devices (struct iaxc_audio_driver *d, int input, int output, int ring) {
+    return 0;
+}
+
+static int file_selected_devices (struct iaxc_audio_driver *d, int *input, int *output, int *ring) {
+    *input = 0;
+    *output = 0;
+    *ring = 0;
+    return 0;
+}
+
+static int file_destroy (struct iaxc_audio_driver *d ) 
+{
+       /* TODO: something should happen here */
+    return 0;
+}
+
+static float file_input_level_get(struct iaxc_audio_driver *d){
+    return -1;
+}
+
+static float file_output_level_get(struct iaxc_audio_driver *d){
+    return -1;
+}
+
+static int file_input_level_set(struct iaxc_audio_driver *d, float level){
+    return -1;
+}
+
+static int file_output_level_set(struct iaxc_audio_driver *d, float level){
+    return -1;
+}
+
+EXPORT int iaxc_set_files(FILE *input, FILE *output) {
+    inFile = input;
+    outFile = output;
+    return 0;
+}
+
+
+/* initialize audio driver */
+int file_initialize (struct iaxc_audio_driver *d , int sample_rate) {
+
+    if(sample_rate != 8000 ) return -1;
+
+    /* setup methods */
+    d->initialize = file_initialize;
+    d->destroy = file_destroy;
+    d->select_devices = file_select_devices;
+    d->selected_devices = file_selected_devices;
+    d->start = file_start;
+    d->stop = file_stop;
+    d->output = file_output;
+    d->input = file_input;
+    d->input_level_get = file_input_level_get;
+    d->input_level_set = file_input_level_set;
+    d->output_level_get = file_output_level_get;
+    d->output_level_set = file_output_level_set;
+    d->play_sound = file_play_sound;
+    d->stop_sound = file_stop_sound;
+
+    return 0;
+}
diff --git a/utils/iaxclient/lib/audio_file.h b/utils/iaxclient/lib/audio_file.h
new file mode 100644 (file)
index 0000000..51f8008
--- /dev/null
@@ -0,0 +1,18 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003 HorizonLive.com, (c) 2004, Horizon Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License
+ */
+#ifndef _AUDIO_FILE_H
+#define _AUDIO_FILE_H
+
+int file_initialize(struct iaxc_audio_driver *d , int sample_rate);
+
+#endif
diff --git a/utils/iaxclient/lib/audio_openal.c b/utils/iaxclient/lib/audio_openal.c
new file mode 100644 (file)
index 0000000..fbc9c4b
--- /dev/null
@@ -0,0 +1,314 @@
+#include "iaxclient_lib.h"
+
+#ifdef __APPLE__
+#include <OpenAL/al.h>
+#include <OpenAL/alc.h>
+#elif defined(OPENALSDK)
+#include <al.h>
+#include <alc.h>
+#else
+#include <AL/al.h>
+#include <AL/alc.h>
+#endif
+
+struct openal_priv_data
+{
+    int sample_rate;
+    int num_buffers;
+    int buffers_head;
+    int buffers_tail;
+    int buffers_free;
+    ALuint* buffers;
+    ALCcontext* out_ctx;
+    ALuint source;
+    ALCdevice* in_dev;
+    double input_level;
+    double output_level;
+};
+
+static struct iaxc_audio_device device = { 
+    "default", 
+    IAXC_AD_INPUT | IAXC_AD_OUTPUT | IAXC_AD_RING | IAXC_AD_INPUT_DEFAULT | IAXC_AD_OUTPUT_DEFAULT | IAXC_AD_RING_DEFAULT,
+    0 
+};
+
+static int openal_error(const char* function, int err)
+{
+    fprintf(stderr, "OpenAl function %s failed with code %d\n", function, err);
+    return -1;
+}
+
+int openal_input(struct iaxc_audio_driver *d, void *samples, int *nSamples)
+{
+    int err;
+    struct openal_priv_data* priv = (struct openal_priv_data*)(d->priv);
+
+    ALCint available;
+    ALCsizei request;
+
+    alcGetIntegerv(priv->in_dev, ALC_CAPTURE_SAMPLES, sizeof(available), &available);
+    /* do not return less data than caller wanted, iaxclient does not like it */
+    request = (available < *nSamples) ? 0 : *nSamples;
+    if (request > 0)
+    {
+       err = alcGetError(priv->in_dev);
+       alcCaptureSamples(priv->in_dev, samples, request);    
+       err = alcGetError(priv->in_dev);
+       if (err)
+       {
+           openal_error("alcCaptureSamples", err);
+           *nSamples = 0;
+           return 1;
+       }
+       // software mute, but keep data flowing for sync purposes
+       if (priv->input_level == 0)
+       {
+           memset(samples, 0, 2 * request);
+       }
+    }
+    *nSamples = request;
+    
+    return 0;
+}
+
+static void openal_unqueue(struct openal_priv_data* priv)
+{
+    int i;
+    ALint err;
+    ALint processed;
+
+    alGetSourcei(priv->source, AL_BUFFERS_PROCESSED, &processed);
+
+#ifdef OPENAL_DEBUG
+    {
+       ALint queued;
+       ALint state;
+       
+       alGetSourcei(priv->source, AL_BUFFERS_QUEUED, &queued);
+       alGetSourcei(priv->source, AL_SOURCE_STATE, &state);
+
+       fprintf(stderr, "free: %d processed: %d queued: %d head: %d tail: %d state: %d\n", 
+           priv->buffers_free, processed, queued, priv->buffers_head, priv->buffers_tail, state);
+    }
+#endif
+       
+    alGetError();
+    for(i = 0; i < processed; i++)
+    {
+       alSourceUnqueueBuffers(priv->source, 1, priv->buffers + priv->buffers_tail);
+       err = alGetError();
+       if (err)
+       {
+           openal_error("alSourceUnqueueBuffers", err);
+           break;
+       }
+       if (++priv->buffers_tail >= priv->num_buffers)
+       {
+           priv->buffers_tail = 0;
+       }
+       ++priv->buffers_free;
+    }
+}
+
+int openal_output(struct iaxc_audio_driver *d, void *samples, int nSamples)
+{
+    struct openal_priv_data* priv = (struct openal_priv_data*)(d->priv);
+
+    openal_unqueue(priv);
+    /* If we run out of buffers, wait for an arbitrary number to become free */
+    if (priv->buffers_free == 0)
+    {
+       while(priv->buffers_free < 4)
+       {
+           iaxc_millisleep(100);
+           openal_unqueue(priv);
+       }
+    }
+    
+    if (priv->buffers_free > 0)
+    {
+       ALuint buffer = priv->buffers[priv->buffers_head++];
+       if (priv->buffers_head >= priv->num_buffers)
+       {
+           priv->buffers_head = 0;
+       }
+       
+       alBufferData(buffer, AL_FORMAT_MONO16, samples, nSamples * 2, priv->sample_rate);
+       alSourceQueueBuffers(priv->source, 1, &buffer);
+       --priv->buffers_free;
+       
+       /* delay start of output until we have 2 buffers */
+       if (priv->buffers_free == priv->num_buffers - 2)
+       {
+           ALint state;
+       
+           alGetSourcei(priv->source, AL_SOURCE_STATE, &state);
+           if (state != AL_PLAYING)
+           {
+#ifdef OPENAL_DEBUG
+               fprintf(stderr, "calling alSourcePlay\n");
+#endif     
+               alSourcePlay(priv->source);
+           }
+       }
+    } else {
+       fprintf(stderr, "openal_output buffer overflow\n");
+       return 1;
+    }
+    
+    return 0;
+}
+
+int openal_select_devices(struct iaxc_audio_driver *d, int input, int output, int ring)
+{
+    return (input != 0 || output !=0 || ring != 0) ? -1 : 0;
+}
+
+int openal_selected_devices(struct iaxc_audio_driver *d, int *input, int *output, int *ring)
+{
+    *input = 0;
+    *output = 0;
+    *ring = 0;
+    
+    return 0;
+}
+
+/* 
+    Apparently iaxclient calls openal_start a gazillion times and doesn't call openal_stop.
+    So let's just make them no-ops.
+*/
+int openal_start(struct iaxc_audio_driver *d)
+{
+    int iret = 0;
+    struct openal_priv_data* priv = (struct openal_priv_data*)(d->priv);
+    if (priv) /* just to stop compiler noise */
+        iret = 0;
+    return iret;
+}
+
+int openal_stop(struct iaxc_audio_driver *d)
+{
+    int iret = 0;
+    struct openal_priv_data* priv = (struct openal_priv_data*)(d->priv);
+    if (priv) /* just to stop compiler noise */
+        iret = 0;
+    return iret;
+}
+
+float openal_input_level_get(struct iaxc_audio_driver *d)
+{
+    struct openal_priv_data* priv = (struct openal_priv_data*)(d->priv);
+
+    return (float)priv->input_level;
+}
+
+float openal_output_level_get(struct iaxc_audio_driver *d)
+{
+    struct openal_priv_data* priv = (struct openal_priv_data*)(d->priv);
+
+    return priv->output_level;
+}
+
+int openal_input_level_set(struct iaxc_audio_driver *d, float level)
+{
+    struct openal_priv_data* priv = (struct openal_priv_data*)(d->priv);
+    priv->input_level = level;
+
+    return 0;
+}
+
+int openal_output_level_set(struct iaxc_audio_driver *d, float level)
+{
+    struct openal_priv_data* priv = (struct openal_priv_data*)(d->priv);
+    priv->output_level = level;
+    alSourcef(priv->source, AL_GAIN, level);
+
+    return 0;
+}
+
+int openal_play_sound(struct iaxc_sound *s, int ring)
+{
+    return 0;
+}
+
+int openal_stop_sound(int id)
+{
+    return 0;
+}
+
+int openal_mic_boost_get(struct iaxc_audio_driver *d)
+{
+    return 0;
+}
+
+int openal_mic_boost_set(struct iaxc_audio_driver *d, int enable)
+{
+    return 0;
+}
+
+int openal_destroy(struct iaxc_audio_driver *d)
+{
+    return 0;
+}
+
+int openal_initialize(struct iaxc_audio_driver *d, int sample_rate)
+{
+    struct openal_priv_data* priv = malloc(sizeof(struct openal_priv_data));
+    int err = alGetError();
+    d->priv = priv;
+   
+    priv->out_ctx = alcGetCurrentContext();
+
+    if( priv->out_ctx == NULL ) { // FGCom standalone only
+       ALCdevice* out_dev = alcOpenDevice(0);
+       if (out_dev == 0) return openal_error("alcOpenDevice", alGetError());
+
+       priv->out_ctx = alcCreateContext(out_dev, 0);
+       if (priv->out_ctx == 0) return openal_error("alcCreateContext", alGetError());
+    }
+
+    alcMakeContextCurrent(priv->out_ctx);
+    if ((err = alGetError())) return openal_error("alcMakeContextCurrent", err);
+
+    priv->sample_rate = sample_rate;    
+    priv->num_buffers = 20;
+    priv->input_level = 1;
+    priv->output_level = 1;
+    priv->buffers_head = 0;
+    priv->buffers_tail = 0;
+    priv->buffers_free = priv->num_buffers;
+    priv->buffers = (ALuint*)malloc(sizeof(ALuint) * priv->num_buffers);
+
+    alGenBuffers(priv->num_buffers, priv->buffers);
+    if ((err = alGetError())) return openal_error("alGenBuffers", err);
+    
+    alGenSources(1, &priv->source);
+    if ((err = alGetError())) return openal_error("alGenSources", err);
+
+    priv->in_dev = alcCaptureOpenDevice(0, 8000, AL_FORMAT_MONO16, 800);
+    if (!priv->in_dev) return openal_error("alcCaptureOpenDevice", 0);
+
+    alcCaptureStart(priv->in_dev);
+    if ((err = alGetError())) return openal_error("alcCaptureStart", err);
+
+    d->initialize = openal_initialize;
+    d->destroy = openal_destroy;
+    d->select_devices = openal_select_devices;
+    d->selected_devices = openal_selected_devices;
+    d->start = openal_start;
+    d->stop = openal_stop;
+    d->output = openal_output;
+    d->input = openal_input;
+    d->input_level_get = openal_input_level_get;
+    d->input_level_set = openal_input_level_set;
+    d->output_level_get = openal_output_level_get;
+    d->output_level_set = openal_output_level_set;
+    d->mic_boost_get = openal_mic_boost_get;
+    d->mic_boost_set = openal_mic_boost_set;
+    d->play_sound = openal_play_sound;
+    d->stop_sound = openal_stop_sound;
+    d->nDevices = 1;
+    d->devices = &device;
+    
+    return 0;
+}
diff --git a/utils/iaxclient/lib/audio_openal.h b/utils/iaxclient/lib/audio_openal.h
new file mode 100644 (file)
index 0000000..a698235
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _AUDIO_OPENAL_H
+#define _AUDIO_OPENAL_H
+
+int openal_initialize();
+
+#endif
diff --git a/utils/iaxclient/lib/audio_portaudio.c b/utils/iaxclient/lib/audio_portaudio.c
new file mode 100644 (file)
index 0000000..0d57ef0
--- /dev/null
@@ -0,0 +1,1158 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003-2006, Horizon Wimba, Inc.
+ * Copyright (C) 2007, Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ * Michael Van Donselaar <mvand@vandonselaar.org>
+ * Shawn Lawrence <shawn.lawrence@terracecomm.com>
+ * Erik Bunce <kde@bunce.us>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ *
+ * Module: audio_portaudio
+ * Purpose: Audio code to provide portaudio driver support for IAX library
+ * Developed by: Shawn Lawrence, Terrace Communications Inc.
+ * Creation Date: April 18, 2003
+ *
+ * This library uses the PortAudio Portable Audio Library
+ * For more information see: http://www.portaudio.com/
+ * PortAudio Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ */
+
+#if defined(WIN32)  ||  defined(_WIN32_WCE)
+#include <stdlib.h>
+#define strcasecmp _stricmp
+#else
+#include <strings.h>
+#endif
+
+#include "audio_portaudio.h"
+#include "iaxclient_lib.h"
+#include "ringbuffer.h"
+#include "portmixer.h"
+
+#ifdef USE_MEC2
+#define DO_EC
+#include "mec3.h"
+static echo_can_state_t *ec;
+#endif
+
+#ifdef SPAN_EC
+#define DO_EC
+#include "ec/echo.h"
+static echo_can_state_t *ec;
+#endif
+
+#if defined(SPEEX_EC) && ! defined (WIN32)
+#define DO_EC
+#define restrict __restrict
+#include "speex/speex_echo.h"
+static SpeexEchoState *ec;
+#endif
+
+#define EC_RING_SZ  8192 /* must be pow(2) */
+
+
+typedef short SAMPLE;
+
+static PaStream *iStream, *oStream, *aStream;
+static PxMixer *iMixer = NULL, *oMixer = NULL;
+
+static int selectedInput, selectedOutput, selectedRing;
+
+static int sample_rate = 8000;
+static int mixers_initialized;
+
+
+#define MAX_SAMPLE_RATE       48000
+#ifndef MS_PER_FRAME
+# define MS_PER_FRAME         40
+#endif
+#define SAMPLES_PER_FRAME     (MS_PER_FRAME * sample_rate / 1000)
+
+/* static frame buffer allocation */
+#define MAX_SAMPLES_PER_FRAME (MS_PER_FRAME * MAX_SAMPLE_RATE  / 1000)
+
+/* echo_tail length, in frames must be pow(2) for mec/span ? */
+#define ECHO_TAIL 4096
+
+/* RingBuffer Size; Needs to be Pow(2), 1024 = 512 samples = 64ms */
+#ifndef OUTRBSZ
+# define OUTRBSZ 32768
+#endif
+
+/* Input ringbuffer size;  this doesn't seem to be as critical, and making it big
+ * causes issues when we're answering calls, etc., and the audio system is running
+ * but not being drained */
+#ifndef INRBSZ
+# define INRBSZ  2048
+#endif
+
+/* TUNING:  The following constants may help in tuning for situations
+ * where you are getting audio-level under/overruns.
+ *
+ * If you are running iaxclient on a system where you cannot get
+ * low-latency scheduling, you may need to increase these.  This tends
+ * to be an issue on non-MacOSX unix systems, when you are not running
+ * as root, and cannot ask the OS for higher priority.
+ *
+ * RBOUTTARGET:  This a target size of the output ringbuffer, in milliseconds,
+ * where audio for your speakers goes after being decoded and mixed, and
+ * before the audio callback asks for it.  It can get larger than this
+ * (up to OUTRBSZ, above), but when it does, for a bit, we will start
+ * dropping some frames.  For no drops at all, this needs to be set to
+ * contain the number of samples in your largest scheduling gap
+ *
+ * PA_NUMBUFFERS:  This is the number of buffers that the low-level
+ * operating system driver will use, for buffering our output (and also
+ * our input) between the soundcard and portaudio.  This should also be
+ * set to the maximum scheduling delay.  Some drivers, though, will
+ * callback _into_ portaudio with a higher priority, so this doesn't
+ * necessarily need to be as big as RBOUTMAXSZ, although on linux, it
+ * does.  The default is to leave this up to portaudio..
+ */
+
+/* 80ms if average outRing length is more than this many bytes, start dropping */
+#ifndef RBOUTTARGET
+# define RBOUTTARGET (80)
+#endif
+
+/* size in bytes of ringbuffer target */
+#define RBOUTTARGET_BYTES (RBOUTTARGET * (sample_rate / 1000) * sizeof(SAMPLE))
+
+static char inRingBuf[INRBSZ], outRingBuf[OUTRBSZ];
+static rb_RingBuffer inRing, outRing;
+
+static int outRingLenAvg;
+
+static int oneStream;
+static int auxStream;
+static int virtualMonoIn;
+static int virtualMonoOut;
+static int virtualMonoRing;
+
+static int running;
+
+static struct iaxc_sound *sounds;
+static int  nextSoundId = 1;
+
+static MUTEX sound_lock;
+
+/* forward declarations */
+static int pa_start (struct iaxc_audio_driver *d );
+static void handle_paerror(PaError err, char * where);
+static int pa_input_level_set(struct iaxc_audio_driver *d, float level);
+static float pa_input_level_get(struct iaxc_audio_driver *d);
+
+/* scan devices and stash pointers to dev structures.
+ *  But, these structures only remain valid while Pa is initialized,
+ *  which, with pablio, is only while it's running!
+ *  Also, storing these things in two separate arrays loses the actual
+ *  PaDeviceID's associated with devices (since their index in these
+ *  input/output arrays isn't the same as their index in the combined
+ *  array */
+static int scan_devices(struct iaxc_audio_driver *d)
+{
+       int nDevices;
+       int i;
+
+       d->nDevices = nDevices = Pa_GetDeviceCount();
+       d->devices = (struct iaxc_audio_device *)
+               malloc(nDevices * sizeof(struct iaxc_audio_device));
+
+       for ( i=0; i < nDevices; i++ )
+       {
+               const PaDeviceInfo *pa;
+               struct iaxc_audio_device *dev;
+
+               pa=Pa_GetDeviceInfo(i);
+               dev = &(d->devices[i]);
+
+               if ( pa ) //frik: under Terminal Services this is NULL
+               {
+                       dev->name = (char *)pa->name;
+                       dev->devID = i;
+                       dev->capabilities = 0;
+
+                       if ( pa->maxInputChannels > 0 )
+                               dev->capabilities |= IAXC_AD_INPUT;
+
+                       if ( pa->maxOutputChannels > 0 )
+                       {
+                               dev->capabilities |= IAXC_AD_OUTPUT;
+                               dev->capabilities |= IAXC_AD_RING;
+                       }
+
+                       if ( i == Pa_GetDefaultInputDevice() )
+                               dev->capabilities |= IAXC_AD_INPUT_DEFAULT;
+
+                       if ( i == Pa_GetDefaultOutputDevice() )
+                       {
+                               dev->capabilities |= IAXC_AD_OUTPUT_DEFAULT;
+                               dev->capabilities |= IAXC_AD_RING_DEFAULT;
+                       }
+               }
+               else //frik: under Terminal Services
+               {
+                       dev->name = "Not usable device";
+                       dev->devID = i;
+                       dev->capabilities = 0;
+               }
+       }
+
+       return 0;
+}
+
+static void mono2stereo(SAMPLE *out, SAMPLE *in, int nSamples)
+{
+       int i;
+       //fprintf(stderr, "mono2stereo: %d samples\n", nSamples);
+       for ( i=0; i < nSamples; i++ )
+       {
+               *(out++) = *in;
+               *(out++) = *(in++);
+       }
+}
+
+static void stereo2mono(SAMPLE *out, SAMPLE *in, int nSamples)
+{
+       int i;
+       //fprintf(stderr, "stereo2mono: %d samples\n", nSamples);
+       for ( i=0; i < nSamples; i++ )
+       {
+               *(out) = *(in++);
+               out++; in++;
+               //*(out++) += *(in++);
+       }
+}
+
+static void mix_slin(short *dst, short *src, int samples, int virtualMono)
+{
+       int i=0,val=0;
+       for ( i=0; i < samples; i++ )
+       {
+               if ( virtualMono )
+                       val = ((short *)dst)[2*i] + ((short *)src)[i];
+               else
+                       val = ((short *)dst)[i] + ((short *)src)[i];
+
+               if ( val > 0x7fff )
+               {
+                       val = 0x7fff-1;
+               } else if (val < -0x7fff)
+               {
+                       val = -0x7fff+1;
+               }
+
+               if ( virtualMono )
+               {
+                       dst[2*i] = val;
+                       dst[2*i+1] = val;
+               } else
+               {
+                       dst[i] = val;
+               }
+
+       }
+}
+
+static int pa_mix_sounds (void *outputBuffer, unsigned long frames, int channel, int virtualMono)
+{
+       struct iaxc_sound *s;
+       struct iaxc_sound **sp;
+       unsigned long outpos;
+
+       MUTEXLOCK(&sound_lock);
+       /* mix each sound into the outputBuffer */
+       sp = &sounds;
+       while ( sp && *sp )
+       {
+               s = *sp;
+               outpos = 0;
+
+               if ( s->channel == channel )
+               {
+                       /* loop over the sound until we've played it enough
+                        * times, or we've filled the outputBuffer */
+                       for(;;)
+                       {
+                               int n;
+
+                               if ( outpos == frames )
+                                       break;  /* we've filled the buffer */
+                               if ( s->pos == s->len )
+                               {
+                                       if ( s->repeat == 0 )
+                                       {
+                                               // XXX free the sound
+                                               // structure, and maybe the
+                                               // buffer!
+                                               (*sp) = s->next;
+                                               if(s->malloced)
+                                                       free(s->data);
+                                               free(s);
+                                               break;
+                                       }
+                                       s->pos = 0;
+                                       s->repeat--;
+                               }
+
+                               /* how many frames do we add in this loop? */
+                               n = (frames - outpos) < (unsigned long)(s->len - s->pos) ?
+                                       (frames - outpos) :
+                                       (unsigned long)(s->len - s->pos);
+
+                               /* mix in the frames */
+                               mix_slin((short *)outputBuffer + outpos,
+                                               s->data+s->pos, n, virtualMono);
+
+                               s->pos += n;
+                               outpos += n;
+                       }
+               }
+               if ( *sp ) /* don't advance if we removed this member */
+                       sp = &((*sp)->next);
+       }
+       MUTEXUNLOCK(&sound_lock);
+       return 0;
+}
+
+static int pa_play_sound(struct iaxc_sound *inSound, int ring)
+{
+       struct iaxc_sound *sound;
+
+       sound = (struct iaxc_sound *)malloc(sizeof(struct iaxc_sound));
+       if ( !sound )
+               return 1;
+
+       *sound = *inSound;
+
+       MUTEXLOCK(&sound_lock);
+       sound->channel = ring;
+       sound->id = nextSoundId++;
+       sound->pos = 0;
+
+       sound->next = sounds;
+       sounds = sound;
+       MUTEXUNLOCK(&sound_lock);
+
+       if ( !running )
+               pa_start(NULL); /* XXX fixme: start/stop semantics */
+
+       return sound->id;
+}
+
+static int pa_stop_sound(int soundID)
+{
+       struct iaxc_sound **sp;
+       int retval = 1; /* not found */
+
+       MUTEXLOCK(&sound_lock);
+       for ( sp = &sounds; *sp; (*sp) = (*sp)->next )
+       {
+               struct iaxc_sound *s = *sp;
+               if ( s->id == soundID )
+               {
+                       if ( s->malloced )
+                               free(s->data);
+                       /* remove from list */
+                       (*sp) = s->next;
+                       free(s);
+
+                       retval= 0; /* found */
+                       break;
+               }
+       }
+       MUTEXUNLOCK(&sound_lock);
+
+       return retval; /* found? */
+}
+
+static void iaxc_echo_can(short *inputBuffer, short *outputBuffer, int n)
+{
+       static rb_RingBuffer ecOutRing;
+       static char outRingBuf[EC_RING_SZ];
+       static long bias = 0;
+       short  delayedBuf[1024];
+       int i;
+
+       /* remove bias -- whether ec is on or not. */
+       for ( i = 0; i < n; i++ )
+       {
+               bias += ((((long int) inputBuffer[i]) << 15) - bias) >> 14;
+               inputBuffer[i] -= (short int) (bias >> 15);
+       }
+
+       /* if ec is off, clear ec state -- this way, we start fresh if/when
+        * it's turned back on. */
+       if ( !(iaxc_get_filters() & IAXC_FILTER_ECHO) )
+       {
+#if defined(DO_EC)
+               if ( ec )
+               {
+#if defined(USE_MEC2) || defined(SPAN_EC)
+                       echo_can_free(ec);
+                       ec = NULL;
+#elif defined(SPEEX_EC)
+                       speex_echo_state_destroy(ec);
+                       ec = NULL;
+#endif
+               }
+#endif
+
+               return;
+       }
+
+       /* we want echo cancellation */
+
+#if defined(DO_EC)
+       if ( !ec )
+       {
+               rb_InitializeRingBuffer(&ecOutRing, EC_RING_SZ, &outRingBuf);
+#if defined(USE_MEC2) || defined(SPAN_EC)
+               ec = echo_can_create(ECHO_TAIL, 0);
+#elif defined(SPEEX_EC)
+               ec = speex_echo_state_init(SAMPLES_PER_FRAME, ECHO_TAIL);
+#endif
+       }
+#endif
+
+       /* fill ecOutRing */
+       rb_WriteRingBuffer(&ecOutRing, outputBuffer, n * 2);
+
+       // Make sure we have enough buffer.
+       // Currently, just one SAMPLES_PER_FRAME's worth.
+       if ( rb_GetRingBufferReadAvailable(&ecOutRing) < ((n + SAMPLES_PER_FRAME) * 2) )
+               return;
+
+       rb_ReadRingBuffer(&ecOutRing, delayedBuf, n * 2);
+
+#if defined(DO_EC) && defined(SPEEX_EC)
+       {
+               short cancelledBuffer[1024];
+
+               speex_echo_cancel(ec, inputBuffer, delayedBuf,
+                               cancelledBuffer, NULL);
+
+               for ( i = 0; i < n; i++ )
+                       inputBuffer[i] = cancelledBuffer[i];
+       }
+#endif
+
+#if defined(USE_MEC2) || defined(SPAN_EC)
+       for ( i = 0; i < n; i++ )
+               inputBuffer[i] = echo_can_update(ec, delayedBuf[i],
+                               inputBuffer[i]);
+#endif
+}
+
+static int pa_callback(void *inputBuffer, void *outputBuffer,
+           unsigned long samplesPerFrame,
+           const PaStreamCallbackTimeInfo* outTime,
+           PaStreamCallbackFlags statusFlags,
+           void *userData)
+{
+       int totBytes = samplesPerFrame * sizeof(SAMPLE);
+
+       short virtualInBuffer[MAX_SAMPLES_PER_FRAME * 2];
+       short virtualOutBuffer[MAX_SAMPLES_PER_FRAME * 2];
+
+#if 0
+       /* I think this can't happen */
+       if(virtualMono && samplesPerFrame > SAMPLES_PER_FRAME) {
+               fprintf(stderr, "ERROR: buffer in callback is too big!\n");
+               exit(1);
+       }
+#endif
+
+       if ( outputBuffer )
+       {
+               int bWritten;
+               /* output underflow might happen here */
+               if (virtualMonoOut)
+               {
+                       bWritten = rb_ReadRingBuffer(&outRing, virtualOutBuffer,
+                                       totBytes);
+                       /* we zero "virtualOutBuffer", then convert the whole thing,
+                        * yes, because we use virtualOutBuffer for ec below */
+                       if ( bWritten < totBytes )
+                       {
+                               memset(((char *)virtualOutBuffer) + bWritten,
+                                               0, totBytes - bWritten);
+                               //fprintf(stderr, "*U*");
+                       }
+                       mono2stereo((SAMPLE *)outputBuffer, virtualOutBuffer,
+                                       samplesPerFrame);
+               }
+               else
+               {
+                       bWritten = rb_ReadRingBuffer(&outRing, outputBuffer, totBytes);
+                       if ( bWritten < totBytes)
+                       {
+                               memset((char *)outputBuffer + bWritten,
+                                               0, totBytes - bWritten);
+                               //fprintf(stderr, "*U*");
+                       }
+               }
+
+               /* zero underflowed space [ silence might be more golden
+                * than garbage? ] */
+
+               pa_mix_sounds(outputBuffer, samplesPerFrame, 0, virtualMonoOut);
+
+               if(!auxStream)
+                       pa_mix_sounds(outputBuffer, samplesPerFrame, 1, virtualMonoOut);
+       }
+
+
+       if ( inputBuffer )
+       {
+               /* input overflow might happen here */
+               if ( virtualMonoIn )
+               {
+                       stereo2mono(virtualInBuffer, (SAMPLE *)inputBuffer,
+                                       samplesPerFrame);
+                       iaxc_echo_can(virtualInBuffer, virtualOutBuffer,
+                                       samplesPerFrame);
+
+                       rb_WriteRingBuffer(&inRing, virtualInBuffer, totBytes);
+               }
+               else
+               {
+                       iaxc_echo_can((short *)inputBuffer,
+                                       (short *)outputBuffer,
+                                       samplesPerFrame);
+
+                       rb_WriteRingBuffer(&inRing, inputBuffer, totBytes);
+               }
+       }
+
+       return 0;
+}
+
+static int pa_aux_callback(void *inputBuffer, void *outputBuffer,
+           unsigned long samplesPerFrame,
+           const PaStreamCallbackTimeInfo* outTime,
+           PaStreamCallbackFlags statusFlags,
+           void *userData)
+{
+       int totBytes = samplesPerFrame * sizeof(SAMPLE) * (virtualMonoRing + 1);
+
+       if ( outputBuffer )
+       {
+               memset((char *)outputBuffer, 0, totBytes);
+               pa_mix_sounds(outputBuffer, samplesPerFrame, 1, virtualMonoRing);
+       }
+       return 0;
+}
+
+static int pa_open(int single, int inMono, int outMono)
+{
+       PaError err;
+       PaDeviceInfo *result;
+
+       struct PaStreamParameters in_stream_params, out_stream_params, no_device;
+       in_stream_params.device = selectedInput;
+       in_stream_params.channelCount = (inMono ? 1 : 2);
+       in_stream_params.sampleFormat = paInt16;
+       result = (PaDeviceInfo *)Pa_GetDeviceInfo(selectedInput);
+       if ( result == NULL ) return -1;
+       in_stream_params.suggestedLatency = result->defaultLowInputLatency;
+       in_stream_params.hostApiSpecificStreamInfo = NULL;
+
+       out_stream_params.device = selectedOutput;
+       out_stream_params.channelCount = (outMono ? 1 : 2);
+       out_stream_params.sampleFormat = paInt16;
+       result = (PaDeviceInfo *)Pa_GetDeviceInfo(selectedOutput);
+       if ( result == NULL ) return -1;
+       out_stream_params.suggestedLatency = result->defaultLowOutputLatency;
+       out_stream_params.hostApiSpecificStreamInfo = NULL;
+
+       no_device.device = paNoDevice;
+       no_device.channelCount = 0;
+       no_device.sampleFormat = paInt16;
+       result = (PaDeviceInfo *)Pa_GetDeviceInfo(selectedInput);
+       if ( result == NULL ) return -1;
+       no_device.suggestedLatency = result->defaultLowInputLatency; // FEEDBACK - unsure if appropriate
+       no_device.hostApiSpecificStreamInfo = NULL;
+
+       if ( single )
+       {
+               err = Pa_OpenStream(&iStream,
+                       &in_stream_params,
+                       &out_stream_params,
+                       sample_rate,
+                       paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate
+                       paNoFlag,
+                       (PaStreamCallback *)pa_callback,
+                       NULL);
+               if (err != paNoError) return -1;
+               oStream = iStream;
+               oneStream = 1;
+       } else
+       {
+               err = Pa_OpenStream(&iStream,
+                       &in_stream_params,
+                       &no_device,
+                       sample_rate,
+                       paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate
+                       paNoFlag,
+                       (PaStreamCallback *)pa_callback,
+                       NULL);
+               if ( err != paNoError ) return -1;
+
+               err = Pa_OpenStream(&oStream,
+                       &no_device,
+                       &out_stream_params,
+                       sample_rate,
+                       paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate
+                       paNoFlag,
+                       (PaStreamCallback *)pa_callback,
+                       NULL);
+
+               if ( err != paNoError )
+               {
+                       Pa_CloseStream(iStream);
+                       iStream = NULL;
+                       return -1;
+               }
+               oneStream = 0;
+       }
+
+       virtualMonoIn = (inMono ? 0 : 1);
+       virtualMonoOut = (outMono ? 0 : 1);
+       return 0;
+}
+
+/* some commentary here:
+ * 1: MacOSX: MacOSX often needs "virtual mono" and a single stream.
+ * That doesn't work for some USB devices (a Platronics headset), so
+ * mono in, virtual mono out, and mono in/out are also tried.
+ *
+ * 2: Unix/OSS: most cards are OK with real mono, and a single stream.
+ * Except some.  For those, a single open with real mono will succeed,
+ * but execution will fail.  Maybe others will open OK with a single
+ * stream, and real mono, but fail later? Two stream mono is tried first,
+ * since it reportedly provides better sound quality with ALSA
+ * and Sound Blaster Live.
+ *
+ * The failure mode I saw with a volunteer was that reads/writes would
+ * return -enodev (down in the portaudio code).  Bummer.
+ *
+ * Win32 works fine, in all cases, with a single stream and real mono,
+ * so far.
+ *
+ * We could probably do this more cleanly, because there are still cases
+ * where we will fail (i.e. if the user has only mono in and out on a Mac).
+ *
+ * */
+static int pa_openstreams (struct iaxc_audio_driver *d )
+{
+       int err;
+
+#ifdef LINUX
+       err = pa_open(0, 1, 1) && /* two stream mono */
+               pa_open(1, 1, 1) &&   /* one stream mono */
+               pa_open(0, 0, 0);     /* two stream stereo */
+#else
+#ifdef MACOSX
+       err = pa_open(1, 0, 0) &&  /* one stream stereo */
+               pa_open(1, 1, 0) &&    /* one stream mono in stereo out */
+               pa_open(1, 1, 1) &&    /* one stream mono */
+               pa_open(0, 0, 0);      /* two stream stereo */
+#else
+       err = pa_open(1, 1, 1) &&  /* one stream mono */
+               pa_open(1, 0, 0) &&    /* one stream stereo */
+               pa_open(1, 1, 0) &&    /* one stream mono in stereo out */
+               pa_open(0, 0, 0);      /* two stream stereo */
+#endif /*MACOSX */
+#endif /* LINUX */
+
+       if (err)
+       {
+               handle_paerror(err, "Unable to open streams");
+               return -1;
+       }
+       return 0;
+}
+
+static int pa_openauxstream (struct iaxc_audio_driver *d )
+{
+       PaError err;
+
+       struct PaStreamParameters ring_stream_params;
+
+       // setup the ring parameters
+       ring_stream_params.device = selectedRing;
+       ring_stream_params.sampleFormat = paInt16;
+       ring_stream_params.suggestedLatency =
+               Pa_GetDeviceInfo(selectedRing)->defaultLowOutputLatency;
+       ring_stream_params.hostApiSpecificStreamInfo = NULL;
+
+       // first we'll try mono
+       ring_stream_params.channelCount = 1; 
+
+       err = Pa_OpenStream(&aStream,
+                       NULL,
+                       &ring_stream_params,
+                       sample_rate,
+                       paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate
+                       paNoFlag,
+                       (PaStreamCallback *)pa_aux_callback,
+                       NULL);
+
+       if ( err != paNoError )
+       {
+               // next we'll try virtual mono (stereo)
+               ring_stream_params.channelCount = 1; 
+
+               err = Pa_OpenStream(&aStream,
+                               NULL,
+                               &ring_stream_params,
+                               sample_rate,
+                               paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate
+                               paNoFlag,
+                               (PaStreamCallback *)pa_aux_callback,
+                               NULL);
+       }
+
+       // mmok, failure...
+       if ( err != paNoError )
+       {
+               // fprintf(stderr, "Failure opening ring device with params: id: %d, output %d, default output %d\n",
+               // selectedRing, selectedOutput, Pa_GetDefaultOutputDevice());
+
+               handle_paerror(err, "opening separate ring stream");
+               return -1;
+       }
+
+       // Determine whether virtual mono is being used
+       virtualMonoRing = ring_stream_params.channelCount - 1;
+
+       return 0;
+}
+
+static int pa_start(struct iaxc_audio_driver *d)
+{
+       static int errcnt = 0;
+
+       if ( running )
+               return 0;
+
+       /* re-open mixers if necessary */
+       if ( iMixer )
+       {
+               Px_CloseMixer(iMixer);
+               iMixer = NULL;
+       }
+
+       if ( oMixer )
+       {
+               Px_CloseMixer(oMixer);
+               oMixer = NULL;
+       }
+
+       if ( errcnt > 5 )
+       {
+               iaxci_usermsg(IAXC_TEXT_TYPE_FATALERROR,
+                               "iaxclient audio: Can't open Audio Device. "
+                               "Perhaps you do not have an input or output device?");
+               /* OK, we'll give the application the option to abort or
+                * not here, but we will throw a fatal error anyway */
+               iaxc_millisleep(1000);
+               //return -1; // Give Up.  Too many errors.
+       }
+
+       /* flush the ringbuffers */
+       rb_InitializeRingBuffer(&inRing, INRBSZ, inRingBuf);
+       rb_InitializeRingBuffer(&outRing, OUTRBSZ, outRingBuf);
+
+       if ( pa_openstreams(d) )
+       {
+               errcnt++;
+               return -1;
+       }
+
+       errcnt = 0; // only count consecutive errors.
+
+       if ( Pa_StartStream(iStream) != paNoError )
+               return -1;
+
+       iMixer = Px_OpenMixer(iStream, 0);
+
+       if ( !oneStream )
+       {
+               PaError err = Pa_StartStream(oStream);
+               oMixer = Px_OpenMixer(oStream, 0);
+               if ( err != paNoError )
+               {
+                       Pa_StopStream(iStream);
+                       return -1;
+               }
+       }
+
+       if ( selectedRing != selectedOutput )
+       {
+               auxStream = 1;
+       }
+       else
+       {
+               auxStream = 0;
+       }
+
+       if ( auxStream )
+       {
+               pa_openauxstream(d);
+               if ( Pa_StartStream(aStream) != paNoError )
+               {
+                       auxStream = 0;
+               }
+       }
+
+       /* select the microphone as the input source */
+       if ( iMixer != NULL && !mixers_initialized )
+       {
+               /* First, select the "microphone" device, if it's available */
+               /* try the new method, reverting to the old if it fails */
+               if ( Px_SetCurrentInputSourceByName( iMixer, "microphone" ) != 0 )
+               {
+                       int n = Px_GetNumInputSources( iMixer ) - 1;
+                       for ( ; n > 0; --n )
+                       {
+                               if ( !strcasecmp("microphone",
+                                               Px_GetInputSourceName(iMixer, n)) )
+                               {
+                                       Px_SetCurrentInputSource( iMixer, n );
+                               }
+                       }
+               }
+
+               /* try to set the microphone boost -- we just turn off this
+                * "boost" feature, because it often leads to clipping, which
+                * we can't fix later -- but we can deal with low input levels
+                * much more gracefully */
+               Px_SetMicrophoneBoost( iMixer, 0 );
+
+               /* If the input level is very low, raise it up a bit.
+                * Otherwise, AGC cannot detect speech, and cannot adjust
+                * levels */
+               if ( pa_input_level_get(d) < 0.5f )
+                       pa_input_level_set(d, 0.6f);
+               mixers_initialized = 1;
+       }
+
+       running = 1;
+       return 0;
+}
+
+static int pa_stop (struct iaxc_audio_driver *d )
+{
+       PaError err;
+
+       if ( !running )
+               return 0;
+
+       if ( sounds )
+               return 0;
+
+       err = Pa_AbortStream(iStream);
+       err = Pa_CloseStream(iStream);
+
+       if ( !oneStream )
+       {
+               err = Pa_AbortStream(oStream);
+               err = Pa_CloseStream(oStream);
+       }
+
+       if ( auxStream )
+       {
+               err = Pa_AbortStream(aStream);
+               err = Pa_CloseStream(aStream);
+       }
+
+       running = 0;
+       return 0;
+}
+
+/* Mihai: apparently nobody loves this function. Some actually hate it.
+ * I bet if it's gone, no one will miss it.  Such a cold, cold world!
+static void pa_shutdown()
+{
+       CloseAudioStream( iStream );
+       if(!oneStream) CloseAudioStream( oStream );
+       if(auxStream) CloseAudioStream( aStream );
+}
+*/
+
+static void handle_paerror(PaError err, char * where)
+{
+       fprintf(stderr, "PortAudio error at %s: %s\n", where,
+                       Pa_GetErrorText(err));
+}
+
+static int pa_input(struct iaxc_audio_driver *d, void *samples, int *nSamples)
+{
+       int bytestoread;
+
+       bytestoread = *nSamples * sizeof(SAMPLE);
+
+       /* we don't return partial buffers */
+       if ( rb_GetRingBufferReadAvailable(&inRing) < bytestoread )
+       {
+               *nSamples = 0;
+               return 0;
+       }
+
+       rb_ReadRingBuffer(&inRing, samples, bytestoread);
+
+       return 0;
+}
+
+static int pa_output(struct iaxc_audio_driver *d, void *samples, int nSamples)
+{
+       int bytestowrite = nSamples * sizeof(SAMPLE);
+       int outRingLen;
+
+       outRingLen = rb_GetRingBufferReadAvailable(&outRing);
+       outRingLenAvg = (outRingLenAvg * 9 + outRingLen ) / 10;
+
+       /* if we've got a big output buffer, drop this */
+       if (outRingLen > (int)RBOUTTARGET_BYTES &&
+                       outRingLenAvg > (int)RBOUTTARGET_BYTES)
+       {
+         //fprintf(stderr, "*O*");
+         return outRingLen/2;
+       }
+
+       //if(rb_GetRingBufferWriteAvailable(&outRing) < bytestowrite)
+       //      fprintf(stderr, "O");
+
+       rb_WriteRingBuffer(&outRing, samples, bytestowrite);
+
+       return (outRingLen + bytestowrite)/2;
+
+}
+
+static int pa_select_devices(struct iaxc_audio_driver *d, int input,
+               int output, int ring)
+{
+       selectedInput = input;
+       selectedOutput = output;
+       selectedRing = ring;
+       if ( running )
+       {
+               /* stop/start audio, in order to switch devices */
+               pa_stop(d);
+               pa_start(d);
+       }
+       else
+       {
+               /* start/stop audio, in order to initialize mixers and levels */
+               pa_start(d);
+               pa_stop(d);
+       }
+       return 0;
+}
+
+static int pa_selected_devices(struct iaxc_audio_driver *d, int *input,
+               int *output, int *ring)
+{
+       *input = selectedInput;
+       *output = selectedOutput;
+       *ring = selectedRing;
+       return 0;
+}
+
+static int pa_destroy(struct iaxc_audio_driver *d)
+{
+       if( iMixer )
+       {
+               Px_CloseMixer(iMixer);
+               iMixer = NULL;
+       }
+       if ( oMixer )
+       {
+               Px_CloseMixer(oMixer);
+               oMixer = NULL;
+       }
+       if ( d )
+       {
+               if ( d->devices )
+               {
+                       free(d->devices);
+                       d->devices= NULL;
+               }
+       }
+       return Pa_Terminate();
+}
+
+static float pa_input_level_get(struct iaxc_audio_driver *d)
+{
+       /* iMixer should be non-null if we using either one or two streams */
+       if ( !iMixer )
+               return -1;
+
+       /* make sure this device supports input volume controls */
+       if ( Px_GetNumInputSources( iMixer ) == 0 )
+               return -1;
+
+       return Px_GetInputVolume(iMixer);
+}
+
+static float pa_output_level_get(struct iaxc_audio_driver *d)
+{
+       PxMixer *mix;
+
+       /* oMixer may be null if we're using one stream,
+          in which case, iMixer should not be null,
+          if it is, return an error */
+
+       if ( oMixer )
+               mix = oMixer;
+       else if ( iMixer )
+               mix = iMixer;
+       else
+               return -1;
+
+       /* prefer the pcm output, but default to the master output */
+       if ( Px_SupportsPCMOutputVolume(mix) )
+               return Px_GetPCMOutputVolume(mix);
+       else
+               return Px_GetMasterVolume(mix);
+}
+
+static int pa_input_level_set(struct iaxc_audio_driver *d, float level)
+{
+       /* make sure this device supports input volume controls */
+       if ( !iMixer || Px_GetNumInputSources(iMixer) == 0 )
+               return -1;
+
+       Px_SetInputVolume(iMixer, level);
+
+       return 0;
+}
+
+static int pa_output_level_set(struct iaxc_audio_driver *d, float level)
+{
+       PxMixer *mix;
+
+       if ( oMixer )
+               mix = oMixer;
+       else if ( iMixer )
+               mix = iMixer;
+       else
+               return -1;
+
+       /* prefer the pcm output, but default to the master output */
+       if ( Px_SupportsPCMOutputVolume(mix) )
+               Px_SetPCMOutputVolume(mix, level);
+       else
+               Px_SetMasterVolume(mix, level);
+
+       return 0;
+}
+
+static int pa_mic_boost_get(struct iaxc_audio_driver* d)
+{
+       if ( !iMixer )
+               return -1;
+
+       return Px_GetMicrophoneBoost(iMixer);
+}
+
+int pa_mic_boost_set(struct iaxc_audio_driver* d, int enable)
+{
+       if ( !iMixer )
+               return -1;
+
+       return Px_SetMicrophoneBoost(iMixer, enable);
+}
+
+/* initialize audio driver */
+static int _pa_initialize (struct iaxc_audio_driver *d, int sr)
+{
+       PaError  err;
+
+       sample_rate = sr;
+
+       /* initialize portaudio */
+       if ( paNoError != (err = Pa_Initialize()) )
+       {
+               iaxci_usermsg(IAXC_TEXT_TYPE_ERROR, "Failed Pa_Initialize");
+               return err;
+       }
+
+       /* scan devices */
+       scan_devices(d);
+
+       /* setup methods */
+       d->initialize = pa_initialize;
+       d->destroy = pa_destroy;
+       d->select_devices = pa_select_devices;
+       d->selected_devices = pa_selected_devices;
+       d->start = pa_start;
+       d->stop = pa_stop;
+       d->output = pa_output;
+       d->input = pa_input;
+       d->input_level_get = pa_input_level_get;
+       d->input_level_set = pa_input_level_set;
+       d->output_level_get = pa_output_level_get;
+       d->output_level_set = pa_output_level_set;
+       d->play_sound = pa_play_sound;
+       d->stop_sound = pa_stop_sound;
+       d->mic_boost_get = pa_mic_boost_get;
+       d->mic_boost_set = pa_mic_boost_set;
+
+       /* setup private data stuff */
+       selectedInput  = Pa_GetDefaultInputDevice();
+       selectedOutput = Pa_GetDefaultOutputDevice();
+       selectedRing   = Pa_GetDefaultOutputDevice();
+       sounds = NULL;
+       MUTEXINIT(&sound_lock);
+
+       rb_InitializeRingBuffer(&inRing, INRBSZ, inRingBuf);
+       rb_InitializeRingBuffer(&outRing, OUTRBSZ, outRingBuf);
+
+       running = 0;
+
+       return 0;
+}
+
+/* standard initialization:  Do the normal initialization, and then
+   also initialize mixers and levels */
+int pa_initialize(struct iaxc_audio_driver *d, int sr)
+{
+       _pa_initialize(d, sr);
+
+       /* TODO: Kludge alert. We only do the funny audio start-stop
+        * business if iaxci_audio_output_mode is not set. This is a
+        * hack to allow certain specific users of iaxclient to avoid
+        * certain problems associated with portaudio initialization
+        * hitting a deadlock condition.
+        */
+       if ( iaxci_audio_output_mode )
+               return 0;
+
+       /* start/stop audio, in order to initialize mixers and levels */
+       pa_start(d);
+       pa_stop(d);
+
+       return 0;
+}
+
+/* alternate initialization:  delay mixer/level initialization until
+   we actually start the device.  This is somewhat useful when you're about to start
+   the device as soon as you've initialized it, and want to avoid the time it
+   takes to start/stop the device before starting it again */
+int pa_initialize_deferred(struct iaxc_audio_driver *d, int sr)
+{
+       _pa_initialize(d, sr);
+       return 0;
+}
+
diff --git a/utils/iaxclient/lib/audio_portaudio.h b/utils/iaxclient/lib/audio_portaudio.h
new file mode 100644 (file)
index 0000000..099cc1c
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003-2006, Horizon Wimba, Inc.
+ * Copyright (C) 2007, Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ */
+
+#ifndef _AUDIO_PORTAUDIO_H
+#define _AUDIO_PORTAUDIO_H
+
+#include "iaxclient_lib.h"
+
+/* normal initialization */
+int pa_initialize (struct iaxc_audio_driver *d, int sr);
+
+/* faster initialization which defers initialization of mixers and levels
+       until the device is started */
+int pa_initialize_deferred (struct iaxc_audio_driver *d, int sr);
+
+#endif
diff --git a/utils/iaxclient/lib/codec_alaw.c b/utils/iaxclient/lib/codec_alaw.c
new file mode 100644 (file)
index 0000000..4064c06
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2004 Cyril VELTER
+ *
+ * Contributors:
+ * Cyril VELTER <cyril.velter@metadys.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ */
+
+#include "codec_alaw.h"
+#include "iaxclient_lib.h"
+
+#if defined(_MSC_VER)
+#define INLINE __inline
+#else
+#define INLINE inline
+#endif
+
+struct state {
+    plc_state_t plc;
+};
+
+static INLINE short int alawdecode (unsigned char alaw)
+{
+       int value;
+       int segment;
+
+       /* Mask value */
+       alaw ^= 0x55;
+
+       /* Extract and scale value */
+       value = (alaw & 0x0f) << 4;
+
+       /* Extract segment number */
+       segment = (alaw & 0x70) >> 4;
+
+       /* Compute value */
+       switch (segment) {
+               case 0:
+                       break;
+               case 1:
+                       value += 0x100;
+                       break;
+               default:
+                       value += 0x100;
+                       value <<= segment - 1;
+       }
+
+       /* Extract sign */
+       return (alaw & 0x80) ? value : -value;
+}
+
+static INLINE unsigned char alawencode (short int linear)
+{
+       int mask = 0x55;
+       int segment;
+       unsigned char alaw;
+
+       static int segments[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};
+
+       if (linear >= 0)
+       {
+         /* Sign (7th) bit = 1 */
+         mask |= 0x80;
+       }
+       else
+       {
+         /* Sign (7th) bit = 0 */
+         linear = -linear;
+       }
+
+       /* Find the segment */
+       for (segment = 0;segment < 8;segment++)
+               if (linear <= segments[segment])
+                       break;
+
+       /* Combine the sign, segment, and quantization bits. */
+
+       if (segment < 8)
+       {
+               if (segment < 2)
+                       alaw = (linear >> 4) & 0x0F;
+               else
+                       alaw = (linear >> (segment + 3)) & 0x0F;
+
+               return ((alaw | (segment << 4)) ^ mask);
+       }
+       else
+               /* out of range, return maximum value. */
+               return (0x7F ^ mask);
+}
+
+static int decode ( struct iaxc_audio_codec *c,
+    int *inlen, unsigned char *in, int *outlen, short *out ) {
+    struct state *state = (struct state *)(c->decstate);
+    short *orig_out = out;
+    short sample;
+
+
+    if(*inlen == 0) {
+       int interp_len = 160;
+       if(*outlen < interp_len) interp_len = *outlen;
+       plc_fillin(&state->plc,out,interp_len);
+       *outlen -= interp_len;
+       return 0;
+    }
+
+
+    while ((*inlen > 0) && (*outlen > 0)) {
+       sample = alawdecode((unsigned char)*(in++));
+       *(out++) = sample;
+       (*inlen)--; (*outlen)--;
+    }
+    plc_rx(&state->plc, orig_out, (int)(out - orig_out));
+
+    return 0;
+}
+
+static int encode ( struct iaxc_audio_codec *c,
+    int *inlen, short *in, int *outlen, unsigned char *out ) {
+
+    while ((*inlen > 0) && (*outlen > 0)) {
+       *(out++) = alawencode(*(in++));
+       (*inlen)--; (*outlen)--;
+    }
+
+    return 0;
+}
+
+static void destroy ( struct iaxc_audio_codec *c) {
+    free(c);
+}
+
+struct iaxc_audio_codec *codec_audio_alaw_new() {
+
+  struct iaxc_audio_codec *c = (struct iaxc_audio_codec *)calloc(1, sizeof(struct iaxc_audio_codec));
+
+  if(!c) return c;
+
+  strcpy(c->name,"alaw");
+  c->format = IAXC_FORMAT_ALAW;
+  c->encode = encode;
+  c->decode = decode;
+  c->destroy = destroy;
+
+  /* really, we can use less, but don't want to */
+  c->minimum_frame_size = 160;
+
+  /* decoder state, used for interpolation */
+  c->decstate = calloc(sizeof(struct state),1);
+  plc_init(&((struct state *)c->decstate)->plc);
+
+  return c;
+}
+
diff --git a/utils/iaxclient/lib/codec_alaw.h b/utils/iaxclient/lib/codec_alaw.h
new file mode 100644 (file)
index 0000000..bc4d213
--- /dev/null
@@ -0,0 +1,14 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2004 Cyril VELTER
+ *
+ * Contributors:
+ * Cyril VELTER <cyril.velter@metadys.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ */
+
+struct iaxc_audio_codec *codec_audio_alaw_new();
diff --git a/utils/iaxclient/lib/codec_ffmpeg.c b/utils/iaxclient/lib/codec_ffmpeg.c
new file mode 100644 (file)
index 0000000..ec96f0f
--- /dev/null
@@ -0,0 +1,748 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003-2006, Horizon Wimba, Inc.
+ * Copyright (C) 2007, Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ * Peter Grayson <jpgrayson@gmail.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ *
+ * A video codec using the ffmpeg library.
+ * 
+ * TODO: this code still uses its own slicing mechanism
+ * It should be converted to use the API provided in slice.[ch]
+ */
+
+#include <stdlib.h>
+
+#include "codec_ffmpeg.h"
+#include "iaxclient_lib.h"
+
+#ifdef WIN32
+#include "libavcodec/avcodec.h"
+#else
+#include <ffmpeg/avcodec.h>
+#endif
+
+struct slice_header_t
+{
+       unsigned char version;
+       unsigned short source_id;
+       unsigned char frame_index;
+       unsigned char slice_index;
+       unsigned char num_slices;
+};
+
+struct encoder_ctx
+{
+       AVCodecContext * avctx;
+       AVFrame * picture;
+
+       struct slice_header_t slice_header;
+
+       unsigned char *frame_buf;
+       int frame_buf_len;
+};
+
+struct decoder_ctx
+{
+       AVCodecContext * avctx;
+       AVFrame * picture;
+
+       struct slice_header_t slice_header;
+       int frame_size;
+
+       unsigned char * frame_buf;
+       int frame_buf_len;
+};
+
+static struct slice_set_t * g_slice_set = 0;
+
+static enum CodecID map_iaxc_codec_to_avcodec(int format)
+{
+       switch (format)
+       {
+       case IAXC_FORMAT_H261:
+               return CODEC_ID_H261;
+
+       case IAXC_FORMAT_H263:
+               return CODEC_ID_H263;
+
+       case IAXC_FORMAT_H263_PLUS:
+               return CODEC_ID_H263P;
+
+       case IAXC_FORMAT_MPEG4:
+               return CODEC_ID_MPEG4;
+
+       case IAXC_FORMAT_H264:
+               return CODEC_ID_H264;
+
+       case IAXC_FORMAT_THEORA:
+               return CODEC_ID_THEORA;
+
+       default:
+               return CODEC_ID_NONE;
+       }
+}
+
+static void destroy(struct iaxc_video_codec *c)
+{
+       if (c)
+       {
+               struct encoder_ctx *e = (struct encoder_ctx *) c->encstate;
+               struct decoder_ctx *d = (struct decoder_ctx *) c->decstate;
+
+               if (e)
+               {
+                       av_freep(&e->avctx);
+                       av_freep(&e->picture);
+                       if (e->frame_buf)
+                               free(e->frame_buf);
+                       free(e);
+               }
+
+               if (d)
+               {
+                       av_freep(&d->avctx);
+                       av_freep(&d->picture);
+                       if (d->frame_buf)
+                               free(d->frame_buf);
+                       free(d);
+               }
+
+               free(c);
+       }
+}
+
+static void reset_decoder_frame_state(struct decoder_ctx * d)
+{
+       memset(d->frame_buf, 0, d->frame_buf_len);
+       d->frame_size = 0;
+       d->slice_header.slice_index = 0;
+}
+
+static int frame_to_frame_xlate(AVCodecContext * avctx, AVFrame * picture,
+               int * outlen, char * out)
+{
+       int line;
+
+       *outlen = avctx->width * avctx->height * 6 / 4;
+
+       for ( line = 0; line < avctx->height / 2; ++line )
+       {
+               /* y even */
+               memcpy(out + avctx->width * (2 * line + 0),
+                      picture->data[0] + (2 * line + 0) * picture->linesize[0],
+                      avctx->width);
+
+               /* y odd */
+               memcpy(out + avctx->width * (2 * line + 1),
+                      picture->data[0] + (2 * line + 1) * picture->linesize[0],
+                      avctx->width);
+
+               /* u + v */
+               memcpy(out + avctx->width * avctx->height
+                               + line * avctx->width / 2,
+                      picture->data[1] + line * picture->linesize[1],
+                      avctx->width / 2);
+
+               memcpy(out + avctx->width * avctx->height * 5 / 4
+                               + line * avctx->width / 2,
+                      picture->data[2] + line * picture->linesize[2],
+                      avctx->width / 2);
+       }
+
+       return 0;
+}
+
+static int pass_frame_to_decoder(AVCodecContext * avctx, AVFrame * picture,
+               int inlen, unsigned char * in, int * outlen, char * out)
+{
+       int bytes_decoded;
+       int got_picture;
+
+       bytes_decoded = avcodec_decode_video(avctx, picture, &got_picture,
+                       in, inlen);
+
+       if ( bytes_decoded != inlen )
+       {
+               fprintf(stderr,
+                       "codec_ffmpeg: decode: failed to decode whole frame %d / %d\n",
+                       bytes_decoded, inlen);
+               return -1;
+       }
+
+       if ( !got_picture )
+       {
+               fprintf(stderr,
+                       "codec_ffmpeg: decode: failed to get picture\n");
+               return -1;
+       }
+
+       frame_to_frame_xlate(avctx, picture, outlen, out);
+
+       return 0;
+}
+
+static char *parse_slice_header(char * in, struct slice_header_t * slice_header)
+{
+       slice_header->version     = in[0];
+       slice_header->source_id   = (in[1] << 8) | in[2];
+       slice_header->frame_index = in[3];
+       slice_header->slice_index = in[4];
+       slice_header->num_slices  = in[5];
+
+       if ( slice_header->version != 0 )
+       {
+               fprintf(stderr,
+                       "codec_ffmpeg: decode: unknown slice header version %d\n",
+                       slice_header->version);
+               return 0;
+       }
+
+       return in + 6;
+}
+
+static int decode_iaxc_slice(struct iaxc_video_codec * c, int inlen,
+               char * in, int * outlen, char * out)
+{
+       struct decoder_ctx *d = (struct decoder_ctx *) c->decstate;
+       struct slice_header_t * sh_saved = &d->slice_header;
+       struct slice_header_t sh_this;
+       char * inp;
+       int ret;
+
+       inp = parse_slice_header(in, &sh_this);
+
+       if ( !inp )
+               return -1;
+
+       inlen -= inp - in;
+
+       if ( sh_this.source_id == sh_saved->source_id )
+       {
+               unsigned char frame_delta;
+
+               frame_delta = sh_this.frame_index - sh_saved->frame_index;
+
+               if ( frame_delta > 20 )
+               {
+                       /* This is an old slice. It's too late, we ignore it. */
+                       return 1;
+               }
+               else if ( frame_delta > 0 )
+               {
+                       /* This slice belongs to a future frame */
+                       if ( sh_saved->slice_index > 0 )
+                       {
+                               /* We have received slices for a previous
+                                * frame (e.g. the one we were previously
+                                * working on), so we go ahead and send this
+                                * partial frame to the decoder and get setup
+                                * for the new frame.
+                                */
+
+                               ret = pass_frame_to_decoder(d->avctx, d->picture,
+                                               d->frame_size, d->frame_buf,
+                                               outlen, out);
+
+                               reset_decoder_frame_state(d);
+
+                               if ( ret )
+                                       return -1;
+                       }
+
+                       sh_saved->frame_index = sh_this.frame_index;
+               }
+       }
+       else
+       {
+               sh_saved->source_id = sh_this.source_id;
+               sh_saved->frame_index = sh_this.frame_index;
+               sh_saved->slice_index = 0;
+               d->frame_size = 0;
+       }
+
+       if ( c->fragsize * sh_this.slice_index + inlen > d->frame_buf_len )
+       {
+               fprintf(stderr,
+                       "codec_ffmpeg: decode: slice overflows decoder frame buffer\n");
+               return -1;
+       }
+
+       memcpy(d->frame_buf + c->fragsize * sh_this.slice_index,
+                       inp, inlen);
+       sh_saved->slice_index++;
+       d->frame_size = c->fragsize * sh_this.slice_index + inlen;
+
+       if ( sh_saved->slice_index < sh_this.num_slices )
+       {
+               /* Do not decode yet, there are more slices coming for
+                * this frame.
+                */
+               return 1;
+       }
+
+       ret = pass_frame_to_decoder(d->avctx, d->picture, d->frame_size,
+                       d->frame_buf, outlen, out);
+
+       reset_decoder_frame_state(d);
+
+       if ( ret )
+               return -1;
+
+       return 0;
+}
+
+static int decode_rtp_slice(struct iaxc_video_codec * c,
+                 int inlen, char * in, int * outlen, char * out)
+{
+       struct decoder_ctx *d = (struct decoder_ctx *) c->decstate;
+       int ret = 1;
+
+       while ( inlen )
+       {
+               int bytes_decoded;
+               int got_picture;
+
+               bytes_decoded = avcodec_decode_video(d->avctx, d->picture,
+                               &got_picture, (unsigned char *)in, inlen);
+
+               if ( bytes_decoded < 0 )
+               {
+                       fprintf(stderr,
+                               "codec_ffmpeg: decode: error decoding frame\n");
+                       return -1;
+               }
+
+               inlen -= bytes_decoded;
+               in += bytes_decoded;
+
+               if ( got_picture && ret == 0)
+               {
+                       fprintf(stderr,
+                               "codec_ffmpeg: decode: unexpected second frame\n");
+                       return -1;
+               }
+
+               if ( got_picture )
+               {
+                       frame_to_frame_xlate(d->avctx, d->picture, outlen, out);
+                       ret = 0;
+               }
+       }
+
+       return ret;
+}
+
+static void slice_encoded_frame(struct slice_header_t * sh,
+               struct slice_set_t * slice_set,
+               unsigned char * in, int inlen, int fragsize)
+{
+       sh->num_slices = slice_set->num_slices = (inlen - 1) / fragsize + 1;
+
+       for (sh->slice_index = 0; sh->slice_index < sh->num_slices;
+                       ++sh->slice_index)
+       {
+               int slice_size = (sh->slice_index == sh->num_slices - 1) ?
+                       inlen % fragsize : fragsize;
+
+               slice_set->size[sh->slice_index] = slice_size + 6;
+               slice_set->data[sh->slice_index][0] = sh->version;
+               slice_set->data[sh->slice_index][1] = sh->source_id >> 8;
+               slice_set->data[sh->slice_index][2] = sh->source_id & 0xff;
+               slice_set->data[sh->slice_index][3] = sh->frame_index;
+               slice_set->data[sh->slice_index][4] = sh->slice_index;
+               slice_set->data[sh->slice_index][5] = sh->num_slices;
+
+               memcpy(&slice_set->data[sh->slice_index][6], in, slice_size);
+
+               in += slice_size;
+       }
+
+       sh->frame_index++;
+}
+
+static int encode(struct iaxc_video_codec *c,
+               int inlen, char * in, struct slice_set_t * slice_set)
+{
+       struct encoder_ctx *e = (struct encoder_ctx *) c->encstate;
+       int encoded_size;
+
+       avcodec_get_frame_defaults(e->picture);
+
+       e->picture->data[0] = (unsigned char *)in;
+       e->picture->data[1] = (unsigned char *)in
+               + e->avctx->width * e->avctx->height;
+       e->picture->data[2] = (unsigned char *)in
+               + e->avctx->width * e->avctx->height * 5 / 4;
+
+       e->picture->linesize[0] = e->avctx->width;
+       e->picture->linesize[1] = e->avctx->width / 2;
+       e->picture->linesize[2] = e->avctx->width / 2;
+
+       /* TODO: investigate setting a real pts value */
+       e->picture->pts = AV_NOPTS_VALUE;
+
+       /* TODO: investigate quality */
+       e->picture->quality = 10;
+
+       g_slice_set = slice_set;
+       slice_set->num_slices = 0;
+
+       encoded_size = avcodec_encode_video(e->avctx,
+                       e->frame_buf, e->frame_buf_len, e->picture);
+
+       if (!encoded_size)
+       {
+               fprintf(stderr, "codec_ffmpeg: encode failed\n");
+               return -1;
+       }
+
+       slice_set->key_frame = e->avctx->coded_frame->key_frame;
+
+       /* This is paranoia, of course. */
+       g_slice_set = 0;
+
+       /* We are in one of two modes here.
+        *
+        * The first possibility is that the codec supports rtp
+        * packetization. In this case, the slice_set has already been
+        * filled via encode_rtp_callback() calls made during the call
+        * to avcodec_encode_video().
+        *
+        * The second possibility is that we have one big encoded frame
+        * that we need to slice-up ourselves.
+        */
+
+       if (!e->avctx->rtp_payload_size)
+               slice_encoded_frame(&e->slice_header, slice_set,
+                               e->frame_buf, encoded_size, c->fragsize);
+
+       return 0;
+}
+
+void encode_rtp_callback(struct AVCodecContext *avctx, void *data, int size,
+                    int mb_nb)
+{
+       memcpy(&g_slice_set->data[g_slice_set->num_slices], data, size);
+       g_slice_set->size[g_slice_set->num_slices] = size;
+       g_slice_set->num_slices++;
+}
+
+struct iaxc_video_codec *codec_video_ffmpeg_new(int format, int w, int h,
+                                                    int framerate, int bitrate,
+                                                    int fragsize)
+{
+       struct encoder_ctx *e;
+       struct decoder_ctx *d;
+       AVCodec *codec;
+       int ff_enc_id, ff_dec_id;
+       char *name;
+
+       struct iaxc_video_codec *c = calloc(sizeof(struct iaxc_video_codec), 1);
+
+       if (!c)
+       {
+               fprintf(stderr,
+                       "codec_ffmpeg: failed to allocate video context\n");
+               return NULL;
+       }
+
+       avcodec_init();
+       avcodec_register_all();
+
+       c->format = format;
+       c->width = w;
+       c->height = h;
+       c->framerate = framerate;
+       c->bitrate = bitrate;
+       /* TODO: Is a fragsize of zero valid? If so, there's a divide
+        * by zero error to contend with.
+        */
+       c->fragsize = fragsize;
+
+       c->encode = encode;
+       c->decode = decode_iaxc_slice;
+       c->destroy = destroy;
+
+       c->encstate = calloc(sizeof(struct encoder_ctx), 1);
+       if (!c->encstate)
+               goto bail;
+       e = c->encstate;
+       e->avctx = avcodec_alloc_context();
+       if (!e->avctx)
+               goto bail;
+       e->picture = avcodec_alloc_frame();
+       if (!e->picture)
+               goto bail;
+       /* The idea here is that the encoded frame that will land in this
+        * buffer will be no larger than the size of an uncompressed 32-bit
+        * rgb frame.
+        *
+        * TODO: Is this assumption really valid?
+        */
+       e->frame_buf_len = w * h * 4;
+       e->frame_buf = malloc(e->frame_buf_len);
+       if (!e->frame_buf)
+               goto bail;
+
+       c->decstate = calloc(sizeof(struct decoder_ctx), 1);
+       if (!c->decstate)
+               goto bail;
+       d = c->decstate;
+       d->avctx = avcodec_alloc_context();
+       if (!d->avctx)
+               goto bail;
+       d->picture = avcodec_alloc_frame();
+       if (!d->picture)
+               goto bail;
+       d->frame_buf_len = e->frame_buf_len;
+       d->frame_buf = malloc(d->frame_buf_len);
+       if (!d->frame_buf)
+               goto bail;
+
+       e->slice_header.version = 0;
+       srandom(time(0));
+       e->slice_header.source_id = random() & 0xffff;
+
+       e->avctx->time_base.num = 1;
+       e->avctx->time_base.den = framerate;
+
+       e->avctx->width = w;
+       e->avctx->height = h;
+
+       e->avctx->bit_rate = bitrate;
+
+       /* This determines how often i-frames are sent */
+       e->avctx->gop_size = framerate * 3;
+       e->avctx->pix_fmt = PIX_FMT_YUV420P;
+       e->avctx->has_b_frames = 0;
+
+       e->avctx->mb_qmin = e->avctx->qmin = 10;
+       e->avctx->mb_qmax = e->avctx->qmax = 10;
+
+       e->avctx->lmin = 2 * FF_QP2LAMBDA;
+       e->avctx->lmax = 10 * FF_QP2LAMBDA;
+       e->avctx->global_quality = FF_QP2LAMBDA * 2;
+       e->avctx->qblur = 0.5;
+       e->avctx->global_quality = 10;
+
+       e->avctx->flags |= CODEC_FLAG_PSNR;
+       e->avctx->flags |= CODEC_FLAG_QSCALE;
+
+       e->avctx->mb_decision = FF_MB_DECISION_SIMPLE;
+
+       ff_enc_id = ff_dec_id = map_iaxc_codec_to_avcodec(format);
+
+       /* Note, when fragsize is used (non-zero) ffmpeg will use a "best
+        * effort" strategy: the fragment size will be fragsize +/- 20%
+        */
+
+       switch (format)
+       {
+
+       case IAXC_FORMAT_H261:
+               /* TODO: H261 only works with specific resolutions. */
+               name = "H.261";
+               break;
+
+       case IAXC_FORMAT_H263:
+               /* TODO: H263 only works with specific resolutions. */
+               name = "H.263";
+               e->avctx->flags |= CODEC_FLAG_AC_PRED;
+               if (fragsize)
+               {
+                       c->decode = decode_rtp_slice;
+                       e->avctx->rtp_payload_size = fragsize;
+                       e->avctx->flags |=
+                               CODEC_FLAG_TRUNCATED | CODEC_FLAG2_STRICT_GOP;
+                       e->avctx->rtp_callback = encode_rtp_callback;
+                       d->avctx->flags |= CODEC_FLAG_TRUNCATED;
+               }
+               break;
+
+       case IAXC_FORMAT_H263_PLUS:
+               /* Although the encoder is CODEC_ID_H263P, the decoder
+                * is the regular h.263, so we handle this special case
+                * here.
+                */
+               ff_dec_id = CODEC_ID_H263;
+               name = "H.263+";
+               e->avctx->flags |= CODEC_FLAG_AC_PRED;
+               if (fragsize)
+               {
+                       c->decode = decode_rtp_slice;
+                       e->avctx->rtp_payload_size = fragsize;
+                       e->avctx->flags |=
+                               CODEC_FLAG_TRUNCATED |
+                               CODEC_FLAG_H263P_SLICE_STRUCT |
+                               CODEC_FLAG2_STRICT_GOP |
+                               CODEC_FLAG2_LOCAL_HEADER;
+                       e->avctx->rtp_callback = encode_rtp_callback;
+                       d->avctx->flags |= CODEC_FLAG_TRUNCATED;
+               }
+               break;
+
+       case IAXC_FORMAT_MPEG4:
+               name = "MPEG4";
+               c->decode = decode_rtp_slice;
+               e->avctx->rtp_payload_size = fragsize;
+               e->avctx->rtp_callback = encode_rtp_callback;
+               e->avctx->flags |=
+                       CODEC_FLAG_TRUNCATED |
+                       CODEC_FLAG_H263P_SLICE_STRUCT |
+                       CODEC_FLAG2_STRICT_GOP |
+                       CODEC_FLAG2_LOCAL_HEADER;
+
+               d->avctx->flags |= CODEC_FLAG_TRUNCATED;
+               break;
+
+       case IAXC_FORMAT_H264:
+               name = "H.264";
+
+               /*
+                * Encoder flags
+                */
+
+               /* Headers are not repeated */
+               /* e->avctx->flags |= CODEC_FLAG_GLOBAL_HEADER; */
+
+               /* Slower, less blocky */
+               /* e->avctx->flags |= CODEC_FLAG_LOOP_FILTER; */
+
+               e->avctx->flags |= CODEC_FLAG_PASS1;
+               /* e->avctx->flags |= CODEC_FLAG_PASS2; */
+
+               /* Compute psnr values at encode-time (avctx->error[]) */
+               /* e->avctx->flags |= CODEC_FLAG_PSNR; */
+
+               /* e->avctx->flags2 |= CODEC_FLAG2_8X8DCT; */
+
+               /* Access Unit Delimiters */
+               e->avctx->flags2 |= CODEC_FLAG2_AUD;
+
+               /* Allow b-frames to be used as reference */
+               /* e->avctx->flags2 |= CODEC_FLAG2_BPYRAMID; */
+
+               /* b-frame rate distortion optimization */
+               /* e->avctx->flags2 |= CODEC_FLAG2_BRDO; */
+
+               /* e->avctx->flags2 |= CODEC_FLAG2_FASTPSKIP; */
+
+               /* Multiple references per partition */
+               /* e->avctx->flags2 |= CODEC_FLAG2_MIXED_REFS; */
+
+               /* Weighted biprediction for b-frames */
+               /* e->avctx->flags2 |= CODEC_FLAG2_WPRED; */
+
+               /*
+                * Decoder flags
+                */
+
+               /* Do not draw edges */
+               /* d->avctx->flags |= CODEC_FLAG_EMU_EDGE; */
+
+               /* Decode grayscale only */
+               /* d->avctx->flags |= CODEC_FLAG_GRAY; */
+
+               /* d->avctx->flags |= CODEC_FLAG_LOW_DELAY; */
+
+               /* Allow input bitstream to be randomly truncated */
+               /* d->avctx->flags |= CODEC_FLAG_TRUNCATED; */
+
+               /* Allow out-of-spec speed tricks */
+               /* d->avctx->flags2 |= CODEC_FLAG2_FAST; */
+               break;
+
+       case IAXC_FORMAT_THEORA:
+               /* TODO: ffmpeg only has a theora decoder. Until it has
+                * an encoder also, we cannot use ffmpeg for theora.
+                */
+               name = "Theora";
+               break;
+
+       default:
+               fprintf(stderr, "codec_ffmpeg: unsupported format (0x%08x)\n",
+                               format);
+               goto bail;
+       }
+
+       strcpy(c->name, "ffmpeg-");
+       strncat(c->name, name, sizeof(c->name));
+
+       /* Get the codecs */
+       codec = avcodec_find_encoder(ff_enc_id);
+       if (!codec)
+       {
+               iaxci_usermsg(IAXC_TEXT_TYPE_ERROR,
+                            "codec_ffmpeg: cannot find encoder %d\n",
+                            ff_enc_id);
+               goto bail;
+       }
+
+       if (avcodec_open(e->avctx, codec))
+       {
+               iaxci_usermsg(IAXC_TEXT_TYPE_ERROR,
+                            "codec_ffmpeg: cannot open encoder %s\n", name);
+               goto bail;
+       }
+
+       codec = avcodec_find_decoder(ff_dec_id);
+       if (!codec)
+       {
+               iaxci_usermsg(IAXC_TEXT_TYPE_ERROR,
+                            "codec_ffmpeg: cannot find decoder %d\n",
+                            ff_dec_id);
+               goto bail;
+       }
+       if (avcodec_open(d->avctx, codec))
+       {
+               iaxci_usermsg(IAXC_TEXT_TYPE_ERROR,
+                            "codec_ffmpeg: cannot open decoder %s\n", name);
+               goto bail;
+       }
+
+       {
+               enum PixelFormat fmts[] = { PIX_FMT_YUV420P, -1 };
+               if (d->avctx->get_format(d->avctx, fmts) != PIX_FMT_YUV420P)
+               {
+                       iaxci_usermsg(IAXC_TEXT_TYPE_ERROR,
+                                       "codec_ffmpeg: cannot set decode format to YUV420P\n");
+                       goto bail;
+               }
+       }
+
+       return c;
+
+bail:
+       destroy(c);
+       return 0;
+}
+
+int codec_video_ffmpeg_check_codec(int format)
+{
+       AVCodec *codec;
+       enum CodecID codec_id;
+
+       /* These functions are idempotent, so it is okay that we
+        * may call them elsewhere at a different time.
+        */
+       avcodec_init();
+       avcodec_register_all();
+
+       codec_id = map_iaxc_codec_to_avcodec(format);
+
+       if (codec_id == CODEC_ID_NONE)
+               return 0;
+
+       codec = avcodec_find_encoder(codec_id);
+
+       return codec ? 1 : 0;
+}
+
diff --git a/utils/iaxclient/lib/codec_ffmpeg.h b/utils/iaxclient/lib/codec_ffmpeg.h
new file mode 100644 (file)
index 0000000..acc8307
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003-2006, Horizon Wimba, Inc.
+ * Copyright (C) 2007, Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ * Peter Grayson <jpgrayson@gmail.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ *
+ * A video codec using the ffmpeg library.
+ */
+
+struct iaxc_video_codec *codec_video_ffmpeg_new(int format, int w, int h, int framerate, int bitrate, int fragsize);
+
+int codec_video_ffmpeg_check_codec(int format);
diff --git a/utils/iaxclient/lib/codec_gsm.c b/utils/iaxclient/lib/codec_gsm.c
new file mode 100644 (file)
index 0000000..0f6ac9f
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003-2006, Horizon Wimba, Inc.
+ * Copyright (C) 2007, Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ */
+
+#include "codec_gsm.h"
+#include "iaxclient_lib.h"
+#include "gsm.h"
+
+struct state {
+    gsm gsmstate;
+    plc_state_t plc;
+};
+
+
+static void destroy ( struct iaxc_audio_codec *c) {
+
+    struct state * encstate = (struct state *) c->encstate;
+    struct state * decstate = (struct state *) c->decstate;
+
+    gsm_destroy(encstate->gsmstate);
+    gsm_destroy(decstate->gsmstate);
+    free(c->encstate);
+    free(c->decstate);
+    free(c);
+}
+
+
+static int decode ( struct iaxc_audio_codec *c,
+    int *inlen, unsigned char *in, int *outlen, short *out ) {
+    struct state * decstate = (struct state *) c->decstate;
+
+    /* use generic interpolation */
+    if(*inlen == 0) {
+        int interp_len = 160;
+        if(*outlen < interp_len) interp_len = *outlen;
+        plc_fillin(&decstate->plc,out,interp_len);
+        *outlen -= interp_len;
+        return 0;
+    }
+
+    /* need to decode minimum of 33 bytes to 160 byte output */
+    while( (*inlen >= 33) && (*outlen >= 160) ) {
+       if(gsm_decode(decstate->gsmstate, in, out))
+       {
+           fprintf(stderr, "codec_gsm: gsm_decode returned error\n");
+           return -1;
+       }
+
+       /* push decoded data to interpolation buffer */
+       plc_rx(&decstate->plc,out,160);
+
+       /* we used 33 bytes of input, and 160 bytes of output */
+       *inlen -= 33;
+       in += 33;
+       *outlen -= 160;
+       out += 160;
+    }
+
+    return 0;
+}
+
+static int encode ( struct iaxc_audio_codec *c,
+    int *inlen, short *in, int *outlen, unsigned char *out ) {
+
+    struct state * encstate = (struct state *) c->encstate;
+
+
+    /* need to encode minimum of 160 bytes to 33 byte output */
+    while( (*inlen >= 160) && (*outlen >= 33) ) {
+       gsm_encode(encstate->gsmstate, in, out);
+
+       /* we used 160 bytes of input, and 33 bytes of output */
+       *inlen -= 160;
+       in += 160;
+       *outlen -= 33;
+       out += 33;
+    }
+
+    return 0;
+}
+
+struct iaxc_audio_codec *codec_audio_gsm_new() {
+
+  struct state * encstate;
+  struct state * decstate;
+  struct iaxc_audio_codec *c = (struct iaxc_audio_codec *)calloc(sizeof(struct iaxc_audio_codec),1);
+
+
+  if(!c) return c;
+
+  strcpy(c->name,"gsm 06.10");
+  c->format = IAXC_FORMAT_GSM;
+  c->encode = encode;
+  c->decode = decode;
+  c->destroy = destroy;
+
+  c->minimum_frame_size = 160;
+
+  c->encstate = calloc(sizeof(struct state),1);
+  c->decstate = calloc(sizeof(struct state),1);
+
+  /* leaks a bit on no-memory */
+  if(!(c->encstate && c->decstate))
+      return NULL;
+
+  encstate = (struct state *) c->encstate;
+  decstate = (struct state *) c->decstate;
+
+  encstate->gsmstate = gsm_create();
+  decstate->gsmstate = gsm_create();
+
+  if(!(encstate->gsmstate && decstate->gsmstate))
+      return NULL;
+
+  return c;
+}
+
diff --git a/utils/iaxclient/lib/codec_gsm.h b/utils/iaxclient/lib/codec_gsm.h
new file mode 100644 (file)
index 0000000..2407066
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003-2006, Horizon Wimba, Inc.
+ * Copyright (C) 2007, Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ */
+
+struct iaxc_audio_codec *codec_audio_gsm_new();
diff --git a/utils/iaxclient/lib/codec_ilbc.c b/utils/iaxclient/lib/codec_ilbc.c
new file mode 100644 (file)
index 0000000..a0da40b
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003-2006, Horizon Wimba, Inc.
+ * Copyright (C) 2007, Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ */
+
+#include "codec_ilbc.h"
+#include "iaxclient_lib.h"
+#include "iLBC/iLBC_encode.h"
+#include "iLBC/iLBC_decode.h"
+
+
+static void destroy ( struct iaxc_audio_codec *c) {
+    free(c->encstate);
+    free(c->decstate);
+    free(c);
+}
+
+
+static int decode ( struct iaxc_audio_codec *c,
+    int *inlen, char *in, int *outlen, short *out ) {
+
+    float fbuf[240];
+    int i;
+
+    if(*inlen == 0) {
+        //fprintf(stderr, "ILBC Interpolate\n");
+       iLBC_decode(fbuf, NULL, c->decstate, 0);
+       for(i=0;i<240;i++)
+           out[i] = fbuf[i];
+        *outlen -= 240;
+        return 0;
+    }
+
+
+    /* need to decode minimum of 33 bytes to 160 byte output */
+    if( (*inlen < 50) || (*outlen < 240) ) {
+       fprintf(stderr, "codec_ilbc: inlen = %d outlen= %d\n",*inlen,*outlen);
+       return -1;
+    }
+
+    while( (*inlen >= 50) && (*outlen >= 240) ) {
+       iLBC_decode(fbuf, in, c->decstate, 1);
+       for(i=0;i<240;i++)
+           out[i] = fbuf[i];
+
+       out += 240;
+       *outlen -= 240;
+       in += 50;
+       *inlen -= 50;
+    }
+
+    return 0;
+}
+
+static int encode ( struct iaxc_audio_codec *c,
+    int *inlen, short *in, int *outlen, char *out ) {
+
+    float fbuf[240];
+    int i;
+
+    while( (*inlen >= 240) && (*outlen >= 50) ) {
+
+       for(i=0;i<240;i++)
+           fbuf[i] = in[i];
+
+       iLBC_encode(out,fbuf, c->encstate);
+
+       out += 50;
+       *outlen -= 50;
+       in += 240;
+       *inlen -= 240;
+    }
+
+    return 0;
+}
+
+struct iaxc_audio_codec *codec_audio_ilbc_new() {
+  struct iaxc_audio_codec *c = calloc(sizeof(struct iaxc_audio_codec),1);
+
+
+  if(!c) return c;
+
+  strcpy(c->name,"iLBC");
+  c->format = IAXC_FORMAT_ILBC;
+  c->encode = encode;
+  c->decode = decode;
+  c->destroy = destroy;
+
+  c->minimum_frame_size = 240;
+
+  c->encstate = calloc(sizeof(iLBC_Enc_Inst_t),1);
+  c->decstate = calloc(sizeof(iLBC_Dec_Inst_t),1);
+
+  /* leaks a bit on no-memory */
+  if(!(c->encstate && c->decstate))
+      return NULL;
+
+  /* the 30 parameters are used for the latest iLBC sources, in
+   * http://www.ietf.org/internet-drafts/draft-ietf-avt-ilbc-codec-05.txt
+   * as used in asterisk-CVS as of 14 Oct 2004 */
+  initEncode(c->encstate, 30);
+  initDecode(c->decstate, 30, 1); /* use enhancer */
+
+  return c;
+}
+
diff --git a/utils/iaxclient/lib/codec_ilbc.h b/utils/iaxclient/lib/codec_ilbc.h
new file mode 100644 (file)
index 0000000..ee9889b
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003-2006, Horizon Wimba, Inc.
+ * Copyright (C) 2007, Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ */
+
+struct iaxc_audio_codec *codec_audio_ilbc_new();
diff --git a/utils/iaxclient/lib/codec_speex.c b/utils/iaxclient/lib/codec_speex.c
new file mode 100644 (file)
index 0000000..0a97149
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003-2004, Horizon Wimba, Inc.
+ * Copyright (C) 2007, Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ */
+
+#include "codec_speex.h"
+#include "iaxclient_lib.h"
+#include "speex/speex.h"
+
+struct State
+{
+       void *state;
+       int frame_size;
+       SpeexBits bits;
+};
+
+
+static void destroy ( struct iaxc_audio_codec *c)
+{
+       struct State * encstate = (struct State *) c->encstate;
+       struct State * decstate = (struct State *) c->decstate;
+
+       speex_bits_destroy(&encstate->bits);
+       speex_bits_destroy(&decstate->bits);
+       speex_encoder_destroy(encstate->state);
+       speex_decoder_destroy(decstate->state);
+
+       free(c->encstate);
+       free(c->decstate);
+
+       free(c);
+}
+
+
+static int decode( struct iaxc_audio_codec *c,
+               int *inlen, unsigned char *in, int *outlen, short *out )
+{
+       struct State * decstate = (struct State *) c->decstate;
+
+       if ( *inlen == 0 )
+       {
+               speex_decode_int(decstate->state, NULL, out);
+               *outlen -= decstate->frame_size;
+               return 0;
+       }
+
+       speex_bits_read_from(&decstate->bits, (char *) in, *inlen);
+       *inlen = 0;
+
+       while ( speex_bits_remaining(&decstate->bits) &&
+                       *outlen >= decstate->frame_size )
+       {
+               int ret = speex_decode_int(decstate->state, &decstate->bits, out);
+
+               // from speex/speex.h, speex_decode returns:
+               // @return return status (0 for no error, -1 for end of stream, -2 other)
+               if (ret == 0)
+               {
+                       /* one frame of output */
+                       *outlen -= decstate->frame_size;
+                       out += decstate->frame_size;
+               } else if (ret == -1)
+               {
+                       /* at end of stream, or just a terminator */
+                       int bits_left = speex_bits_remaining(&decstate->bits) % 8;
+                       if(bits_left >= 5)
+                               speex_bits_advance(&decstate->bits, bits_left);
+                       else
+                               break;
+               } else
+               {
+                       /* maybe there's not a whole frame somehow? */
+                       fprintf(stderr, "decode_int returned non-zero => %d\n",ret);
+                       break;
+               }
+       }
+       return 0;
+}
+
+static int encode( struct iaxc_audio_codec *c,
+               int *inlen, short *in, int *outlen, unsigned char *out )
+{
+       int bytes;
+       struct State * encstate = (struct State *) c->encstate;
+
+       /* need to encode minimum of encstate->frame_size samples */
+
+       /*  only add terminator at end of bits */
+       speex_bits_reset(&encstate->bits);
+
+       /* need to encode minimum of encstate->frame_size samples */
+       while(*inlen >= encstate->frame_size)
+       {
+               //fprintf(stderr, "encode: inlen=%d outlen=%d\n", *inlen, *outlen);
+               speex_encode_int(encstate->state, in, &encstate->bits);
+               *inlen -= encstate->frame_size;
+               in += encstate->frame_size;
+       }
+
+       /* add terminator */
+       speex_bits_pack(&encstate->bits, 15, 5);
+
+       bytes = speex_bits_write(&encstate->bits, (char *) out, *outlen);
+
+       /* can an error happen here?  no bytes? */
+       *outlen -= bytes;
+
+       return 0;
+}
+
+struct iaxc_audio_codec *codec_audio_speex_new(struct iaxc_speex_settings *set)
+{
+       struct State * encstate;
+       struct State * decstate;
+       struct iaxc_audio_codec *c = (struct iaxc_audio_codec *)calloc(sizeof(struct iaxc_audio_codec),1);
+       const SpeexMode *sm;
+
+       if(!c)
+               return c;
+
+       strcpy(c->name,"speex");
+       c->format = IAXC_FORMAT_SPEEX;
+       c->encode = encode;
+       c->decode = decode;
+       c->destroy = destroy;
+
+       c->encstate = calloc(sizeof(struct State),1);
+       c->decstate = calloc(sizeof(struct State),1);
+
+       /* leaks a bit on no-memory */
+       if(!(c->encstate && c->decstate))
+               return NULL;
+
+       encstate = (struct State *) c->encstate;
+       decstate = (struct State *) c->decstate;
+
+       sm = speex_lib_get_mode(SPEEX_MODEID_NB);
+
+       encstate->state = speex_encoder_init(sm);
+       decstate->state = speex_decoder_init(sm);
+       speex_bits_init(&encstate->bits);
+       speex_bits_init(&decstate->bits);
+       speex_bits_reset(&encstate->bits);
+       speex_bits_reset(&decstate->bits);
+
+       speex_decoder_ctl(decstate->state, SPEEX_SET_ENH, &set->decode_enhance);
+
+       speex_encoder_ctl(encstate->state, SPEEX_SET_COMPLEXITY, &set->complexity);
+
+       if(set->quality >= 0) {
+               if(set->vbr) {
+                       speex_encoder_ctl(encstate->state, SPEEX_SET_VBR_QUALITY, &set->quality);
+               } else {
+                       int quality = (int)set->quality;
+                       speex_encoder_ctl(encstate->state, SPEEX_SET_QUALITY, &quality);
+               }
+       }
+       if(set->bitrate >= 0)
+               speex_encoder_ctl(encstate->state, SPEEX_SET_BITRATE, &set->bitrate);
+       if(set->vbr)
+               speex_encoder_ctl(encstate->state, SPEEX_SET_VBR, &set->vbr);
+       if(set->abr)
+               speex_encoder_ctl(encstate->state, SPEEX_SET_ABR, &set->abr);
+
+       /* set up frame sizes (normally, this is 20ms worth) */
+       speex_encoder_ctl(encstate->state,SPEEX_GET_FRAME_SIZE,&encstate->frame_size);
+       speex_decoder_ctl(decstate->state,SPEEX_GET_FRAME_SIZE,&decstate->frame_size);
+
+       c->minimum_frame_size = 160;
+
+       if(encstate->frame_size > c->minimum_frame_size)
+               c->minimum_frame_size = encstate->frame_size;
+       if(decstate->frame_size > c->minimum_frame_size)
+               c->minimum_frame_size = decstate->frame_size;
+
+       if(!(encstate->state && decstate->state))
+               return NULL;
+
+       return c;
+}
+
diff --git a/utils/iaxclient/lib/codec_speex.h b/utils/iaxclient/lib/codec_speex.h
new file mode 100644 (file)
index 0000000..72e5682
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003-2006, Horizon Wimba, Inc.
+ * Copyright (C) 2007, Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ */
+
+#include "speex/speex.h"
+
+struct iaxc_speex_settings {
+       int decode_enhance;
+       float quality;
+       int bitrate;
+       int vbr;
+       int abr; /* abr bitrate */
+       int complexity;
+};
+
+struct iaxc_audio_codec *codec_audio_speex_new(struct iaxc_speex_settings *settings);
diff --git a/utils/iaxclient/lib/codec_theora.c b/utils/iaxclient/lib/codec_theora.c
new file mode 100644 (file)
index 0000000..cfa4e25
--- /dev/null
@@ -0,0 +1,502 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003-2006, Horizon Wimba, Inc.
+ * Copyright (C) 2007, Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ * Mihai Balea <mihai at hates dot ms>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ */
+
+/*
+ * Some comments about Theora streaming
+ * Theora video codec has two problems when it comes to streaming
+ * and broadcasting video:
+ *
+ * - Large headers that need to be passed from the encoder to the decoder
+ *   to initialize it. The conventional wisdom says we should transfer the
+ *   headers out of band, but that complicates things with IAX, which does
+ *   not have a separate signalling channel. Also, it makes things really
+ *   difficult in a video conference scenario, where video gets switched
+ *   between participants regularly. To solve this issue, we initialize
+ *   the encoder and the decoder at the same time, using the headers from
+ *   the local encoder to initialize the decoder. This works if the
+ *   endpoints use the exact same version of Theora and the exact same
+ *   parameters for initialization.
+ *
+ * - No support for splitting the frame into multiple slices.  Frames can
+ *   be relatively large. For a 320x240 video stream, you can see key
+ *   frames larger than 9KB, which is the maximum UDP packet size on Mac
+ *   OS X. To work around this limitation, we use the slice API to fragment
+ *   encoded frames to a reasonable size that UDP can safely transport
+ * 
+ * Other miscellaneous comments:
+ *
+ * - For quality reasons, when we detect a video stream switch, we reject all
+ *   incoming frames until we receive a key frame.
+ *
+ * - Theora only accepts video that has dimensions multiple of 16. If we combine
+ *   his with a 4:3 aspect ratio requirement, we get a very limited number
+ *   of available resolutions. To work around this limitation, we pad the video
+ *   on encoding, up to the closest multiple of 16. On the decoding side, we
+ *   remove the padding. This way, video resolution can be any multiple of 2
+ *
+ * We should probably look more into this (how to deal with missing and
+ * out of order slices)
+ */
+
+#include <stdlib.h>
+#include "iaxclient_lib.h"
+#include "video.h"
+#include "slice.h"
+#include "codec_theora.h"
+#include <theora/theora.h>
+
+#define MAX_SLICE_SIZE         8000
+
+struct theora_decoder
+{
+       theora_state            td;
+       theora_info             ti;
+       theora_comment          tc;
+       struct deslicer_context *dsc;
+       int                     got_key_frame;
+};
+
+struct theora_encoder
+{
+       theora_state          td;
+       theora_info           ti;
+       theora_comment        tc;
+       int                   needs_padding;
+       struct slicer_context *sc;
+       unsigned char         *pad_buffer;
+};
+
+static void destroy( struct iaxc_video_codec *c)
+{
+       struct theora_encoder *e;
+       struct theora_decoder *d;
+
+       if ( !c )
+               return;
+
+       if ( c->encstate )
+       {
+               e = (struct theora_encoder *)c->encstate;
+               if ( e->pad_buffer )
+                       free(e->pad_buffer);
+               if ( e->sc )
+                       free_slicer_context(e->sc);
+               theora_comment_clear(&e->tc);
+               theora_info_clear(&e->ti);
+               theora_clear(&e->td);
+               free(e);
+       }
+       if ( c->decstate )
+       {
+               d = (struct theora_decoder *)c->decstate;
+               if ( d->dsc )
+                       free_deslicer_context(d->dsc);
+               theora_comment_clear(&d->tc);
+               theora_info_clear(&d->ti);
+               theora_clear(&d->td);
+               free(c->decstate);
+       }
+       free(c);
+}
+
+static int decode(struct iaxc_video_codec *c, int inlen, const char *in,
+               int *outlen, char *out)
+{
+       struct theora_decoder *d;
+       ogg_packet            op;
+       yuv_buffer            picture;
+       unsigned int          line;
+       int                   my_out_len;
+       int                   w, h, ph; 
+       int                   flen;
+       char                  *frame;
+
+       // Sanity checks
+       if ( !c || !c->decstate || !in || inlen <= 0 || !out || !outlen )
+               return -1;
+
+       // Assemble slices
+       d = (struct theora_decoder *)c->decstate;
+       if ( !d->dsc )
+               return -1;
+
+       frame = deslice(in, inlen, &flen, d->dsc);
+       if ( frame == NULL )
+               return 1;
+       
+       /* decode into an OP structure */
+       memset(&op, 0, sizeof(op));
+       op.bytes = flen;
+       op.packet = (unsigned char *)frame;
+
+       /* reject all incoming frames until we get a key frame */
+       if ( !d->got_key_frame )
+       {
+               if ( theora_packet_iskeyframe(&op) )
+                       d->got_key_frame = 1;
+               else
+                       return 1;
+       }
+
+       if ( theora_decode_packetin(&d->td, &op) == OC_BADPACKET )
+       {
+               fprintf(stderr,
+                       "codec_theora: warning: theora_decode_packetin says bad packet\n");
+               return -1;
+       }
+
+       w = d->ti.frame_width;
+       h = d->ti.frame_height;
+       ph = d->ti.height;
+
+       my_out_len = d->ti.frame_width * d->ti.frame_height * 3 / 2;
+
+       /* make sure we have enough room for the goodies */
+       if ( *outlen < my_out_len )
+       {
+               fprintf(stderr, "codec_theora: not enough room for decoding\n");
+               return -1;
+       }
+
+       /* finally, here's where we get our goodies */
+       if ( theora_decode_YUVout(&d->td, &picture) )
+       {
+               fprintf(stderr, "codec_theora: error getting our goodies\n");
+               return -1;
+       }
+
+       //clear output
+       memset(out, 127, my_out_len);
+
+       for( line = 0 ; line < d->ti.frame_height / 2 ; line++ )
+       {
+               // Y-even
+               memcpy(out + picture.y_width * 2 * line,
+                      picture.y + 2 * line * picture.y_stride,
+                      picture.y_width);
+               // Y-odd
+               memcpy(out + picture.y_width * (2 * line + 1),
+                      picture.y + (2 * line + 1) * picture.y_stride,
+                      picture.y_width);
+               // U + V
+               memcpy(out + (d->ti.frame_width * d->ti.frame_height) + line * d->ti.frame_width / 2,
+                      picture.u + line * picture.uv_stride,
+                      picture.uv_width);
+               memcpy(out + (d->ti.frame_width * d->ti.frame_height * 5 / 4) + line * d->ti.frame_width / 2,
+                      picture.v + line * picture.uv_stride,
+                      picture.uv_width);
+       }
+
+       *outlen = my_out_len;
+
+       return 0;
+}
+
+// Pads a w by h frame to bring it up to pw by ph size using value
+static void pad_channel(const char *src, int w, int h, unsigned char *dst,
+               int pw, int ph, unsigned char value)
+{
+       int i;
+
+       if ( w == pw )
+       {
+               // We don't need to pad each line, just copy the data
+               memcpy(dst, src, w * h);
+       } else
+       {
+               // We DO need to pad each line
+               for ( i=0 ; i<h ; i++ )
+               {
+                       memcpy(&dst[i*pw], &src[i*w], w);
+                       memset(&dst[i*pw+w], value, pw-w);
+               }
+       }
+       // Pad the bottom of the frame if necessary
+       if ( h < ph )
+               memset(dst + pw * h, value, (ph - h) * pw);
+}
+
+static int encode(struct iaxc_video_codec * c, int inlen, const char * in,
+               struct slice_set_t * slice_set)
+{
+       struct theora_encoder   *e;
+       ogg_packet              op;
+       yuv_buffer              picture;
+
+       // Sanity checks
+       if ( !c || !c->encstate || !in || !slice_set )
+               return -1;
+
+       e = (struct theora_encoder *)c->encstate;
+
+       // Prepare the YUV buffer
+       if ( e->needs_padding )
+       {
+               // We copy a padded image into the pad buffer and set up the pointers
+               // Use pad_channel for each of the YUV channels
+               // Use a pad value of 0 for luma and 128 for chroma
+               pad_channel(in,
+                               e->ti.frame_width,
+                               e->ti.frame_height,
+                               e->pad_buffer,
+                               e->ti.width,
+                               e->ti.height,
+                               0);
+
+               pad_channel(in + e->ti.frame_width * e->ti.frame_height,
+                               e->ti.frame_width / 2,
+                               e->ti.frame_height / 2,
+                               e->pad_buffer + e->ti.width * e->ti.height,
+                               e->ti.width / 2,
+                               e->ti.height / 2,
+                               128);
+
+               pad_channel(in + e->ti.frame_width * e->ti.frame_height * 5 / 4,
+                               e->ti.frame_width / 2,
+                               e->ti.frame_height / 2,
+                               e->pad_buffer + e->ti.width * e->ti.height * 5 / 4,
+                               e->ti.width / 2,
+                               e->ti.height / 2,
+                               128);
+
+               picture.y = e->pad_buffer;
+       } else
+       {
+               // use the original buffer
+               picture.y = (unsigned char *)in;
+       }
+       picture.u = picture.y + e->ti.width * e->ti.height;
+       picture.v = picture.u + e->ti.width * e->ti.height / 4;
+       picture.y_width = e->ti.width;
+       picture.y_height = e->ti.height;
+       picture.y_stride = e->ti.width;
+       picture.uv_width = e->ti.width / 2;
+       picture.uv_height = e->ti.height / 2;
+       picture.uv_stride = e->ti.width / 2;
+
+       // Send data in for encoding
+       if ( theora_encode_YUVin(&e->td, &picture) )
+       {
+               fprintf(stderr, "codec_theora: failed theora_encode_YUVin\n");
+               return -1;
+       }
+
+       // Get data from the encoder
+       if ( theora_encode_packetout(&e->td, 0, &op) != 1 )
+       {
+               fprintf(stderr, "codec_theora: failed theora_encode_packetout\n");
+               return -1;
+       }
+
+       // Check to see if we have a key frame
+       slice_set->key_frame = theora_packet_iskeyframe(&op) == 1;
+       
+       // Slice the frame
+       slice((char *)op.packet, op.bytes, slice_set, e->sc);
+
+       return 0;
+}
+
+struct iaxc_video_codec *codec_video_theora_new(int format, int w, int h,
+               int framerate, int bitrate, int fragsize)
+{
+       struct iaxc_video_codec *c;
+       struct theora_encoder   *e;
+       struct theora_decoder   *d;
+       unsigned short          source_id;
+       ogg_packet              headerp, commentp, tablep;
+
+       /* Basic sanity checks */
+       if ( w <= 0 || h <= 0 || framerate <= 0 || bitrate <= 0 || fragsize <= 0 )
+       {
+               fprintf(stderr, "codec_theora: bogus codec params: %d %d %d %d %d\n",
+                               w, h, framerate, bitrate, fragsize);
+               return NULL;
+       }
+
+       if ( w % 2 || h % 2 )
+       {
+               fprintf(stderr, "codec_theora: video dimensions must be multiples of 2\n");
+               return NULL;
+       }
+
+       if ( fragsize > MAX_SLICE_SIZE )
+               fragsize = MAX_SLICE_SIZE;
+
+       c = (struct iaxc_video_codec *)calloc(sizeof(struct iaxc_video_codec), 1);
+
+       if ( !c )
+               goto bail;
+
+       c->decstate = calloc(sizeof(struct theora_decoder), 1);
+
+       if ( !c->decstate )
+               goto bail;
+
+       c->encstate = calloc(sizeof(struct theora_encoder), 1);
+
+       if ( !c->encstate )
+               goto bail;
+
+       c->format = format;
+       c->width = w;
+       c->height = h;
+       c->framerate = framerate;
+       c->bitrate = bitrate;
+       c->fragsize = fragsize;
+
+       c->encode = encode;
+       c->decode = decode;
+       c->destroy = destroy;
+
+       e = (struct theora_encoder *)c->encstate;
+       d = (struct theora_decoder *)c->decstate;
+
+       // Initialize slicer    
+       // Generate random source id
+       srand((unsigned int)time(0));
+       source_id = rand() & 0xffff;
+       e->sc = create_slicer_context(source_id, fragsize);
+       if ( !e->sc ) 
+               goto bail;
+       
+       
+       /* set up some parameters in the contexts */
+
+       theora_info_init(&e->ti);
+
+       /* set up common parameters */
+       e->ti.frame_width = w;
+       e->ti.frame_height = h;
+       e->ti.width = ((w - 1) / 16 + 1) * 16;
+       e->ti.height = ((h - 1) / 16 + 1) * 16;
+       e->ti.offset_x = 0;
+       e->ti.offset_y = 0;
+
+       // We set up a padded frame with dimensions that are multiple of 16
+       // We allocate a buffer to hold this frame
+       e->needs_padding = e->ti.width != e->ti.frame_width ||
+               e->ti.height != e->ti.frame_height;
+
+       if ( e->needs_padding )
+       {
+               e->pad_buffer = (unsigned char *)
+                       malloc(e->ti.width * e->ti.height * 3 / 2);
+
+               if ( !e->pad_buffer )
+                       goto bail;
+       }
+       else
+       {
+               e->pad_buffer = 0;
+       }
+
+       e->ti.fps_numerator = framerate;
+       e->ti.fps_denominator = 1;
+
+       e->ti.aspect_numerator = 1;
+       e->ti.aspect_denominator = 1;
+
+       e->ti.colorspace = OC_CS_UNSPECIFIED;
+       e->ti.pixelformat = OC_PF_420;
+
+       e->ti.target_bitrate = bitrate;
+
+       e->ti.quality = 0;
+
+       e->ti.dropframes_p = 0;
+       e->ti.quick_p = 1;
+       e->ti.keyframe_auto_p = 0;
+       e->ti.keyframe_frequency = framerate;
+       e->ti.keyframe_frequency_force = framerate;
+       e->ti.keyframe_data_target_bitrate = bitrate * 3;
+       e->ti.keyframe_auto_threshold = 80;
+       e->ti.keyframe_mindistance = 8;
+       e->ti.noise_sensitivity = 0;
+
+       if ( theora_encode_init(&e->td, &e->ti) )
+               goto bail;
+
+       // Obtain the encoder headers and set up the decoder headers from
+       // data in the encoder headers
+       memset(&headerp, 0, sizeof(headerp));
+       memset(&commentp, 0, sizeof(commentp));
+       memset(&tablep, 0, sizeof(tablep));
+
+       // Set up the decoder using the encoder headers
+       theora_info_init(&d->ti);
+       theora_comment_init(&d->tc);
+       theora_comment_init(&e->tc);
+
+       if ( theora_encode_header(&e->td, &headerp) )
+               goto bail;
+
+       headerp.b_o_s = 1;
+
+       if ( theora_decode_header(&d->ti, &d->tc, &headerp) )
+               goto bail;
+
+       if ( theora_encode_comment(&e->tc, &commentp) )
+               goto bail;
+
+       if ( theora_decode_header(&d->ti, &d->tc, &commentp) )
+               goto bail;
+
+       theora_comment_clear(&e->tc);
+
+       if ( theora_encode_tables(&e->td, &tablep) )
+               goto bail;
+
+       if ( theora_decode_header(&d->ti, &d->tc, &tablep) )
+               goto bail;
+
+       if ( theora_decode_init(&d->td, &d->ti) )
+               goto bail;
+
+       d->got_key_frame = 0;
+       
+       // Initialize deslicer context
+       d->dsc = create_deslicer_context(c->fragsize);
+       if ( !d->dsc )
+               goto bail;
+
+       strcpy(c->name, "Theora");
+       return c;
+
+bail:
+       fprintf(stderr, "codec_theora: failed to initialize encoder or decoder\n");
+
+       if ( c )
+       {
+               if ( c->encstate )
+               {
+                       e = (struct theora_encoder *)c->encstate;
+                       if ( e->sc )
+                               free_slicer_context(e->sc);
+                       free(c->encstate);
+               }
+               if ( c->decstate )
+               {
+                       d = (struct theora_decoder *)c->decstate;
+                       if ( d->dsc )
+                               free_deslicer_context(d->dsc);
+                       free(c->decstate);
+               }
+               free(c);
+       }
+
+       return NULL;
+}
+
diff --git a/utils/iaxclient/lib/codec_theora.h b/utils/iaxclient/lib/codec_theora.h
new file mode 100644 (file)
index 0000000..ddda931
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003-2006, Horizon Wimba, Inc.
+ * Copyright (C) 2007, Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ * Mihai Balea <mihai at hates dot ms>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ */
+
+struct iaxc_video_codec *codec_video_theora_new(int format, int w, int h,
+               int framerate, int bitrate, int fragsize);
diff --git a/utils/iaxclient/lib/codec_ulaw.c b/utils/iaxclient/lib/codec_ulaw.c
new file mode 100644 (file)
index 0000000..4910e0d
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003-2006, Horizon Wimba, Inc.
+ * Copyright (C) 2007, Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ */
+
+#include "codec_ulaw.h"
+#include "iaxclient_lib.h"
+
+struct state {
+    plc_state_t plc;
+};
+
+static short ulaw_2lin [256];
+static unsigned char lin_2ulaw [16384];
+static int initialized=0;
+
+/* this looks similar to asterisk, but comes from public domain code by craig reese
+   I've just followed asterisk's table sizes for lin_2u, and also too lazy to do binary arith to decide which
+   iterations to skip -- this way we get the same result.. */
+static void initialize() {
+    int i;
+
+    /* ulaw_2lin */
+    for(i=0;i<256;i++) {
+         int b = ~i;
+         int exp_lut[8] = {0,132,396,924,1980,4092,8316,16764};
+         int sign, exponent, mantissa, sample;
+
+         sign = (b & 0x80);
+         exponent = (b >> 4) & 0x07;
+         mantissa = b & 0x0F;
+         sample = exp_lut[exponent] + (mantissa << (exponent + 3));
+         if (sign != 0) sample = -sample;
+         ulaw_2lin[i] = sample;
+    }
+
+    /* lin_2ulaw */
+    for(i=-32767;i<32768;i+=4) {
+       int sample = i;
+       int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
+                             4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+                             5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+                             5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+                             6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+                             6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+                             6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+                             6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+                             7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+                             7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+                             7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+                             7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+                             7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+                             7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+                             7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+                             7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
+       int sign, exponent, mantissa;
+       unsigned char ulawbyte;
+
+       /* Get the sample into sign-magnitude. */
+       sign = (sample >> 8) & 0x80;            /* set aside the sign */
+       if (sign != 0) sample = -sample;                /* get magnitude */
+       if (sample > 32635) sample = 32635;             /* clip the magnitude */
+
+       /* Convert from 16 bit linear to ulaw. */
+       sample = sample + 0x84;
+       exponent = exp_lut[(sample >> 7) & 0xFF];
+       mantissa = (sample >> (exponent + 3)) & 0x0F;
+       ulawbyte = ~(sign | (exponent << 4) | mantissa);
+       if (ulawbyte == 0) ulawbyte = 0x02;     /* optional CCITT trap */
+
+       lin_2ulaw[((unsigned short)i) >> 2] = ulawbyte;
+    }
+
+    initialized = 1;
+}
+
+static void destroy ( struct iaxc_audio_codec *c) {
+       if ( c->decstate )
+               free(c->decstate);
+       free(c);
+}
+
+
+static int decode ( struct iaxc_audio_codec *c,
+    int *inlen, unsigned char *in, int *outlen, short *out ) {
+    struct state *state = (struct state *)c->decstate;
+    short *orig_out = out;
+    short sample;
+
+    if(*inlen == 0) {
+       int interp_len = 160;
+       if(*outlen < interp_len) interp_len = *outlen;
+       plc_fillin(&state->plc,out,interp_len);
+       *outlen -= interp_len;
+       return 0;
+    }
+
+    while ((*inlen > 0) && (*outlen > 0)) {
+       sample = ulaw_2lin[(unsigned char)*(in++)];
+       *(out++) = sample;
+       (*inlen)--; (*outlen)--;
+    }
+    plc_rx(&state->plc, orig_out, (int)(out - orig_out));
+
+    return 0;
+}
+
+static int encode ( struct iaxc_audio_codec *c,
+    int *inlen, short *in, int *outlen, unsigned char *out ) {
+
+    while ((*inlen > 0) && (*outlen > 0)) {
+       *(out++) = lin_2ulaw[((unsigned short)*(in++)) >> 2];
+       (*inlen)--; (*outlen)--;
+    }
+
+    return 0;
+}
+
+
+struct iaxc_audio_codec *codec_audio_ulaw_new() {
+
+  struct iaxc_audio_codec *c = (struct iaxc_audio_codec *)calloc(sizeof(struct iaxc_audio_codec),1);
+
+  if(!c) return c;
+
+  if(!initialized) initialize();
+
+  strcpy(c->name,"ulaw");
+  c->format = IAXC_FORMAT_ULAW;
+  c->encode = encode;
+  c->decode = decode;
+  c->destroy = destroy;
+
+  /* really, we can use less, but don't want to */
+  c->minimum_frame_size = 160;
+
+  /* decoder state, used for interpolation */
+  c->decstate = calloc(sizeof(struct state),1);
+  plc_init(&((struct state *)c->decstate)->plc);
+
+  return c;
+}
+
diff --git a/utils/iaxclient/lib/codec_ulaw.h b/utils/iaxclient/lib/codec_ulaw.h
new file mode 100644 (file)
index 0000000..26cf413
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003-2006, Horizon Wimba, Inc.
+ * Copyright (C) 2007, Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ */
+
+struct iaxc_audio_codec *codec_audio_ulaw_new();
diff --git a/utils/iaxclient/lib/gsm/copyright b/utils/iaxclient/lib/gsm/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/utils/iaxclient/lib/gsm/inc/config.h b/utils/iaxclient/lib/gsm/inc/config.h
new file mode 100644 (file)
index 0000000..1fb3d70
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+/*$Header$*/
+
+#ifndef        CONFIG_H
+#define        CONFIG_H
+
+/*efine        SIGHANDLER_T    int             / * signal handlers are void    */
+/*efine HAS_SYSV_SIGNAL        1               / * sigs not blocked/reset?     */
+
+#define        HAS_STDLIB_H    1               /* /usr/include/stdlib.h        */
+/*efine        HAS_LIMITS_H    1               / * /usr/include/limits.h       */
+#define        HAS_FCNTL_H     1               /* /usr/include/fcntl.h         */
+/*efine        HAS_ERRNO_DECL  1               / * errno.h declares errno      */
+
+#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                */
+/*efine        HAS__FSETMODE   1               / * _fsetmode -- set file mode  */
+
+#define        HAS_STRING_H    1               /* /usr/include/string.h        */
+/*efine        HAS_STRINGS_H   1               / * /usr/include/strings.h      */
+
+#define        HAS_UNISTD_H    1               /* /usr/include/unistd.h        */
+#define        HAS_UTIME       1               /* POSIX utime(path, times)     */
+/*efine        HAS_UTIMES      1               / * use utimes()        syscall instead */
+#define        HAS_UTIME_H     1               /* UTIME header file            */
+/*efine        HAS_UTIMBUF     1               / * struct utimbuf              */
+/*efine        HAS_UTIMEUSEC   1               / * microseconds in utimbuf?    */
+
+#endif /* CONFIG_H */
diff --git a/utils/iaxclient/lib/gsm/inc/gsm.h b/utils/iaxclient/lib/gsm/inc/gsm.h
new file mode 100644 (file)
index 0000000..81065e5
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+/*$Header$*/
+
+#ifndef        GSM_H
+#define        GSM_H
+
+#ifdef __cplusplus
+#      define  NeedFunctionPrototypes  1
+#endif
+
+#if __STDC__
+#      define  NeedFunctionPrototypes  1
+#endif
+
+#ifdef _NO_PROTO
+#      undef   NeedFunctionPrototypes
+#endif
+
+#ifdef NeedFunctionPrototypes
+#   include    <stdio.h>               /* for FILE *   */
+#endif
+
+#undef GSM_P
+#if NeedFunctionPrototypes
+#      define  GSM_P( protos ) protos
+#else
+#      define  GSM_P( protos ) ( /* protos */ )
+#endif
+
+/*
+ *     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
+
+extern gsm  gsm_create         GSM_P((void));
+extern void gsm_destroy GSM_P((gsm));  
+
+extern int  gsm_print   GSM_P((FILE *, gsm, gsm_byte  *));
+extern int  gsm_option  GSM_P((gsm, int, int *));
+
+extern void gsm_encode  GSM_P((gsm, gsm_signal *, gsm_byte  *));
+extern int  gsm_decode  GSM_P((gsm, gsm_byte   *, gsm_signal *));
+
+extern int  gsm_explode GSM_P((gsm, gsm_byte   *, gsm_signal *));
+extern void gsm_implode GSM_P((gsm, gsm_signal *, gsm_byte   *));
+
+#undef GSM_P
+
+#endif /* GSM_H */
diff --git a/utils/iaxclient/lib/gsm/inc/private.h b/utils/iaxclient/lib/gsm/inc/private.h
new file mode 100644 (file)
index 0000000..19c14ce
--- /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.
+ */
+
+/*$Header$*/
+
+#ifndef        PRIVATE_H
+#define        PRIVATE_H
+
+typedef short                  word;           /* 16 bit signed int    */
+typedef long                   longword;       /* 32 bit signed int    */
+
+typedef unsigned short         uword;          /* unsigned word        */
+typedef unsigned long          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 */
+};
+
+
+#define        MIN_WORD        (-32767 - 1)
+#define        MAX_WORD          32767
+
+#define        MIN_LONGWORD    (-2147483647 - 1)
+#define        MAX_LONGWORD      2147483647
+
+#ifdef SASR            /* flag: >> is a signed arithmetic shift right */
+#undef SASR
+#define        SASR(x, by)     ((x) >> (by))
+#else
+#define        SASR(x, by)     ((x) >= 0 ? (x) >> (by) : (~(-((x) + 1) >> (by))))
+#endif /* SASR */
+
+#include "proto.h"
+
+/*
+ *     Prototypes from add.c
+ */
+extern word    gsm_mult        P((word a, word b));
+extern longword gsm_L_mult     P((word a, word b));
+extern word    gsm_mult_r      P((word a, word b));
+
+extern word    gsm_div         P((word num, word denum));
+
+extern word    gsm_add         P(( word a, word b ));
+extern longword gsm_L_add      P(( longword a, longword b ));
+
+extern word    gsm_sub         P((word a, word b));
+extern longword gsm_L_sub      P((longword a, longword b));
+
+extern word    gsm_abs         P((word a));
+
+extern word    gsm_norm        P(( longword a ));
+
+extern longword gsm_L_asl      P((longword a, int n));
+extern word    gsm_asl         P((word a, int n));
+
+extern longword gsm_L_asr      P((longword a, int n));
+extern word    gsm_asr         P((word a, int n));
+
+/*
+ *  Inlined functions from add.h 
+ */
+
+/* 
+ * #define GSM_MULT_R(a, b) (* word a, word b, !(a == b == MIN_WORD) *)        \
+ *     (0x0FFFF & SASR(((longword)(a) * (longword)(b) + 16384), 15))
+ */
+#define GSM_MULT_R(a, b) /* word a, word b, !(a == b == MIN_WORD) */   \
+       (SASR( ((longword)(a) * (longword)(b) + 16384), 15 ))
+
+# define GSM_MULT(a,b)  /* word a, word b, !(a == b == MIN_WORD) */    \
+       (SASR( ((longword)(a) * (longword)(b)), 15 ))
+
+# define GSM_L_MULT(a, b) /* word a, word b */ \
+       (((longword)(a) * (longword)(b)) << 1)
+
+#if defined(__GNUC__) && defined(__i386__)
+
+static __inline__ int GSM_L_ADD(int a, int b)
+{
+       __asm__ __volatile__(
+       
+                       "addl %2,%0; jno 0f; movl $0x7fffffff,%0; adcl $0,%0; 0:"
+                       : "=r" (a)
+                       : "0" (a), "ir" (b)
+                       : "cc"
+               );
+       return(a);
+}
+
+static __inline__ short GSM_ADD(short a, short b)
+{
+       __asm__ __volatile__(
+                       "addw %2,%0; jno 0f; movw $0x7fff,%0; adcw $0,%0; 0:"
+                       : "=r" (a)
+                       : "0" (a), "ir" (b)
+                       : "cc"
+               );
+       return(a);
+}
+
+static __inline__ short GSM_SUB(short a, short b)
+{
+       __asm__ __volatile__(
+                       "subw %2,%0; jno 0f; movw $0x7fff,%0; adcw $0,%0; 0:"
+                       : "=r" (a)
+                       : "0" (a), "ir" (b)
+                       : "cc"
+               );
+       return(a);
+}
+
+#else
+
+# define GSM_L_ADD(a, b)       \
+       ( (a) <  0 ? ( (b) >= 0 ? (a) + (b)     \
+                : (utmp = (ulongword)-((a) + 1) + (ulongword)-((b) + 1)) \
+                  >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)utmp-2 )   \
+       : ((b) <= 0 ? (a) + (b)   \
+                 : (utmp = (ulongword)(a) + (ulongword)(b)) >= MAX_LONGWORD \
+                   ? MAX_LONGWORD : utmp))
+
+/*
+ * # define GSM_ADD(a, b)      \
+ *     ((ltmp = (longword)(a) + (longword)(b)) >= MAX_WORD \
+ *     ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp)
+ */
+/* Nonportable, but faster: */
+
+#define        GSM_ADD(a, b)   \
+       (short) ((ulongword)((ltmp = (longword)(a) + (longword)(b)) - MIN_WORD) > \
+               MAX_WORD - MIN_WORD ? (ltmp > 0 ? MAX_WORD : MIN_WORD) : ltmp)
+
+# define GSM_SUB(a, b) \
+       ((ltmp = (longword)(a) - (longword)(b)) >= MAX_WORD \
+       ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp)
+
+#endif
+
+# define GSM_ABS(a)    ((a) < 0 ? ((a) == MIN_WORD ? MAX_WORD : -(a)) : (a))
+
+/* Use these if necessary:
+
+# define GSM_MULT_R(a, b)      gsm_mult_r(a, b)
+# define GSM_MULT(a, b)                gsm_mult(a, b)
+# define GSM_L_MULT(a, b)      gsm_L_mult(a, b)
+
+# define GSM_L_ADD(a, b)       gsm_L_add(a, b)
+# define GSM_ADD(a, b)         gsm_add(a, b)
+# define GSM_SUB(a, b)         gsm_sub(a, b)
+
+# define GSM_ABS(a)            gsm_abs(a)
+
+*/
+
+/*
+ *  More prototypes from implementations..
+ */
+extern void Gsm_Coder P((
+               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    */));
+
+extern void Gsm_Long_Term_Predictor P((                /* 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     */));
+
+extern void Gsm_LPC_Analysis P((
+               struct gsm_state * S,
+               word * s,        /* 0..159 signals      IN/OUT  */
+               word * LARc));   /* 0..7   LARc's       OUT     */
+
+extern void Gsm_Preprocess P((
+               struct gsm_state * S,
+               word * s, word * so));
+
+extern void Gsm_Encoding P((
+               struct gsm_state * S,
+               word    * e,    
+               word    * ep,   
+               word    * xmaxc,
+               word    * Mc,   
+               word    * xMc));
+
+extern void Gsm_Short_Term_Analysis_Filter P((
+               struct gsm_state * S,
+               word    * LARc, /* coded log area ratio [0..7]  IN      */
+               word    * d     /* st res. signal [0..159]      IN/OUT  */));
+
+extern void Gsm_Decoder P((
+               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     */
+
+extern void Gsm_Decoding P((
+               struct gsm_state * S,
+               word    xmaxcr,
+               word    Mcr,
+               word    * xMcr,         /* [0..12]              IN      */
+               word    * erp));        /* [0..39]              OUT     */
+
+extern void Gsm_Long_Term_Synthesis_Filtering P((
+               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 P((
+       struct gsm_state *S,
+               word xmaxcr,
+               word Mcr,
+               word * xMcr,  /* [0..12], 3 bits             IN      */
+               word * erp)); /* [0..39]                     OUT     */
+
+void Gsm_RPE_Encoding P((
+               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 */
+
+extern void Gsm_Short_Term_Synthesis_Filter P((
+               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   */
+
+extern void Gsm_Update_of_reconstructed_short_time_residual_signal P((
+               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 */
+
+       extern void  gsm_debug_words     P((char * name, int, int, word *));
+       extern void  gsm_debug_longwords P((char * name, int, int, longword *));
+       extern void  gsm_debug_longword  P((char * name, longword));
+       extern void  gsm_debug_word      P((char * name, word));
+
+#endif /* !NDEBUG */
+
+#include "unproto.h"
+
+#endif /* PRIVATE_H */
diff --git a/utils/iaxclient/lib/gsm/inc/proto.h b/utils/iaxclient/lib/gsm/inc/proto.h
new file mode 100644 (file)
index 0000000..87cf05e
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+/*$Header$*/
+
+#ifndef        PROTO_H
+#define        PROTO_H
+
+#if __cplusplus
+#      define  NeedFunctionPrototypes  1
+#endif
+
+#if __STDC__
+#      define  NeedFunctionPrototypes  1
+#endif
+
+#ifdef _NO_PROTO
+#      undef   NeedFunctionPrototypes
+#endif
+
+#undef P       /* gnu stdio.h actually defines this...         */
+#undef P0
+#undef P1
+#undef P2
+#undef P3
+#undef P4
+#undef P5
+#undef P6
+#undef P7
+#undef P8
+
+#if NeedFunctionPrototypes
+
+#      define  P( protos )     protos
+
+#      define  P0()                            (void)
+#      define  P1(x, a)                        (a)
+#      define  P2(x, a, b)                     (a, b)
+#      define  P3(x, a, b, c)                  (a, b, c)
+#      define  P4(x, a, b, c, d)               (a, b, c, d)    
+#      define  P5(x, a, b, c, d, e)            (a, b, c, d, e)
+#      define  P6(x, a, b, c, d, e, f)         (a, b, c, d, e, f)
+#      define  P7(x, a, b, c, d, e, f, g)      (a, b, c, d, e, f, g)
+#      define  P8(x, a, b, c, d, e, f, g, h)   (a, b, c, d, e, f, g, h)
+
+#else /* !NeedFunctionPrototypes */
+
+#      define  P( protos )     ( /* protos */ )
+
+#      define  P0()                            ()
+#      define  P1(x, a)                        x a;
+#      define  P2(x, a, b)                     x a; b;
+#      define  P3(x, a, b, c)                  x a; b; c;
+#      define  P4(x, a, b, c, d)               x a; b; c; d;
+#      define  P5(x, a, b, c, d, e)            x a; b; c; d; e;
+#      define  P6(x, a, b, c, d, e, f)         x a; b; c; d; e; f;
+#      define  P7(x, a, b, c, d, e, f, g)      x a; b; c; d; e; f; g;
+#      define  P8(x, a, b, c, d, e, f, g, h)   x a; b; c; d; e; f; g; h;
+
+#endif  /* !NeedFunctionPrototypes */
+
+#endif /* PROTO_H */
diff --git a/utils/iaxclient/lib/gsm/inc/unproto.h b/utils/iaxclient/lib/gsm/inc/unproto.h
new file mode 100644 (file)
index 0000000..ccd5651
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+/*$Header$*/
+
+#ifdef PROTO_H         /* sic */
+#undef PROTO_H
+
+#undef P
+#undef P0
+#undef P1
+#undef P2
+#undef P3
+#undef P4
+#undef P5
+#undef P6
+#undef P7
+#undef P8
+
+#endif /* PROTO_H */
diff --git a/utils/iaxclient/lib/gsm/libgsm.prj b/utils/iaxclient/lib/gsm/libgsm.prj
new file mode 100644 (file)
index 0000000..f908e56
--- /dev/null
@@ -0,0 +1,65 @@
+; Wedit project file. Syntax: Name = value
+[libgsm]
+PrjFiles=18
+File1=SRC\TABLE.C
+File2=SRC\SHORT_TERM.C
+File3=SRC\RPE.C
+File4=SRC\PREPROCESS.C
+File5=SRC\LPC.C
+File6=SRC\LONG_TERM.C
+File7=SRC\GSM_PRINT.C
+File8=SRC\GSM_OPTION.C
+File9=SRC\GSM_IMPLODE.C
+File10=SRC\GSM_EXPLODE.C
+File11=SRC\GSM_ENCODE.C
+File12=SRC\GSM_DESTROY.C
+File13=SRC\GSM_DECODE.C
+File14=SRC\GSM_CREATE.C
+File15=SRC\DECODE.C
+File16=SRC\DEBUG.C
+File17=SRC\CODE.C
+File18=SRC\ADD.C
+UserCount=1
+User1=ADMINISTRATOR
+CmsDirectory=Z:\utils\tools\IAX\DLL\gsm\CMS
+PutOptions=4
+GetOptions=0
+FileOptions=0
+LockOptions=1
+UsersOptions=1
+ProjectFlags=0
+ExtraCmsFilesCount=0
+File19=SRC\LPC.C
+File20=SRC\PREPROCESS.C
+File21=SRC\RPE.C
+File22=SRC\SHORT_TERM.C
+File23=SRC\TABLE.C
+Frame=0 108 765 642
+StatusBar=0,0,0,0
+Name=libgsm
+CurrentFile=
+OpenFiles=0
+ProjectPath=Z:\UTILS\TOOLS\IAX\DLL\GSM
+SourcesDir=Z:\utils\tools\IAX\DLL\gsm
+Defines=
+Includes=c:\programme\lcc\include;z:\utils\tools\iax\dll\gsm\inc
+Libraries=
+LinkerArgs=
+ProjectTime=1218
+MakeName=c:\programme\lcc\bin\make.exe
+MakeDir=Z:\utils\tools\IAX\DLL\gsm\lcc
+Exe=z:\utils\tools\iax\dll\gsm\lcc\libgsm.lib
+DebuggerArguments=
+DbgExeName=z:\utils\tools\iax\dll\gsm\lcc\libgsm.lib
+DbgDir=z:\utils\tools\iax\dll\gsm\lcc
+CompilerFlags=1032
+FortranFlags=0
+EiffelFlags=0
+Useframework=0
+NumberOfBreakpoints=0
+ErrorFile=
+NrOfFileProcessors=0
+UserName=ADMINISTRATOR
+OpenFile1="z:\utils\tools\iax\dll\gsm\src\table.c" 18 146 204 820 391
+OpenFile2="c:\test\ax\gsm\src\code.c" 12 181 233 877 610
+File24=C:\PROGRAMME\LCC\LIB\LIBC.LIB
diff --git a/utils/iaxclient/lib/gsm/readme b/utils/iaxclient/lib/gsm/readme
new file mode 100644 (file)
index 0000000..cb6af85
--- /dev/null
@@ -0,0 +1,37 @@
+
+GSM 06.10 13 kbit/s RPE/LTP speech compression available
+--------------------------------------------------------
+
+The Communications and Operating Systems Research Group (KBS) at the
+Technische Universitaet Berlin is currently working on a set of
+UNIX-based tools for computer-mediated telecooperation that will be
+made freely available.
+
+As part of this effort we are publishing an implementation of the
+European GSM 06.10 provisional standard for full-rate speech
+transcoding, prI-ETS 300 036, which uses RPE/LTP (residual pulse
+excitation/long term prediction) coding at 13 kbit/s.
+
+GSM 06.10 compresses frames of 160 13-bit samples (8 kHz sampling
+rate, i.e. a frame rate of 50 Hz) into 260 bits; for compatibility
+with typical UNIX applications, our implementation turns frames of 160
+16-bit linear samples into 33-byte frames (1650 Bytes/s).
+The quality of the algorithm is good enough for reliable speaker
+recognition; even music often survives transcoding in recognizable 
+form (given the bandwidth limitations of 8 kHz sampling rate).
+
+The interfaces offered are a front end modelled after compress(1), and
+a library API.  Compression and decompression run faster than realtime
+on most SPARCstations.  The implementation has been verified against the
+ETSI standard test patterns.
+
+Jutta Degener (jutta@cs.tu-berlin.de)
+Carsten Bormann (cabo@cs.tu-berlin.de)
+
+Communications and Operating Systems Research Group, TU Berlin
+Fax: +49.30.31425156, Phone: +49.30.31424315
+
+--
+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.
diff --git a/utils/iaxclient/lib/gsm/src/add.c b/utils/iaxclient/lib/gsm/src/add.c
new file mode 100644 (file)
index 0000000..d8a21c0
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+/*
+ *  See private.h for the more commonly used macro versions.
+ */
+
+#include       <stdio.h>
+#include       <assert.h>
+
+#include       "private.h"
+#include       "gsm.h"
+#include       "proto.h"
+
+#define        saturate(x)     \
+       ((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x))
+
+word gsm_add P2((a,b), word a, word b)
+{
+       longword sum = (longword)a + (longword)b;
+       return (word) saturate(sum);
+}
+
+word gsm_sub P2((a,b), word a, word b)
+{
+       longword diff = (longword)a - (longword)b;
+       return (word) saturate(diff);
+}
+
+word gsm_mult P2((a,b), word a, word b)
+{
+       if (a == MIN_WORD && b == MIN_WORD) return MAX_WORD;
+       else return SASR( (longword)a * (longword)b, 15 );
+}
+
+word gsm_mult_r P2((a,b), 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 P1((a), word a)
+{
+       return a < 0 ? (a == MIN_WORD ? MAX_WORD : -a) : a;
+}
+
+longword gsm_L_mult P2((a,b),word a, word b)
+{
+       assert( a != MIN_WORD || b != MIN_WORD );
+       return ((longword)a * (longword)b) << 1;
+}
+
+longword gsm_L_add P2((a,b), 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 P2((a,b), 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 P1((a), 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 P2((a,n), 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_asl P2((a,n), 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 P2((a,n), longword a, int n)
+{
+       if (n >= 32) return -(a < 0);
+       if (n <= -32) return 0;
+       if (n < 0) return a << -n;
+
+#      ifdef   SASR
+               return a >> n;
+#      else
+               if (a >= 0) return a >> n;
+               else return -(longword)( -(ulongword)a >> n );
+#      endif
+}
+
+word gsm_asr P2((a,n), word a, int n)
+{
+       if (n >= 16) return -(a < 0);
+       if (n <= -16) return 0;
+       if (n < 0) return a << -n;
+
+#      ifdef   SASR
+               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 P2((num,denum), 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;
+}
diff --git a/utils/iaxclient/lib/gsm/src/code.c b/utils/iaxclient/lib/gsm/src/code.c
new file mode 100644 (file)
index 0000000..98ad884
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include       "config.h"
+
+
+//#ifdef       HAS_STDLIB_H
+#include       <stdlib.h>
+//#else
+#      include "proto.h"
+#      include "string.h"
+       //extern char   * memcpy P((char *, char *, int));
+//#endif
+
+#include       "private.h"
+#include       "gsm.h"
+#include       "proto.h"
+
+/*
+ *  4.2 FIXED POINT IMPLEMENTATION OF THE RPE-LTP CODER
+ */
+
+void Gsm_Coder P8((S,s,LARc,Nc,bc,Mc,xmaxc,xMc),
+
+       struct gsm_state        * S,
+
+       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  = S->dp0 + 120;   /* [ -120...-1 ] */
+       word    * dpp = dp;             /* [ 0...39 ]    */
+
+       static word e[50];
+
+       word    so[160];
+
+       Gsm_Preprocess                  (S, s, so);
+       Gsm_LPC_Analysis                (S, so, LARc);
+       Gsm_Short_Term_Analysis_Filter  (S, LARc, so);
+
+       for (k = 0; k <= 3; k++, xMc += 13) {
+
+               Gsm_Long_Term_Predictor ( S,
+                                        so+k*40, /* d      [0..39] IN  */
+                                        dp,      /* dp  [-120..-1] IN  */
+                                       e + 5,    /* e      [0..39] OUT */
+                                       dpp,      /* dpp    [0..39] OUT */
+                                        Nc++,
+                                        bc++);
+
+               Gsm_RPE_Encoding        ( S,
+                                       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;
+                 register longword ltmp;
+                 for (i = 0; i <= 39; i++)
+                       dp[ i ] = GSM_ADD( e[5 + i], dpp[i] );
+               }
+               dp  += 40;
+               dpp += 40;
+
+       }
+       (void)memcpy( (char *)S->dp0, (char *)(S->dp0 + 160),
+               120 * sizeof(*S->dp0) );
+}
diff --git a/utils/iaxclient/lib/gsm/src/debug.c b/utils/iaxclient/lib/gsm/src/debug.c
new file mode 100644 (file)
index 0000000..22dfa80
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include "private.h"
+
+#ifndef        NDEBUG
+
+/* If NDEBUG _is_ defined and no debugging should be performed,
+ * calls to functions in this module are #defined to nothing
+ * in private.h.
+ */
+
+#include <stdio.h>
+#include "proto.h"
+
+void gsm_debug_words P4( (name, from, to, ptr), 
+       char          * name,
+       int             from,
+       int             to,
+       word            * ptr)
+{
+       int     nprinted = 0;
+
+       fprintf( stderr, "%s [%d .. %d]: ", name, from, to );
+       while (from <= to) {
+               fprintf(stderr, "%d ", ptr[ from ] );
+               from++;
+               if (nprinted++ >= 7) {
+                       nprinted = 0;
+                       if (from < to) putc('\n', stderr);
+               }
+       }
+       putc('\n', stderr);
+}
+
+void gsm_debug_longwords P4( (name, from, to, ptr),
+       char          * name,
+       int             from,
+       int             to,
+       longword      * ptr)
+{
+       int     nprinted = 0;
+
+       fprintf( stderr, "%s [%d .. %d]: ", name, from, to );
+       while (from <= to) {
+
+               fprintf(stderr, "%d ", ptr[ from ] );
+               from++;
+               if (nprinted++ >= 7) {
+                       nprinted = 0;
+                       if (from < to) putc('\n', stderr);
+               }
+       }
+       putc('\n', stderr);
+}
+
+void gsm_debug_longword P2(  (name, value),
+       char            * name,
+       longword          value )
+{
+       fprintf(stderr, "%s: %d\n", name, (long)value );
+}
+
+void gsm_debug_word P2(  (name, value),
+       char    * name,
+       word      value )
+{
+       fprintf(stderr, "%s: %d\n", name, (long)value);
+}
+
+#endif
diff --git a/utils/iaxclient/lib/gsm/src/decode.c b/utils/iaxclient/lib/gsm/src/decode.c
new file mode 100644 (file)
index 0000000..34e5586
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include <stdio.h>
+
+#include       "private.h"
+#include       "gsm.h"
+#include       "proto.h"
+
+/*
+ *  4.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER
+ */
+
+static void Postprocessing P2((S,s),
+       struct gsm_state        * S,
+       register word           * s)
+{
+       register int            k;
+       register word           msr = S->msr;
+       register longword       ltmp;   /* for GSM_ADD */
+       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 P8((S,LARcr, Ncr,bcr,Mcr,xmaxcr,xMcr,s),
+       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);
+}
diff --git a/utils/iaxclient/lib/gsm/src/gsm_create.c b/utils/iaxclient/lib/gsm/src/gsm_create.c
new file mode 100644 (file)
index 0000000..a59aa2f
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+static char const      ident[] = "$Header$";
+
+#include       "config.h"
+
+#ifdef HAS_STRING_H
+#include       <string.h>
+#else
+#      include "proto.h"
+       extern char     * memset P((char *, int, int));
+#endif
+
+#ifdef HAS_STDLIB_H
+#      include <stdlib.h>
+#else
+#      ifdef   HAS_MALLOC_H
+#              include         <malloc.h>
+#      else
+               extern char * malloc();
+#      endif
+#endif
+
+#include <stdio.h>
+
+#include "gsm.h"
+#include "private.h"
+#include "proto.h"
+
+gsm gsm_create P0()
+{
+       gsm  r;
+
+       r = (gsm)malloc(sizeof(struct gsm_state));
+       if (!r) return r;
+
+       memset((char *)r, 0, sizeof(*r));
+       r->nrp = 40;
+
+       return r;
+}
diff --git a/utils/iaxclient/lib/gsm/src/gsm_decode.c b/utils/iaxclient/lib/gsm/src/gsm_decode.c
new file mode 100644 (file)
index 0000000..7318ba2
--- /dev/null
@@ -0,0 +1,361 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+int gsm_decode P3((s, c, target), 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;
+}
diff --git a/utils/iaxclient/lib/gsm/src/gsm_destroy.c b/utils/iaxclient/lib/gsm/src/gsm_destroy.c
new file mode 100644 (file)
index 0000000..4807c0a
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include "gsm.h"
+#include "config.h"
+#include "proto.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 P1((S), gsm S)
+{
+       if (S) free((char *)S);
+}
diff --git a/utils/iaxclient/lib/gsm/src/gsm_encode.c b/utils/iaxclient/lib/gsm/src/gsm_encode.c
new file mode 100644 (file)
index 0000000..6233830
--- /dev/null
@@ -0,0 +1,451 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include "private.h"
+#include "gsm.h"
+#include "proto.h"
+
+void gsm_encode P3((s, source, c), 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);
+
+       }
+}
diff --git a/utils/iaxclient/lib/gsm/src/gsm_explode.c b/utils/iaxclient/lib/gsm/src/gsm_explode.c
new file mode 100644 (file)
index 0000000..a906fc2
--- /dev/null
@@ -0,0 +1,417 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include "private.h"
+#include "gsm.h"
+#include "proto.h"
+
+int gsm_explode P3((s, c, target), gsm s, gsm_byte * c, gsm_signal * target)
+{
+#      define  LARc    target
+#      define  Nc      *((gsm_signal (*) [17])(target + 8))
+#      define  bc      *((gsm_signal (*) [17])(target + 9))
+#      define  Mc      *((gsm_signal (*) [17])(target + 10))
+#      define  xmaxc   *((gsm_signal (*) [17])(target + 11))
+
+
+#ifdef WAV49
+       if (s->wav_fmt) {
+
+               uword sr = 0;
+
+               if (s->frame_index == 1) {
+
+                       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;
+#undef xmc
+#define        xmc     (target + 12)
+                       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;
+#undef xmc
+#define        xmc     (target + 29 - 13)
+
+                       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;
+
+#undef xmc
+#define        xmc     (target + 46 - 26)
+
+                       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;
+#undef xmc
+#define        xmc     (target + 63 - 39)
+
+                       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;
+#undef xmc
+#define        xmc     (target + 12)
+                       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;
+#undef xmc
+#define        xmc     (target + 29 - 13)
+
+                       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;
+#undef xmc
+#define        xmc     (target + 46 - 26)
+                       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;
+
+#undef xmc
+#define        xmc     (target + 63 - 39)
+
+                       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;
+
+#undef xmc
+#define        xmc     (target + 12)
+
+       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;
+
+#undef xmc
+#define        xmc     (target + 29 - 13)
+
+       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;
+
+#undef xmc
+#define        xmc     (target + 46 - 26)
+
+       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;
+
+#undef xmc
+#define        xmc     (target + 63 - 39)
+
+       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 */
+       }
+
+       return 0;
+}
diff --git a/utils/iaxclient/lib/gsm/src/gsm_implode.c b/utils/iaxclient/lib/gsm/src/gsm_implode.c
new file mode 100644 (file)
index 0000000..453b8cf
--- /dev/null
@@ -0,0 +1,515 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+void gsm_implode P3((s, source, c), gsm s, gsm_signal * source, gsm_byte * c)
+{
+       /*      variable        size    index
+
+               GSM_MAGIC       4       -
+
+               LARc[0]         6       0
+               LARc[1]         6       1
+               LARc[2]         5       2
+               LARc[3]         5       3
+               LARc[4]         4       4
+               LARc[5]         4       5
+               LARc[6]         3       6
+               LARc[7]         3       7
+
+               Nc[0]           7       8
+               bc[0]           2       9
+               Mc[0]           2       10
+               xmaxc[0]        6       11
+               xmc[0]          3       12
+               xmc[1]          3       13
+               xmc[2]          3       14
+               xmc[3]          3       15
+               xmc[4]          3       16
+               xmc[5]          3       17
+               xmc[6]          3       18
+               xmc[7]          3       19
+               xmc[8]          3       20
+               xmc[9]          3       21
+               xmc[10]         3       22
+               xmc[11]         3       23
+               xmc[12]         3       24
+
+               Nc[1]           7       25
+               bc[1]           2       26
+               Mc[1]           2       27
+               xmaxc[1]        6       28
+               xmc[13]         3       29
+               xmc[14]         3       30
+               xmc[15]         3       31
+               xmc[16]         3       32
+               xmc[17]         3       33
+               xmc[18]         3       34
+               xmc[19]         3       35
+               xmc[20]         3       36
+               xmc[21]         3       37
+               xmc[22]         3       38
+               xmc[23]         3       39
+               xmc[24]         3       40
+               xmc[25]         3       41
+
+               Nc[2]           7       42
+               bc[2]           2       43
+               Mc[2]           2       44
+               xmaxc[2]        6       45
+               xmc[26]         3       46
+               xmc[27]         3       47
+               xmc[28]         3       48
+               xmc[29]         3       49
+               xmc[30]         3       50
+               xmc[31]         3       51
+               xmc[32]         3       52
+               xmc[33]         3       53
+               xmc[34]         3       54
+               xmc[35]         3       55
+               xmc[36]         3       56
+               xmc[37]         3       57
+               xmc[38]         3       58
+
+               Nc[3]           7       59
+               bc[3]           2       60
+               Mc[3]           2       61
+               xmaxc[3]        6       62
+               xmc[39]         3       63
+               xmc[40]         3       64
+               xmc[41]         3       65
+               xmc[42]         3       66
+               xmc[43]         3       67
+               xmc[44]         3       68
+               xmc[45]         3       69
+               xmc[46]         3       70
+               xmc[47]         3       71
+               xmc[48]         3       72
+               xmc[49]         3       73
+               xmc[50]         3       74
+               xmc[51]         3       75
+       */
+
+       /*      There are 76 parameters per frame.  The first eight are
+        *      unique.  The remaining 68 are four identical subframes of
+        *      17 parameters each.  gsm_implode converts from a representation
+        *      of these parameters as values in one array of signed words
+        *      to the "packed" version of a GSM frame.
+        */
+
+#      define  LARc    source
+#      define  Nc      *((gsm_signal (*) [17])(source + 8))
+#      define  bc      *((gsm_signal (*) [17])(source + 9))
+#      define  Mc      *((gsm_signal (*) [17])(source + 10))
+#      define  xmaxc   *((gsm_signal (*) [17])(source + 11))
+
+#ifdef WAV49
+       if (s->wav_fmt) {
+
+               uword sr = 0;
+               if (s->frame_index == 0) {
+
+                       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;
+#undef xmc
+#define        xmc     (source + 12)
+                       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;
+#undef xmc
+#define        xmc     (source + 29 - 13)
+                       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;
+#undef xmc
+#define        xmc     (source + 46 - 26)
+                       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;
+#undef xmc
+#define        xmc     (source + 63 - 39)
+
+                       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;
+#undef xmc
+#define        xmc     (source + 12)
+                       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;
+#undef xmc
+#define        xmc     (source + 29 - 13)
+                       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;
+#undef xmc
+#define        xmc     (source + 46 - 26)
+                       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;
+#undef xmc
+#define        xmc     (source + 63 - 39)
+
+                       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 
+       {
+
+       *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)
+
+#undef xmc
+#define        xmc     (source + 12)
+
+              | ((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)
+
+#undef xmc
+#define        xmc     (source + 29 - 13)
+
+              | ((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)
+
+#undef xmc
+#define        xmc     (source + 46 - 26)
+
+              | ((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)
+
+#undef xmc
+#define        xmc     (source + 63 - 39)
+
+              | ((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);
+       }
+}
diff --git a/utils/iaxclient/lib/gsm/src/gsm_option.c b/utils/iaxclient/lib/gsm/src/gsm_option.c
new file mode 100644 (file)
index 0000000..2807801
--- /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.
+ */
+
+/* $Header$ */
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+int gsm_option P3((r, opt, val), 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;
+}
diff --git a/utils/iaxclient/lib/gsm/src/gsm_print.c b/utils/iaxclient/lib/gsm/src/gsm_print.c
new file mode 100644 (file)
index 0000000..af745bc
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include       <stdio.h>
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+int gsm_print P3((f, s, c), FILE * f, gsm s, gsm_byte * c)
+{
+       word    LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
+
+       /* 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 */
+
+       fprintf(f,
+             "LARc:\t%2.2d  %2.2d  %2.2d  %2.2d  %2.2d  %2.2d  %2.2d  %2.2d\n",
+              LARc[0],LARc[1],LARc[2],LARc[3],LARc[4],LARc[5],LARc[6],LARc[7]);
+
+       fprintf(f, "#1:         Nc %4.4d    bc %d    Mc %d    xmaxc %d\n",
+               Nc[0], bc[0], Mc[0], xmaxc[0]);
+       fprintf(f,
+"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n",
+               xmc[0],xmc[1],xmc[2],xmc[3],xmc[4],xmc[5],xmc[6],
+               xmc[7],xmc[8],xmc[9],xmc[10],xmc[11],xmc[12] );
+
+       fprintf(f, "#2:         Nc %4.4d    bc %d    Mc %d    xmaxc %d\n",
+               Nc[1], bc[1], Mc[1], xmaxc[1]);
+       fprintf(f,
+"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n",
+               xmc[13+0],xmc[13+1],xmc[13+2],xmc[13+3],xmc[13+4],xmc[13+5],
+               xmc[13+6], xmc[13+7],xmc[13+8],xmc[13+9],xmc[13+10],xmc[13+11],
+               xmc[13+12] );
+
+       fprintf(f, "#3:         Nc %4.4d    bc %d    Mc %d    xmaxc %d\n",
+               Nc[2], bc[2], Mc[2], xmaxc[2]);
+       fprintf(f,
+"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n",
+               xmc[26+0],xmc[26+1],xmc[26+2],xmc[26+3],xmc[26+4],xmc[26+5],
+               xmc[26+6], xmc[26+7],xmc[26+8],xmc[26+9],xmc[26+10],xmc[26+11],
+               xmc[26+12] );
+
+       fprintf(f, "#4:         Nc %4.4d    bc %d    Mc %d    xmaxc %d\n",
+               Nc[3], bc[3], Mc[3], xmaxc[3]);
+       fprintf(f,
+"\t%.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d %.2d\n",
+               xmc[39+0],xmc[39+1],xmc[39+2],xmc[39+3],xmc[39+4],xmc[39+5],
+               xmc[39+6], xmc[39+7],xmc[39+8],xmc[39+9],xmc[39+10],xmc[39+11],
+               xmc[39+12] );
+
+       return 0;
+}
diff --git a/utils/iaxclient/lib/gsm/src/k6opt.h b/utils/iaxclient/lib/gsm/src/k6opt.h
new file mode 100644 (file)
index 0000000..16ea2ac
--- /dev/null
@@ -0,0 +1,84 @@
+/* k6opt.h  vector functions optimized for MMX extensions to x86
+ *
+ * Copyright (C) 1999 by Stanley J. Brooks <stabro@megsinet.net>
+ * 
+ * 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;
+ * not even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.
+ * 
+ * Chicago, 03.12.1999
+ * Stanley J. Brooks
+ */
+
+extern void Weighting_filter P2((e, x),
+       const word      * e,    /* signal [-5..0.39.44] IN  */
+       word    * x             /* signal [0..39]       OUT */
+)
+;
+
+extern longword k6maxcc P3((wt,dp,Nc_out),
+       const word *wt,
+       const word *dp, 
+       word            * Nc_out        /*              OUT     */
+)
+;
+/*
+ * k6maxmin(p,n,out[])
+ *  input p[n] is array of shorts (require n>0)
+ *  returns (long) maximum absolute value..
+ *  if out!=NULL, also returns out[0] the maximum and out[1] the minimum
+ */
+extern longword k6maxmin P3((p,n,out),
+       const word *p,
+       int n, 
+       word *out       /*              out[0] is max, out[1] is min */
+)
+;
+
+extern longword k6iprod P3((p,q,n),
+       const word *p,
+       const word *q,
+       int n
+)
+;
+
+/*
+ * k6vsraw(p,n,bits)
+ *  input p[n] is array of shorts (require n>0)
+ *  shift/round each to the right by bits>=0 bits.
+ */
+extern void k6vsraw P3((p,n,bits),
+       const word *p,
+       int n, 
+       int bits
+)
+;
+
+/*
+ * k6vsllw(p,n,bits)
+ *  input p[n] is array of shorts (require n>0)
+ *  shift each to the left by bits>=0 bits.
+ */
+extern void k6vsllw P3((p,n,bits),
+       const word *p,
+       int n, 
+       int bits
+)
+;
+
+#if 1  /* there isn't any significant speed gain from mmx here: */
+extern void Short_term_analysis_filteringx P4((u0,rp0,k_n,s),
+       register word * u0,
+       register word   * rp0,  /* [0..7]       IN      */
+       register int    k_n,    /*   k_end - k_start    */
+       register word   * s     /* [0..n-1]     IN/OUT  */
+)
+;
+/*
+#define Short_term_analysis_filtering Short_term_analysis_filteringx
+*/
+#endif
diff --git a/utils/iaxclient/lib/gsm/src/k6opt.s b/utils/iaxclient/lib/gsm/src/k6opt.s
new file mode 100644 (file)
index 0000000..3be5c18
--- /dev/null
@@ -0,0 +1,755 @@
+/* k6opt.s  vector functions optimized for MMX extensions to x86
+ *
+ * Copyright (C) 1999 by Stanley J. Brooks <stabro@megsinet.net>
+ * 
+ * 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;
+ * not even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE.
+ * 
+ * Chicago, 03.12.1999
+ * Stanley J. Brooks
+ */
+
+       .file   "k6opt.s"
+       .version        "01.01"
+/* gcc2_compiled.: */
+.section       .rodata
+       .align 4
+       .type    coefs,@object
+       .size    coefs,24
+coefs:
+       .value -134
+       .value -374
+       .value 0
+       .value 2054
+       .value 5741
+       .value 8192
+       .value 5741
+       .value 2054
+       .value 0
+       .value -374
+       .value -134
+       .value 0
+.text
+       .align 4
+/* void Weighting_filter (const short *e, short *x) */
+.globl Weighting_filter
+       .type    Weighting_filter,@function
+Weighting_filter:
+       pushl %ebp
+       movl %esp,%ebp
+       pushl %edi
+       pushl %esi
+       pushl %ebx
+       movl 12(%ebp),%edi
+       movl 8(%ebp),%ebx
+       addl $-10,%ebx
+       emms
+       movl $0x1000,%eax; movd %eax,%mm5  /* for rounding */
+       movq coefs,%mm1
+       movq coefs+8,%mm2
+       movq coefs+16,%mm3
+       xorl %esi,%esi
+       .p2align 2
+.L21:
+       movq (%ebx,%esi,2),%mm0
+       pmaddwd %mm1,%mm0
+
+       movq 8(%ebx,%esi,2),%mm4
+       pmaddwd %mm2,%mm4
+       paddd %mm4,%mm0
+
+       movq 16(%ebx,%esi,2),%mm4
+       pmaddwd %mm3,%mm4
+       paddd %mm4,%mm0
+
+       movq %mm0,%mm4
+       punpckhdq %mm0,%mm4  /* mm4 has high int32 of mm0 dup'd */
+       paddd %mm4,%mm0;
+
+       paddd %mm5,%mm0 /* add for roundoff */
+       psrad $13,%mm0
+       packssdw %mm0,%mm0      
+       movd %mm0,%eax  /* ax has result */
+       movw %ax,(%edi,%esi,2)
+       incl %esi
+       cmpl $39,%esi
+       jle .L21
+       emms
+       popl %ebx
+       popl %esi
+       popl %edi
+       leave
+       ret
+.Lfe1:
+       .size    Weighting_filter,.Lfe1-Weighting_filter
+
+.macro ccstep n
+.if \n
+       movq \n(%edi),%mm1
+       movq \n(%esi),%mm2
+.else
+       movq (%edi),%mm1
+       movq (%esi),%mm2
+.endif
+       pmaddwd %mm2,%mm1
+       paddd %mm1,%mm0
+.endm
+
+       .align 4
+/* long k6maxcc(const short *wt, const short *dp, short *Nc_out) */
+.globl k6maxcc
+       .type    k6maxcc,@function
+k6maxcc:
+       pushl %ebp
+       movl %esp,%ebp
+       pushl %edi
+       pushl %esi
+       pushl %ebx
+       emms
+       movl 8(%ebp),%edi
+       movl 12(%ebp),%esi
+       movl $0,%edx  /* will be maximum inner-product */
+       movl $40,%ebx
+       movl %ebx,%ecx /* will be index of max inner-product */
+       subl $80,%esi
+       .p2align 2
+.L41:
+       movq (%edi),%mm0
+       movq (%esi),%mm2
+       pmaddwd %mm2,%mm0
+       ccstep 8
+       ccstep 16
+       ccstep 24
+       ccstep 32
+       ccstep 40
+       ccstep 48
+       ccstep 56
+       ccstep 64
+       ccstep 72
+
+       movq %mm0,%mm1
+       punpckhdq %mm0,%mm1  /* mm1 has high int32 of mm0 dup'd */
+       paddd %mm1,%mm0;
+       movd %mm0,%eax  /* eax has result */
+
+       cmpl %edx,%eax
+       jle .L40
+       movl %eax,%edx
+       movl %ebx,%ecx
+       .p2align 2
+.L40:
+       subl $2,%esi
+       incl %ebx
+       cmpl $120,%ebx
+       jle .L41
+       movl 16(%ebp),%eax
+       movw %cx,(%eax)
+       movl %edx,%eax
+       emms
+       popl %ebx
+       popl %esi
+       popl %edi
+       leave
+       ret
+.Lfe2:
+       .size    k6maxcc,.Lfe2-k6maxcc
+
+
+       .align 4
+/* long k6iprod (const short *p, const short *q, int n) */
+.globl k6iprod
+       .type    k6iprod,@function
+k6iprod:
+       pushl %ebp
+       movl %esp,%ebp
+       pushl %edi
+       pushl %esi
+       emms
+       pxor %mm0,%mm0
+       movl 8(%ebp),%esi
+       movl 12(%ebp),%edi
+       movl 16(%ebp),%eax
+       leal -32(%esi,%eax,2),%edx /* edx = top - 32 */
+
+       cmpl %edx,%esi; ja .L202
+
+       .p2align 2
+.L201:
+       ccstep 0
+       ccstep 8
+       ccstep 16
+       ccstep 24
+
+       addl $32,%esi
+       addl $32,%edi
+       cmpl %edx,%esi; jbe .L201
+
+       .p2align 2
+.L202:
+       addl $24,%edx  /* now edx = top-8 */
+       cmpl %edx,%esi; ja .L205
+
+       .p2align 2
+.L203:
+       ccstep 0
+
+       addl $8,%esi
+       addl $8,%edi
+       cmpl %edx,%esi; jbe .L203
+
+       .p2align 2
+.L205:
+       addl $4,%edx  /* now edx = top-4 */
+       cmpl %edx,%esi; ja .L207
+
+       movd (%edi),%mm1
+       movd (%esi),%mm2
+       pmaddwd %mm2,%mm1
+       paddd %mm1,%mm0
+
+       addl $4,%esi
+       addl $4,%edi
+
+       .p2align 2
+.L207:
+       addl $2,%edx  /* now edx = top-2 */
+       cmpl %edx,%esi; ja .L209
+
+       movswl (%edi),%eax
+       movd %eax,%mm1
+       movswl (%esi),%eax
+       movd %eax,%mm2
+       pmaddwd %mm2,%mm1
+       paddd %mm1,%mm0
+
+       .p2align 2
+.L209:
+       movq %mm0,%mm1
+       punpckhdq %mm0,%mm1  /* mm1 has high int32 of mm0 dup'd */
+       paddd %mm1,%mm0;
+       movd %mm0,%eax  /* eax has result */
+
+       emms
+       popl %esi
+       popl %edi
+       leave
+       ret
+.Lfe3:
+       .size    k6iprod,.Lfe3-k6iprod
+
+
+       .align 4
+/* void k6vsraw P3((short *p, int n, int bits) */
+.globl k6vsraw
+       .type    k6vsraw,@function
+k6vsraw:
+       pushl %ebp
+       movl %esp,%ebp
+       pushl %esi
+       movl 8(%ebp),%esi
+       movl 16(%ebp),%ecx
+       andl %ecx,%ecx; jle .L399
+       movl 12(%ebp),%eax
+       leal -16(%esi,%eax,2),%edx /* edx = top - 16 */
+       emms
+       movd %ecx,%mm3
+       movq ones,%mm2
+       psllw %mm3,%mm2; psrlw $1,%mm2
+       cmpl %edx,%esi; ja .L306
+
+       .p2align 2
+.L302: /* 8 words per iteration */
+       movq (%esi),%mm0
+       movq 8(%esi),%mm1
+       paddsw %mm2,%mm0
+       psraw %mm3,%mm0;
+       paddsw %mm2,%mm1
+       psraw %mm3,%mm1;
+       movq %mm0,(%esi)
+       movq %mm1,8(%esi)
+       addl $16,%esi
+       cmpl %edx,%esi
+       jbe .L302
+
+       .p2align 2
+.L306:
+       addl $12,%edx /* now edx = top-4 */
+       cmpl %edx,%esi; ja .L310
+
+       .p2align 2
+.L308: /* do up to 6 words, two at a time */
+       movd  (%esi),%mm0
+       paddsw %mm2,%mm0
+       psraw %mm3,%mm0;
+       movd %mm0,(%esi)
+       addl $4,%esi
+       cmpl %edx,%esi
+       jbe .L308
+
+       .p2align 2
+.L310:
+       addl $2,%edx /* now edx = top-2 */
+       cmpl %edx,%esi; ja .L315
+       
+       movzwl (%esi),%eax
+       movd %eax,%mm0
+       paddsw %mm2,%mm0
+       psraw %mm3,%mm0;
+       movd %mm0,%eax
+       movw %ax,(%esi)
+
+       .p2align 2
+.L315:
+       emms
+.L399:
+       popl %esi
+       leave
+       ret
+.Lfe4:
+       .size    k6vsraw,.Lfe4-k6vsraw
+       
+       .align 4
+/* void k6vsllw P3((short *p, int n, int bits) */
+.globl k6vsllw
+       .type    k6vsllw,@function
+k6vsllw:
+       pushl %ebp
+       movl %esp,%ebp
+       pushl %esi
+       movl 8(%ebp),%esi
+       movl 16(%ebp),%ecx
+       andl %ecx,%ecx; jle .L499
+       movl 12(%ebp),%eax
+       leal -16(%esi,%eax,2),%edx /* edx = top - 16 */
+       emms
+       movd %ecx,%mm3
+       cmpl %edx,%esi; ja .L406
+
+       .p2align 2
+.L402: /* 8 words per iteration */
+       movq (%esi),%mm0
+       movq 8(%esi),%mm1
+       psllw %mm3,%mm0;
+       psllw %mm3,%mm1;
+       movq %mm0,(%esi)
+       movq %mm1,8(%esi)
+       addl $16,%esi
+       cmpl %edx,%esi
+       jbe .L402
+
+       .p2align 2
+.L406:
+       addl $12,%edx /* now edx = top-4 */
+       cmpl %edx,%esi; ja .L410
+
+       .p2align 2
+.L408: /* do up to 6 words, two at a time */
+       movd (%esi),%mm0
+       psllw %mm3,%mm0;
+       movd %mm0,(%esi)
+       addl $4,%esi
+       cmpl %edx,%esi
+       jbe .L408
+
+       .p2align 2
+.L410:
+       addl $2,%edx /* now edx = top-2 */
+       cmpl %edx,%esi; ja .L415
+       
+       movzwl (%esi),%eax
+       movd %eax,%mm0
+       psllw %mm3,%mm0;
+       movd %mm0,%eax
+       movw %ax,(%esi)
+
+       .p2align 2
+.L415:
+       emms
+.L499:
+       popl %esi
+       leave
+       ret
+.Lfe5:
+       .size    k6vsllw,.Lfe5-k6vsllw
+
+
+.section       .rodata
+       .align 4
+       .type    extremes,@object
+       .size    extremes,8
+extremes:
+       .long 0x80008000
+       .long 0x7fff7fff
+       .type    ones,@object
+       .size    ones,8
+ones:
+       .long 0x00010001
+       .long 0x00010001
+
+.text
+       .align 4
+/* long k6maxmin (const short *p, int n, short *out) */
+.globl k6maxmin
+       .type    k6maxmin,@function
+k6maxmin:
+       pushl %ebp
+       movl %esp,%ebp
+       pushl %esi
+       emms
+       movl 8(%ebp),%esi
+       movl 12(%ebp),%eax
+       leal -8(%esi,%eax,2),%edx
+
+       cmpl %edx,%esi
+       jbe .L52
+       movd extremes,%mm0
+       movd extremes+4,%mm1
+       jmp .L58
+
+       .p2align 2
+.L52:
+       movq (%esi),%mm0   /* mm0 will be max's */
+       movq %mm0,%mm1     /* mm1 will be min's */
+       addl $8,%esi
+       cmpl %edx,%esi
+       ja .L56
+
+       .p2align 2
+.L54:
+       movq (%esi),%mm2
+
+       movq %mm2,%mm3
+       pcmpgtw %mm0,%mm3  /* mm3 is bitmask for words where mm2 > mm0 */ 
+       movq %mm3,%mm4
+       pand %mm2,%mm3     /* mm3 is mm2 masked to new max's */
+       pandn %mm0,%mm4    /* mm4 is mm0 masked to its max's */
+       por %mm3,%mm4
+       movq %mm4,%mm0     /* now mm0 is updated max's */
+       
+       movq %mm1,%mm3
+       pcmpgtw %mm2,%mm3  /* mm3 is bitmask for words where mm2 < mm1 */ 
+       pand %mm3,%mm2     /* mm2 is mm2 masked to new min's */
+       pandn %mm1,%mm3    /* mm3 is mm1 masked to its min's */
+       por %mm3,%mm2
+       movq %mm2,%mm1     /* now mm1 is updated min's */
+
+       addl $8,%esi
+       cmpl %edx,%esi
+       jbe .L54
+
+       .p2align 2
+.L56: /* merge down the 4-word max/mins to lower 2 words */
+
+       movq %mm0,%mm2
+       psrlq $32,%mm2
+       movq %mm2,%mm3
+       pcmpgtw %mm0,%mm3  /* mm3 is bitmask for words where mm2 > mm0 */ 
+       pand %mm3,%mm2     /* mm2 is mm2 masked to new max's */
+       pandn %mm0,%mm3    /* mm3 is mm0 masked to its max's */
+       por %mm3,%mm2
+       movq %mm2,%mm0     /* now mm0 is updated max's */
+
+       movq %mm1,%mm2
+       psrlq $32,%mm2
+       movq %mm1,%mm3
+       pcmpgtw %mm2,%mm3  /* mm3 is bitmask for words where mm2 < mm1 */ 
+       pand %mm3,%mm2     /* mm2 is mm2 masked to new min's */
+       pandn %mm1,%mm3    /* mm3 is mm1 masked to its min's */
+       por %mm3,%mm2
+       movq %mm2,%mm1     /* now mm1 is updated min's */
+
+       .p2align 2
+.L58:
+       addl $4,%edx       /* now dx = top-4 */
+       cmpl %edx,%esi
+       ja .L62
+       /* here, there are >= 2 words of input remaining */
+       movd (%esi),%mm2
+
+       movq %mm2,%mm3
+       pcmpgtw %mm0,%mm3  /* mm3 is bitmask for words where mm2 > mm0 */ 
+       movq %mm3,%mm4
+       pand %mm2,%mm3     /* mm3 is mm2 masked to new max's */
+       pandn %mm0,%mm4    /* mm4 is mm0 masked to its max's */
+       por %mm3,%mm4
+       movq %mm4,%mm0     /* now mm0 is updated max's */
+       
+       movq %mm1,%mm3
+       pcmpgtw %mm2,%mm3  /* mm3 is bitmask for words where mm2 < mm1 */ 
+       pand %mm3,%mm2     /* mm2 is mm2 masked to new min's */
+       pandn %mm1,%mm3    /* mm3 is mm1 masked to its min's */
+       por %mm3,%mm2
+       movq %mm2,%mm1     /* now mm1 is updated min's */
+
+       addl $4,%esi
+
+       .p2align 2
+.L62:
+       /* merge down the 2-word max/mins to 1 word */
+
+       movq %mm0,%mm2
+       psrlq $16,%mm2
+       movq %mm2,%mm3
+       pcmpgtw %mm0,%mm3  /* mm3 is bitmask for words where mm2 > mm0 */ 
+       pand %mm3,%mm2     /* mm2 is mm2 masked to new max's */
+       pandn %mm0,%mm3    /* mm3 is mm0 masked to its max's */
+       por %mm3,%mm2
+       movd %mm2,%ecx     /* cx is max so far */
+
+       movq %mm1,%mm2
+       psrlq $16,%mm2
+       movq %mm1,%mm3
+       pcmpgtw %mm2,%mm3  /* mm3 is bitmask for words where mm2 < mm1 */ 
+       pand %mm3,%mm2     /* mm2 is mm2 masked to new min's */
+       pandn %mm1,%mm3    /* mm3 is mm1 masked to its min's */
+       por %mm3,%mm2
+       movd %mm2,%eax     /* ax is min so far */
+       
+       addl $2,%edx       /* now dx = top-2 */
+       cmpl %edx,%esi
+       ja .L65
+
+       /* here, there is one word of input left */
+       cmpw (%esi),%cx
+       jge .L64
+       movw (%esi),%cx
+       .p2align 2
+.L64:
+       cmpw (%esi),%ax
+       jle .L65
+       movw (%esi),%ax
+
+       .p2align 2
+.L65:  /* (finally!) cx is the max, ax the min */
+       movswl %cx,%ecx
+       movswl %ax,%eax
+
+       movl 16(%ebp),%edx /* ptr to output max,min vals */
+       andl %edx,%edx; jz .L77
+       movw %cx,(%edx)  /* max */
+       movw %ax,2(%edx) /* min */
+       .p2align 2
+.L77:
+       /* now calculate max absolute val */
+       negl %eax
+       cmpl %ecx,%eax
+       jge .L81
+       movl %ecx,%eax
+       .p2align 2
+.L81:
+       emms
+       popl %esi
+       leave
+       ret
+.Lfe6:
+       .size    k6maxmin,.Lfe6-k6maxmin
+
+/* void Short_term_analysis_filtering (short *u0, const short *rp0, int kn, short *s) */
+       .equiv pm_u0,8
+       .equiv pm_rp0,12
+       .equiv pm_kn,16
+       .equiv pm_s,20
+       .equiv lv_u_top,-4
+       .equiv lv_s_top,-8
+       .equiv lv_rp,-40 /* local version of rp0 with each word twice */
+       .align 4
+.globl Short_term_analysis_filteringx
+       .type    Short_term_analysis_filteringx,@function
+Short_term_analysis_filteringx:
+       pushl %ebp
+       movl %esp,%ebp
+       subl $40,%esp
+       pushl %edi
+       pushl %esi
+
+       movl pm_rp0(%ebp),%esi;
+       leal lv_rp(%ebp),%edi;
+       cld
+       lodsw; stosw; stosw
+       lodsw; stosw; stosw
+       lodsw; stosw; stosw
+       lodsw; stosw; stosw
+       lodsw; stosw; stosw
+       lodsw; stosw; stosw
+       lodsw; stosw; stosw
+       lodsw; stosw; stosw
+       emms
+       movl $0x4000,%eax;
+       movd %eax,%mm4;
+       punpckldq %mm4,%mm4 /* (0x00004000,0x00004000) for rounding dword product pairs */
+
+       movl pm_u0(%ebp),%eax
+       addl $16,%eax
+       movl %eax,lv_u_top(%ebp) /* UTOP */
+       movl pm_s(%ebp),%edx  /* edx is local s ptr throughout below */
+       movl pm_kn(%ebp),%eax
+       leal (%edx,%eax,2),%eax
+       movl %eax,lv_s_top(%ebp)
+       cmpl %eax,%edx
+       jae .L179
+       .p2align 2
+.L181:
+       leal lv_rp(%ebp),%esi  /* RP */
+       movl pm_u0(%ebp),%edi  /* U  */
+       movw (%edx),%ax /* (0,DI) */
+       roll $16,%eax
+       movw (%edx),%ax /* (DI,DI) */
+       .p2align 2
+.L185: /* RP is %esi */
+       movl %eax,%ecx
+       movw (%edi),%ax  /* (DI,U) */
+       movd (%esi),%mm3 /* mm3 is (0,0,RP,RP) */
+       movw %cx,(%edi)
+
+       movd %eax,%mm2   /* mm2 is (0,0,DI,U) */
+       rorl $16,%eax 
+       movd %eax,%mm1   /* mm1 is (0,0,U,DI) */
+
+       movq %mm1,%mm0
+       pmullw %mm3,%mm0
+       pmulhw %mm3,%mm1
+       punpcklwd %mm1,%mm0 /* mm0 is (RP*U,RP*DI) */
+       paddd %mm4,%mm0     /* mm4 is 0x00004000,0x00004000 */
+       psrad $15,%mm0      /* (RP*U,RP*DI) adjusted */
+       packssdw %mm0,%mm0  /* (*,*,RP*U,RP*DI) adjusted and saturated to word */
+       paddsw %mm2,%mm0    /* mm0 is (?,?, DI', U') */
+       movd %mm0,%eax      /* (DI,U') */
+
+       addl $2,%edi
+       addl $4,%esi
+       cmpl lv_u_top(%ebp),%edi
+       jb .L185
+
+       rorl $16,%eax
+       movw %ax,(%edx) /* last DI goes to *s */
+       addl $2,%edx    /* next s */
+       cmpl lv_s_top(%ebp),%edx
+       jb .L181
+       .p2align 2
+.L179:
+       emms
+       popl %esi
+       popl %edi
+       leave
+       ret
+.Lfe7:
+       .size    Short_term_analysis_filteringx,.Lfe7-Short_term_analysis_filteringx
+
+.end
+
+/* 'as' macro's seem to be case-insensitive */
+.macro STEP n
+.if \n
+       movd \n(%esi),%mm3 /* mm3 is (0,0,RP,RP) */
+.else
+       movd (%esi),%mm3 /* mm3 is (0,0,RP,RP) */
+.endif
+       movq %mm5,%mm1;
+       movd %mm4,%ecx; movw %cx,%ax  /* (DI,U) */
+       psllq $48,%mm1; psrlq $16,%mm4; por %mm1,%mm4
+       psllq $48,%mm0; psrlq $16,%mm5; por %mm0,%mm5
+
+       movd %eax,%mm2   /* mm2 is (0,0,DI,U) */
+       rorl $16,%eax 
+       movd %eax,%mm1   /* mm1 is (0,0,U,DI) */
+
+       movq %mm1,%mm0
+       pmullw %mm3,%mm0
+       pmulhw %mm3,%mm1
+       punpcklwd %mm1,%mm0 /* mm0 is (RP*U,RP*DI) */
+       paddd %mm6,%mm0     /* mm6 is 0x00004000,0x00004000 */
+       psrad $15,%mm0      /* (RP*U,RP*DI) adjusted */
+       packssdw %mm0,%mm0  /* (*,*,RP*U,RP*DI) adjusted and saturated to word */
+       paddsw %mm2,%mm0    /* mm0 is (?,?, DI', U') */
+       movd %mm0,%eax      /* (DI,U') */
+.endm
+
+/* void Short_term_analysis_filtering (short *u0, const short *rp0, int kn, short *s) */
+       .equiv pm_u0,8
+       .equiv pm_rp0,12
+       .equiv pm_kn,16
+       .equiv pm_s,20
+       .equiv lv_rp_top,-4
+       .equiv lv_s_top,-8
+       .equiv lv_rp,-40 /* local version of rp0 with each word twice */
+       .align 4
+.globl Short_term_analysis_filteringx
+       .type    Short_term_analysis_filteringx,@function
+Short_term_analysis_filteringx:
+       pushl %ebp
+       movl %esp,%ebp
+       subl $56,%esp
+       pushl %edi
+       pushl %esi
+       pushl %ebx
+
+       movl pm_rp0(%ebp),%esi;
+       leal lv_rp(%ebp),%edi;
+       cld
+       lodsw; stosw; stosw
+       lodsw; stosw; stosw
+       lodsw; stosw; stosw
+       lodsw; stosw; stosw
+       lodsw; stosw; stosw
+       lodsw; stosw; stosw
+       lodsw; stosw; stosw
+       lodsw; stosw; stosw
+       movl %edi,lv_rp_top(%ebp)
+       emms
+
+       movl $0x4000,%eax;
+       movd %eax,%mm6;
+       punpckldq %mm6,%mm6 /* (0x00004000,0x00004000) for rounding dword product pairs */
+
+       movl pm_u0(%ebp),%ebx
+       movq (%ebx),%mm4; movq 8(%ebx),%mm5 /* the 8 u's */
+       movl pm_s(%ebp),%edx  /* edx is local s ptr throughout below */
+       movl pm_kn(%ebp),%eax
+       leal (%edx,%eax,2),%eax
+       movl %eax,lv_s_top(%ebp)
+       cmpl %eax,%edx
+       jae .L179
+       .p2align 2
+.L181:
+       leal lv_rp(%ebp),%esi  /* RP */
+       movw (%edx),%ax /* (0,DI) */
+       roll $16,%eax
+       movw (%edx),%ax /* (DI,DI) */
+       movd %eax,%mm0
+       .p2align 2
+.L185: /* RP is %esi */
+       step 0
+       step 4
+       step 8
+       step 12
+/*
+       step 16
+       step 20
+       step 24
+       step 28
+*/
+       addl $16,%esi
+       cmpl lv_rp_top(%ebp),%esi 
+       jb .L185
+
+       rorl $16,%eax
+       movw %ax,(%edx) /* last DI goes to *s */
+       addl $2,%edx    /* next s */
+       cmpl lv_s_top(%ebp),%edx
+       jb .L181
+.L179:
+       movq %mm4,(%ebx); movq %mm5,8(%ebx) /* the 8 u's */
+       emms
+       popl %ebx
+       popl %esi
+       popl %edi
+       leave
+       ret
+.Lfe7:
+       .size    Short_term_analysis_filteringx,.Lfe7-Short_term_analysis_filteringx
+       .ident  "GCC: (GNU) 2.95.2 19991109 (Debian GNU/Linux)"
diff --git a/utils/iaxclient/lib/gsm/src/long_term.c b/utils/iaxclient/lib/gsm/src/long_term.c
new file mode 100644 (file)
index 0000000..15ae21e
--- /dev/null
@@ -0,0 +1,954 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+#ifdef K6OPT
+#include "k6opt.h"
+#endif
+/*
+ *  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 P5((st, d,dp,bc_out,Nc_out),
+
+       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(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( 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 P4((d,dp,bc_out,Nc_out),
+       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( d[k], scal );
+
+       /* Search for the maximum cross-correlation and coding of the LTP lag
+        */
+# ifdef K6OPT
+       L_max = k6maxcc(wt,dp,&Nc);
+#      else
+       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;
+               }
+       }
+#      endif
+       *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( 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;
+}
+
+#else  /* USE_FLOAT_MUL */
+
+#ifdef LTP_CUT
+
+static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out),
+       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(dmax, scal) * st->ltp_cut / 100; 
+
+
+       /*  Initialization of a working array wt
+        */
+
+       for (k = 0; k < 40; k++) {
+               register word w = SASR( 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( 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 P4((d,dp,bc_out,Nc_out),
+       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;
+
+       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);
+
+       /*  Initialization of a working array wt
+        */
+
+       for (k =    0; k < 40; k++) wt_float[k] =  SASR( d[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( 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;
+}
+
+#ifdef FAST
+#ifdef LTP_CUT
+
+static void Cut_Fast_Calculation_of_the_LTP_parameters P5((st,
+                                                       d,dp,bc_out,Nc_out),
+       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 P4((d,dp,bc_out,Nc_out),
+       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;
+
+       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)d[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 P6((bc,Nc,dp,d,dpp,e),
+       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;
+       register longword ltmp;
+
+#      undef STEP
+#      define STEP(BP)                                 \
+       for (k = 0; k <= 39; k++) {                     \
+               dpp[k]  = GSM_MULT_R( BP, dp[k - Nc]);  \
+               e[k]    = (word) 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 P7((S,d,dp,e,dpp,Nc,bc),  /* 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 P5((S,Ncr,bcr,erp,drp),
+       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 longword       ltmp;   /* for ADD */
+       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 ];
+}
diff --git a/utils/iaxclient/lib/gsm/src/lpc.c b/utils/iaxclient/lib/gsm/src/lpc.c
new file mode 100644 (file)
index 0000000..4ec52ee
--- /dev/null
@@ -0,0 +1,371 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+#ifdef K6OPT
+#include "k6opt.h"
+#endif
+
+#undef P
+
+/*
+ *  4.2.4 .. 4.2.7 LPC ANALYSIS SECTION
+ */
+
+/* 4.2.4 */
+
+
+static void Autocorrelation P2((s, L_ACF),
+       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.
+        */
+#ifndef K6OPT
+       smax = 0;
+       for (k = 0; k <= 159; k++) {
+               temp = GSM_ABS( s[k] );
+               if (temp > smax) smax = temp;
+       }
+#else
+       {
+               longword lmax;
+               lmax = k6maxmin(s,160,NULL);
+               smax = (lmax > MAX_WORD) ? MAX_WORD : lmax;
+       }
+#endif
+       /*  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) {
+#      ifndef K6OPT
+
+# 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
+
+#      else /* K6OPT */
+               k6vsraw(s,160,scalauto);
+#      endif
+       }
+# ifdef        USE_FLOAT_MUL
+       else for (k = 0; k <= 159; k++) float_s[k] = (float) s[k];
+# endif
+
+       /*  Compute the L_ACF[..].
+        */
+#ifndef K6OPT
+       {
+# 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) ; 
+
+       }
+
+#else
+       {
+               int k;
+               for (k=0; k<9; k++) {
+                       L_ACF[k] = 2*k6iprod(s,s+k,160-k);
+               }
+       }
+#endif
+       /*   Rescaling of the array s[0..159]
+        */
+       if (scalauto > 0) {
+               assert(scalauto <= 4); 
+#ifndef K6OPT
+               for (k = 160; k--; *s++ <<= scalauto) ;
+#      else /* K6OPT */
+               k6vsllw(s,160,scalauto);
+#      endif
+       }
+}
+
+#if defined(USE_FLOAT_MUL) && defined(FAST)
+
+static void Fast_Autocorrelation P2((s, L_ACF),
+       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 P2( (L_ACF, r),
+       longword        * L_ACF,                /* 0...8        IN      */
+       register word   * r                     /* 0...7        OUT     */
+)
+{
+       register int    i, m, n;
+       register word   temp;
+       register longword ltmp;
+       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_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 P1((r),
+       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 P1((LAR),
+       register word * LAR     /* [0..7]       IN/OUT  */
+)
+{
+       register word   temp;
+       longword        ltmp;
+
+
+       /*  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(     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 P3((S, s,LARc),
+       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);
+}
diff --git a/utils/iaxclient/lib/gsm/src/preprocess.c b/utils/iaxclient/lib/gsm/src/preprocess.c
new file mode 100644 (file)
index 0000000..83c3f6a
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include       <stdio.h>
+#include       <assert.h>
+
+#include "private.h"
+
+#include       "gsm.h"
+#include       "proto.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 P3((S, s, so),
+       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;
+
+
+       word            SO;
+
+       longword        ltmp;           /* for   ADD */
+       ulongword       utmp;           /* for L_ADD */
+
+       register int            k = 160;
+
+       while (k--) {
+
+       /*  4.2.1   Downscaling of the input signal
+        */
+               /* SO = SASR( *s, 3 ) << 2;*/
+               SO = SASR( *s, 1 ) & ~3;
+               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);
+
+       /* SJB Remark: float might be faster than the mess that follows */
+
+               /*   Compute the recursive part
+                */
+
+               /*   Execution of a 31 bv 16 bits multiplication
+                */
+               {
+               word            msp, lsp;
+               longword L_s2;
+               longword L_temp;
+               
+               L_s2 = s1;
+               L_s2 <<= 15;
+#ifndef __GNUC__ 
+               msp = SASR( L_z2, 15 );
+               lsp = L_z2 & 0x7fff; /* 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 );
+               /* above does L_z2  = L_z2 * 0x7fd5/0x8000 + L_s2 */
+#else
+               L_z2 = ((long long)L_z2*32735 + 0x4000)>>15;
+               /* alternate (ansi) version of above line does slightly different rounding:
+                * L_temp = L_z2 >> 9;
+                * L_temp += L_temp >> 5;
+                * L_temp = (++L_temp) >> 1;
+                * L_z2 = L_z2 - L_temp;
+                */
+               L_z2 = GSM_L_ADD(L_z2,L_s2);
+#endif
+               /*    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_temp, 15 );
+               *so++ = GSM_ADD( mp, msp );
+               }
+       }
+
+       S->z1   = z1;
+       S->L_z2 = L_z2;
+       S->mp   = mp;
+}
diff --git a/utils/iaxclient/lib/gsm/src/rpe.c b/utils/iaxclient/lib/gsm/src/rpe.c
new file mode 100644 (file)
index 0000000..80cce0b
--- /dev/null
@@ -0,0 +1,491 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+
+/*  4.2.13 .. 4.2.17  RPE ENCODING SECTION
+ */
+
+/* 4.2.13 */
+#ifdef K6OPT
+#include "k6opt.h"
+#else
+static void Weighting_filter P2((e, x),
+       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_result, 13 );
+               x[k] = (word) (L_result < MIN_WORD ? MIN_WORD
+                       : (L_result > MAX_WORD ? MAX_WORD : L_result));
+       }
+}
+#endif /* K6OPT */
+
+/* 4.2.14 */
+
+static void RPE_grid_selection P3((x,xM,Mc_out),
+       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( 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( 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 P3((xmaxc,exp_out,mant_out),
+       word            xmaxc,          /* IN   */
+       word            * exp_out,      /* OUT  */
+       word            * mant_out )    /* OUT  */
+{
+       word    exp, mant;
+
+       /* Compute exponent and mantissa of the decoded version of xmaxc
+        */
+
+       exp = 0;
+       if (xmaxc > 15) exp = SASR(xmaxc, 3) - 1;
+       mant = xmaxc - (exp << 3);
+
+       if (mant == 0) {
+               exp  = -4;
+               mant = 7;
+       }
+       else {
+               while (mant <= 7) {
+                       mant = mant << 1 | 1;
+                       exp--;
+               }
+               mant -= 8;
+       }
+
+       assert( exp  >= -4 && exp <= 6 );
+       assert( mant >= 0 && mant <= 7 );
+
+       *exp_out  = exp;
+       *mant_out = mant;
+}
+
+static void APCM_quantization P5((xM,xMc,mant_out,exp_out,xmaxc_out),
+       word            * xM,           /* [0..12]              IN      */
+
+       word            * xMc,          /* [0..12]              OUT     */
+       word            * mant_out,     /*                      OUT     */
+       word            * exp_out,      /*                      OUT     */
+       word            * xmaxc_out     /*                      OUT     */
+)
+{
+       int     i, itest;
+
+       word    xmax, xmaxc, temp, temp1, temp2;
+       word    exp, 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.
+        */
+
+       exp   = 0;
+       temp  = SASR( xmax, 9 );
+       itest = 0;
+
+       for (i = 0; i <= 5; i++) {
+
+               itest |= (temp <= 0);
+               temp = SASR( temp, 1 );
+
+               assert(exp <= 5);
+               if (itest == 0) exp++;          /* exp = add (exp, 1) */
+       }
+
+       assert(exp <= 6 && exp >= 0);
+       temp = exp + 5;
+
+       assert(temp <= 11 && temp >= 0);
+       xmaxc = gsm_add( SASR(xmax, temp), exp << 3 );
+
+       /*   Quantizing and coding of the xM[0..12] RPE sequence
+        *   to get the xMc[0..12]
+        */
+
+       APCM_quantization_xmaxc_to_exp_mant( xmaxc, &exp, &mant );
+
+       /*  This computation uses the fact that the decoded version of xmaxc
+        *  can be calculated by using the exponent 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 exponent.  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( exp <= 4096 && exp >= -4096);
+       assert( mant >= 0 && mant <= 7 ); 
+
+       temp1 = 6 - exp;                /* normalization by the exponent */
+       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(temp, 12);
+               xMc[i] = temp + 4;              /* see note below */
+       }
+
+       /*  NOTE: This equation is used to make all the xMc[i] positive.
+        */
+
+       *mant_out  = mant;
+       *exp_out   = exp;
+       *xmaxc_out = xmaxc;
+}
+
+/* 4.2.16 */
+
+static void APCM_inverse_quantization P4((xMc,mant,exp,xMp),
+       register word   * xMc,  /* [0..12]                      IN      */
+       word            mant,
+       word            exp,
+       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;
+       longword        ltmp;
+
+       assert( mant >= 0 && mant <= 7 ); 
+
+       temp1 = gsm_FAC[ mant ];        /* see 4.2-15 for mant */
+       temp2 = gsm_sub( 6, exp );      /* 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 P3((Mc,xMp,ep),
+       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 P3((dpp, ep, dp),
+       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 P5((S,e,xmaxc,Mc,xMc),
+
+       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, exp;
+
+       Weighting_filter(e, x);
+       RPE_grid_selection(x, xM, Mc);
+
+       APCM_quantization(      xM, xMc, &mant, &exp, xmaxc);
+       APCM_inverse_quantization(  xMc,  mant,  exp, xMp);
+
+       RPE_grid_positioning( *Mc, xMp, e );
+
+}
+
+void Gsm_RPE_Decoding P5((S, xmaxcr, Mcr, xMcr, erp),
+       struct gsm_state        * S,
+
+       word            xmaxcr,
+       word            Mcr,
+       word            * xMcr,  /* [0..12], 3 bits             IN      */
+       word            * erp    /* [0..39]                     OUT     */
+)
+{
+       word    exp, mant;
+       word    xMp[ 13 ];
+
+       APCM_quantization_xmaxc_to_exp_mant( xmaxcr, &exp, &mant );
+       APCM_inverse_quantization( xMcr, mant, exp, xMp );
+       RPE_grid_positioning( Mcr, xMp, erp );
+
+}
diff --git a/utils/iaxclient/lib/gsm/src/short_term.c b/utils/iaxclient/lib/gsm/src/short_term.c
new file mode 100644 (file)
index 0000000..e7dd754
--- /dev/null
@@ -0,0 +1,452 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "private.h"
+
+#include "gsm.h"
+#include "proto.h"
+#ifdef K6OPT
+#include "k6opt.h"
+
+#define Short_term_analysis_filtering Short_term_analysis_filteringx
+
+#endif
+/*
+ *  SHORT TERM ANALYSIS FILTERING SECTION
+ */
+
+/* 4.2.8 */
+
+static void Decoding_of_the_coded_Log_Area_Ratios P2((LARc,LARpp),
+       word    * LARc,         /* coded log area ratio [0..7]  IN      */
+       word    * LARpp)        /* out: decoded ..                      */
+{
+       register word   temp1 /* , temp2 */;
+       register long   ltmp;   /* for GSM_ADD */
+
+       /*  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    = (word) GSM_ADD( *LARc++, MIC ) << 10;        \
+               temp1    = (word) GSM_SUB( temp1, B << 1 );             \
+               temp1    = (word) GSM_MULT_R( INVA, temp1 );            \
+               *LARpp++ = (word) 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 P3((LARpp_j_1, LARpp_j, LARp),
+       register word * LARpp_j_1,
+       register word * LARpp_j,
+       register word * LARp)
+{
+       register int    i;
+       register longword ltmp;
+
+       for (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) {
+               *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 ));
+               *LARp = GSM_ADD( *LARp,  SASR( *LARpp_j_1, 1));
+       }
+}
+
+static void Coefficients_13_26 P3((LARpp_j_1, LARpp_j, LARp),
+       register word * LARpp_j_1,
+       register word * LARpp_j,
+       register word * LARp)
+{
+       register int i;
+       register longword ltmp;
+       for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) {
+               *LARp = GSM_ADD( SASR( *LARpp_j_1, 1), SASR( *LARpp_j, 1 ));
+       }
+}
+
+static void Coefficients_27_39 P3((LARpp_j_1, LARpp_j, LARp),
+       register word * LARpp_j_1,
+       register word * LARpp_j,
+       register word * LARp)
+{
+       register int i;
+       register longword ltmp;
+
+       for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) {
+               *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 ));
+               *LARp = GSM_ADD( *LARp, SASR( *LARpp_j, 1 ));
+       }
+}
+
+
+static void Coefficients_40_159 P2((LARpp_j, LARp),
+       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 P1((LARp),
+       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;
+       register longword       ltmp;
+
+       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( temp >> 2, 26112 )));
+               } else {
+                       temp  = *LARp;
+                       *LARp =    (temp < 11059) ? temp << 1
+                               : ((temp < 20070) ? temp + 11059
+                               :  GSM_ADD( temp >> 2, 26112 ));
+               }
+       }
+}
+
+
+/* 4.2.10 */
+#ifndef Short_term_analysis_filtering
+
+/* SJB Remark:
+ * I tried 2 MMX versions of this function, neither is significantly
+ * faster than the C version which follows.  MMX might be useful if
+ * one were processing 2 input streams in parallel.
+ */
+static void Short_term_analysis_filtering P4((u0,rp0,k_n,s),
+       register word * u0,
+       register word   * rp0,  /* [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 u0[0..7] in memory for each call.
+ */
+{
+       register word           * u_top = u0 + 8;
+       register word           * s_top = s + k_n;
+
+       while (s < s_top) {
+               register word           *u, *rp ;
+               register longword               di, u_out;
+               di = u_out = *s;
+               for (rp=rp0, u=u0; u<u_top;) {
+                       register longword       ui, rpi;
+                       ui    = *u;
+                       *u++  = (word) u_out;
+                       rpi   = *rp++;
+                       u_out = ui + (((rpi*di)+0x4000)>>15);
+                       di    = di + (((rpi*ui)+0x4000)>>15);
+                       /* make the common case fastest: */
+                       if ((u_out == (word)u_out) && (di == (word)di)) continue;
+                       /* otherwise do slower fixup (saturation) */
+                       if (u_out>MAX_WORD) u_out=MAX_WORD;
+                       else if (u_out<MIN_WORD) u_out=MIN_WORD;
+                       if (di>MAX_WORD) di=MAX_WORD;
+                       else if (di<MIN_WORD) di=MIN_WORD;
+               }
+               *s++ = (word) di;
+       }
+}
+#endif
+
+#if defined(USE_FLOAT_MUL) && defined(FAST)
+
+static void Fast_Short_term_analysis_filtering P4((u,rp,k_n,s),
+       register word * u;
+       register word   * rp,   /* [0..7]       IN      */
+       register int    k_n,    /*   k_end - k_start    */
+       register word   * s     /* [0..n-1]     IN/OUT  */
+)
+{
+       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)) */
+
+/*
+ * SJB Remark: modified Short_term_synthesis_filtering() below
+ *  for significant (abt 35%) speedup of decompression.
+ *    (gcc-2.95, k6 cpu)
+ *  Please don't change this without benchmarking decompression
+ *  to see that you haven't harmed speed.
+ *  This function burns most of CPU time for untoasting.
+ *  Unfortunately, didn't see any good way to benefit from mmx.
+ */
+static void Short_term_synthesis_filtering P5((S,rrp,k,wt,sr),
+       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 longword               sri;
+
+       while (k--) {
+               sri = *wt++;
+               for (i = 8; i--;) {
+                       register longword               tmp1, tmp2;
+
+                       /* sri = GSM_SUB( sri, gsm_mult_r( rrp[i], v[i] ) );
+                        */
+                       tmp1 = rrp[i];
+                       tmp2 = v[i];
+
+                       tmp2 = (( tmp1 * tmp2 + 16384) >> 15) ;
+                       /* saturation done below */
+                       sri  -= tmp2;
+                       if (sri != (word)sri) {
+                               sri = (sri<0)? MIN_WORD:MAX_WORD;
+                       }
+                       /* v[i+1] = GSM_ADD( v[i], gsm_mult_r( rrp[i], sri ) );
+                        */
+
+                       tmp1 = (( tmp1 * sri + 16384) >> 15) ;
+                       /* saturation done below */
+                       tmp1 += v[i];
+                       if (tmp1 != (word)tmp1) {
+                               tmp1 = (tmp1<0)? MIN_WORD:MAX_WORD;
+                       }
+                       v[i+1] = (word) tmp1;
+               }
+               *sr++ = v[0] = (word) sri;
+       }
+}
+
+
+#if defined(FAST) && defined(USE_FLOAT_MUL)
+
+static void Fast_Short_term_synthesis_filtering P5((S,rrp,k,wt,sr),
+       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 P3((S,LARc,s),
+
+       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->u, LARp, 13, s);
+
+       Coefficients_13_26( LARpp_j_1, LARpp_j, LARp);
+       LARp_to_rp( LARp );
+       FILTER( S->u, LARp, 14, s + 13);
+
+       Coefficients_27_39( LARpp_j_1, LARpp_j, LARp);
+       LARp_to_rp( LARp );
+       FILTER( S->u, LARp, 13, s + 27);
+
+       Coefficients_40_159( LARpp_j, LARp);
+       LARp_to_rp( LARp );
+       FILTER( S->u, LARp, 120, s + 40);
+       
+}
+
+void Gsm_Short_Term_Synthesis_Filter P4((S, LARcr, wt, s),
+       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);
+}
diff --git a/utils/iaxclient/lib/gsm/src/table.c b/utils/iaxclient/lib/gsm/src/table.c
new file mode 100644 (file)
index 0000000..16a0411
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+/* $Header$ */
+
+/*  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 "private.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 };
diff --git a/utils/iaxclient/lib/iaxclient.h b/utils/iaxclient/lib/iaxclient.h
new file mode 100644 (file)
index 0000000..4d4c407
--- /dev/null
@@ -0,0 +1,1379 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003-2006, Horizon Wimba, Inc.
+ * Copyright (C) 2007, Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ * Frik Strecker <frik@gatherworks.com>
+ * Mihai Balea <mihai AT hates DOT ms>
+ * Peter Grayson <jpgrayson@gmail.com>
+ * Bill Cholewka <bcholew@gmail.com>
+ * Erik Bunce <kde@bunce.us>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ */
+#ifndef _iaxclient_h
+#define _iaxclient_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+  \file iaxclient.h
+  \brief The IAXClient API
+       
+       
+
+  \note This is the include file which declares all external API functions to
+  IAXClient.  It should include all functions and declarations needed
+  by IAXClient library users, but not include internal structures, or
+  require the inclusion of library internals (or sub-libraries) 
+*/
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+#ifdef _MSC_VER
+typedef int socklen_t;
+#endif
+#if defined(WIN32)  ||  defined(_WIN32_WCE)
+#include "winpoop.h"
+#else
+#include <sys/socket.h>
+#endif
+
+#ifdef BUILDING_DLL
+# if defined(WIN32) ||  defined(_WIN32_WCE)
+#  ifdef _MSC_VER
+#   define EXPORT __declspec(dllexport)
+#  else
+#   define EXPORT  __stdcall __declspec(dllexport)
+#  endif
+# else
+#  define EXPORT
+#endif
+#else
+# define EXPORT
+#endif
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+#if defined(WIN32)  ||  defined(_WIN32_WCE)
+#if defined(_MSC_VER)
+       typedef int (__stdcall *iaxc_sendto_t)(SOCKET, const void *, size_t, int,
+                       const struct sockaddr *, socklen_t);
+       typedef int (__stdcall *iaxc_recvfrom_t)(SOCKET, void *, size_t, int,
+                       struct sockaddr *, socklen_t *);
+#else
+       typedef int PASCAL (*iaxc_sendto_t)(SOCKET, const char *, int, int,
+                       const struct sockaddr *, int);
+       typedef int PASCAL (*iaxc_recvfrom_t)(SOCKET, char *, int, int,
+                       struct sockaddr *, int *);
+#endif
+#else
+       /*!
+               Defines the portotype for an application provided sendto implementation.
+       */
+       typedef int (*iaxc_sendto_t)(int, const void *, size_t, int,
+                       const struct sockaddr *, socklen_t);
+       /*!
+               Defines the portotype for an application provided recvfrom implementation.
+       */
+       typedef int (*iaxc_recvfrom_t)(int, void *, size_t, int,
+                       struct sockaddr *, socklen_t *);
+#endif
+
+/*!
+       Mask containing all potentially valid audio formats
+*/
+#define IAXC_AUDIO_FORMAT_MASK  ((1<<16)-1)
+
+/*!
+       Mask containing all potentially valid video formats
+*/
+#define IAXC_VIDEO_FORMAT_MASK  (((1<<25)-1) & ~IAXC_AUDIO_FORMAT_MASK)
+
+/* payload formats : WARNING: must match libiax values!!! */
+/* Data formats for capabilities and frames alike */
+#define IAXC_FORMAT_G723_1       (1 << 0)   /*!< G.723.1 compression */
+#define IAXC_FORMAT_GSM          (1 << 1)   /*!< GSM compression */
+#define IAXC_FORMAT_ULAW         (1 << 2)   /*!< Raw mu-law data (G.711) */
+#define IAXC_FORMAT_ALAW         (1 << 3)   /*!< Raw A-law data (G.711) */
+#define IAXC_FORMAT_G726         (1 << 4)   /*!< ADPCM, 32kbps  */
+#define IAXC_FORMAT_ADPCM        (1 << 5)   /*!< ADPCM IMA */
+#define IAXC_FORMAT_SLINEAR      (1 << 6)   /*!< Raw 16-bit Signed Linear (8000 Hz) PCM */
+#define IAXC_FORMAT_LPC10        (1 << 7)   /*!< LPC10, 180 samples/frame */
+#define IAXC_FORMAT_G729A        (1 << 8)   /*!< G.729a Audio */
+#define IAXC_FORMAT_SPEEX        (1 << 9)   /*!< Speex Audio */
+#define IAXC_FORMAT_ILBC         (1 << 10)  /*!< iLBC Audio */
+
+#define IAXC_FORMAT_MAX_AUDIO    (1 << 15)  /*!< Maximum audio format value */
+#define IAXC_FORMAT_JPEG         (1 << 16)  /*!< JPEG Images */
+#define IAXC_FORMAT_PNG          (1 << 17)  /*!< PNG Images */
+#define IAXC_FORMAT_H261         (1 << 18)  /*!< H.261 Video */
+#define IAXC_FORMAT_H263         (1 << 19)  /*!< H.263 Video */
+#define IAXC_FORMAT_H263_PLUS    (1 << 20)  /*!< H.263+ Video */
+#define IAXC_FORMAT_H264         (1 << 21)  /*!< H264 Video */
+#define IAXC_FORMAT_MPEG4        (1 << 22)  /*!< MPEG4 Video */
+#define IAXC_FORMAT_THEORA       (1 << 24)  /*!< Theora Video */
+#define IAXC_FORMAT_MAX_VIDEO    (1 << 24)  /*!< Maximum Video format value*/
+
+#define IAXC_EVENT_TEXT          1   /*!< Indicates a text event */
+#define IAXC_EVENT_LEVELS        2   /*!< Indicates a level event */
+#define IAXC_EVENT_STATE         3   /*!< Indicates a call state change event */
+#define IAXC_EVENT_NETSTAT       4   /*!< Indicates a network statistics update event */
+#define IAXC_EVENT_URL           5   /*!< Indicates a URL push via IAX(2) */
+#define IAXC_EVENT_VIDEO         6   /*!< Indicates a video event */
+#define IAXC_EVENT_REGISTRATION  8   /*!< Indicates a registration event */
+#define IAXC_EVENT_DTMF          9   /*!< Indicates a DTMF event */
+#define IAXC_EVENT_AUDIO         10  /*!< Indicates an audio event */
+#define IAXC_EVENT_VIDEOSTATS    11  /*!< Indicates a video statistics update event */
+#define IAXC_EVENT_VIDCAP_ERROR  12  /*!< Indicates a video capture error occurred */
+#define IAXC_EVENT_VIDCAP_DEVICE 13  /*!< Indicates a possible video capture device insertion/removal */
+
+#define IAXC_CALL_STATE_FREE     0       /*!< Indicates a call slot is free */
+#define IAXC_CALL_STATE_ACTIVE   (1<<1)  /*!< Indicates a call is active */
+#define IAXC_CALL_STATE_OUTGOING (1<<2)  /*!< Indicates a call is outgoing */
+#define IAXC_CALL_STATE_RINGING  (1<<3)  /*!< Indicates a call is ringing */
+#define IAXC_CALL_STATE_COMPLETE (1<<4)  /*!< Indicates a completed call */
+#define IAXC_CALL_STATE_SELECTED (1<<5)  /*!< Indicates the call is selected */
+#define IAXC_CALL_STATE_BUSY     (1<<6)  /*!< Indicates a call is busy */
+#define IAXC_CALL_STATE_TRANSFER (1<<7)  /*!< Indicates the call transfer has been released */
+
+/*! Indicates that text is for an IAXClient status change */
+#define IAXC_TEXT_TYPE_STATUS     1   
+/*!  Indicates that text is an IAXClient warning message */
+#define IAXC_TEXT_TYPE_NOTICE     2   
+/*!  Represents that text is for an IAXClient error message */
+#define IAXC_TEXT_TYPE_ERROR      3   
+/*!  
+       Represents that text is for an IAXClient fatal error message.
+       
+       The User Agent should probably display error message text, then die 
+*/
+#define IAXC_TEXT_TYPE_FATALERROR 4   
+/*!  Represents a message sent from the server across the IAX stream*/
+#define IAXC_TEXT_TYPE_IAX        5   
+
+/* registration replys, corresponding to IAX_EVENTs*/
+#define IAXC_REGISTRATION_REPLY_ACK     18   /*!< Indicates the registration was accepted (See IAX_EVENT_REGACC)  */
+#define IAXC_REGISTRATION_REPLY_REJ     30   /*!< Indicates the registration was rejected (See IAX_EVENT_REGREJ)  */
+#define IAXC_REGISTRATION_REPLY_TIMEOUT 6    /*!< Indicates the registration timed out (See IAX_EVENT_TIMEOUT) */
+
+#define IAXC_URL_URL              1  /*!< URL received */
+#define IAXC_URL_LDCOMPLETE       2  /*!< URL loading complete */
+#define IAXC_URL_LINKURL          3  /*!< URL link request */
+#define IAXC_URL_LINKREJECT       4  /*!< URL link reject */
+#define IAXC_URL_UNLINK           5  /*!< URL unlink */
+
+/* The source of the video or audio data triggering the event. */
+#define IAXC_SOURCE_LOCAL  1 /*!<  Indicates that the event data source is local */
+#define IAXC_SOURCE_REMOTE 2 /*!<  Indicates that the event data source is remote */
+
+/*!
+       The maximum size of a string contained within an event
+ */
+#define IAXC_EVENT_BUFSIZ 256
+
+/*!
+       A structure containing information about an audio level event.
+*/
+struct iaxc_ev_levels {
+       /*!
+               The input level in dB.
+       */
+       float input;
+
+       /*!
+               The output level in dB.
+       */
+       float output;
+};
+
+/*!
+       A structure containing information about a text event.
+*/
+struct iaxc_ev_text {
+       /*!
+               The type of text event. 
+
+               Valid values are from the IAXC_TEXT_TYPE_{} family of defines.
+               \see IAXC_TEXT_TYPE_STATUS, IAXC_TEXT_TYPE_NOTICE, IAXC_TEXT_TYPE_ERROR, 
+               IAXC_TEXT_TYPE_FATALERROR, IAXC_TEXT_TYPE_IAX
+       */
+       int type;
+
+       /*!
+               The call the text is associated with or -1 if general text.
+       */
+       int callNo; 
+
+       /*!
+               The UTF8 encoded text of the message.
+       */
+       char message[IAXC_EVENT_BUFSIZ];
+};
+
+/*!
+       A structure containing information about a call state change event.
+*/
+struct iaxc_ev_call_state {
+       /*!
+               The call number whose state this is
+       */
+       int callNo;
+
+       /*!
+               The call state represented using the IAXC_CALL_STATE_{} defines.
+
+               \see IAXC_CALL_STATE_FREE, IAXC_CALL_STATE_ACTIVE, IAXC_CALL_STATE_OUTGOING,
+               IAXC_CALL_STATE_RINGING, IAXC_CALL_STATE_COMPLETE, IAXC_CALL_STATE_SELECTED,
+               IAXC_CALL_STATE_BUSY, IAXC_CALL_STATE_TRANSFER
+       */
+       int state;
+       
+       /*!
+               The audio format of the call.
+
+               \see IAXC_FORMAT_G723_1, IAXC_FORMAT_GSM, IAXC_FORMAT_ULAW, IAXC_FORMAT_ALAW,
+               IAXC_FORMAT_G726, IAXC_FORMAT_ADPCM, IAXC_FORMAT_SLINEAR, IAXC_FORMAT_LPC10,
+               IAXC_FORMAT_G729A, IAXC_FORMAT_SPEEX, IAXC_FORMAT_ILBC, IAXC_FORMAT_MAX_AUDIO
+       */
+       int format;
+       
+       /*!
+               The audio format of the call.
+
+               \see IAXC_FORMAT_JPEG, IAXC_FORMAT_PNG, IAXC_FORMAT_H261, IAXC_FORMAT_H263,
+               IAXC_FORMAT_H263_PLUS, IAXC_FORMAT_H264, IAXC_FORMAT_MPEG4, 
+               IAXC_FORMAT_THEORA, IAXC_FORMAT_MAX_VIDEO
+       */
+       int vformat;
+
+       /*!
+               The remote number.
+       */
+       char remote[IAXC_EVENT_BUFSIZ];
+
+       /*!
+               The remote name.
+       */
+       char remote_name[IAXC_EVENT_BUFSIZ];
+       
+       /*!
+               The local number.
+       */
+       char local[IAXC_EVENT_BUFSIZ];
+
+       /*!
+               The local calling context.
+       */
+       char local_context[IAXC_EVENT_BUFSIZ];
+};
+
+/*!
+       A structure containing information about a set of network statistics.
+*/
+struct iaxc_netstat {
+       /*!
+               The amount of observed jitter.
+       */
+       int jitter;
+
+       /*!
+               The lost frame percentage.
+       */
+       int losspct;
+
+       /*!
+               The number of missing frames.
+       */
+       int losscnt;
+
+       /*!
+               The number of frames received.
+       */
+       int packets;
+
+       /*!
+               The observed delay.
+       */
+       int delay;
+       
+       /*!
+               The number of frames dropped.
+       */
+       int dropped;
+
+       /*!
+               The number of frames received out of order.
+       */
+       int ooo;
+};
+
+/*!
+       A structure containing information about a network statistics event.
+*/
+struct iaxc_ev_netstats {
+       /*!
+               The call whose statistics these are.
+       */
+       int callNo;
+       
+       /*!
+               The Round Trip Time
+       */
+       int rtt;
+
+       /*!
+               The locally observed network statistics.
+       */
+       struct iaxc_netstat local;
+
+       /*!
+               The remotely (peer) observed network statistics.
+       */
+       struct iaxc_netstat remote;
+};
+
+/*!
+       A structure containing video statistics data.
+*/
+struct iaxc_video_stats
+{
+       unsigned long received_slices;  /*!< Number of received slices. */
+       unsigned long acc_recv_size;    /*!< Accumulated size of inbound slices. */
+       unsigned long sent_slices;      /*!< Number of sent slices. */
+       unsigned long acc_sent_size;    /*!< Accumulated size of outbound slices. */
+
+       unsigned long dropped_frames;   /*!< Number of frames dropped by the codec (incomplete frames). */
+       unsigned long inbound_frames;   /*!< Number of frames decoded by the codec (complete frames). */
+       unsigned long outbound_frames;  /*!< Number of frames sent to the encoder. */
+
+       float         avg_inbound_fps;  /*!< Average fps of inbound complete frames. */
+       unsigned long avg_inbound_bps;  /*!< Average inbound bitrate. */
+       float         avg_outbound_fps; /*!< Average fps of outbound frames. */
+       unsigned long avg_outbound_bps; /*!< Average outbound bitrate. */
+
+       struct timeval start_time;      /*!< Timestamp of the moment we started measuring. */
+};
+
+/*!
+       A structure containing information about a video statistics event.
+*/
+struct iaxc_ev_video_stats {
+       /*!
+               The call whose statistics these are.
+       */
+       int callNo;
+
+       /*!
+               The video statistics for the call.
+       */
+       struct iaxc_video_stats stats;
+};
+
+/*!
+       A structure containing information about an URL event.
+*/
+struct iaxc_ev_url {
+       /*!
+               The call this is for.
+       */
+       int callNo;
+
+       /*!
+               The type of URL received. See the IAXC_URL_{} defines.
+
+               \see IAXC_URL_URL, IAXC_URL_LINKURL, IAXC_URL_LDCOMPLETE, IAXC_URL_UNLINK,
+               IAXC_URL_LINKREJECT
+       */
+       int type;
+
+       /*!
+               The received URL.
+       */
+       char url[IAXC_EVENT_BUFSIZ];
+};
+
+/*!
+       A structure containing data for a video event.
+*/
+struct iaxc_ev_video {
+       /*!
+               The call this video data is for.
+
+               Will be -1 for local video.
+       */
+       int callNo;
+
+       /*!
+               Timestamp of the video
+       */
+       unsigned int ts;
+
+       /*!
+               The format of the video data.
+
+       \see IAXC_FORMAT_JPEG, IAXC_FORMAT_PNG, IAXC_FORMAT_H261, IAXC_FORMAT_H263,
+       IAXC_FORMAT_H263_PLUS, IAXC_FORMAT_H264, IAXC_FORMAT_MPEG4, 
+       IAXC_FORMAT_THEORA, IAXC_FORMAT_MAX_VIDEO
+       */
+       int format;
+       
+       /*!
+               The width of the video.
+       */
+       int width;
+       
+       /*!
+               The height of the video.
+       */
+       int height;
+
+       /*!
+               Is the data encoded.
+
+               1 for encoded data, 0 for raw.
+       */
+       int encoded;
+
+       /*!
+               The source of the data.
+
+               \see IAXC_SOURCE_LOCAL, IAXC_SOURCE_REMOTE
+       */
+       int source;
+
+       /*!
+               The size of the video data in bytes.
+       */
+       int size;
+
+       /*!
+               The buffer containing the video data.
+       */
+       char *data;
+};
+
+/*!
+       A structure containing data for an audio event.
+*/
+struct iaxc_ev_audio
+{
+       /*!
+               The call this audio data is for.
+       */
+       int callNo;
+
+       /*!
+               Timestamp of the video
+       */
+       unsigned int ts;
+
+       /*!
+               The format of the data.
+
+       \see IAXC_FORMAT_G723_1, IAXC_FORMAT_GSM, IAXC_FORMAT_ULAW, IAXC_FORMAT_ALAW,
+       IAXC_FORMAT_G726, IAXC_FORMAT_ADPCM, IAXC_FORMAT_SLINEAR, IAXC_FORMAT_LPC10,
+       IAXC_FORMAT_G729A, IAXC_FORMAT_SPEEX, IAXC_FORMAT_ILBC, IAXC_FORMAT_MAX_AUDIO
+       */
+       int format;
+
+       /*!
+               Is the data encoded.
+
+               1 for encoded data, 0 for raw.
+       */
+       int encoded;
+
+       /*!
+               The source of the data.
+
+               \see IAXC_SOURCE_LOCAL, IAXC_SOURCE_REMOTE
+       */
+       int source;
+
+       /*!
+               The size of the audio data in bytes.
+       */ 
+       int size;
+
+       /*!
+               The buffer containing the audio data.
+       */
+       unsigned char *data;
+};
+
+/*!
+       A structure containing information about a registration event 
+*/
+struct iaxc_ev_registration {
+       /*!
+               Indicates the registration id this event corresponds to.
+
+               \see iaxc_register
+       */
+       int id;
+
+       /*!
+               The registration reply.
+
+               The values are from the IAXC_REGISTRATION_REPLY_{} family of macros.
+               \see IAX_EVENT_REGACC, IAX_EVENT_REGREJ, IAX_EVENT_TIMEOUT
+       */
+       int reply;
+
+       /*!
+               The number of 'voicemail' messages.
+       */
+       int msgcount;
+};
+
+/*!
+       A structure containing information about a DTMF event
+ */
+struct iaxc_ev_dtmf {
+       /*!
+               The call this DTMF event is for.
+        */
+       int  callNo;
+
+       /*!
+               The digit represented by this DTMF tone
+        */
+       char digit;
+};
+
+/*!
+       A structure describing a single IAXClient event.
+*/
+typedef struct iaxc_event_struct {
+       /*!
+               Points to the next entry in the event queue
+               \internal
+       */
+       struct iaxc_event_struct *next;
+
+       /*!
+               The type uses one of the IAXC_EVENT_{} macros to describe which type of
+               event is being presented
+       */
+       int type; 
+       
+       /*!
+               Contains the data specific to the type of event.
+       */
+       union {
+               /*! Contains level data if type = IAXC_EVENT_LEVELS */
+               struct iaxc_ev_levels           levels;
+               /*! Contains text data if type = IAXC_EVENT_TEXT */
+               struct iaxc_ev_text             text;       
+               /*! Contains call state data if type = IAXC_EVENT_STATE */
+               struct iaxc_ev_call_state       call;       
+               /*! Contains network statistics if type = IAXC_EVENT_NETSTAT */
+               struct iaxc_ev_netstats         netstats;   
+               /*! Contains video statistics if type = IAXC_EVENT_VIDEOSTATS */
+               struct iaxc_ev_video_stats      videostats; 
+               /*! Contains url data if type = IAXC_EVENT_URL */
+               struct iaxc_ev_url              url;        
+               /*! Contains video data if type = IAXC_EVENT_VIDEO */
+               struct iaxc_ev_video            video;      
+               /*! Contains audio data if type = IAXC_EVENT_AUDIO */
+               struct iaxc_ev_audio            audio;      
+               /*! Contains registration data if type = IAXC_EVENT_REGISTRATION */
+               struct iaxc_ev_registration     reg;
+               /*! Contains DTMF data if type = IAXC_EVENT_DTMF */
+               struct iaxc_ev_dtmf             dtmf;
+       } ev;
+} iaxc_event;
+
+/*!
+       Defines the prototype for event callback handlers
+       \param e The event structure being passed to the callback
+       
+       \return The result of processing the event; > 0 if successfully handled the event, 0 if not handled, < 0 to indicate an error occurred processing the event.
+*/
+typedef int (*iaxc_event_callback_t)(iaxc_event e);
+
+/*!
+       Sets the callback to call with IAXClient events
+       \param func The callback function to call with events
+*/
+EXPORT void iaxc_set_event_callback(iaxc_event_callback_t func);
+
+/*!
+       Sets iaxclient to post a pointer to a copy of event using o/s specific Post method 
+       \param handle
+       \param id
+*/
+EXPORT int iaxc_set_event_callpost(void *handle, int id);
+
+/*!
+       frees event delivered via o/s specific Post method 
+       \param e The event to free
+*/
+EXPORT void iaxc_free_event(iaxc_event *e);
+
+
+/* Event Accessors */
+/*!
+       Returns the levels data associated with event \a e.
+       \param e The event to retrieve the levels from.
+*/
+EXPORT struct iaxc_ev_levels *iaxc_get_event_levels(iaxc_event *e);
+
+/*!
+       Returns the text data associated with event \a e.
+       \param e The event to retrieve text from.
+*/
+EXPORT struct iaxc_ev_text *iaxc_get_event_text(iaxc_event *e);
+
+/*!
+       Returns the event state data associated with event \a e.
+       \param e The event to retrieve call state from.
+*/
+EXPORT struct iaxc_ev_call_state *iaxc_get_event_state(iaxc_event *e);
+
+/*!
+       Set Preferred UDP Port:
+       \param sourceUdpPort The source UDP port to prefer
+       0 Use the default port (4569), <0 Uses a dynamically assigned port, and
+       >0 tries to bind to the specified port
+
+       \note must be called before iaxc_initialize()
+*/
+EXPORT void iaxc_set_preferred_source_udp_port(int sourceUdpPort);
+
+/*!
+       Returns the UDP port that has been bound to.
+
+       \return The UDP port bound to; -1 if no port or
+*/
+EXPORT int iaxc_get_bind_port();
+
+/*!
+       Initializes the IAXClient library
+       \param num_calls The maximum number of simultaneous calls to handle.
+
+       This initializes the IAXClient 
+*/
+EXPORT int iaxc_initialize(int num_calls);
+
+/*!
+       Shutsdown the IAXClient library.
+       
+       This should be called by applications utilizing iaxclient before they exit.
+       It dumps all calls, and releases any audio/video drivers being used.
+
+       \note It is unsafe to call most IAXClient API's after calling this!
+*/
+EXPORT void iaxc_shutdown();
+
+/*!
+       Sets the formats to be used
+       \param preferred The single preferred audio format
+       \param allowed A mask containing all audio formats to allow
+
+       \see IAXC_FORMAT_G723_1, IAXC_FORMAT_GSM, IAXC_FORMAT_ULAW, IAXC_FORMAT_ALAW,
+       IAXC_FORMAT_G726, IAXC_FORMAT_ADPCM, IAXC_FORMAT_SLINEAR, IAXC_FORMAT_LPC10,
+       IAXC_FORMAT_G729A, IAXC_FORMAT_SPEEX, IAXC_FORMAT_ILBC, IAXC_FORMAT_MAX_AUDIO
+*/
+EXPORT void iaxc_set_formats(int preferred, int allowed);
+
+/*!
+       Sets the minimum outgoing frame size.
+       \param samples The minimum number of samples to include in an outgoing frame.
+*/
+EXPORT void iaxc_set_min_outgoing_framesize(int samples);
+
+/*!
+       Sets the caller id \a name and \a number.
+       \param name The caller id name.
+       \param number The caller id number.
+*/
+EXPORT void iaxc_set_callerid(const char * name, const char * number);
+
+/*!
+       Starts all the internal processing thread(s).
+
+       \note Should be called after iaxc_initialize, but before any call processing
+       related functions.
+*/
+EXPORT int iaxc_start_processing_thread();
+
+/*!
+       Stops all the internal processing thread(s).
+
+       \note Should be called before iaxc_shutdown.
+*/
+EXPORT int iaxc_stop_processing_thread();
+
+/*!
+       Initiates a call to an end point
+       \param num The entity to call in the format of [user[:password]]@@peer[:portno][/exten[@@context]]
+
+       \return The call number upon sucess; -1 otherwise.
+
+       \note This is the same as calling iaxc_call_ex(num, NULL, NULL, 1).
+*/
+EXPORT int iaxc_call(const char * num);
+
+/*!
+       Initiates a call to an end point
+       \param num The entity to call in the format of [user[:password]]@@peer[:portno][/exten[@@context]]
+       \param callerid_name The local caller id name to use
+       \param callerid_number The local caller id number to use
+       \param video 0 indicates no-video. Any non-zero value indicates video is requested
+
+       \return The call number upon sucess; -1 otherwise.
+*/
+EXPORT int iaxc_call_ex(const char* num, const char* callerid_name, const char* callerid_number, int video);
+
+/*!
+       Unregisters IAXClient from a server
+       \param id The registration number returned by iaxc_register.
+*/
+EXPORT int iaxc_unregister( int id );
+
+/*!
+       Registers the IAXClient instance with an IAX server
+       \param user The username to register as
+       \param pass The password to register with
+       \param host The address of the host/peer to register with
+
+       \return The registration id number upon success; -1 otherwise.
+*/
+EXPORT int iaxc_register(const char * user, const char * pass, const char * host);
+
+/*!
+       Registers the IAXClient instance with an IAX server
+       \param user The username to register as
+       \param pass The password to register with
+       \param host The address of the host/peer to register with
+       \param refresh The registration refresh period
+
+       \return The registration id number upon success; -1 otherwise.
+*/
+EXPORT int iaxc_register_ex(const char * user, const char * pass, const char * host, int refresh);
+
+/*!
+       Respond to incoming call \a callNo as busy.
+*/
+EXPORT void iaxc_send_busy_on_incoming_call(int callNo);
+
+/*!
+       Answers the incoming call \a callNo.
+       \param callNo The number of the call to answer.
+*/
+EXPORT void iaxc_answer_call(int callNo);
+
+/*!
+       Initiate a blind call transfer of \a callNo to \a number.
+       \param callNo The active call to transfer.
+       \param number The number to transfer the call to. See draft-guy-iax-03 section 8.4.1 for further details.
+*/
+EXPORT void iaxc_blind_transfer_call(int callNo, const char * number);
+
+/*!
+       Setup a transfer of \a sourceCallNo to \a targetCallNo.
+       \param sourceCallNo The number of the active call session to transfer.
+       \param targetCallNo The active call session to be transferred to.
+
+       This is used in performing as the final step in an attended call transfer.
+*/
+EXPORT void iaxc_setup_call_transfer(int sourceCallNo, int targetCallNo);
+
+/*!
+       Hangs up and frees all non-free calls.
+*/
+EXPORT void iaxc_dump_all_calls(void);
+
+/*!
+       Hangs up and frees call \a callNo
+       \param callNo The call number to reject.
+*/
+EXPORT void iaxc_dump_call_number( int callNo );
+
+/*!
+       Hangs up and frees the currently selected call.
+*/
+EXPORT void iaxc_dump_call(void);
+
+/*!
+       Rejects the currently selected call.
+
+       \note This is pretty much a useless API, since the act of selecting a call
+       will answer it.
+*/
+EXPORT void iaxc_reject_call(void);
+
+/*!
+       Rejects the incoming call \a callNo.
+       \param callNo The call number to reject.
+*/
+EXPORT void iaxc_reject_call_number(int callNo);
+
+/*!
+       Sends a DTMF digit to the currently selected call.
+       \param digit The DTMF digit to send (0-9, A-D, *, #).
+*/
+EXPORT void iaxc_send_dtmf(char digit);
+
+/*!
+       Sends text to the currently selected call.
+*/
+EXPORT void iaxc_send_text(const char * text);
+
+/*!
+       Sends \a text to call \a callNo
+*/
+EXPORT void iaxc_send_text_call(int callNo, const char * text);
+
+/*!
+       Sends a URL across the currently selected call
+       \param url The URL to send across.
+       \param link If non-zero the URL is a link
+*/
+EXPORT void iaxc_send_url(const char *url, int link); /* link == 1 ? AST_HTML_LINKURL : AST_HTML_URL */
+
+/*!
+       Suspends thread execution for an interval measured in milliseconds
+       \param ms The number of milliseconds to sleep
+*/
+EXPORT void iaxc_millisleep(long ms);
+
+/*!
+       Sets the silence threshold to \a thr.
+       \param thr The threshold value in dB. A value of 0.0f effectively mutes audio input.
+*/
+EXPORT void iaxc_set_silence_threshold(float thr);
+
+/*!
+       Sets the audio output to \a mode.
+       \param mode The audio mode 0 indicates remote audio should be played; non-zero prevents remote audio from being played.
+*/
+EXPORT void iaxc_set_audio_output(int mode);
+
+/*!
+       Sets \a callNo as the currently selected call
+       \param callNo The call to select or < 0 to indicate no selected call.
+
+       \note Will answer an incoming ringing call as a side effect. Personally I
+       believe this behavior is undesirable and feel it renders iaxc_reject_call
+       pretty much useless.
+*/
+EXPORT int iaxc_select_call(int callNo);
+
+/*!
+       Returns the first free call number.
+*/
+EXPORT int iaxc_first_free_call();
+
+/*!
+       Returns the number of the currently selected call.
+*/
+EXPORT int iaxc_selected_call();
+
+/*!
+       Causes the audio channel for \a callNo to QUELCH (be squelched).
+       \param callNo The number of the active, accepted call to quelch.
+       \param MOH If non-zero Music On Hold should be played on the QUELCH'd call.
+*/
+EXPORT int iaxc_quelch(int callNo, int MOH);
+
+/*!
+       Causes the audio channel for \a callNo to be UNQUELCH (unsquelched).
+*/
+EXPORT int iaxc_unquelch(int callNo);
+
+/*!
+       Returns the current mic boost setting.
+
+       \return 0 if mic boost is disabled; otherwise non-zero.
+*/
+EXPORT int iaxc_mic_boost_get( void ) ;
+
+/*!
+       Sets the mic boost setting.
+       \param enable If non-zero enable the mic boost; otherwise disable.
+*/
+EXPORT int iaxc_mic_boost_set( int enable ) ;
+
+/*!
+       Returns a copy of IAXClient library version
+       \param ver A buffer to store the version string in. It MUST be at least 
+       IAXC_EVENT_BUFSIZ bytes in size.
+
+       \return the version string (as stored in \a ver).
+*/
+EXPORT char* iaxc_version(char *ver);
+
+/*!
+       Fine tune jitterbuffer control
+       \param value
+*/
+EXPORT void iaxc_set_jb_target_extra( long value );
+
+/*!
+       Application-defined networking; give substitute sendto and recvfrom 
+       functions.
+       \param st The send function to use.
+       \param rf The receive function to use.
+
+       \note Must be called before iaxc_initialize! 
+*/
+EXPORT void iaxc_set_networking(iaxc_sendto_t st, iaxc_recvfrom_t rf) ;
+
+/*!
+       wrapper for libiax2 get_netstats 
+       \param call
+       \param rtt
+       \param local
+       \param remote
+*/
+EXPORT int iaxc_get_netstats(int call, int *rtt, struct iaxc_netstat *local, struct iaxc_netstat *remote);
+
+/*!
+       A structure containing information about a video capture device.
+*/
+struct iaxc_video_device {
+       /*!
+               The "human readable" name of the device
+       */
+       const char *name;
+
+       /*!
+               unique id of the device
+       */
+       const char *id_string;
+
+       /*!
+               iaxclient id of the device
+       */
+       int id;
+};
+
+#define IAXC_AD_INPUT           (1<<0) /*!< Device is usable for input*/
+#define IAXC_AD_OUTPUT          (1<<1) /*!< Device is usable for output */
+#define IAXC_AD_RING            (1<<2) /*!< Device is usable for ring */
+#define IAXC_AD_INPUT_DEFAULT   (1<<3) /*!< Indicates the default input device */
+#define IAXC_AD_OUTPUT_DEFAULT  (1<<4) /*!< Indicates the default output device */
+#define IAXC_AD_RING_DEFAULT    (1<<5) /*!< Indicates the default ring device */
+
+/*!
+       A structure containing information about an audio device.
+*/
+struct iaxc_audio_device {
+       /*!
+               The "human readable" name of the device
+       */
+       const char * name;
+
+       /*!
+               Capability flags, defined using the IAXC_AD_{} macros.
+       */
+       long capabilities;      
+
+       /*!
+               The device driver specific ID.
+       */
+       int devID;
+};
+
+/*! Get audio device information:
+        \param devs Returns an array of iaxc_audio_device structures.
+               The array will will be valid as long as iaxc is initialized.
+        \param nDevs Returns the number of devices in the devs array
+        \param input Returns the currently selected input device
+        \param output Returns the currently selected output device
+        \param ring Returns the currently selected ring device
+ */
+EXPORT int iaxc_audio_devices_get(struct iaxc_audio_device **devs, int *nDevs, int *input, int *output, int *ring);
+
+/*!
+       Sets the current audio devices
+       \param input The device to use for audio input
+       \param output The device to use for audio output
+       \param ring The device to use to present ring sounds
+ */
+EXPORT int iaxc_audio_devices_set(int input, int output, int ring);
+
+/*!
+       Get the audio device input level.
+       
+       \return the input level in the range of 0.0f minimum to 1.0f maximum.
+ */
+EXPORT float iaxc_input_level_get();
+
+/*!
+       Get the audio device output level.
+       
+       \return the input level in the range of 0.0f minimum to 1.0f maximum.
+ */
+EXPORT float iaxc_output_level_get();
+
+/*!
+       Sets the audio input level to \a level.
+       \param level The level in the range from 0.0f (min) to 1.0f (max).
+*/
+EXPORT int iaxc_input_level_set(float level);
+
+/*!
+       Sets the audio output level to \a level.
+       \param level The level in the range from 0.0f (min) to 1.0f (max).
+ */
+EXPORT int iaxc_output_level_set(float level);
+
+/*!
+       A structure describing a sound to IAXClient
+*/
+struct iaxc_sound {
+       short   *data;           /*!< Sound sample data in 8KHz 16-bit signed format. */
+       long    len;             /*!< Length of sample in frames. */
+       int     malloced;        /*!< Should the library free() the data after it is played? */
+       int     channel;         /*!< The channel used: 0 for output, 1 for ring. */
+       int     repeat;          /*!< Number of times to repeat (-1 = infinite). */
+       long    pos;             /*!< \internal use: current play position. */
+       int     id;              /*!< \internal use: sound ID. */
+       struct iaxc_sound *next; /*!< \internal use: next in list. */
+};
+
+/*!
+       Play a sound.
+       \param sound An iaxc_sound structure.
+       \param ring 0 to play through output device or 1 to play through the "ring" device.
+
+       \return The id number of the sound being played
+*/
+EXPORT int iaxc_play_sound(struct iaxc_sound *sound, int ring);
+
+/*! 
+       Stop sound \a id from being played.
+       \param id The id of a sound to stop as returned from iaxc_play_sound.
+*/
+EXPORT int iaxc_stop_sound(int id);
+
+#define IAXC_FILTER_DENOISE     (1<<0) /*!< Noise reduction filter */
+#define IAXC_FILTER_AGC         (1<<1) /*!< Automatic Gain Control */
+#define IAXC_FILTER_ECHO        (1<<2) /*!< Echo cancellation filter */
+#define IAXC_FILTER_AAGC        (1<<3) /*!< Analog (mixer-based) Automatic Gain Control */
+#define IAXC_FILTER_CN          (1<<4) /*!< Send Comfort Noise (CN) frames when silence is detected */
+
+/*!
+       Returns the set of audio filters being applied.
+
+       The IAXC_FILTER_{} defines are used to specify the filters.
+       \see IAXC_FILTER_DENOISE, IAXC_FILTER_AGC, IAXC_FILTER_ECHO, IAXC_FILTER_AAGC,
+       IAXC_FILTER_CN
+ */
+EXPORT int iaxc_get_filters(void);
+
+/*!
+       Sets the current audio filters to apply.
+       \param filters The combination of all the audio filters to use (IAXC_FILTER_{} defines).
+
+       The IAXC_FILTER_{} defines are used to specify the filters.
+       \see IAXC_FILTER_DENOISE, IAXC_FILTER_AGC, IAXC_FILTER_ECHO, IAXC_FILTER_AAGC,
+       IAXC_FILTER_CN
+ */
+EXPORT void iaxc_set_filters(int filters);
+
+/*! 
+       Sets speex specific codec settings 
+       \param decode_enhance 1/0  perceptual enhancement for decoder
+       \param quality: Generally, set either quality (0-9) or bitrate. -1 for "default"
+       \param bitrate in kbps.  Applies to CBR only; -1 for default.
+      (overrides "quality" for CBR mode)
+       \param vbr Variable bitrate mode:  0/1
+       \param abr mode/rate: 0 for not ABR, bitrate for ABR mode
+       \param complexity Algorithmic complexity.  Think -N for gzip.
+      Higher numbers take more CPU for better quality.  3 is
+      default and good choice.
+
+       A good choice is (1,-1,-1,0,8000,3): 8kbps ABR 
+ */
+EXPORT void iaxc_set_speex_settings(int decode_enhance, float quality, int bitrate, int vbr, int abr, int complexity);
+
+/*
+ Functions and flags for setting and getting audio callback preferences
+  The application can request to receive local/remote, raw/encoded audio
+  through the callback mechanism. Please note that changing callback
+  settings will overwrite all previous settings.
+*/
+/*! 
+       Indicates the preference that local audio should be passed to the registered callback in a raw 8KHz 16-bit signed format. 
+*/
+#define IAXC_AUDIO_PREF_RECV_LOCAL_RAW      (1 << 0) 
+
+/*!
+       Indicates the preference that local audio should be passed to the registered callback in the current encoded format.
+*/
+#define IAXC_AUDIO_PREF_RECV_LOCAL_ENCODED  (1 << 1) 
+
+/*!
+       Indicates the preference that remote audio should be passed to the registered callback in a raw 8KHz 16-bit signed format.
+*/
+#define IAXC_AUDIO_PREF_RECV_REMOTE_RAW     (1 << 2) 
+
+/*!
+       Indicates the preference that remote audio should be passed to the registered callback in the current encoded format.
+*/
+#define IAXC_AUDIO_PREF_RECV_REMOTE_ENCODED (1 << 3) 
+
+/*!
+       Indicates the preference that sending of audio should be disabled.
+*/
+#define IAXC_AUDIO_PREF_SEND_DISABLE        (1 << 4) 
+
+/*! 
+        Returns the various audio delivery preferences.
+
+        The preferences are represented using the AIXC_AUDIO_PREF_{} family of defines.
+*/
+EXPORT unsigned int iaxc_get_audio_prefs(void);
+
+/*!
+       Set the various audio delivery preferences
+       \param prefs The desired preferences to use. They are represented using the AIXC_AUDIO_PREF_{} family of defines.
+        
+        \return 0 on success and -1 on error.
+
+        \see IAXC_AUDIO_PREF_RECV_LOCAL_RAW, IAXC_AUDIO_PREF_RECV_LOCAL_ENCODED,
+        IAXC_AUDIO_PREF_RECV_REMOTE_RAW, IAXC_AUDIO_PREF_RECV_REMOTE_ENCODED,
+        IAXC_AUDIO_PREF_SEND_DISABLE
+ */
+EXPORT int iaxc_set_audio_prefs(unsigned int prefs);
+
+/*!
+       Get video capture device information.
+       WARNING: the array pointed to by parameter 'devs' below is owned
+                by iaxclient, and may be freed on subsequent calls to
+                this function.
+        \param devs Returns an array of iaxc_video_device structures.
+               The array will only be valid until this function is
+               called again (if the device list changes), or until
+               iaxc is shutdown.
+        \param nDevs Returns the number of devices in the devs array
+        \param devId Returns the id of the currently selected video capture device
+
+        \return -1 on error, 0 if no change to the device list, 1 if it's been updated
+ */
+EXPORT int iaxc_video_devices_get(struct iaxc_video_device **devs, int *nDevs, int *devId);
+
+/*!
+       Sets the current video capture device
+       \param devId The id of the device to use for video capture
+ */
+EXPORT int iaxc_video_device_set(int devId);
+
+/*
+ * Acceptable range for video rezolution
+ */
+#define IAXC_VIDEO_MAX_WIDTH    704 /*!< Maximum video width */
+#define IAXC_VIDEO_MAX_HEIGHT   576 /*!< Maximum video height */
+#define IAXC_VIDEO_MIN_WIDTH    80  /*!< Minimum video width */
+#define IAXC_VIDEO_MIN_HEIGHT   60  /*!< Minimum video height */
+
+/*
+ Video callback preferences
+ The client application can obtain any combination of
+ remote/local, encoded/raw video through the event callback
+ mechanism
+ Use these flags to specify what kind of video do you want to receive
+ */
+
+/*! 
+       Indicates the preference that local video should be passed to the registered callback in a raw format (typically YUV420). 
+*/
+#define IAXC_VIDEO_PREF_RECV_LOCAL_RAW      (1 << 0) 
+
+/*!
+       Indicates the preference that local video should be passed to the registered callback in the current encoded format.
+*/
+#define IAXC_VIDEO_PREF_RECV_LOCAL_ENCODED  (1 << 1) 
+
+/*!
+       Indicates the preference that remote video should be passed to the registered callback in a raw format (typically YUV420).
+*/
+#define IAXC_VIDEO_PREF_RECV_REMOTE_RAW     (1 << 2) 
+
+/*!
+       Indicates the preference that remote video should be passed to the registered callback in the current encoded format.
+*/
+#define IAXC_VIDEO_PREF_RECV_REMOTE_ENCODED (1 << 3) 
+
+/*!
+       Indicates the preference that sending of video should be disabled.
+*/
+#define IAXC_VIDEO_PREF_SEND_DISABLE        (1 << 4) 
+
+/*!
+       This flag specifies that you want raw video in RGB32 format
+
+       RGB32: FFRRGGBB aligned 4 bytes per pixel
+  When this flag is set, iaxclient will convert YUV420 raw video into
+  RGB32 before passing it to the main app.
+ */
+#define IAXC_VIDEO_PREF_RECV_RGB32          (1 << 5)
+
+/*!
+  Use this flag to disable/enable camera hardware
+ */
+#define IAXC_VIDEO_PREF_CAPTURE_DISABLE     (1 << 6)
+
+/*!
+       Returns the current video preferences.
+
+        The preferences are represented using the AIXC_VIDEO_PREF_{} family of macros.
+
+       \see IAXC_VIDEO_PREF_RECV_LOCAL_RAW, IAXC_VIDEO_PREF_RECV_LOCAL_ENCODED,
+       IAXC_VIDEO_PREF_RECV_REMOTE_RAW, IAXC_VIDEO_PREF_RECV_REMOTE_ENCODED,
+       IAXC_VIDEO_PREF_SEND_DISABLE, IAXC_VIDEO_PREF_RECV_RGB32, 
+       IAXC_VIDEO_PREF_CAPTURE_DISABLE
+*/
+EXPORT unsigned int iaxc_get_video_prefs(void);
+
+/*!
+       Sets the current video preferences.
+       \param prefs The desired preferences to use. They are represented using the IAXC_VIDEO_PREF_{} family of defines.
+       
+  Please note that this overwrites all previous preferences. In other
+  words, a read-modify-write must be done to change a single preference.
+
+       \return 0 on success and -1 on error.
+
+       \see IAXC_VIDEO_PREF_RECV_LOCAL_RAW, IAXC_VIDEO_PREF_RECV_LOCAL_ENCODED,
+       IAXC_VIDEO_PREF_RECV_REMOTE_RAW, IAXC_VIDEO_PREF_RECV_REMOTE_ENCODED,
+       IAXC_VIDEO_PREF_SEND_DISABLE, IAXC_VIDEO_PREF_RECV_RGB32, 
+       IAXC_VIDEO_PREF_CAPTURE_DISABLE
+ */
+EXPORT int iaxc_set_video_prefs(unsigned int prefs);
+
+/*!
+       Returns the video format settings
+       \param preferred Receives the single preferred video format
+       \param allowed Receives the mask of the allowed video formats
+
+       \see IAXC_FORMAT_JPEG, IAXC_FORMAT_PNG, IAXC_FORMAT_H261, IAXC_FORMAT_H263,
+       IAXC_FORMAT_H263_PLUS, IAXC_FORMAT_H264, IAXC_FORMAT_MPEG4, 
+       IAXC_FORMAT_THEORA, IAXC_FORMAT_MAX_VIDEO
+*/
+EXPORT void iaxc_video_format_get_cap(int *preferred, int *allowed);
+
+/*!
+       Sets the video format capabilities
+       \param preferred The single preferred video format
+       \param allowed The mask of the allowed video formats
+
+       \see IAXC_FORMAT_JPEG, IAXC_FORMAT_PNG, IAXC_FORMAT_H261, IAXC_FORMAT_H263,
+       IAXC_FORMAT_H263_PLUS, IAXC_FORMAT_H264, IAXC_FORMAT_MPEG4, 
+       IAXC_FORMAT_THEORA, IAXC_FORMAT_MAX_VIDEO
+*/
+EXPORT void iaxc_video_format_set_cap(int preferred, int allowed);
+
+/*!
+       Sets the allowed/preferred video formats
+       \param preferred The single preferred video format
+       \param allowed The mask of the allowed video formats
+       \param framerate The video frame rate in fps.
+       \param bitrate The video bitrate in bps.
+       \param width The width of the video.
+       \param height The height of the video.
+       \param fs The video fragment size.
+
+       \see IAXC_FORMAT_JPEG, IAXC_FORMAT_PNG, IAXC_FORMAT_H261, IAXC_FORMAT_H263,
+       IAXC_FORMAT_H263_PLUS, IAXC_FORMAT_H264, IAXC_FORMAT_MPEG4, 
+       IAXC_FORMAT_THEORA, IAXC_FORMAT_MAX_VIDEO
+*/
+EXPORT void iaxc_video_format_set(int preferred, int allowed, int framerate, int bitrate, int width, int height, int fs);
+
+/*!
+ Change video params for the current call on the fly
+ This will destroy the existing encoder and create a new one
+ use negative values for parameters that should not change
+ \param framerate The video frame rate in fps.
+ \param bitrate The video bitrate in bps.
+ \param width The width of the video.
+ \param height The height of the video.
+ \param fs The video fragment size.
+*/
+EXPORT void iaxc_video_params_change(int framerate, int bitrate, int width, int height, int fs);
+
+/*! Set holding frame to be used in some kind of video calls */
+EXPORT int iaxc_set_holding_frame(char *);
+
+/*!
+       Helper function to control use of jitter buffer for video events 
+
+       \todo make this a video pref, perhaps? 
+*/
+
+EXPORT int iaxc_video_bypass_jitter(int);
+
+/*!
+  Returns 1 if the default camera is working; 0 otherwise
+ */
+EXPORT int iaxc_is_camera_working();
+
+/*!
+       Converts a YUV420 image to RGB32
+       \param width The width of the image
+       \param height The height of the image
+       \param src The buffer containing the source image
+       \param dest The buffer to write the converted image to. The buffer should be \a width * height * 4 bytes in size.
+
+       Converts the image based on the forumulas found at
+       http://en.wikipedia.org/wiki/YUV
+*/
+EXPORT void iaxc_YUV420_to_RGB32(int width, int height, const char *src, char *dest);
+
+/*
+ * Test mode functionality
+ * In test mode, iaxclient will do the following:
+ *   - skip audio and video hardware initialization
+ *   - wait for outgoing media to be provided by the main application
+ *   - return incoming media to the calling application if required, via callbacks
+ *   - not generate any meaningful statistics
+ * Test mode is designed to be used without a GUI, and with multiple instances of iaxclient
+ * running on the same machine. However, some applications might actually benefit from having
+ * this level of control.
+ * iaxc_set_test_mode() should be called before iaxc_initialize()
+ */
+EXPORT void iaxc_set_test_mode(int);
+
+/*!
+       \brief Sends compressed audio data to the currently selected call.
+       \param data compressed audio data
+       \param size Size of the compressed audio data in bytes
+       \param samples The number of (uncompressed) samples represented by the compressed audio data. We normally use 20ms packets at a sampling rate of 8000Hz, so this would be 160.
+
+       \note Data must be in the audio format that was negotiated for the current call
+       otherwise bad magic may occur on the recieving side.
+*/
+EXPORT int iaxc_push_audio(void *data, unsigned int size, unsigned int samples);
+
+/*!
+       \brief Sends compressed video data to the currently selected call.
+       \param data compressed video data
+       \param size Size of the compressed video data in bytes
+       \param fragment If true, split video frames larger than the current fragsize into multiple fragments, otherwise send the data as jumbo frames.
+
+       \note Data must be in the video format that was negotiated for the current call
+       otherwise bad magic may occur on the recieving side.
+*/
+EXPORT int iaxc_push_video(void *data, unsigned int size, int fragment);
+
+/*!
+       Sets the IAX debug set to \a enable.
+       \param enable If non-zero enable iax protocol debugging
+*/
+EXPORT void iaxc_debug_iax_set(int enable);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/utils/iaxclient/lib/iaxclient_lib.c b/utils/iaxclient/lib/iaxclient_lib.c
new file mode 100644 (file)
index 0000000..21c0d1e
--- /dev/null
@@ -0,0 +1,1982 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003-2006, Horizon Wimba, Inc.
+ * Copyright (C) 2007, Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ * Michael Van Donselaar <mvand@vandonselaar.org>
+ * Shawn Lawrence <shawn.lawrence@terracecomm.com>
+ * Frik Strecker <frik@gatherworks.com>
+ * Mihai Balea <mihai AT hates DOT ms>
+ * Peter Grayson <jpgrayson@gmail.com>
+ * Bill Cholewka <bcholew@gmail.com>
+ * Erik Bunce <kde@bunce.us>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ */
+
+#include <assert.h>
+
+#if defined(WIN32) || defined(_WIN32_WCE)
+#include <stdlib.h>
+#endif
+
+/* Win32 has _vsnprintf instead of vsnprintf */
+#if ! HAVE_VSNPRINTF
+# if HAVE__VSNPRINTF
+#  define vsnprintf _vsnprintf
+# endif
+#endif
+
+#include "iaxclient_lib.h"
+#include "audio_portaudio.h"
+#include "audio_encode.h"
+#ifdef USE_VIDEO
+#include "video.h"
+#endif
+#include "iax-client.h"
+#include "jitterbuf.h"
+
+#include <stdarg.h>
+
+#ifdef AUDIO_ALSA
+#include "audio_alsa.h"
+#endif
+
+#define IAXC_ERROR  IAXC_TEXT_TYPE_ERROR
+#define IAXC_STATUS IAXC_TEXT_TYPE_STATUS
+#define IAXC_NOTICE IAXC_TEXT_TYPE_NOTICE
+
+#define DEFAULT_CALLERID_NAME    "Not Available"
+#define DEFAULT_CALLERID_NUMBER  "7005551212"
+
+#undef JB_DEBUGGING
+
+/* global test mode flag */
+int test_mode = 0;
+
+/* configurable jitterbuffer options */
+static long jb_target_extra = -1;
+
+struct iaxc_registration
+{
+       struct iax_session *session;
+       struct timeval last;
+       char host[256];
+       char user[256];
+       char pass[256];
+       long refresh;
+       int id;
+       struct iaxc_registration *next;
+};
+
+static int next_registration_id = 0;
+static struct iaxc_registration *registrations = NULL;
+
+static struct iaxc_audio_driver audio_driver;
+
+static int audio_format_capability;
+static int audio_format_preferred;
+
+// Audio callback behavior
+// By default apps should let iaxclient handle audio
+static unsigned int audio_prefs = 0;
+
+void * post_event_handle = NULL;
+int post_event_id = 0;
+
+static int minimum_outgoing_framesize = 160; /* 20ms */
+
+static MUTEX iaxc_lock;
+static MUTEX event_queue_lock;
+
+static int iaxci_bound_port = -1;
+
+// default to use port 4569 unless set by iaxc_set_preferred_source_udp_port
+static int source_udp_port = IAX_DEFAULT_PORTNO;
+
+int iaxci_audio_output_mode = 0; // Normal
+
+int selected_call; // XXX to be protected by mutex?
+struct iaxc_call* calls;
+int max_calls; // number of calls for this library session
+
+static void service_network();
+static int service_audio();
+
+/* external global networking replacements */
+static iaxc_sendto_t iaxc_sendto = (iaxc_sendto_t)sendto;
+static iaxc_recvfrom_t iaxc_recvfrom = (iaxc_recvfrom_t)recvfrom;
+
+
+static THREAD main_proc_thread;
+#if defined(WIN32) || defined(_WIN32_WCE)
+static THREADID main_proc_thread_id;
+#endif
+
+/* 0 running, 1 should quit, -1 not running */
+static int main_proc_thread_flag = -1;
+
+static iaxc_event_callback_t iaxc_event_callback = NULL;
+
+// Internal queue of events, waiting to be posted once the library
+// lock is released.
+static iaxc_event *event_queue = NULL;
+
+// Lock the library
+static void get_iaxc_lock()
+{
+       MUTEXLOCK(&iaxc_lock);
+}
+
+int try_iaxc_lock()
+{
+       return MUTEXTRYLOCK(&iaxc_lock);
+}
+
+// Unlock the library and post any events that were queued in the meantime
+void put_iaxc_lock()
+{
+       iaxc_event *prev, *event;
+
+       MUTEXLOCK(&event_queue_lock);
+       event = event_queue;
+       event_queue = NULL;
+       MUTEXUNLOCK(&event_queue_lock);
+
+       MUTEXUNLOCK(&iaxc_lock);
+
+       while (event)
+       {
+               iaxci_post_event(*event);
+               prev = event;
+               event = event->next;
+               free(prev);
+       }
+}
+
+EXPORT void iaxc_set_audio_output(int mode)
+{
+       iaxci_audio_output_mode = mode;
+}
+
+long iaxci_usecdiff(struct timeval * t0, struct timeval * t1)
+{
+       return (t0->tv_sec - t1->tv_sec) * 1000000L + t0->tv_usec - t1->tv_usec;
+}
+
+long iaxci_msecdiff(struct timeval * t0, struct timeval * t1)
+{
+       return iaxci_usecdiff(t0, t1) / 1000L;
+}
+
+EXPORT void iaxc_set_event_callback(iaxc_event_callback_t func)
+{
+       iaxc_event_callback = func;
+}
+
+EXPORT int iaxc_set_event_callpost(void *handle, int id)
+{
+       post_event_handle = handle;
+       post_event_id = id;
+       iaxc_event_callback = iaxci_post_event_callback;
+       return 0;
+}
+
+EXPORT void iaxc_free_event(iaxc_event *e)
+{
+       free(e);
+}
+
+EXPORT struct iaxc_ev_levels *iaxc_get_event_levels(iaxc_event *e)
+{
+       return &e->ev.levels;
+}
+
+EXPORT struct iaxc_ev_text *iaxc_get_event_text(iaxc_event *e)
+{
+       return &e->ev.text;
+}
+
+EXPORT struct iaxc_ev_call_state *iaxc_get_event_state(iaxc_event *e)
+{
+       return &e->ev.call;
+}
+
+// Messaging functions
+static void default_message_callback(const char * message)
+{
+       //fprintf(stderr, "IAXCLIENT: %s\n", message);
+}
+
+// Post Events back to clients
+void iaxci_post_event(iaxc_event e)
+{
+       if ( e.type == 0 )
+       {
+               iaxci_usermsg(IAXC_ERROR,
+                       "Error: something posted to us an invalid event");
+               return;
+       }
+
+       if ( MUTEXTRYLOCK(&iaxc_lock) )
+       {
+               iaxc_event **tail;
+
+               /* We could not obtain the lock. Queue the event. */
+               MUTEXLOCK(&event_queue_lock);
+               tail = &event_queue;
+               e.next = NULL;
+               while ( *tail )
+                       tail = &(*tail)->next;
+               *tail = (iaxc_event *)malloc(sizeof(iaxc_event));
+               memcpy(*tail, &e, sizeof(iaxc_event));
+               MUTEXUNLOCK(&event_queue_lock);
+               return;
+       }
+
+       /* TODO: This is not the best. Since we were able to get the
+        * lock, we decide that it is okay to go ahead and do the
+        * callback to the application. This is really nasty because
+        * it gives the appearance of serialized callbacks, but in
+        * reality, we could callback an application multiple times
+        * simultaneously. So, as things stand, an application must
+        * do some locking in their callback function to make it
+        * reentrant. Barf. More ideally, iaxclient would guarantee
+        * serialized callbacks to the application.
+        */
+       MUTEXUNLOCK(&iaxc_lock);
+
+       if ( iaxc_event_callback )
+       {
+               int rv;
+
+               rv = iaxc_event_callback(e);
+
+               if ( e.type == IAXC_EVENT_VIDEO )
+               {
+                       /* We can free the frame data once it is off the
+                        * event queue and has been processed by the client.
+                        */
+                       free(e.ev.video.data);
+               }
+               else if ( e.type == IAXC_EVENT_AUDIO )
+               {
+                       free(e.ev.audio.data);
+               }
+
+               if ( rv < 0 )
+                       default_message_callback(
+                               "IAXCLIENT: BIG PROBLEM, event callback returned failure!");
+               // > 0 means processed
+               if ( rv > 0 )
+                       return;
+
+               // else, fall through to "defaults"
+       }
+
+       switch ( e.type )
+       {
+               case IAXC_EVENT_TEXT:
+                       default_message_callback(e.ev.text.message);
+                       // others we just ignore too
+                       return;
+       }
+}
+
+
+void iaxci_usermsg(int type, const char *fmt, ...)
+{
+       va_list args;
+       iaxc_event e;
+
+       e.type = IAXC_EVENT_TEXT;
+       e.ev.text.type = type;
+       e.ev.text.callNo = -1;
+       va_start(args, fmt);
+       vsnprintf(e.ev.text.message, IAXC_EVENT_BUFSIZ, fmt, args);
+       va_end(args);
+
+       iaxci_post_event(e);
+}
+
+
+void iaxci_do_levels_callback(float input, float output)
+{
+       iaxc_event e;
+       e.type = IAXC_EVENT_LEVELS;
+       e.ev.levels.input = input;
+       e.ev.levels.output = output;
+       iaxci_post_event(e);
+}
+
+void iaxci_do_state_callback(int callNo)
+{
+       iaxc_event e;
+       if ( callNo < 0 || callNo >= max_calls )
+               return;
+       e.type = IAXC_EVENT_STATE;
+       e.ev.call.callNo = callNo;
+       e.ev.call.state = calls[callNo].state;
+       e.ev.call.format = calls[callNo].format;
+       e.ev.call.vformat = calls[callNo].vformat;
+       strncpy(e.ev.call.remote,        calls[callNo].remote,        IAXC_EVENT_BUFSIZ);
+       strncpy(e.ev.call.remote_name,   calls[callNo].remote_name,   IAXC_EVENT_BUFSIZ);
+       strncpy(e.ev.call.local,         calls[callNo].local,         IAXC_EVENT_BUFSIZ);
+       strncpy(e.ev.call.local_context, calls[callNo].local_context, IAXC_EVENT_BUFSIZ);
+       iaxci_post_event(e);
+}
+
+void iaxci_do_registration_callback(int id, int reply, int msgcount)
+{
+       iaxc_event e;
+       e.type = IAXC_EVENT_REGISTRATION;
+       e.ev.reg.id = id;
+       e.ev.reg.reply = reply;
+       e.ev.reg.msgcount = msgcount;
+       iaxci_post_event(e);
+}
+
+void iaxci_do_audio_callback(int callNo, unsigned int ts, int source,
+               int encoded, int format, int size, unsigned char *data)
+{
+       iaxc_event e;
+
+       e.type = IAXC_EVENT_AUDIO;
+       e.ev.audio.ts = ts;
+       e.ev.audio.encoded = encoded;
+       assert(source == IAXC_SOURCE_REMOTE || source == IAXC_SOURCE_LOCAL);
+       e.ev.audio.source = source;
+       e.ev.audio.size = size;
+       e.ev.audio.callNo = callNo;
+       e.ev.audio.format = format;
+
+       e.ev.audio.data = (unsigned char *)malloc(size);
+
+       if ( !e.ev.audio.data )
+       {
+               iaxci_usermsg(IAXC_ERROR,
+                               "failed to allocate memory for audio event");
+               return;
+       }
+
+       memcpy(e.ev.audio.data, data, size);
+
+       iaxci_post_event(e);
+}
+
+void iaxci_do_dtmf_callback(int callNo, char digit)
+{
+       iaxc_event e;
+       e.type = IAXC_EVENT_DTMF;
+       e.ev.dtmf.callNo = callNo;
+       e.ev.dtmf.digit  = digit;
+       iaxci_post_event(e);
+}
+
+static int iaxc_remove_registration_by_id(int id)
+{
+       struct iaxc_registration *curr, *prev;
+       int count = 0;
+       for ( prev = NULL, curr = registrations; curr != NULL;
+                       prev = curr, curr = curr->next )
+       {
+               if ( curr->id == id )
+               {
+                       count++;
+                       if ( curr->session != NULL )
+                               iax_destroy( curr->session );
+                       if ( prev != NULL )
+                               prev->next = curr->next;
+                       else
+                               registrations = curr->next;
+                       free( curr );
+                       break;
+               }
+       }
+       return count;
+}
+
+EXPORT int iaxc_first_free_call()
+{
+       int i;
+       for ( i = 0; i < max_calls; i++ )
+               if ( calls[i].state == IAXC_CALL_STATE_FREE )
+                       return i;
+
+       return -1;
+}
+
+
+static void iaxc_clear_call(int toDump)
+{
+       // XXX libiax should handle cleanup, I think..
+       calls[toDump].state = IAXC_CALL_STATE_FREE;
+       calls[toDump].format = 0;
+       calls[toDump].vformat = 0;
+       calls[toDump].session = NULL;
+       iaxci_do_state_callback(toDump);
+}
+
+/* select a call.  */
+/* XXX Locking??  Start/stop audio?? */
+EXPORT int iaxc_select_call(int callNo)
+{
+       // continue if already selected?
+       //if ( callNo == selected_call ) return;
+
+       if ( callNo >= max_calls )
+       {
+               iaxci_usermsg(IAXC_ERROR, "Error: tried to select out_of_range call %d", callNo);
+               return -1;
+       }
+
+       // callNo < 0 means no call selected (i.e. all on hold)
+       if ( callNo < 0 )
+       {
+               if ( selected_call >= 0 )
+               {
+                       calls[selected_call].state &= ~IAXC_CALL_STATE_SELECTED;
+               }
+               selected_call = callNo;
+               return 0;
+       }
+
+       // de-select and notify the old call if not also the new call
+       if ( callNo != selected_call )
+       {
+               if ( selected_call >= 0 )
+               {
+                       calls[selected_call].state &= ~IAXC_CALL_STATE_SELECTED;
+                       iaxci_do_state_callback(selected_call);
+               }
+               selected_call = callNo;
+               calls[selected_call].state |= IAXC_CALL_STATE_SELECTED;
+       }
+
+       // if it's an incoming call, and ringing, answer it.
+       if ( !(calls[selected_call].state & IAXC_CALL_STATE_OUTGOING) &&
+             (calls[selected_call].state & IAXC_CALL_STATE_RINGING) )
+       {
+               iaxc_answer_call(selected_call);
+       } else
+       {
+               // otherwise just update state (answer does this for us)
+               iaxci_do_state_callback(selected_call);
+       }
+
+       return 0;
+}
+
+/* external API accessor */
+EXPORT int iaxc_selected_call()
+{
+       return selected_call;
+}
+
+EXPORT void iaxc_set_networking(iaxc_sendto_t st, iaxc_recvfrom_t rf)
+{
+       iaxc_sendto = st;
+       iaxc_recvfrom = rf;
+}
+
+EXPORT void iaxc_set_jb_target_extra( long value )
+{
+       /* store in jb_target_extra, a static global */
+       jb_target_extra = value;
+}
+
+static void jb_errf(const char *fmt, ...)
+{
+       va_list args;
+       char buf[1024];
+
+       va_start(args, fmt);
+       vsnprintf(buf, 1024, fmt, args);
+       va_end(args);
+
+       iaxci_usermsg(IAXC_ERROR, buf);
+}
+
+static void jb_warnf(const char *fmt, ...)
+{
+       va_list args;
+       char buf[1024];
+
+       va_start(args, fmt);
+       vsnprintf(buf, 1024, fmt, args);
+       va_end(args);
+
+       iaxci_usermsg(IAXC_NOTICE, buf);
+}
+
+#ifdef JB_DEBUGGING
+static void jb_dbgf(const char *fmt, ...)
+{
+       va_list args;
+
+       va_start(args, fmt);
+       vfprintf(stderr, fmt, args);
+       va_end(args);
+}
+#endif
+
+static void setup_jb_output()
+{
+#ifdef JB_DEBUGGING
+       jb_setoutput(jb_errf, jb_warnf, jb_dbgf);
+#else
+       jb_setoutput(jb_errf, jb_warnf, NULL);
+#endif
+}
+
+// Note: Must be called before iaxc_initialize()
+EXPORT void iaxc_set_preferred_source_udp_port(int port)
+{
+       source_udp_port = port;
+}
+
+/* For "slow" systems. See iax.c code */
+EXPORT int iaxc_video_bypass_jitter(int mode)
+{
+       /* TODO:
+        * 1. When switching from jitter to no-jitter the buffer must be
+        *    flushed of queued video packet and must be sent a key-frame
+        *    to redraw the screen (partially done).
+        * 2. When switching from no-jitter to jitter we must drop all
+        *    enqueued events prior the mode change (must be touched
+        *    iax_sched_del and iax_get_event).
+        */
+       return iax_video_bypass_jitter(calls[selected_call].session,mode);
+}
+
+EXPORT int iaxc_get_bind_port()
+{
+       return iaxci_bound_port;
+}
+
+EXPORT int iaxc_initialize(int num_calls)
+{
+       int i;
+       int port;
+
+       os_init();
+
+       setup_jb_output();
+
+       MUTEXINIT(&iaxc_lock);
+       MUTEXINIT(&event_queue_lock);
+
+       iaxc_set_audio_prefs(0);
+
+       if ( iaxc_recvfrom != (iaxc_recvfrom_t)recvfrom )
+               iax_set_networking(iaxc_sendto, iaxc_recvfrom);
+
+       /* Note that iax_init() only sets up the receive port when the
+        * sendto/recvfrom functions have not been replaced. We need
+        * to call iaxc_init in either case because there is other
+        * initialization beyond the socket setup that needs to be done.
+        */
+       if ( (port = iax_init(source_udp_port)) < 0 )
+       {
+               iaxci_usermsg(IAXC_ERROR,
+                               "Fatal error: failed to initialize iax with port %d",
+                               port);
+               return -1;
+       }
+
+       if ( iaxc_recvfrom == (iaxc_recvfrom_t)recvfrom )
+               iaxci_bound_port = port;
+       else
+               iaxci_bound_port = -1;
+
+       /* tweak the jitterbuffer settings */
+       iax_set_jb_target_extra( jb_target_extra );
+
+       max_calls = num_calls;
+       /* initialize calls */
+       if ( max_calls <= 0 )
+               max_calls = 1; /* 0 == Default? */
+
+       /* calloc zeroes for us */
+       calls = (struct iaxc_call *)calloc(sizeof(struct iaxc_call), max_calls);
+       if ( !calls )
+       {
+               iaxci_usermsg(IAXC_ERROR, "Fatal error: can't allocate memory");
+               return -1;
+       }
+
+       selected_call = -1;
+
+       for ( i = 0; i < max_calls; i++ )
+       {
+               strncpy(calls[i].callerid_name,   DEFAULT_CALLERID_NAME,   IAXC_EVENT_BUFSIZ);
+               strncpy(calls[i].callerid_number, DEFAULT_CALLERID_NUMBER, IAXC_EVENT_BUFSIZ);
+       }
+
+       if ( !test_mode )
+       {
+#ifdef AUDIO_PA
+               if ( pa_initialize(&audio_driver, 8000) )
+               {
+                       iaxci_usermsg(IAXC_ERROR, "failed pa_initialize");
+                       return -1;
+               }
+#endif
+#ifdef AUDIO_ALSA
+               /* TODO: It is unknown whether this stuff for direct access to
+               * alsa should be left in iaxclient. We're leaving it in here for
+               * the time being, but unless it becomes clear that someone cares
+               * about having it, it will be removed. Also note that portaudio
+               * is capable of using alsa. This is another reason why this
+               * direct alsa access may be unneeded.
+               */
+               if ( alsa_initialize(&audio_driver, 8000) )
+                       return -1;
+#endif
+#ifdef AUDIO_OPENAL
+               if ( openal_initialize(&audio_driver, 8000) )
+               {
+                       iaxci_usermsg(IAXC_ERROR, "failed openal_initialize");
+                       return -1;
+               }
+#endif
+       }
+#ifdef USE_VIDEO
+       if ( video_initialize() )
+               iaxci_usermsg(IAXC_ERROR,
+                               "iaxc_initialize: cannot initialize video!\n");
+#endif
+
+       /* Default audio format capabilities */
+       audio_format_capability =
+           IAXC_FORMAT_ULAW |
+           IAXC_FORMAT_ALAW |
+#ifdef CODEC_GSM
+           IAXC_FORMAT_GSM |
+#endif
+           IAXC_FORMAT_SPEEX;
+       audio_format_preferred = IAXC_FORMAT_SPEEX;
+
+       return 0;
+}
+
+EXPORT void iaxc_shutdown()
+{
+       iaxc_dump_all_calls();
+
+       get_iaxc_lock();
+
+       if ( !test_mode )
+       {
+               audio_driver.destroy(&audio_driver);
+#ifdef USE_VIDEO
+               video_destroy();
+#endif
+       }
+       
+       /* destroy enocders and decoders for all existing calls */
+       if ( calls ) 
+       {
+                int i;
+               for ( i=0 ; i<max_calls ; i++ ) 
+               {
+                       if ( calls[i].encoder )
+                               calls[i].encoder->destroy(calls[i].encoder);
+                       if ( calls[i].decoder )
+                               calls[i].decoder->destroy(calls[i].decoder);
+                       if ( calls[i].vencoder )
+                               calls[i].vencoder->destroy(calls[i].vencoder);
+                       if ( calls[i].vdecoder )
+                               calls[i].vdecoder->destroy(calls[i].vdecoder);
+                }
+               free(calls);
+               calls = NULL;
+       }
+       put_iaxc_lock();
+#ifdef WIN32
+       closesocket(iax_get_fd()); //fd:
+#endif
+
+       free(calls);
+
+       MUTEXDESTROY(&event_queue_lock);
+       MUTEXDESTROY(&iaxc_lock);
+}
+
+
+EXPORT void iaxc_set_formats(int preferred, int allowed)
+{
+       audio_format_capability = allowed;
+       audio_format_preferred = preferred;
+}
+
+EXPORT void iaxc_set_min_outgoing_framesize(int samples)
+{
+       minimum_outgoing_framesize = samples;
+}
+
+EXPORT void iaxc_set_callerid(const char * name, const char * number)
+{
+       int i;
+
+       for ( i = 0; i < max_calls; i++ )
+       {
+               strncpy(calls[i].callerid_name,   name,   IAXC_EVENT_BUFSIZ);
+               strncpy(calls[i].callerid_number, number, IAXC_EVENT_BUFSIZ);
+       }
+}
+
+static void iaxc_note_activity(int callNo)
+{
+       if ( callNo < 0 )
+               return;
+       calls[callNo].last_activity = iax_tvnow();
+}
+
+static void iaxc_refresh_registrations()
+{
+       struct iaxc_registration *cur;
+       struct timeval now;
+
+       now = iax_tvnow();
+
+       for ( cur = registrations; cur != NULL; cur = cur->next )
+       {
+               // If there is less than three seconds before the registration is about
+               // to expire, renew it.
+               if ( iaxci_usecdiff(&now, &cur->last) > (cur->refresh - 3) * 1000 *1000 )
+               {
+                       if ( cur->session != NULL )
+                       {
+                               iax_destroy( cur->session );
+                       }
+                       cur->session = iax_session_new();
+                       if ( !cur->session )
+                       {
+                               iaxci_usermsg(IAXC_ERROR, "Can't make new registration session");
+                               return;
+                       }
+                       iax_register(cur->session, cur->host, cur->user, cur->pass, cur->refresh);
+                       cur->last = now;
+               }
+       }
+}
+
+#define LOOP_SLEEP 5 // In ms
+static THREADFUNCDECL(main_proc_thread_func)
+{
+       static int refresh_registration_count = 0;
+
+       THREADFUNCRET(ret);
+
+       /* Increase Priority */
+       iaxci_prioboostbegin();
+
+       while ( !main_proc_thread_flag )
+       {
+               get_iaxc_lock();
+
+               service_network();
+               if ( !test_mode )
+                       service_audio();
+
+               // Check registration refresh once a second
+               if ( refresh_registration_count++ > 1000/LOOP_SLEEP )
+               {
+                       iaxc_refresh_registrations();
+                       refresh_registration_count = 0;
+               }
+
+               put_iaxc_lock();
+
+               iaxc_millisleep(LOOP_SLEEP);
+       }
+
+       /* Decrease priority */
+       iaxci_prioboostend();
+
+       main_proc_thread_flag = -1;
+
+       return ret;
+}
+
+EXPORT int iaxc_start_processing_thread()
+{
+       main_proc_thread_flag = 0;
+
+       if ( THREADCREATE(main_proc_thread_func, NULL, main_proc_thread,
+                               main_proc_thread_id) == THREADCREATE_ERROR)
+               return -1;
+
+       return 0;
+}
+
+EXPORT int iaxc_stop_processing_thread()
+{
+       if ( main_proc_thread_flag >= 0 )
+       {
+               main_proc_thread_flag = 1;
+               THREADJOIN(main_proc_thread);
+       }
+
+       return 0;
+}
+
+static int service_audio()
+{
+       /* TODO: maybe we shouldn't allocate 8kB on the stack here. */
+       short buf [4096];
+
+       int want_send_audio =
+               selected_call >= 0 &&
+               ((calls[selected_call].state & IAXC_CALL_STATE_OUTGOING) ||
+                (calls[selected_call].state & IAXC_CALL_STATE_COMPLETE))
+               && !(audio_prefs & IAXC_AUDIO_PREF_SEND_DISABLE);
+
+       int want_local_audio =
+               (audio_prefs & IAXC_AUDIO_PREF_RECV_LOCAL_RAW) ||
+               (audio_prefs & IAXC_AUDIO_PREF_RECV_LOCAL_ENCODED);
+
+       if ( want_local_audio || want_send_audio )
+       {
+               for ( ;; )
+               {
+                       int to_read;
+                       int cmin;
+
+                       audio_driver.start(&audio_driver);
+
+                       /* use codec minimum if higher */
+                       cmin = want_send_audio && calls[selected_call].encoder ?
+                               calls[selected_call].encoder->minimum_frame_size :
+                               1;
+
+                       to_read = cmin > minimum_outgoing_framesize ?
+                               cmin : minimum_outgoing_framesize;
+
+                       /* Round up to the next multiple */
+                       if ( to_read % cmin )
+                               to_read += cmin - (to_read % cmin);
+
+                       if ( to_read > (int)(sizeof(buf) / sizeof(short)) )
+                       {
+                               fprintf(stderr,
+                                       "internal error: to_read > sizeof(buf)\n");
+                               exit(1);
+                       }
+
+                       /* Currently pa gives us either all the bits we ask for or none */
+                       if ( audio_driver.input(&audio_driver, buf, &to_read) )
+                       {
+                               iaxci_usermsg(IAXC_ERROR, "ERROR reading audio\n");
+                               break;
+                       }
+
+                       /* Frame was not available */
+                       if ( !to_read )
+                               break;
+
+                       if ( audio_prefs & IAXC_AUDIO_PREF_RECV_LOCAL_RAW )
+                               iaxci_do_audio_callback(selected_call, 0,
+                                               IAXC_SOURCE_LOCAL, 0, 0,
+                                               to_read * 2, (unsigned char *)buf);
+
+                       if ( want_send_audio )
+                               audio_send_encoded_audio(&calls[selected_call],
+                                               selected_call, buf,
+                                               calls[selected_call].format &
+                                                       IAXC_AUDIO_FORMAT_MASK,
+                                               to_read);
+               }
+       }
+       else
+       {
+               static int i = 0;
+
+               audio_driver.stop(&audio_driver);
+
+               /*!
+                       \deprecated
+                       Q: Why do we continuously send IAXC_EVENT_LEVELS events
+                  when there is no selected call?
+
+                A: So that certain users of iaxclient do not have to
+                  reset their vu meters when a call ends -- they can just
+                  count on getting level callbacks. This is a bit of a hack
+                  so any applications relying on this behavior should maybe
+                  be changed.
+                */
+               if ( i++ % 50 == 0 )
+                       iaxci_do_levels_callback(AUDIO_ENCODE_SILENCE_DB,
+                                       AUDIO_ENCODE_SILENCE_DB);
+       }
+
+       return 0;
+}
+
+/* handle IAX text events */
+static void handle_text_event(struct iax_event *e, int callNo)
+{
+       iaxc_event ev;
+       int        len;
+
+       if ( callNo < 0 )
+               return;
+
+       memset(&ev, 0, sizeof(iaxc_event));
+       ev.type = IAXC_EVENT_TEXT;
+       ev.ev.text.type = IAXC_TEXT_TYPE_IAX;
+       ev.ev.text.callNo = callNo;
+
+       len = e->datalen <= IAXC_EVENT_BUFSIZ - 1 ? e->datalen : IAXC_EVENT_BUFSIZ - 1;
+       strncpy(ev.ev.text.message, (char *) e->data, len);
+       iaxci_post_event(ev);
+}
+
+/* handle IAX URL events */
+void handle_url_event( struct iax_event *e, int callNo )
+{
+       iaxc_event ev;
+
+       if ( callNo < 0 )
+               return;
+
+       ev.ev.url.callNo = callNo;
+       ev.type = IAXC_EVENT_URL;
+       strcpy( ev.ev.url.url, "" );
+
+       switch ( e->subclass )
+       {
+               case AST_HTML_URL:
+                       ev.ev.url.type = IAXC_URL_URL;
+                       if ( e->datalen )
+                       {
+                               if ( e->datalen > IAXC_EVENT_BUFSIZ )
+                               {
+                                       fprintf( stderr, "ERROR: URL too long %d > %d\n",
+                                                       e->datalen, IAXC_EVENT_BUFSIZ );
+                               } else
+                               {
+                                       strncpy( ev.ev.url.url, (char *) e->data, e->datalen );
+                               }
+                       }
+                       /* fprintf( stderr, "URL:%s\n", ev.ev.url.url ); */
+                       break;
+               case AST_HTML_LINKURL:
+                       ev.ev.url.type = IAXC_URL_LINKURL;
+                       /* fprintf( stderr, "LINKURL event\n" ); */
+                       break;
+               case AST_HTML_LDCOMPLETE:
+                       ev.ev.url.type = IAXC_URL_LDCOMPLETE;
+                       /* fprintf( stderr, "LDCOMPLETE event\n" ); */
+                       break;
+               case AST_HTML_UNLINK:
+                       ev.ev.url.type = IAXC_URL_UNLINK;
+                       /* fprintf( stderr, "UNLINK event\n" ); */
+                       break;
+               case AST_HTML_LINKREJECT:
+                       ev.ev.url.type = IAXC_URL_LINKREJECT;
+                       /* fprintf( stderr, "LINKREJECT event\n" ); */
+                       break;
+               default:
+                       fprintf( stderr, "Unknown URL event %d\n", e->subclass );
+                       break;
+       }
+       iaxci_post_event( ev );
+}
+
+/* DANGER: bad things can happen if iaxc_netstat != iax_netstat.. */
+EXPORT int iaxc_get_netstats(int call, int *rtt, struct iaxc_netstat *local,
+               struct iaxc_netstat *remote)
+{
+       return iax_get_netstats(calls[call].session, rtt,
+                       (struct iax_netstat *)local,
+                       (struct iax_netstat *)remote);
+}
+
+/* handle IAX text events */
+static void generate_netstat_event(int callNo)
+{
+       iaxc_event ev;
+
+       if ( callNo < 0 )
+               return;
+
+       ev.type = IAXC_EVENT_NETSTAT;
+       ev.ev.netstats.callNo = callNo;
+
+       /* only post the event if the session is valid, etc */
+       if ( !iaxc_get_netstats(callNo, &ev.ev.netstats.rtt,
+                               &ev.ev.netstats.local, &ev.ev.netstats.remote))
+               iaxci_post_event(ev);
+}
+
+static void handle_audio_event(struct iax_event *e, int callNo)
+{
+       int total_consumed = 0;
+       short fr[4096];
+       const int fr_samples = sizeof(fr) / sizeof(short);
+       int samples, format;
+#ifdef WIN32
+       int cycles_max = 100; //fd:
+#endif
+       struct iaxc_call *call;
+
+       if ( callNo < 0 )
+               return;
+
+       call = &calls[callNo];
+
+       if ( callNo != selected_call )
+       {
+           /* drop audio for unselected call? */
+           return;
+       }
+
+       samples = fr_samples;
+       format = call->format & IAXC_AUDIO_FORMAT_MASK;
+
+       do
+       {
+               int bytes_decoded;
+
+               int mainbuf_delta = fr_samples - samples;
+
+               bytes_decoded = audio_decode_audio(call,
+                               fr,
+                               e->data + total_consumed,
+                               e->datalen - total_consumed,
+                               format,
+                               &samples);
+
+               if ( bytes_decoded < 0 )
+               {
+                       iaxci_usermsg(IAXC_STATUS,
+                               "Bad or incomplete voice packet. Unable to decode. dropping");
+                       return;
+               }
+
+               /* Pass encoded audio back to the app if required */
+               if ( audio_prefs & IAXC_AUDIO_PREF_RECV_REMOTE_ENCODED )
+                       iaxci_do_audio_callback(callNo, e->ts, IAXC_SOURCE_REMOTE,
+                                       1, format & IAXC_AUDIO_FORMAT_MASK,
+                                       e->datalen - total_consumed,
+                                       e->data + total_consumed);
+
+#ifdef WIN32
+               //fd: start: for some reason it loops here. Try to avoid it
+               cycles_max--;
+               if ( cycles_max < 0 )
+               {
+                       iaxc_millisleep(0);
+               }
+               //fd: end
+#endif
+               total_consumed += bytes_decoded;
+               if ( audio_prefs & IAXC_AUDIO_PREF_RECV_REMOTE_RAW )
+               {
+                       // audio_decode_audio returns the number of samples.
+                       // We are using 16 bit samples, so we need to double
+                       // the number to obtain the size in bytes.
+                       // format will also be 0 since this is raw audio
+                       int size = (fr_samples - samples - mainbuf_delta) * 2;
+                       iaxci_do_audio_callback(callNo, e->ts, IAXC_SOURCE_REMOTE,
+                                       0, 0, size, (unsigned char *)fr);
+               }
+
+               if ( iaxci_audio_output_mode )
+                       continue;
+
+               if ( !test_mode )
+                       audio_driver.output(&audio_driver, fr,
+                           fr_samples - samples - mainbuf_delta);
+
+       } while ( total_consumed < e->datalen );
+}
+
+#ifdef USE_VIDEO
+static void handle_video_event(struct iax_event *e, int callNo)
+{
+       struct iaxc_call *call;
+
+       if ( callNo < 0 )
+               return;
+
+       if ( e->datalen == 0 )
+       {
+               iaxci_usermsg(IAXC_STATUS, "Received 0-size packet. Unable to decode.");
+               return;
+       }
+
+       call = &calls[callNo];
+
+       if ( callNo != selected_call )
+       {
+               /* drop video for unselected call? */
+               return;
+       }
+
+       if ( call->vformat )
+       {
+               if ( video_recv_video(call, selected_call, e->data,
+                                       e->datalen, e->ts, call->vformat) < 0 )
+               {
+                       iaxci_usermsg(IAXC_STATUS,
+                               "Bad or incomplete video packet. Unable to decode.");
+                       return;
+               }
+       }
+}
+#endif /* USE_VIDEO */
+
+static void iaxc_handle_network_event(struct iax_event *e, int callNo)
+{
+       if ( callNo < 0 )
+               return;
+
+       iaxc_note_activity(callNo);
+
+       switch ( e->etype )
+       {
+       case IAX_EVENT_NULL:
+               break;
+       case IAX_EVENT_HANGUP:
+               iaxci_usermsg(IAXC_STATUS, "Call disconnected by remote");
+               // XXX does the session go away now?
+               iaxc_clear_call(callNo);
+               break;
+       case IAX_EVENT_REJECT:
+               iaxci_usermsg(IAXC_STATUS, "Call rejected by remote");
+               iaxc_clear_call(callNo);
+               break;
+       case IAX_EVENT_ACCEPT:
+               calls[callNo].format = e->ies.format & IAXC_AUDIO_FORMAT_MASK;
+               calls[callNo].vformat = e->ies.format & IAXC_VIDEO_FORMAT_MASK;
+               if ( !(e->ies.format & IAXC_VIDEO_FORMAT_MASK) )
+               {
+                       iaxci_usermsg(IAXC_NOTICE,
+                                       "Failed video codec negotiation.");
+               }
+               iaxci_usermsg(IAXC_STATUS,"Call %d accepted", callNo);
+               break;
+       case IAX_EVENT_ANSWER:
+               calls[callNo].state &= ~IAXC_CALL_STATE_RINGING;
+               calls[callNo].state |= IAXC_CALL_STATE_COMPLETE;
+               iaxci_do_state_callback(callNo);
+               iaxci_usermsg(IAXC_STATUS,"Call %d answered", callNo);
+               //iaxc_answer_call(callNo);
+               // notify the user?
+               break;
+       case IAX_EVENT_BUSY:
+               calls[callNo].state &= ~IAXC_CALL_STATE_RINGING;
+               calls[callNo].state |= IAXC_CALL_STATE_BUSY;
+               iaxci_do_state_callback(callNo);
+               iaxci_usermsg(IAXC_STATUS, "Call %d busy", callNo);
+               break;
+       case IAX_EVENT_VOICE:
+               handle_audio_event(e, callNo);
+               if ( (calls[callNo].state & IAXC_CALL_STATE_OUTGOING) &&
+                    (calls[callNo].state & IAXC_CALL_STATE_RINGING) )
+               {
+                       calls[callNo].state &= ~IAXC_CALL_STATE_RINGING;
+                       calls[callNo].state |= IAXC_CALL_STATE_COMPLETE;
+                       iaxci_do_state_callback(callNo);
+                       iaxci_usermsg(IAXC_STATUS,"Call %d progress",
+                                    callNo);
+               }
+               break;
+#ifdef USE_VIDEO
+       case IAX_EVENT_VIDEO:
+               handle_video_event(e, callNo);
+               break;
+#endif
+       case IAX_EVENT_TEXT:
+               handle_text_event(e, callNo);
+               break;
+       case IAX_EVENT_RINGA:
+               calls[callNo].state |= IAXC_CALL_STATE_RINGING;
+               iaxci_do_state_callback(callNo);
+               iaxci_usermsg(IAXC_STATUS,"Call %d ringing", callNo);
+               break;
+       case IAX_EVENT_PONG:
+               generate_netstat_event(callNo);
+               break;
+       case IAX_EVENT_URL:
+               handle_url_event(e, callNo);
+               break;
+       case IAX_EVENT_CNG:
+               /* ignore? */
+               break;
+       case IAX_EVENT_TIMEOUT:
+               iax_hangup(e->session, "Call timed out");
+               iaxci_usermsg(IAXC_STATUS, "Call %d timed out.", callNo);
+               iaxc_clear_call(callNo);
+               break;
+       case IAX_EVENT_TRANSFER:
+               calls[callNo].state |= IAXC_CALL_STATE_TRANSFER;
+               iaxci_do_state_callback(callNo);
+               iaxci_usermsg(IAXC_STATUS,"Call %d transfer released", callNo);
+               break;
+       case IAX_EVENT_DTMF:
+               iaxci_do_dtmf_callback(callNo,e->subclass);
+               iaxci_usermsg(IAXC_STATUS, "DTMF digit %c received", e->subclass);
+               break;
+       default:
+               iaxci_usermsg(IAXC_STATUS, "Unknown event: %d for call %d", e->etype, callNo);
+               break;
+       }
+}
+
+EXPORT int iaxc_unregister( int id )
+{
+       int count = 0;
+       get_iaxc_lock();
+       count = iaxc_remove_registration_by_id(id);
+       put_iaxc_lock();
+       return count;
+}
+
+EXPORT int iaxc_register(const char * user, const char * pass, const char * host)
+{
+       return iaxc_register_ex(user, pass, host, 60);
+}
+
+EXPORT int iaxc_register_ex(const char * user, const char * pass, const char * host, int refresh)
+{
+       struct iaxc_registration *newreg;
+
+       newreg = (struct iaxc_registration *)malloc(sizeof (struct iaxc_registration));
+       if ( !newreg )
+       {
+               iaxci_usermsg(IAXC_ERROR, "Can't make new registration");
+               return -1;
+       }
+
+       get_iaxc_lock();
+       newreg->session = iax_session_new();
+       if ( !newreg->session )
+       {
+               iaxci_usermsg(IAXC_ERROR, "Can't make new registration session");
+               put_iaxc_lock();
+               return -1;
+       }
+
+       newreg->last = iax_tvnow();
+       newreg->refresh = refresh;  
+
+       strncpy(newreg->host, host, 256);
+       strncpy(newreg->user, user, 256);
+       strncpy(newreg->pass, pass, 256);
+
+       /* send out the initial registration with refresh seconds */
+       iax_register(newreg->session, host, user, pass, refresh);
+
+       /* add it to the list; */
+       newreg->id = ++next_registration_id;
+       newreg->next = registrations;
+       registrations = newreg;
+
+       put_iaxc_lock();
+       return newreg->id;
+}
+
+static void codec_destroy( int callNo )
+{
+       if ( calls[callNo].encoder )
+       {
+               calls[callNo].encoder->destroy( calls[callNo].encoder );
+               calls[callNo].encoder = NULL;
+       }
+       if ( calls[callNo].decoder )
+       {
+               calls[callNo].decoder->destroy( calls[callNo].decoder );
+               calls[callNo].decoder = NULL;
+       }
+       if ( calls[callNo].vdecoder )
+       {
+               calls[callNo].vdecoder->destroy(calls[callNo].vdecoder);
+               calls[callNo].vdecoder = NULL;
+       }
+       if ( calls[callNo].vencoder )
+       {
+               calls[callNo].vencoder->destroy(calls[callNo].vencoder);
+               calls[callNo].vencoder = NULL;
+       }
+}
+
+EXPORT int iaxc_call(const char * num)
+{
+       return iaxc_call_ex(num, NULL, NULL, 1);
+}
+
+EXPORT int iaxc_call_ex(const char *num, const char* callerid_name, const char* callerid_number, int video)
+{
+       int video_format_capability = 0;
+       int video_format_preferred = 0;
+       int callNo = -1;
+       struct iax_session *newsession;
+       char *ext = strstr(num, "/");
+
+       get_iaxc_lock();
+
+       // if no call is selected, get a new appearance
+       if ( selected_call < 0 )
+       {
+               callNo = iaxc_first_free_call();
+       } else
+       {
+               // use selected call if not active, otherwise, get a new appearance
+               if ( calls[selected_call].state  & IAXC_CALL_STATE_ACTIVE )
+               {
+                       callNo = iaxc_first_free_call();
+               } else
+               {
+                       callNo = selected_call;
+               }
+       }
+
+       if ( callNo < 0 )
+       {
+               iaxci_usermsg(IAXC_STATUS, "No free call appearances");
+               goto iaxc_call_bail;
+       }
+
+       newsession = iax_session_new();
+       if ( !newsession )
+       {
+               iaxci_usermsg(IAXC_ERROR, "Can't make new session");
+               goto iaxc_call_bail;
+       }
+
+       calls[callNo].session = newsession;
+
+       codec_destroy( callNo );
+
+       if ( ext )
+       {
+               strncpy(calls[callNo].remote_name, num, IAXC_EVENT_BUFSIZ);
+               strncpy(calls[callNo].remote,    ++ext, IAXC_EVENT_BUFSIZ);
+       } else
+       {
+               strncpy(calls[callNo].remote_name, num, IAXC_EVENT_BUFSIZ);
+               strncpy(calls[callNo].remote,      "" , IAXC_EVENT_BUFSIZ);
+       }
+
+       if ( callerid_number != NULL )
+               strncpy(calls[callNo].callerid_number, callerid_number, IAXC_EVENT_BUFSIZ);
+
+       if ( callerid_name != NULL )
+               strncpy(calls[callNo].callerid_name, callerid_name, IAXC_EVENT_BUFSIZ);
+
+       strncpy(calls[callNo].local        , calls[callNo].callerid_name, IAXC_EVENT_BUFSIZ);
+       strncpy(calls[callNo].local_context, "default", IAXC_EVENT_BUFSIZ);
+
+       calls[callNo].state = IAXC_CALL_STATE_ACTIVE | IAXC_CALL_STATE_OUTGOING;
+
+       /* reset activity and ping "timers" */
+       iaxc_note_activity(callNo);
+       calls[callNo].last_ping = calls[callNo].last_activity;
+
+#ifdef USE_VIDEO
+       if ( video )
+               iaxc_video_format_get_cap(&video_format_preferred, &video_format_capability);
+#endif
+
+       iaxci_usermsg(IAXC_NOTICE, "Originating an %s call",
+                       video_format_preferred ? "audio+video" : "audio only");
+       iax_call(calls[callNo].session, calls[callNo].callerid_number,
+                       calls[callNo].callerid_name, num, NULL, 0,
+                       audio_format_preferred | video_format_preferred,
+                       audio_format_capability | video_format_capability);
+
+       // does state stuff also
+       iaxc_select_call(callNo);
+
+iaxc_call_bail:
+       put_iaxc_lock();
+
+       return callNo;
+}
+
+EXPORT void iaxc_send_busy_on_incoming_call(int callNo)
+{
+       if ( callNo < 0 )
+               return;
+
+       iax_busy(calls[callNo].session);
+}
+
+EXPORT void iaxc_answer_call(int callNo)
+{
+       if ( callNo < 0 )
+               return;
+
+       calls[callNo].state |= IAXC_CALL_STATE_COMPLETE;
+       calls[callNo].state &= ~IAXC_CALL_STATE_RINGING;
+       iax_answer(calls[callNo].session);
+       iaxci_do_state_callback(callNo);
+}
+
+EXPORT void iaxc_blind_transfer_call(int callNo, const char * dest_extension)
+{
+       if ( callNo < 0 || !(calls[callNo].state & IAXC_CALL_STATE_ACTIVE) )
+               return;
+
+       iax_transfer(calls[callNo].session, dest_extension);
+}
+
+EXPORT void iaxc_setup_call_transfer(int sourceCallNo, int targetCallNo)
+{
+       if ( sourceCallNo < 0 || targetCallNo < 0 ||
+                       !(calls[sourceCallNo].state & IAXC_CALL_STATE_ACTIVE) ||
+                       !(calls[targetCallNo].state & IAXC_CALL_STATE_ACTIVE) )
+               return;
+
+       iax_setup_transfer(calls[sourceCallNo].session, calls[targetCallNo].session);
+}
+
+static void iaxc_dump_one_call(int callNo)
+{
+       if ( callNo < 0 )
+               return;
+       if ( calls[callNo].state == IAXC_CALL_STATE_FREE )
+               return;
+
+       iax_hangup(calls[callNo].session,"Dumped Call");
+       iaxci_usermsg(IAXC_STATUS, "Hanging up call %d", callNo);
+       iaxc_clear_call(callNo);
+}
+
+EXPORT void iaxc_dump_all_calls(void)
+{
+       int callNo;
+       get_iaxc_lock();
+       for ( callNo = 0; callNo < max_calls; callNo++ )
+               iaxc_dump_one_call(callNo);
+       put_iaxc_lock();
+}
+
+
+EXPORT void iaxc_dump_call_number( int callNo )
+{
+       if ( ( callNo >= 0 ) && ( callNo < max_calls ) )
+       {
+               get_iaxc_lock();
+               iaxc_dump_one_call(callNo);
+               put_iaxc_lock();
+       }
+}
+
+EXPORT void iaxc_dump_call(void)
+{
+       if ( selected_call >= 0 )
+       {
+               get_iaxc_lock();
+               iaxc_dump_one_call(selected_call);
+               put_iaxc_lock();
+       }
+}
+
+EXPORT void iaxc_reject_call(void)
+{
+       if ( selected_call >= 0 )
+       {
+               iaxc_reject_call_number(selected_call);
+       }
+}
+
+EXPORT void iaxc_reject_call_number( int callNo )
+{
+       if ( ( callNo >= 0 ) && ( callNo < max_calls ) )
+       {
+               get_iaxc_lock();
+               iax_reject(calls[callNo].session, "Call rejected manually.");
+               iaxc_clear_call(callNo);
+               put_iaxc_lock();
+       }
+}
+
+EXPORT void iaxc_send_dtmf(char digit)
+{
+       if ( selected_call >= 0 )
+       {
+               get_iaxc_lock();
+               if ( calls[selected_call].state & IAXC_CALL_STATE_ACTIVE )
+                       iax_send_dtmf(calls[selected_call].session,digit);
+               put_iaxc_lock();
+       }
+}
+
+EXPORT void iaxc_send_text(const char * text)
+{
+       if ( selected_call >= 0 )
+       {
+               get_iaxc_lock();
+               if ( calls[selected_call].state & IAXC_CALL_STATE_ACTIVE )
+                       iax_send_text(calls[selected_call].session, text);
+               put_iaxc_lock();
+       }
+}
+
+EXPORT void iaxc_send_text_call(int callNo, const char * text)
+{
+       if ( callNo < 0 || !(calls[callNo].state & IAXC_CALL_STATE_ACTIVE) )
+               return;
+
+       get_iaxc_lock();
+       if ( calls[callNo].state & IAXC_CALL_STATE_ACTIVE )
+               iax_send_text(calls[callNo].session, text);
+       put_iaxc_lock();
+}
+
+EXPORT void iaxc_send_url(const char * url, int link)
+{
+       if ( selected_call >= 0 )
+       {
+               get_iaxc_lock();
+               if ( calls[selected_call].state & IAXC_CALL_STATE_ACTIVE )
+                       iax_send_url(calls[selected_call].session, url, link);
+               put_iaxc_lock();
+       }
+}
+
+static int iaxc_find_call_by_session(struct iax_session *session)
+{
+       int i;
+       for ( i = 0; i < max_calls; i++ )
+               if ( calls[i].session == session )
+                       return i;
+       return -1;
+}
+
+static struct iaxc_registration *iaxc_find_registration_by_session(
+               struct iax_session *session)
+{
+       struct iaxc_registration *reg;
+       for (reg = registrations; reg != NULL; reg = reg->next)
+               if ( reg->session == session )
+                       break;
+       return reg;
+}
+
+static void iaxc_handle_regreply(struct iax_event *e, struct iaxc_registration *reg)
+{
+       iaxci_do_registration_callback(reg->id, e->etype, e->ies.msgcount);
+
+       // XXX I think the session is no longer valid.. at least, that's
+       // what miniphone does, and re-using the session doesn't seem to
+       // work!
+       iax_destroy(reg->session);
+       reg->session = NULL;
+
+       if ( e->etype == IAX_EVENT_REGREJ )
+       {
+               // we were rejected, so end the registration
+               iaxc_remove_registration_by_id(reg->id);
+       }
+}
+
+/* this is what asterisk does */
+static int iaxc_choose_codec(int formats)
+{
+       int i;
+       static int codecs[] =
+       {
+               IAXC_FORMAT_ULAW,
+               IAXC_FORMAT_ALAW,
+               IAXC_FORMAT_SLINEAR,
+               IAXC_FORMAT_G726,
+               IAXC_FORMAT_ADPCM,
+               IAXC_FORMAT_GSM,
+               IAXC_FORMAT_ILBC,
+               IAXC_FORMAT_SPEEX,
+               IAXC_FORMAT_LPC10,
+               IAXC_FORMAT_G729A,
+               IAXC_FORMAT_G723_1,
+
+               /* To negotiate video codec */
+               IAXC_FORMAT_JPEG,
+               IAXC_FORMAT_PNG,
+               IAXC_FORMAT_H261,
+               IAXC_FORMAT_H263,
+               IAXC_FORMAT_H263_PLUS,
+               IAXC_FORMAT_MPEG4,
+               IAXC_FORMAT_H264,
+               IAXC_FORMAT_THEORA,
+       };
+       for ( i = 0; i < (int)(sizeof(codecs) / sizeof(int)); i++ )
+               if ( codecs[i] & formats )
+                       return codecs[i];
+       return 0;
+}
+
+static void iaxc_handle_connect(struct iax_event * e)
+{
+#ifdef USE_VIDEO
+       int video_format_capability;
+       int video_format_preferred;
+#endif
+       int video_format = 0;
+       int format = 0;
+       int callno;
+
+       callno = iaxc_first_free_call();
+
+       if ( callno < 0 )
+       {
+               iaxci_usermsg(IAXC_STATUS,
+                               "%i \n Incoming Call, but no appearances",
+                               callno);
+               // XXX Reject this call!, or just ignore?
+               //iax_reject(e->session, "Too many calls, we're busy!");
+               iax_accept(e->session, audio_format_preferred & e->ies.capability);
+               iax_busy(e->session);
+               return;
+       }
+
+       /* negotiate codec */
+       /* first, try _their_ preferred format */
+       format = audio_format_capability & e->ies.format;
+       if ( !format )
+       {
+               /* then, try our preferred format */
+               format = audio_format_preferred & e->ies.capability;
+       }
+
+       if ( !format )
+       {
+               /* finally, see if we have one in common */
+               format = audio_format_capability & e->ies.capability;
+
+               /* now choose amongst these, if we got one */
+               if ( format )
+               {
+                       format = iaxc_choose_codec(format);
+               }
+       }
+
+       if ( !format )
+       {
+               iax_reject(e->session, "Could not negotiate common codec");
+               return;
+       }
+
+#ifdef USE_VIDEO
+       iaxc_video_format_get_cap(&video_format_preferred,
+                       &video_format_capability);
+
+       /* first, see if they even want video */
+       video_format = (e->ies.format & IAXC_VIDEO_FORMAT_MASK);
+
+       if ( video_format )
+       {
+               /* next, try _their_ preferred format */
+               video_format &= video_format_capability;
+
+               if ( !video_format )
+               {
+                       /* then, try our preferred format */
+                       video_format = video_format_preferred &
+                               (e->ies.capability & IAXC_VIDEO_FORMAT_MASK);
+               }
+
+               if ( !video_format )
+               {
+                       /* finally, see if we have one in common */
+                       video_format = video_format_capability &
+                               (e->ies.capability & IAXC_VIDEO_FORMAT_MASK);
+
+                       /* now choose amongst these, if we got one */
+                       if ( video_format )
+                       {
+                               video_format = iaxc_choose_codec(video_format);
+                       }
+               }
+
+               /* All video negotiations failed, then warn */
+               if ( !video_format )
+               {
+                       iaxci_usermsg(IAXC_NOTICE,
+                                       "Notice: could not negotiate common video codec");
+                       iaxci_usermsg(IAXC_NOTICE,
+                                       "Notice: switching to audio-only call");
+               }
+       }
+#endif /* USE_VIDEO */
+
+       calls[callno].vformat = video_format;
+       calls[callno].format = format;
+
+       if ( e->ies.called_number )
+               strncpy(calls[callno].local, e->ies.called_number,
+                               IAXC_EVENT_BUFSIZ);
+       else
+               strncpy(calls[callno].local, "unknown",
+                               IAXC_EVENT_BUFSIZ);
+
+       if ( e->ies.called_context )
+               strncpy(calls[callno].local_context, e->ies.called_context,
+                               IAXC_EVENT_BUFSIZ);
+       else
+               strncpy(calls[callno].local_context, "",
+                               IAXC_EVENT_BUFSIZ);
+
+       if ( e->ies.calling_number )
+               strncpy(calls[callno].remote, e->ies.calling_number,
+                               IAXC_EVENT_BUFSIZ);
+       else
+               strncpy(calls[callno].remote, "unknown",
+                               IAXC_EVENT_BUFSIZ);
+
+       if ( e->ies.calling_name )
+               strncpy(calls[callno].remote_name, e->ies.calling_name,
+                               IAXC_EVENT_BUFSIZ);
+       else
+               strncpy(calls[callno].remote_name, "unknown",
+                               IAXC_EVENT_BUFSIZ);
+
+       iaxc_note_activity(callno);
+       iaxci_usermsg(IAXC_STATUS, "Call from (%s)", calls[callno].remote);
+
+       codec_destroy( callno );
+
+       calls[callno].session = e->session;
+       calls[callno].state = IAXC_CALL_STATE_ACTIVE|IAXC_CALL_STATE_RINGING;
+
+       iax_accept(calls[callno].session, format | video_format);
+       iax_ring_announce(calls[callno].session);
+
+       iaxci_do_state_callback(callno);
+
+       iaxci_usermsg(IAXC_STATUS, "Incoming call on line %d", callno);
+}
+
+static void service_network()
+{
+       struct iax_event *e = 0;
+       int callNo;
+       struct iaxc_registration *reg;
+
+       while ( (e = iax_get_event(0)) )
+       {
+#ifdef WIN32
+               iaxc_millisleep(0); //fd:
+#endif
+               // first, see if this is an event for one of our calls.
+               callNo = iaxc_find_call_by_session(e->session);
+               if ( e->etype == IAX_EVENT_NULL )
+               {
+                       // Should we do something here?
+                       // Right now we do nothing, just go with the flow
+                       // and let the event be deallocated.
+               } else if ( callNo >= 0 )
+               {
+                       iaxc_handle_network_event(e, callNo);
+               } else if ( (reg = iaxc_find_registration_by_session(e->session)) != NULL )
+               {
+                       iaxc_handle_regreply(e,reg);
+               } else if ( e->etype == IAX_EVENT_REGACK || e->etype == IAX_EVENT_REGREJ )
+               {
+                       iaxci_usermsg(IAXC_ERROR, "Unexpected registration reply");
+               } else if ( e->etype == IAX_EVENT_REGREQ )
+               {
+                       iaxci_usermsg(IAXC_ERROR,
+                                       "Registration requested by someone, but we don't understand!");
+               } else if ( e->etype == IAX_EVENT_CONNECT )
+               {
+                       iaxc_handle_connect(e);
+               } else if ( e->etype == IAX_EVENT_TIMEOUT )
+               {
+                       iaxci_usermsg(IAXC_STATUS,
+                                       "Timeout for a non-existant session. Dropping",
+                                       e->etype);
+               } else
+               {
+                       iaxci_usermsg(IAXC_STATUS,
+                                       "Event (type %d) for a non-existant session. Dropping",
+                                       e->etype);
+               }
+               iax_event_free(e);
+       }
+}
+
+EXPORT int iaxc_audio_devices_get(struct iaxc_audio_device **devs, int *nDevs,
+               int *input, int *output, int *ring)
+{
+       if ( test_mode )
+               return 0;
+
+       *devs = audio_driver.devices;
+       *nDevs = audio_driver.nDevices;
+       audio_driver.selected_devices(&audio_driver, input, output, ring);
+       return 0;
+}
+
+EXPORT int iaxc_audio_devices_set(int input, int output, int ring)
+{
+       int ret;
+
+       if ( test_mode )
+               return 0;
+
+       get_iaxc_lock();
+       ret = audio_driver.select_devices(&audio_driver, input, output, ring);
+       put_iaxc_lock();
+       return ret;
+}
+
+EXPORT float iaxc_input_level_get()
+{
+       if ( test_mode )
+               return 0;
+
+       return audio_driver.input_level_get(&audio_driver);
+}
+
+EXPORT float iaxc_output_level_get()
+{
+       if ( test_mode )
+               return 0;
+
+       return audio_driver.output_level_get(&audio_driver);
+}
+
+EXPORT int iaxc_input_level_set(float level)
+{
+       if ( test_mode )
+               return 0;
+
+       return audio_driver.input_level_set(&audio_driver, level);
+}
+
+EXPORT int iaxc_output_level_set(float level)
+{
+       if ( test_mode )
+               return 0;
+
+       return audio_driver.output_level_set(&audio_driver, level);
+}
+
+EXPORT int iaxc_play_sound(struct iaxc_sound *s, int ring)
+{
+       int ret;
+
+       if ( test_mode )
+               return 0;
+
+       get_iaxc_lock();
+       ret = audio_driver.play_sound(s,ring);
+       put_iaxc_lock();
+       return ret;
+}
+
+EXPORT int iaxc_stop_sound(int id)
+{
+       int ret;
+
+       if ( test_mode )
+               return 0;
+
+       get_iaxc_lock();
+       ret = audio_driver.stop_sound(id);
+       put_iaxc_lock();
+       return ret;
+}
+
+EXPORT int iaxc_quelch(int callNo, int MOH)
+{
+       struct iax_session *session = calls[callNo].session;
+       if ( !session )
+               return -1;
+
+       return iax_quelch_moh(session, MOH);
+}
+
+EXPORT int iaxc_unquelch(int call)
+{
+       return iax_unquelch(calls[call].session);
+}
+
+EXPORT int iaxc_mic_boost_get( void )
+{
+       return audio_driver.mic_boost_get( &audio_driver ) ;
+}
+
+EXPORT int iaxc_mic_boost_set( int enable )
+{
+       return audio_driver.mic_boost_set( &audio_driver, enable ) ;
+}
+
+EXPORT char* iaxc_version(char * ver)
+{
+#ifndef LIBVER
+#define LIBVER ""
+#endif
+       strncpy(ver, LIBVER, IAXC_EVENT_BUFSIZ);
+       return ver;
+}
+
+EXPORT unsigned int iaxc_get_audio_prefs(void)
+{
+       return audio_prefs;
+}
+
+EXPORT int iaxc_set_audio_prefs(unsigned int prefs)
+{
+       unsigned int prefs_mask =
+               IAXC_AUDIO_PREF_RECV_LOCAL_RAW      |
+               IAXC_AUDIO_PREF_RECV_LOCAL_ENCODED  |
+               IAXC_AUDIO_PREF_RECV_REMOTE_RAW     |
+               IAXC_AUDIO_PREF_RECV_REMOTE_ENCODED |
+               IAXC_AUDIO_PREF_SEND_DISABLE;
+
+       if ( prefs & ~prefs_mask )
+               return -1;
+
+       audio_prefs = prefs;
+       return 0;
+}
+
+EXPORT void iaxc_set_test_mode(int tm)
+{
+       test_mode = tm;
+}
+
+EXPORT int iaxc_push_audio(void *data, unsigned int size, unsigned int samples)
+{
+       struct iaxc_call *call;
+
+       if ( selected_call < 0 )
+               return -1;
+
+       call = &calls[selected_call];
+
+       if ( audio_prefs & IAXC_AUDIO_PREF_SEND_DISABLE )
+               return 0;
+
+       //fprintf(stderr, "iaxc_push_audio: sending audio size %d\n", size);
+
+       if ( iax_send_voice(call->session, call->format, data, size, samples) == -1 )
+       {
+               fprintf(stderr, "iaxc_push_audio: failed to send audio frame of size %d on call %d\n", size, selected_call);
+               return -1;
+       }
+
+       return 0;
+}
+
+void iaxc_debug_iax_set(int enable)
+{
+#ifdef DEBUG_SUPPORT
+       if (enable)
+               iax_enable_debug();
+       else
+               iax_disable_debug();
+#endif
+}
+
diff --git a/utils/iaxclient/lib/iaxclient_lib.h b/utils/iaxclient/lib/iaxclient_lib.h
new file mode 100644 (file)
index 0000000..91776c3
--- /dev/null
@@ -0,0 +1,270 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003-2006, Horizon Wimba, Inc.
+ * Copyright (C) 2007, Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ * Michael Van Donselaar <mvand@vandonselaar.org>
+ * Shawn Lawrence <shawn.lawrence@terracecomm.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ */
+#ifndef _iaxclient_lib_h
+#define _iaxclient_lib_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* This is the internal include file for IAXCLIENT -- externally
+ * accessible APIs should be declared in iaxclient.h */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#if defined(WIN32)  ||  defined(_WIN32_WCE)
+#include "winpoop.h"
+#if !defined(_WIN32_WCE)
+#include <process.h>
+#endif
+#include <stddef.h>
+#include <time.h>
+
+#else
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/time.h>
+#include <pthread.h>
+#endif
+
+#ifdef USE_FFMPEG
+// To access to check_ff function
+#include "codec_ffmpeg.h"
+#endif
+
+#include <stdlib.h>
+#include <math.h>
+#include "spandsp/plc.h"
+
+
+
+/* os-dependent macros, etc */
+#if defined(WIN32) || defined(_WIN32_WCE)
+#define THREAD HANDLE
+#define THREADID unsigned
+#define THREADCREATE(func, args, thread, id) \
+(thread = (HANDLE)_beginthreadex(NULL, 0, func, (PVOID)args, 0, &id))
+#define THREADCREATE_ERROR NULL
+#define THREADFUNCDECL(func) unsigned __stdcall func(PVOID args)
+#define THREADFUNCRET(r) int r = 0
+#define THREADJOIN(t)
+/* causes deadlock with wx GUI on MSW */
+/* #define THREADJOIN(t) WaitForSingleObject(t, INFINITE) */
+#ifndef _WIN32_WINNT
+extern WINBASEAPI BOOL WINAPI TryEnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection );
+#endif
+#define MUTEX CRITICAL_SECTION
+#define MUTEXINIT(m) InitializeCriticalSection(m)
+#define MUTEXLOCK(m) EnterCriticalSection(m)
+#define MUTEXTRYLOCK(m) (!TryEnterCriticalSection(m))
+#define MUTEXUNLOCK(m) LeaveCriticalSection(m)
+#define MUTEXDESTROY(m) DeleteCriticalSection(m)
+
+#else
+#define THREAD pthread_t
+#define THREADID unsigned /* unused for Posix Threads */
+#define THREADCREATE(func, args, thread, id) \
+pthread_create(&thread, NULL, func, args)
+#define THREADCREATE_ERROR -1
+#define THREADFUNCDECL(func) void * func(void *args)
+#define THREADFUNCRET(r) void * r = 0
+#define THREADJOIN(t) pthread_join(t, 0)
+#define MUTEX pthread_mutex_t
+#define MUTEXINIT(m) pthread_mutex_init(m, NULL) //TODO: check error
+#define MUTEXLOCK(m) pthread_mutex_lock(m)
+#define MUTEXTRYLOCK(m) pthread_mutex_trylock(m)
+#define MUTEXUNLOCK(m) pthread_mutex_unlock(m)
+#define MUTEXDESTROY(m) pthread_mutex_destroy(m)
+#endif
+
+#ifdef MACOSX
+#include <mach/mach_init.h>
+#include <mach/thread_policy.h>
+#include <sched.h>
+#include <sys/sysctl.h>
+#endif
+
+#define MAXARGS 10
+#define MAXARG 256
+#define MAX_SESSIONS 4
+#define OUT_INTERVAL 20
+
+/* millisecond interval to time out calls */
+#define IAXC_CALL_TIMEOUT 30000
+
+
+void os_init(void);
+void iaxci_usermsg(int type, const char *fmt, ...);
+void iaxci_do_levels_callback(float input, float output);
+void iaxci_do_audio_callback(int callNo, unsigned int ts, int remote,
+               int encoded, int format, int size, unsigned char *data);
+
+#include "iaxclient.h"
+
+struct iaxc_audio_driver {
+       /* data */
+       char *name;     /* driver name */
+       struct iaxc_audio_device *devices; /* list of devices */
+       int nDevices;   /* count of devices */
+       void *priv;     /* pointer to private data */
+
+       /* methods */
+       int (*initialize)(struct iaxc_audio_driver *d, int sample_rate);
+       int (*destroy)(struct iaxc_audio_driver *d);  /* free resources */
+       int (*select_devices)(struct iaxc_audio_driver *d, int input, int output, int ring);
+       int (*selected_devices)(struct iaxc_audio_driver *d, int *input, int *output, int *ring);
+
+       /*
+        * select_ring ?
+        * set_latency
+        */
+
+       int (*start)(struct iaxc_audio_driver *d);
+       int (*stop)(struct iaxc_audio_driver *d);
+       int (*output)(struct iaxc_audio_driver *d, void *samples, int nSamples);
+       int (*input)(struct iaxc_audio_driver *d, void *samples, int *nSamples);
+
+       /* levels */
+       float (*input_level_get)(struct iaxc_audio_driver *d);
+       float (*output_level_get)(struct iaxc_audio_driver *d);
+       int (*input_level_set)(struct iaxc_audio_driver *d, float level);
+       int (*output_level_set)(struct iaxc_audio_driver *d, float level);
+
+       /* sounds */
+       int (*play_sound)(struct iaxc_sound *s, int ring);
+       int (*stop_sound)(int id);
+
+       /* mic boost */
+       int (*mic_boost_get)(struct iaxc_audio_driver *d ) ;
+       int (*mic_boost_set)(struct iaxc_audio_driver *d, int enable);
+};
+
+struct iaxc_audio_codec {
+       char name[256];
+       int format;
+       int minimum_frame_size;
+       void *encstate;
+       void *decstate;
+       int (*encode) ( struct iaxc_audio_codec *codec, int *inlen, short *in, int *outlen, unsigned char *out );
+       int (*decode) ( struct iaxc_audio_codec *codec, int *inlen, unsigned char *in, int *outlen, short *out );
+       void (*destroy) ( struct iaxc_audio_codec *codec);
+};
+
+#define MAX_TRUNK_LEN  (1<<16)
+#define MAX_NO_SLICES  32
+
+struct slice_set_t
+{
+       int     num_slices;
+       int     key_frame;
+       int     size[MAX_NO_SLICES];
+       char    data[MAX_NO_SLICES][MAX_TRUNK_LEN];
+};
+
+struct iaxc_video_codec {
+       char name[256];
+       int format;
+       int width;
+       int height;
+       int framerate;
+       int bitrate;
+       int fragsize;
+       int params_changed;
+       void *encstate;
+       void *decstate;
+       struct iaxc_video_stats video_stats;
+       int (*encode)(struct iaxc_video_codec * codec, int inlen,
+                       const char * in, struct slice_set_t * out);
+       int (*decode)(struct iaxc_video_codec * codec, int inlen,
+                       const char * in, int * outlen, char * out);
+       void (*destroy)(struct iaxc_video_codec * codec);
+};
+
+
+
+struct iaxc_call {
+       /* to be replaced with codec-structures, with codec-private data  */
+       struct iaxc_audio_codec *encoder;
+       struct iaxc_audio_codec *decoder;
+       struct iaxc_video_codec *vencoder;
+       struct iaxc_video_codec *vdecoder;
+       int vformat;
+
+       /* the "state" of this call */
+       int state;
+       char remote[IAXC_EVENT_BUFSIZ];
+       char remote_name[IAXC_EVENT_BUFSIZ];
+       char local[IAXC_EVENT_BUFSIZ];
+       char local_context[IAXC_EVENT_BUFSIZ];
+
+       /* Outbound CallerID */
+       char callerid_name[IAXC_EVENT_BUFSIZ];
+       char callerid_number[IAXC_EVENT_BUFSIZ];
+
+       /* reset whenever we receive packets from remote */
+       struct   timeval        last_activity;
+       struct   timeval        last_ping;
+
+       /* our negotiated format */
+       int format;
+
+       /* we've sent a silent frame since the last audio frame */
+       int tx_silent;
+
+       struct iax_session *session;
+};
+
+#include "audio_encode.h"
+
+#ifdef AUDIO_PA
+  #include "audio_portaudio.h"
+#endif
+
+#include "audio_file.h"
+
+#ifdef AUDIO_OPENAL
+  #include "audio_openal.h"
+#endif
+
+extern int iaxci_audio_output_mode;
+
+int iaxci_post_event_callback(iaxc_event e);
+
+/* post an event to the application */
+void iaxci_post_event(iaxc_event e);
+
+/* parameters for callback */
+extern void * post_event_handle;
+extern int post_event_id;
+
+/* Priority boost support */
+extern int iaxci_prioboostbegin(void);
+extern int iaxci_prioboostend(void);
+
+long iaxci_usecdiff(struct timeval *t0, struct timeval *t1);
+long iaxci_msecdiff(struct timeval *t0, struct timeval *t1);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/utils/iaxclient/lib/libiax2/AUTHORS b/utils/iaxclient/lib/libiax2/AUTHORS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/utils/iaxclient/lib/libiax2/COPYING b/utils/iaxclient/lib/libiax2/COPYING
new file mode 100644 (file)
index 0000000..6757284
--- /dev/null
@@ -0,0 +1,416 @@
+                   GNU GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                          675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                   GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+
+
+
+
+
+
+
+
+
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+
+
+
+
+
+
+
+
+
+
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                           NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+       Appendix: How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    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.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/utils/iaxclient/lib/libiax2/COPYING.LIB b/utils/iaxclient/lib/libiax2/COPYING.LIB
new file mode 100644 (file)
index 0000000..161a3d1
--- /dev/null
@@ -0,0 +1,482 @@
+                 GNU LIBRARY GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL.  It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+                           Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it.  You can use it for
+your libraries, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library.  If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+\f
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software.  To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+  Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs.  This
+license, the GNU Library General Public License, applies to certain
+designated libraries.  This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+  The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it.  Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program.  However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+  Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries.  We
+concluded that weaker conditions might promote sharing better.
+
+  However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves.  This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them.  (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.)  The hope is that this
+will lead to faster development of free libraries.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+  Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+\f
+                 GNU LIBRARY GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License").  Each licensee is
+addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    c) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    d) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+\f
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                           NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                    END OF TERMS AND CONDITIONS
+\f
+     Appendix: How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+    MA 02111-1307, USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/utils/iaxclient/lib/libiax2/ChangeLog b/utils/iaxclient/lib/libiax2/ChangeLog
new file mode 100644 (file)
index 0000000..311fecb
--- /dev/null
@@ -0,0 +1,21 @@
+libiax
+======
+
+version 0.2.3:
+       * Allow password to be passed in connect
+
+version 0.2.2 (Nov 13th, 2001):
+       * HTML Unlink requests
+       * HTML Reject link requests
+       * Text frames
+
+version 0.2.1 (Oct 20th, 2001):
+       * More space for challenge in IAX
+       * Fixed strncpy security bug
+       * Accept larger packets
+       * Handle out of order packets better
+       * Implemented send_url
+       * Added an iax-config script :-)
+
+version 0.2.0 (Oct 10th, 2001): 
+       * Initial Public Release
diff --git a/utils/iaxclient/lib/libiax2/INSTALL b/utils/iaxclient/lib/libiax2/INSTALL
new file mode 100644 (file)
index 0000000..23e5f25
--- /dev/null
@@ -0,0 +1,236 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
+Software Foundation, Inc.
+
+This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about.  Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory.  After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc.  You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+There may be some features `configure' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+If you want to set default values for `configure' scripts to share, you
+can create a site shell script called `config.site' that gives default
+values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).  Here is a another example:
+
+     /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
+configuration-related scripts to be executed by `/bin/bash'.
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
diff --git a/utils/iaxclient/lib/libiax2/Makefile.am b/utils/iaxclient/lib/libiax2/Makefile.am
new file mode 100644 (file)
index 0000000..40d3da5
--- /dev/null
@@ -0,0 +1,6 @@
+SUBDIRS = src
+
+bin_SCRIPTS=iax-config
+BUILT_SCOURCES=iax-config
+EXTRA_DIST=iax.spec libiax2.vcproj
+iax-config: iax-config.in
diff --git a/utils/iaxclient/lib/libiax2/NEWS b/utils/iaxclient/lib/libiax2/NEWS
new file mode 100644 (file)
index 0000000..233df64
--- /dev/null
@@ -0,0 +1,12 @@
+libiax
+======
+
+0.2.3:
+
+0.2.2:
+
+0.2.1:
+
+0.2.0 (Oct 10th, 2001): 
+       Initial Release. Hooray! Rejoice! :)
+
diff --git a/utils/iaxclient/lib/libiax2/README b/utils/iaxclient/lib/libiax2/README
new file mode 100644 (file)
index 0000000..72f5e9e
--- /dev/null
@@ -0,0 +1,4 @@
+libiax: An implementation of the Inter-Asterisk eXchange protocol distributed
+under the terms of the GNU Lesser General Public License
+
+Written by Mark Spencer <markster@linux-support.net>
diff --git a/utils/iaxclient/lib/libiax2/bootstrap.sh b/utils/iaxclient/lib/libiax2/bootstrap.sh
new file mode 100755 (executable)
index 0000000..640caa7
--- /dev/null
@@ -0,0 +1,6 @@
+echo If this fails you probably need to download the latest
+echo libtool,aclocal,autoconf and automake
+libtoolize --force
+aclocal --force
+autoconf -f
+automake -acf
diff --git a/utils/iaxclient/lib/libiax2/build.sh b/utils/iaxclient/lib/libiax2/build.sh
new file mode 100755 (executable)
index 0000000..9dfda77
--- /dev/null
@@ -0,0 +1,13 @@
+echo configuring automake
+./bootstrap.sh
+echo configuring libiax2
+./configure --enable-newjb
+echo building libiax2
+make
+echo 
+echo
+echo '##################################################################'
+echo '#                                                                #'
+echo '# If all is well, enter "make install" to complete installation. #'
+echo '#                                                                #'
+echo '##################################################################'
diff --git a/utils/iaxclient/lib/libiax2/configure.in b/utils/iaxclient/lib/libiax2/configure.in
new file mode 100644 (file)
index 0000000..24d5dc2
--- /dev/null
@@ -0,0 +1,40 @@
+dnl Yo Yo Yo
+AC_INIT(src/iax.c)
+AM_INIT_AUTOMAKE([iax], [0.2.3])
+
+
+dnl Check for various goodies
+AC_PROG_CC
+AM_PROG_LIBTOOL
+dnl LIBTOOL="$LIBTOOL --silent"
+AC_PROG_INSTALL
+
+dnl Check for libraries
+dnl None available
+
+dnl Check header files
+AC_HEADER_STDC
+
+AC_CHECK_FUNCS(gettimeofday)
+
+AC_SUBST(LIBS)
+
+AC_ARG_ENABLE(snomhack,     [  --enable-snomhack       Use slower memset for SNOM phoneem ],,enable_snomhack=no)
+AC_ARG_ENABLE(extreme_debug,     [  --enable-extreme-debug  Compile with extreme debugging code enabled ],,enable_extreme_debug=no)
+if test "$enable_snomhack" = yes ; then
+       AC_DEFINE(SNOM_HACK)
+fi
+
+if test "$enable_extreme_debug" = yes ; then
+       AC_DEFINE(EXTREME_DEBUG)
+fi
+
+AC_SUBST(IAX_VERSION)
+
+AC_OUTPUT([
+Makefile
+src/Makefile
+iax.spec
+iax-config],[case "$CONFIG_FILES" in
+*iax-config*)chmod +x iax-config;;
+esac])
diff --git a/utils/iaxclient/lib/libiax2/depcomp b/utils/iaxclient/lib/libiax2/depcomp
new file mode 100755 (executable)
index 0000000..04701da
--- /dev/null
@@ -0,0 +1,530 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2005-07-09.11
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005 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., 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 Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+  '')
+     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+  depmode     Dependency tracking mode.
+  source      Source file read by `PROGRAMS ARGS'.
+  object      Object file output by `PROGRAMS ARGS'.
+  DEPDIR      directory where to store dependencies.
+  depfile     Dependency file to output.
+  tmpdepfile  Temporary file to use when outputing dependencies.
+  libtool     Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "depcomp $scriptversion"
+    exit $?
+    ;;
+esac
+
+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
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+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
+      # With Tru64 cc, shared objects can also be used to make a
+      # static library.  This mecanism is used in libtool 1.4 series to
+      # handle both shared and static libraries in a single compilation.
+      # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+      #
+      # With libtool 1.5 this exception was removed, and libtool now
+      # generates 2 separate objects for the 2 libraries.  These two
+      # compilations output dependencies in in $dir.libs/$base.o.d and
+      # in $dir$base.o.d.  We have to check for both files, because
+      # one of the two compilations can be disabled.  We should prefer
+      # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+      # automatically cleaned when .libs/ is deleted, while ignoring
+      # the former would cause a distcleancheck panic.
+      tmpdepfile1=$dir.libs/$base.lo.d   # libtool 1.4
+      tmpdepfile2=$dir$base.o.d          # libtool 1.5
+      tmpdepfile3=$dir.libs/$base.o.d    # libtool 1.5
+      tmpdepfile4=$dir.libs/$base.d      # Compaq CCC V6.2-504
+      "$@" -Wc,-MD
+   else
+      tmpdepfile1=$dir$base.o.d
+      tmpdepfile2=$dir$base.d
+      tmpdepfile3=$dir$base.d
+      tmpdepfile4=$dir$base.d
+      "$@" -MD
+   fi
+
+   stat=$?
+   if test $stat -eq 0; then :
+   else
+      rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+      exit $stat
+   fi
+
+   for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+   do
+     test -f "$tmpdepfile" && break
+   done
+   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 -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+       -e '/^#line [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
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/utils/iaxclient/lib/libiax2/gen.sh b/utils/iaxclient/lib/libiax2/gen.sh
new file mode 100755 (executable)
index 0000000..08c7e93
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+#
+# Run this to generate a new configure script and such  :)
+# 
+#      -- Rob
+#
+
+
+(libtoolize --version) < /dev/null > /dev/null 2>&1 || {
+       echo;
+       echo "You must have libtool installed to compile libiax";
+       echo;
+       exit;
+}
+
+libtoolize --copy --force
+aclocal
+autoconf
+automake
diff --git a/utils/iaxclient/lib/libiax2/iax-config.in b/utils/iaxclient/lib/libiax2/iax-config.in
new file mode 100755 (executable)
index 0000000..a4e82c3
--- /dev/null
@@ -0,0 +1,74 @@
+#!/bin/sh
+iax_libs="-L/usr/lib -liax"
+iax_cflags=""
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+exec_prefix_set=no
+
+usage="\
+Usage: iax-config [--prefix[=DIR]] [--exec-prefix[=DIR]] [--version] [--libs] [--cflags]"
+
+if test $# -eq 0; then
+      echo "${usage}" 1>&2
+      exit 1
+fi
+
+while test $# -gt 0; do
+  case "$1" in
+  -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  case $1 in
+    --prefix=*)
+      prefix=$optarg
+      if test $exec_prefix_set = no ; then
+        exec_prefix=$optarg
+      fi
+      ;;
+    --prefix)
+      echo $prefix
+      ;;
+    --exec-prefix=*)
+      exec_prefix=$optarg
+      exec_prefix_set=yes
+      ;;
+    --exec-prefix)
+      echo $exec_prefix
+      ;;
+    --version)
+      echo @VERSION@
+      ;;
+    --cflags)
+#      if test ${prefix}/include/iax != /usr/include/iax ; then
+        includes=-I${prefix}/include/iax
+        for i in $iax_cflags ; do
+          if test $i = -I${prefix}/include ; then
+            includes=""
+          fi
+        done      
+#      fi
+      echo $includes $iax_cflags
+      ;;
+    --libs)
+      my_iax_libs=
+      libdirs=-L${exec_prefix}/lib
+      for i in $iax_libs ; do
+        if test $i != -L${exec_prefix}/lib ; then
+          if test -z "$my_iax_libs" ; then
+            my_iax_libs="$i"
+          else
+            my_iax_libs="$my_iax_libs $i"
+          fi
+        fi
+      done
+      echo $libdirs $my_iax_libs 
+      ;;
+    *)
+      echo "${usage}" 1>&2
+      exit 1
+      ;;
+  esac
+  shift
+done
diff --git a/utils/iaxclient/lib/libiax2/iax.spec.in b/utils/iaxclient/lib/libiax2/iax.spec.in
new file mode 100644 (file)
index 0000000..1fc057d
--- /dev/null
@@ -0,0 +1,91 @@
+%define name   @PACKAGE@
+%define version        @VERSION@
+%define release        1
+%define prefix /usr
+
+Summary: IAX (Inter Asterisk eXchange) Library
+Name: %{name}
+Version: %{version}
+Release: %{release}
+Copyright: LGPL
+Group: Development/Libraries
+Source: %{name}-%{version}.tar.gz
+URL: http://www.linux-support.net/
+Distribution: RedHat Linux
+Vendor: Linux Support Services
+Packager: Rob Flynn <rob@linux-support.net>
+BuildRoot: /var/tmp/%{name}-%{version}-root
+
+%description
+Inter Asterisk eXchange, lovingly called IAX (pronounced: eeks), is the protocol used by the Asterisk PBX
+system for inter-asterisk-communication.  Other applications may use libiax to communicate with each other
+and other asterisk servers.  IAX is a high performance, feature rich protocol unrelated
+to SIP or H.323.  Its single-socket design allows it to interoperate with NAT and PAT
+masquerade firewalls.  It supports internationalization, remote dialplans, 
+and voice, HTML, image, DTMF, and video content.  For more information see
+http://www.gnophone.com.
+
+%package devel
+Summary: IAX (Inter Asterisk eXchange) Development Package
+Group: Development/Libraries
+Requires: iax
+
+%description devel
+Inter Asterisk eXchange, lovingly called IAX (pronounced: eeks), is the protocol used by the Asterisk PBX
+system for inter-asterisk-communication.  Other applications may use libiax to communicate with each other
+and other asterisk servers.  IAX is a high performance, feature rich protocol unrelated
+to SIP or H.323.  Its single-socket design allows it to interoperate with NAT and PAT
+masquerade firewalls.  It supports internationalization, remote dialplans, 
+and voice, HTML, image, DTMF, and video content.  For more information see
+http://www.gnophone.com.
+
+This package contains all of the development files that you will need in order to compile IAX applications.
+
+%prep
+
+%setup
+
+%build
+CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%{prefix} --enable-autoupdate
+make
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make prefix=$RPM_BUILD_ROOT%{prefix} install-strip
+
+%files
+%defattr(-,root,root)
+%doc NEWS COPYING AUTHORS README
+%{prefix}/lib
+
+%files devel
+%defattr(-,root,root)
+%{prefix}/include/iax
+%{prefix}/bin/*
+
+%clean
+rm -r $RPM_BUILD_ROOT
+
+%changelog
+* Tue Nov 13 2001 Rob Flynn <rob@linux-support.net> (0.2.2 release)
+- HTML Unlink requests
+- HTML Reject link requests
+- Text frames
+
+* Sat Oct 20 2001 Rob Flynn <rob@linux-support.net> (0.2.1 release)
+- More space for challenge in IAX
+- Fixed strncpy security bug
+- Accept larger packets
+- Handle out of order packets better
+- Implemented send_url
+- Added an iax-config script :-)
+
+* Wed Oct 10 2001 Rob Flynn <rob@linux-support.net> (0.2.0 release)
+- Initial public release
+
+%post
+
+%preun
+
+%postun
+
diff --git a/utils/iaxclient/lib/libiax2/install-sh b/utils/iaxclient/lib/libiax2/install-sh
new file mode 100755 (executable)
index 0000000..4d4a951
--- /dev/null
@@ -0,0 +1,323 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2005-05-14.22
+
+# 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}"
+
+chmodcmd="$chmodprog 0755"
+chowncmd=
+chgrpcmd=
+stripcmd=
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=
+dst=
+dir_arg=
+dstarg=
+no_target_directory=
+
+usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+-c         (ignored)
+-d         create directories instead of installing files.
+-g GROUP   $chgrpprog installed files to GROUP.
+-m MODE    $chmodprog installed files to MODE.
+-o USER    $chownprog installed files to USER.
+-s         $stripprog installed files.
+-t DIRECTORY  install into DIRECTORY.
+-T         report an error if DSTFILE is a directory.
+--help     display this help and exit.
+--version  display version info and exit.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+"
+
+while test -n "$1"; do
+  case $1 in
+    -c) shift
+        continue;;
+
+    -d) dir_arg=true
+        shift
+        continue;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+        shift
+        shift
+        continue;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) chmodcmd="$chmodprog $2"
+        shift
+        shift
+        continue;;
+
+    -o) chowncmd="$chownprog $2"
+        shift
+        shift
+        continue;;
+
+    -s) stripcmd=$stripprog
+        shift
+        continue;;
+
+    -t) dstarg=$2
+       shift
+       shift
+       continue;;
+
+    -T) no_target_directory=true
+       shift
+       continue;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    *)  # When -d is used, all remaining arguments are directories to create.
+       # When -t is used, the destination is already specified.
+       test -n "$dir_arg$dstarg" && break
+        # Otherwise, the last argument is the destination.  Remove it from $@.
+       for arg
+       do
+          if test -n "$dstarg"; then
+           # $@ is not empty: it contains at least $arg.
+           set fnord "$@" "$dstarg"
+           shift # fnord
+         fi
+         shift # arg
+         dstarg=$arg
+       done
+       break;;
+  esac
+done
+
+if test -z "$1"; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call `install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+for src
+do
+  # Protect names starting with `-'.
+  case $src in
+    -*) src=./$src ;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    src=
+
+    if test -d "$dst"; then
+      mkdircmd=:
+      chmodcmd=
+    else
+      mkdircmd=$mkdirprog
+    fi
+  else
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dstarg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+
+    dst=$dstarg
+    # Protect names starting with `-'.
+    case $dst in
+      -*) dst=./$dst ;;
+    esac
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+       echo "$0: $dstarg: Is a directory" >&2
+       exit 1
+      fi
+      dst=$dst/`basename "$src"`
+    fi
+  fi
+
+  # This sed command emulates the dirname command.
+  dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
+
+  # Make sure that the destination directory exists.
+
+  # Skip lots of stat calls in the usual case.
+  if test ! -d "$dstdir"; then
+    defaultIFS='
+        '
+    IFS="${IFS-$defaultIFS}"
+
+    oIFS=$IFS
+    # Some sh's can't handle IFS=/ for some reason.
+    IFS='%'
+    set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+    shift
+    IFS=$oIFS
+
+    pathcomp=
+
+    while test $# -ne 0 ; do
+      pathcomp=$pathcomp$1
+      shift
+      if test ! -d "$pathcomp"; then
+        $mkdirprog "$pathcomp"
+       # mkdir can fail with a `File exist' error in case several
+       # install-sh are creating the directory concurrently.  This
+       # is OK.
+       test -d "$pathcomp" || exit
+      fi
+      pathcomp=$pathcomp/
+    done
+  fi
+
+  if test -n "$dir_arg"; then
+    $doit $mkdircmd "$dst" \
+      && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
+      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
+      && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
+      && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
+
+  else
+    dstfile=`basename "$dst"`
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+    trap '(exit $?); exit' 1 2 13 15
+
+    # Copy the file name to the temp name.
+    $doit $cpprog "$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 $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
+      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
+      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
+      && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
+
+    # Now rename the file to the real destination.
+    { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
+      || {
+          # The rename failed, perhaps because mv can't rename something else
+          # to itself, or perhaps because mv is so ancient that it does not
+          # support -f.
+
+          # 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 test -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 1
+              }
+            else
+              :
+            fi
+          } &&
+
+          # Now rename the file to the real destination.
+          $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+        }
+    }
+  fi || { (exit 1); exit 1; }
+done
+
+# The final little trick to "correctly" pass the exit status to the exit trap.
+{
+  (exit 0); exit 0
+}
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/utils/iaxclient/lib/libiax2/libiax2.vcproj b/utils/iaxclient/lib/libiax2/libiax2.vcproj
new file mode 100644 (file)
index 0000000..1c14f6d
--- /dev/null
@@ -0,0 +1,242 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="8.00"
+       Name="libiax2"
+       ProjectGUID="{5CC054B7-6DAA-46BF-9A08-3B33B83E8D3E}"
+       RootNamespace="libiax2"
+       Keyword="Win32Proj"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="4"
+                       CharacterSet="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               InlineFunctionExpansion="0"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LIBIAX;DEBUG_SUPPORT;_CRT_SECURE_NO_DEPRECATE;NEWJB"
+                               MinimalRebuild="true"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="3"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               Detect64BitPortabilityProblems="true"
+                               DebugInformationFormat="4"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLibrarianTool"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="4"
+                       CharacterSet="1"
+                       WholeProgramOptimization="1"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LIBIAX"
+                               RuntimeLibrary="2"
+                               UsePrecompiledHeader="0"
+                               WarningLevel="3"
+                               Detect64BitPortabilityProblems="true"
+                               DebugInformationFormat="3"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLibrarianTool"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+                       >
+                       <File
+                               RelativePath=".\src\iax.c"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\src\iax2-parser.c"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\src\jitterbuf.c"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\src\md5.c"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+                       >
+                       <File
+                               RelativePath=".\src\answer.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\src\busy.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\src\dialtone.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\src\frame.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\src\iax-client.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\src\iax.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\src\iax2-parser.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\src\iax2.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\src\jitterbuf.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\src\md5.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\src\miniphone.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\src\options.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\src\ring10.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\src\ringtone.h"
+                               >
+                       </File>
+                       <File
+                               RelativePath=".\src\winpoop.h"
+                               >
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Resource Files"
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+                       >
+               </Filter>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
diff --git a/utils/iaxclient/lib/libiax2/missing b/utils/iaxclient/lib/libiax2/missing
new file mode 100755 (executable)
index 0000000..894e786
--- /dev/null
@@ -0,0 +1,360 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2005-06-08.21
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
+#   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., 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.
+
+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
+
+msg="missing on your system"
+
+case "$1" in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  # Exit code 63 means version mismatch.  This often happens
+  # when the user try to use an ancient version of a tool on
+  # a file that requires a minimum version.  In this case we
+  # we should proceed has if the program had been absent, or
+  # if --run hadn't been passed.
+  if test $? = 63; then
+    run=:
+    msg="probably too old"
+  fi
+  ;;
+
+  -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]
+
+Send bug reports to <bug-automake@gnu.org>."
+    exit $?
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing $scriptversion (GNU Automake)"
+    exit $?
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+esac
+
+# Now exit if we have it, but it failed.  Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program).
+case "$1" in
+  lex|yacc)
+    # Not GNU programs, they don't have --version.
+    ;;
+
+  tar)
+    if test -n "$run"; then
+       echo 1>&2 "ERROR: \`tar' requires --run"
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       exit 1
+    fi
+    ;;
+
+  *)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       # Could not run --version or --help.  This is probably someone
+       # running `$TOOL --version' or `$TOOL --help' to check whether
+       # $TOOL exists and not knowing $TOOL uses missing.
+       exit 1
+    fi
+    ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+  aclocal*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  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)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  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)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  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*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  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)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+         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' $msg.  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 $msg.  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)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  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)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  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."
+    # The file to touch is that specified with -o ...
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+      # ... or it is the one specified with @setfilename ...
+      infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
+      # ... or it is derived from the source name (dir/f.texi becomes f.info)
+      test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+    fi
+    # If the file does not exist, the user really needs makeinfo;
+    # let's fail without touching anything.
+    test -f $file || exit 1
+    touch $file
+    ;;
+
+  tar)
+    shift
+
+    # 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 is $msg.
+         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
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/utils/iaxclient/lib/libiax2/mkinstalldirs b/utils/iaxclient/lib/libiax2/mkinstalldirs
new file mode 100755 (executable)
index 0000000..259dbfc
--- /dev/null
@@ -0,0 +1,158 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+
+scriptversion=2005-06-29.22
+
+# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain.
+#
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+errstatus=0
+dirmode=
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
+
+Create each directory DIR (with mode MODE, if specified), including all
+leading file name components.
+
+Report bugs to <bug-automake@gnu.org>."
+
+# process command line arguments
+while test $# -gt 0 ; do
+  case $1 in
+    -h | --help | --h*)         # -h for help
+      echo "$usage"
+      exit $?
+      ;;
+    -m)                         # -m PERM arg
+      shift
+      test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+      dirmode=$1
+      shift
+      ;;
+    --version)
+      echo "$0 $scriptversion"
+      exit $?
+      ;;
+    --)                         # 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
+
+# Solaris 8's mkdir -p isn't thread-safe.  If you mkdir -p a/b and
+# mkdir -p a/c at the same time, both will detect that a is missing,
+# one will create a, then the other will try to create a and die with
+# a "File exists" error.  This is a problem when calling mkinstalldirs
+# from a parallel make.  We use --version in the probe to restrict
+# ourselves to GNU mkdir, which is thread-safe.
+case $dirmode in
+  '')
+    if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+      echo "mkdir -p -- $*"
+      exec mkdir -p -- "$@"
+    else
+      # On NextStep and OpenStep, the `mkdir' command does not
+      # recognize any option.  It will interpret all options as
+      # directories to create, and then abort because `.' already
+      # exists.
+      test -d ./-p && rmdir ./-p
+      test -d ./--version && rmdir ./--version
+    fi
+    ;;
+  *)
+    if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
+       test ! -d ./--version; then
+      echo "mkdir -m $dirmode -p -- $*"
+      exec mkdir -m "$dirmode" -p -- "$@"
+    else
+      # Clean up after NextStep and OpenStep mkdir.
+      for d in ./-m ./-p ./--version "./$dirmode";
+      do
+        test -d $d && rmdir $d
+      done
+    fi
+    ;;
+esac
+
+for file
+do
+  case $file in
+    /*) pathcomp=/ ;;
+    *)  pathcomp= ;;
+  esac
+  oIFS=$IFS
+  IFS=/
+  set fnord $file
+  shift
+  IFS=$oIFS
+
+  for d
+  do
+    test "x$d" = x && continue
+
+    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
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/utils/iaxclient/lib/libiax2/src/Makefile.am b/utils/iaxclient/lib/libiax2/src/Makefile.am
new file mode 100644 (file)
index 0000000..ac02c62
--- /dev/null
@@ -0,0 +1,22 @@
+AM_CFLAGS = -Wall -O2
+AM_CFLAGS += -g -Wall -Wstrict-prototypes -I .
+AM_CFLAGS += -DDEBUG_SUPPORT -DLIBIAX
+AM_CFLAGS += -fsigned-char
+# -DDEBUG_DEFAULT 
+AM_CFLAGS += $(UCFLAGS)
+
+
+pkgdir = $(libdir)
+pkg_LTLIBRARIES=libiax.la
+libiax_la_SOURCES = iax2-parser.c iax.c md5.c jitterbuf.c
+EXTRA_DIST = md5.h frame.h iax-client.h iax2.h iax2-parser.h jitterbuf.h
+
+install-data-local:
+       mkdir -p $(includedir)/iax
+       install -m 644 md5.h $(includedir)/iax
+       install -m 644 frame.h $(includedir)/iax
+       install -m 644 iax.h $(includedir)/iax
+       install -m 644 iax2.h $(includedir)/iax
+       install -m 644 iax2-parser.h $(includedir)/iax
+       install -m 644 iax-client.h $(includedir)/iax
+
diff --git a/utils/iaxclient/lib/libiax2/src/answer.h b/utils/iaxclient/lib/libiax2/src/answer.h
new file mode 100644 (file)
index 0000000..2a03420
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+  * Signed 16-bit audio data
+  *
+  * Source: answer.raw
+  *
+  * Copyright (C) 1999, Mark Spencer and Linux Support Services
+  *
+  * Distributed under the terms of the GNU General Public License
+  *
+  */
+
+static signed short answer[] = {
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 0x19b7, 0x0245, 0xeee5, 0xb875, 0xd9a4, 0x6018, 0x660a, 0xc3c6, 
+0x8741, 0xff55, 0x4c2e, 0x2146, 0xfed2, 0xf079, 0xcbd4, 0xe561, 0x3c41, 0x3166, 
+0xd425, 0xdc59, 0x2748, 0x087d, 0xc72b, 0xfe3a, 0x4681, 0x14c6, 0xcf45, 0xdd38, 
+0xf8dd, 0x0a39, 0x3a5a, 0x32b9, 0xbfec, 0x957f, 0x15a3, 0x70f4, 0x1d95, 0xbfc4, 
+0xd367, 0xfda0, 0x0dc0, 0x29eb, 0x1fc2, 0xd684, 0xcab1, 0x19c7, 0x29ef, 0xe679, 
+0xe9d0, 0x2b82, 0x151a, 0xca9f, 0xdb68, 0x1f4a, 0x271c, 0x0e2a, 0xfb32, 0xd1b2, 
+0xc8ff, 0x2382, 0x6380, 0x0a52, 0xa118, 0xccbf, 0x2ddc, 0x33fd, 0x0964, 0xf2a4, 
+0xdd81, 0xe092, 0x1a00, 0x325c, 0xf5e3, 0xd6a1, 0x0b6c, 0x1c75, 0xe4f8, 0xe07c, 
+0x2082, 0x2b3e, 0xf445, 0xdaa9, 0xea13, 0xff3c, 0x245c, 0x35c1, 0xf308, 0xab53, 
+0xdf59, 0x4698, 0x3f3b, 0xe7f7, 0xca84, 0xed4d, 0x0c3f, 0x1e94, 0x1c2d, 0xf06f, 
+0xd4df, 0xff34, 0x23d8, 0x001e, 0xe3f1, 0x0b15, 0x2113, 0xf3fd, 0xd768, 0xf9a0, 
+0x1d31, 0x1c6e, 0x0797, 0xe3a0, 0xce6c, 0xfd7b, 0x422a, 0x2c4c, 0xd364, 0xbf42, 
+0x0278, 0x303e, 0x1c51, 0xf737, 0xe25a, 0xe75f, 0x0a8f, 0x22ab, 0x05f4, 0xe3f9, 
+0xf8c4, 0x1705, 0x0162, 0xe49f, 0xfb8b, 0x1e2b, 0x13ac, 0xf044, 0xe07b, 0xf01a, 
+0x1567, 0x2cbf, 0x0b75, 0xd01b, 0xd206, 0x1563, 0x38d7, 0x0f2e, 0xdb32, 0xdc30, 
+0x023b, 0x1e44, 0x16eb, 0xf5f7, 0xe425, 0xfa33, 0x14d5, 0x0968, 0xeff2, 0xf762, 
+0x1137, 0x0e59, 0xf13a, 0xe651, 0xff41, 0x1d60, 0x18fd, 0xf1e6, 0xd75f, 0xf097, 
+0x20ec, 0x27fa, 0xfba4, 0xd5b8, 0xe68e, 0x1657, 0x2518, 0x04f6, 0xe5a3, 0xe976, 
+0x0578, 0x18fa, 0x0a92, 0xec0a, 0xef2a, 0x111f, 0x12f4, 0xeec3, 0xe95e, 0x0d3a, 
+0x18fd, 0xff72, 0xeefc, 0xf114, 0xfaaa, 0x14ee, 0x21db, 0xf56e, 0xcb49, 0xf621, 
+0x3323, 0x1947, 0xe017, 0xe7e9, 0x0819, 0x0707, 0x084c, 0x0f57, 0xf152, 0xdf92, 
+0x104a, 0x28eb, 0xedcc, 0xd4ad, 0x1415, 0x296d, 0xed9a, 0xdf57, 0x0cc2, 0x0d95, 
+0xf7b5, 0x0deb, 0x0b34, 0xd713, 0xea08, 0x38d6, 0x216d, 0xc727, 0xdc32, 0x2cd2, 
+0x1822, 0xe2d5, 0xfeb3, 0x106c, 0xe6e5, 0xf81e, 0x2fe8, 0x01af, 0xc180, 0x037a, 
+0x42d8, 0xf88d, 0xc344, 0x0a4f, 0x2c4e, 0xf19d, 0xebeb, 0x162c, 0xf9e9, 0xde93, 
+0x1b56, 0x2c60, 0xd8aa, 0xce3e, 0x2a41, 0x2eeb, 0xdab1, 0xde32, 0x1c32, 0x0aba, 
+0xeabe, 0x1008, 0x136d, 0xda2f, 0xec3b, 0x31dd, 0x1130, 0xca79, 0xf5b8, 0x3423, 
+0x0274, 0xd27d, 0x035e, 0x1e68, 0xf641, 0xf904, 0x1691, 0xef7d, 0xd57a, 0x1c3b, 
+0x3c23, 0xe881, 0xc274, 0x0af5, 0x2962, 0xfa34, 0xf676, 0x0f71, 0xefcc, 0xe01f, 
+0x19e7, 0x276f, 0xe694, 0xe134, 0x1c3a, 0x0e8b, 0xd8e7, 0xfa81, 0x2f8b, 0x07c5, 
+0xd904, 0xf6fa, 0x0ca5, 0xf9a2, 0x0dc7, 0x2623, 0xec54, 0xbe23, 0x02b6, 0x4296, 
+0x10cd, 0xda61, 0xf11c, 0x0103, 0xf41c, 0x10b4, 0x2a03, 0xf63c, 0xce1a, 0xfdbd, 
+0x1fb4, 0xfc51, 0xf727, 0x1c8a, 0x04ff, 0xcf41, 0xec05, 0x2913, 0x1ce8, 0xf70c, 
+0xf744, 0xede8, 0xdd77, 0x0d99, 0x43f1, 0x119c, 0xc14f, 0xd60e, 0x17cb, 0x1e19, 
+0x0d4e, 0x0c95, 0xeed1, 0xcdf4, 0xf7a5, 0x331f, 0x1cd0, 0xeb17, 0xf082, 0xfb19, 
+0xe899, 0xfdeb, 0x323c, 0x2036, 0xdad3, 0xd134, 0xfd03, 0x1345, 0x1c10, 0x2239, 
+0xf656, 0xbc22, 0xdc3f, 0x3392, 0x3d59, 0xfd77, 0xdb4d, 0xe23f, 0xedbe, 0x0f7e, 
+0x35cc, 0x1947, 0xd5dc, 0xd1bf, 0x035d, 0x16fc, 0x1174, 0x1675, 0x0249, 0xd2d4, 
+0xd851, 0x184d, 0x32fe, 0x0f91, 0xee14, 0xe1e6, 0xdf9b, 0x016b, 0x3668, 0x2b2b, 
+0xe20c, 0xc554, 0xf257, 0x1c05, 0x1fc5, 0x14f0, 0xf891, 0xd41c, 0xdf83, 0x1865, 
+0x2de1, 0x0b16, 0xed58, 0xea0c, 0xea79, 0xfbd9, 0x22af, 0x2732, 0xf62f, 0xd389, 
+0xe7d9, 0x0b39, 0x1cdc, 0x1de3, 0x038a, 0xd809, 0xd5f7, 0x0b55, 0x305e, 0x1910, 
+0xf02e, 0xe089, 0xe7c7, 0x0195, 0x2265, 0x21da, 0xf743, 0xd8f2, 0xe978, 0x09a1, 
+0x190a, 0x17c5, 0x045a, 0xe46d, 0xdd06, 0xffb2, 0x2293, 0x1cfe, 0xfd4d, 0xe4f9, 
+0xe310, 0xfaf1, 0x1d22, 0x2376, 0x0113, 0xde3a, 0xe21b, 0x0204, 0x1ba1, 0x1bd6, 
+0x0333, 0xe563, 0xe104, 0xfd51, 0x1bc1, 0x1ccf, 0x0285, 0xe757, 0xe35e, 0xfaf2, 
+0x185d, 0x1d46, 0x06b7, 0xec13, 0xe108, 0xef6e, 0x121d, 0x2a17, 0x16a6, 0xe32c, 
+0xc9a9, 0xf070, 0x2f48, 0x3788, 0xfa4e, 0xc32a, 0xd9c2, 0x1fa1, 0x36fe, 0x07fa, 
+0xd9e4, 0xe577, 0x0e5e, 0x1755, 0xfb53, 0xed71, 0x0540, 0x19e0, 0x0301, 0xdc97, 
+0xe391, 0x1937, 0x367c, 0x0bc9, 0xca4c, 0xc96b, 0x105d, 0x461f, 0x2416, 0xd481, 
+0xbc97, 0xf8b7, 0x39af, 0x2ec9, 0xecc6, 0xcb50, 0xeee3, 0x1ffe, 0x1e8e, 0xf700, 
+0xe66a, 0xff58, 0x149f, 0x02e5, 0xe792, 0xf2d8, 0x1a4d, 0x225a, 0xf642, 0xce7f, 
+0xe6a6, 0x25e2, 0x38f5, 0x01d0, 0xc50f, 0xd243, 0x19bd, 0x3fc6, 0x14f0, 0xd2d7, 
+0xcdb6, 0x069a, 0x2ffe, 0x1847, 0xe6f8, 0xdf0a, 0x0337, 0x1a90, 0x067a, 0xeb5b, 
+0xf541, 0x143b, 0x14f2, 0xf092, 0xdc02, 0xfb91, 0x28a3, 0x2274, 0xeaa8, 0xc9e7, 
+0xef48, 0x2d01, 0x322e, 0xf6d2, 0xc7cb, 0xe13b, 0x1fda, 0x3217, 0x0458, 0xd690, 
+0xe2bf, 0x11c4, 0x21d5, 0x0291, 0xe5c8, 0xf3a9, 0x12ba, 0x11aa, 0xf22b, 0xe627, 
+0x03ec, 0x219a, 0x1036, 0xe2f2, 0xd93f, 0x059c, 0x2ed6, 0x1b75, 0xe227, 0xce55, 
+0xfb19, 0x2de0, 0x2477, 0xed08, 0xd148, 0xf307, 0x21d4, 0x2002, 0xf543, 0xdeac, 
+0xf7f9, 0x18a9, 0x11d6, 0xf0ef, 0xe8e4, 0x05ea, 0x1ba5, 0x0727, 0xe448, 0xe748, 
+0x100e, 0x265e, 0x07fc, 0xdbae, 0xde78, 0x0efa, 0x2ce0, 0x0f94, 0xddf1, 0xd9ea, 
+0x0797, 0x28f6, 0x12eb, 0xe60c, 0xdf46, 0x0469, 0x1fbb, 0x0ced, 0xe9f6, 0xe95f, 
+0x09fe, 0x1ab9, 0x02cb, 0xe5a4, 0xef2a, 0x1327, 0x1d7b, 0xfd07, 0xde3d, 0xed9c, 
+0x17e5, 0x22e7, 0xfe3a, 0xdb38, 0xe9b9, 0x161a, 0x2416, 0x0175, 0xde3d, 0xe9de, 
+0x1294, 0x1fc9, 0x00ea, 0xe2a7, 0xeee2, 0x1298, 0x1a7d, 0xfc1d, 0xe3bb, 0xf47a, 
+0x1642, 0x185e, 0xf727, 0xe1af, 0xf709, 0x19c3, 0x18e7, 0xf50d, 0xe010, 0xf75b, 
+0x1a9c, 0x18d8, 0xf4c5, 0xe0c9, 0xf865, 0x1a1c, 0x16d5, 0xf3a6, 0xe257, 0xfaf2, 
+0x1a44, 0x14d5, 0xf34f, 0xe4b6, 0xfc77, 0x17d5, 0x0ff8, 0xf133, 0xe8b7, 0x0344, 
+0x1a37, 0x0ad5, 0xe95e, 0xe61a, 0x08a5, 0x227e, 0x0e33, 0xe4a7, 0xdd70, 0x03b0, 
+0x25f4, 0x17b2, 0xec0a, 0xdb4e, 0xf898, 0x1ba3, 0x18f6, 0xf973, 0xe87f, 0xf77a, 
+0x0b93, 0x096c, 0xfb0e, 0xfb03, 0x0896, 0x0940, 0xf51d, 0xe904, 0xfdc7, 0x1dda, 
+0x1bf9, 0xf29b, 0xd37f, 0xea1b, 0x1f37, 0x3175, 0x07eb, 0xd3f7, 0xd46b, 0x077d, 
+0x2eeb, 0x1e67, 0xeeae, 0xd8c7, 0xef85, 0x1119, 0x18d3, 0x088e, 0xf953, 0xf5ad, 
+0xf556, 0xf63d, 0x0234, 0x167a, 0x19a1, 0xfbf9, 0xd873, 0xdd4b, 0x0f06, 0x3748, 
+0x21e6, 0xe181, 0xc032, 0xe79a, 0x2bec, 0x3e76, 0x0b1b, 0xce41, 0xcb23, 0xff96, 
+0x2d79, 0x26d1, 0xfcc7, 0xdf8a, 0xe525, 0xfd83, 0x10f1, 0x16d7, 0x0f50, 0xfaea, 
+0xe3f1, 0xe20f, 0x0158, 0x27d9, 0x2866, 0xf96f, 0xcb34, 0xd563, 0x11d6, 0x3d25, 
+0x2424, 0xe254, 0xc2c9, 0xe7cd, 0x248d, 0x34f5, 0x0c42, 0xdcd0, 0xd827, 0xfa65, 
+0x19eb, 0x1b50, 0x0721, 0xf396, 0xeb9c, 0xefde, 0x0016, 0x1594, 0x1cc1, 0x0658, 
+0xe22b, 0xd852, 0xfb3e, 0x2923, 0x2c78, 0xfc87, 0xcdb5, 0xd69c, 0x0e3c, 0x3527, 
+0x201f, 0xe993, 0xcf9e, 0xeb21, 0x183f, 0x25ea, 0x0c93, 0xed4d, 0xe5f9, 0xf548, 
+0x07fb, 0x117c, 0x0ff2, 0x0398, 0xf08c, 0xe628, 0xf489, 0x143b, 0x2419, 0x0ccf, 
+0xe2cc, 0xd5a6, 0xf861, 0x2615, 0x2a1b, 0xfeb4, 0xd543, 0xdc53, 0x09b4, 0x2901, 
+0x19ff, 0xf24a, 0xde86, 0xeec4, 0x0b7b, 0x1733, 0x0d0a, 0xfc24, 0xf1bb, 0xf110, 
+0xfa03, 0x0a0f, 0x15d4, 0x0e21, 0xf435, 0xe17e, 0xee90, 0x1225, 0x2527, 0x0efa, 
+0xe61f, 0xd916, 0xf7b8, 0x1f50, 0x2326, 0x0099, 0xe01e, 0xe473, 0x0491, 0x1b37, 
+0x1360, 0xfb17, 0xecd9, 0xf20d, 0x0051, 0x0aec, 0x0d4a, 0x073d, 0xfa5a, 0xeeb8, 
+0xf165, 0x0516, 0x17dc, 0x12da, 0xf71b, 0xe213, 0xed85, 0x0eef, 0x20c8, 0x0e09, 
+0xebcc, 0xe0d4, 0xf848, 0x1637, 0x19d6, 0x026b, 0xec09, 0xed00, 0xff9b, 0x0e5a, 
+0x0d6b, 0x026c, 0xf865, 0xf4da, 0xf888, 0x025a, 0x0cbb, 0x0d53, 0xff96, 0xeefa, 
+0xee80, 0x021c, 0x15d6, 0x126a, 0xf9c1, 0xe724, 0xf017, 0x0aa1, 0x18b6, 0x0b4e, 
+0xf2d7, 0xea91, 0xf957, 0x0cac, 0x1061, 0x03f4, 0xf6ad, 0xf476, 0xfbdf, 0x0489, 
+0x08b1, 0x06df, 0xffcf, 0xf766, 0xf537, 0xfddf, 0x0ad4, 0x0e15, 0x01da, 0xf205, 
+0xf0a0, 0x0082, 0x1066, 0x0e41, 0xfc71, 0xef1b, 0xf4ad, 0x05cd, 0x0f32, 0x07ed, 
+0xf9c8, 0xf401, 0xfa93, 0x04af, 0x088c, 0x04a7, 0xfe15, 0xf9f1, 0xfa64, 0xff1e, 
+0x0539, 0x078c, 0x02af, 0xfa1a, 0xf69d, 0xfd09, 0x075b, 0x0a3d, 0x01f2, 0xf761, 
+0xf642, 0xffa7, 0x08f3, 0x0830, 0xff05, 0xf7db, 0xf9bc, 0x0174, 0x068b, 0x04b2, 
+0xfeff, 0xfb39, 0xfc1a, 000000, 0x0371, 0x03d7, 0x00fe, 0xfd37, 0xfbe0, 0xfe78, 
+0x02af, 0x044a, 0x0180, 0xfd43, 0xfc00, 0xfed1, 0x02aa, 0x0346, 0x00dd, 0xfde0, 
+0xfbfe, 0x0114, 0x0987, 0x04bc, 0xf49d, 0xf23a, 0x06ab, 0x162e, 0x0544, 0xe76b, 
+0xea25, 0x1015, 0x2474, 0x0431, 0xd7d3, 0xe1ec, 0x1923, 0x2df5, 0x01cd, 0xd386, 
+0xe3d9, 0x1b9d, 0x2c62, 0xfeb8, 0xd31a, 0xe6ba, 0x1dbd, 0x2abb, 0xfbab, 0xd2ed, 
+0xe9ab, 0x1fa7, 0x28ef, 0xf8b3, 0xd2f5, 0xeca5, 0x2160, 0x26fd, 0xf5d7, 0xd334, 
+0xefa1, 0x22e5, 0x24ea, 0xf31b, 0xd3a9, 0xf29f, 0x2435, 0x22b6, 0xf07e, 0xd44e, 
+0xf59b, 0x2551, 0x2067, 0xee08, 0xd527, 0xf88e, 0x2639, 0x1e00, 0xebb6, 0xd62d, 
+0xfb77, 0x26eb, 0x1b85, 0xe98b, 0xd75f, 0xfe51, 0x276b, 0x18f9, 0xe78e, 0xd8b9, 
+0x011a, 0x27b6, 0x1660, 0xe5bb, 0xda3a, 0x03cc, 0x27cf, 0x13bd, 0xe415, 0xdbdf, 
+0x066a, 0x27b7, 0x1117, 0xe29e, 0xdda5, 0x08ec, 0x276e, 0x0e6d, 0xe154, 0xdf89, 
+0x0b52, 0x26f6, 0x0bc7, 0xe039, 0xe185, 0x0d96, 0x2653, 0x0924, 0xdf4e, 0xe399, 
+0x0fb9, 0x2584, 0x068b, 0xde93, 0xe5c0, 0x11b8, 0x248e, 0x03fd, 0xde08, 0xe7f8, 
+0x1390, 0x2372, 0x0180, 0xddaa, 0xea3c, 0x1544, 0x2231, 0xff12, 0xdd7a, 0xec89, 
+0x16cf, 0x20d0, 0xfcb9, 0xdd77, 0xeedb, 0x1831, 0x1f52, 0xfa77, 0xdd9f, 0xf132, 
+0x1969, 0x1db7, 0xf850, 0xddf1, 0xf385, 0x1a75, 0x1c06, 0xf645, 0xde6b, 0xf5d7, 
+0x1b5b, 0x1a3f, 0xf457, 0xdf0d, 0xf820, 0x1c13, 0x1867, 0xf288, 0xdfd2, 0xfa5f, 
+0x1ca1, 0x167f, 0xf0db, 0xe0ba, 0xfc92, 0x1d06, 0x148b, 0xef50, 0xe1c1, 0xfeb5, 
+0x1d43, 0x1290, 0xede9, 0xe2e6, 0x00c6, 0x1d58, 0x108e, 0xeca7, 0xe426, 0x02c4, 
+0x1d45, 0x0e8a, 0xeb8a, 0xe57f, 0x04a9, 0x1d0e, 0x0c87, 0xea92, 0xe6ec, 0x0677, 
+0x1cb2, 0x0a87, 0xe9be, 0xe86e, 0x082a, 0x1c34, 0x088b, 0xe912, 0xe9fe, 0x09c1, 
+0x1b95, 0x069c, 0xe88c, 0xeb9c, 0x0b3a, 0x1ad9, 0x04b6, 0xe82a, 0xed43, 0x0c96, 
+0x1a00, 0x02df, 0xe7eb, 0xeef3, 0x0dd0, 0x190d, 0x0116, 0xe7d0, 0xf0a8, 0x0eec, 
+0x1804, 0xff61, 0xe7d8, 0xf25d, 0x0fe6, 0x16e3, 0xfdc0, 0xe800, 0xf412, 0x10bf, 
+0x15b1, 0xfc36, 0xe848, 0xf5c5, 0x1176, 0x146e, 0xfac2, 0xe8ad, 0xf771, 0x120d, 
+0x1320, 0xf969, 0xe92e, 0xf913, 0x1282, 0x11c4, 0xf828, 0xe9cb, 0xfaac, 0x12d8, 
+0x1062, 0xf703, 0xea7e, 0xfc38, 0x130e, 0x0efa, 0xf5fb, 0xeb49, 0xfdb5, 0x1325, 
+0x0d8e, 0xf50e, 0xec26, 0xff20, 0x131e, 0x0c21, 0xf43f, 0xed15, 0x007a, 0x12fa, 
+0x0ab6, 0xf38d, 0xee15, 0x01be, 0x12bd, 0x094f, 0xf2f9, 0xef22, 0x02ef, 0x1265, 
+0x07f0, 0xf283, 0xf037, 0x0408, 0x11f6, 0x0699, 0xf226, 0xf156, 0x050a, 0x1170, 
+0x054b, 0xf1e8, 0xf27a, 0x05f4, 0x10d8, 0x040c, 0xf1c5, 0xf3a3, 0x06c2, 0x102c, 
+0x02da, 0xf1bc, 0xf4cc, 0x0779, 0x0f71, 0x01b7, 0xf1cc, 0xf5f5, 0x0815, 0x0ea7, 
+0x00a8, 0xf1f4, 0xf719, 0x0899, 0x0dd2, 0xffab, 0xf233, 0xf839, 0x0902, 0x0cf4, 
+0xfec0, 0xf288, 0xf950, 0x0952, 0x0c0e, 0xfdec, 0xf2ee, 0xfa5d, 0x0989, 0x0b23, 
+0xfd2d, 0xf368, 0xfb62, 0x09a7, 0x0a35, 0xfc85, 0xf3f1, 0xfc58, 0x09af, 0x0946, 
+0xfbf2, 0xf488, 0xfd3f, 0x09a1, 0x0859, 0xfb77, 0xf52c, 0xfe17, 0x097d, 0x076f, 
+0xfb14, 0xf5d8, 0xfede, 0x0945, 0x068a, 0xfac6, 0xf68d, 0xff93, 0x08fb, 0x05ad, 
+0xfa8e, 0xf747, 0x0034, 0x08a1, 0x04da, 0xfa6f, 0xf805, 0x00c2, 0x0836, 0x0410, 
+0xfa63, 0xf8c6, 0x013c, 0x07bf, 0x0354, 0xfa6c, 0xf985, 0x01a1, 0x073b, 0x02a4, 
+0xfa8a, 0xfa43, 0x01f1, 0x06af, 0x0204, 0xfab9, 0xfafc, 0x022c, 0x0619, 0x0175, 
+0xfafa, 0xfbae, 0x0252, 0x057f, 0x00f6, 0xfb4b, 0xfc5a, 0x0263, 0x04e0, 0x008b, 
+0xfbaa, 0xfcfa, 0x0262, 0x0440, 0x0032, 0xfc16, 0xfd90, 0x024b, 0x03a0, 0xffec, 
+0xfc8c, 0xfe19, 0x0225, 0x0301, 0xffb9, 0xfd0c, 0xfe93, 0x01ea, 0x0267, 0xff9c, 
+0xfd95, 0xfefe, 0x01a0, 0x01d3, 0xff90, 0xfe22, 0xff5a, 0x0147, 0x0145, 0xff99, 
+0xfeb3, 0xffa1, 0x00e0, 0x00c3, 0xffb6, 0xff46, 0xffd9, 0x006d, 0x004b, 0xffe5, 
+0xffda, 0xfffc, 000000, 0xfffe, 000000, 0xffff, 000000, 0xffff, 0xffff, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000 };
diff --git a/utils/iaxclient/lib/libiax2/src/busy.h b/utils/iaxclient/lib/libiax2/src/busy.h
new file mode 100644 (file)
index 0000000..2c642fa
--- /dev/null
@@ -0,0 +1,55 @@
+/* busy.h: Generated from frequencies 480 and 620 
+   by gensound.  400 samples  */
+static short busy[400] = {
+           0, 13697, 24766, 31109, 31585, 26222, 16198,  3569, 
+       -9162, -19575, -25812, -26935, -23069, -15322, -5493,  4339, 
+       12277, 16985, 17934, 15440, 10519,  4585,  -908, -4827, 
+       -6592, -6269, -4489, -2220,  -467,    30,  -983, -3203, 
+       -5839, -7844, -8215, -6301, -2035,  3975, 10543, 16141, 
+       19260, 18787, 14322,  6338, -3845, -14296, -22858, -27611, 
+       -27309, -21691, -11585,  1213, 14285, 25068, 31388, 31915, 
+       26457, 16010,  2568, -11282, -22885, -30054, -31509, -27120, 
+       -17908, -5805,  6760, 17379, 24147, 26028, 23020, 16094, 
+        6931, -2478, -10279, -15136, -16474, -14538, -10253, -4949, 
+           0,  3515,  5052,  4688,  3045,  1069,  -268,  -272, 
+        1269,  3996,  7067,  9381,  9889,  7910,  3365, -3123, 
+       -10320, -16622, -20424, -20510, -16384, -8448,  2006, 13026, 
+       22383, 28040, 28613, 23696, 13996,  1232, -12193, -23670, 
+       -30918, -32459, -27935, -18190, -5103,  8795, 20838, 28764, 
+       31164, 27753, 19395,  7893, -4412, -15136, -22342, -24909, 
+       -22717, -16609, -8143,   780,  8361, 13272, 14909, 13455, 
+        9758,  5067,   678, -2387, -3624, -3133, -1538,   224, 
+        1209,   751, -1315, -4580, -8145, -10848, -11585, -9628, 
+       -4878,  2038,  9844, 16867, 21403, 22124, 18429, 10638, 
+           0, -11524, -21643, -28211, -29702, -25561, -16364, -3737, 
+        9946, 22044, 30180, 32733, 29182, 20210,  7573, -6269, 
+       -18655, -27259, -30558, -28117, -20645, -9807,  2148, 12878, 
+       20426, 23599, 22173, 16865,  9117,   731, -6552, -11426, 
+       -13269, -12216, -9050, -4941, -1118,  1460,  2335,  1635, 
+           0, -1635, -2335, -1460,  1118,  4941,  9050, 12216, 
+       13269, 11426,  6552,  -731, -9117, -16865, -22173, -23599, 
+       -20426, -12878, -2148,  9807, 20645, 28117, 30558, 27259, 
+       18655,  6269, -7573, -20210, -29182, -32733, -30180, -22044, 
+       -9946,  3737, 16364, 25561, 29702, 28211, 21643, 11524, 
+           0, -10638, -18429, -22124, -21403, -16867, -9844, -2038, 
+        4878,  9628, 11585, 10848,  8145,  4580,  1315,  -751, 
+       -1209,  -224,  1538,  3133,  3624,  2387,  -678, -5067, 
+       -9758, -13455, -14909, -13272, -8361,  -780,  8143, 16609, 
+       22717, 24909, 22342, 15136,  4412, -7893, -19395, -27753, 
+       -31164, -28764, -20838, -8795,  5103, 18190, 27935, 32459, 
+       30918, 23670, 12193, -1232, -13996, -23696, -28613, -28040, 
+       -22383, -13026, -2006,  8448, 16384, 20510, 20424, 16622, 
+       10320,  3123, -3365, -7910, -9889, -9381, -7067, -3996, 
+       -1269,   272,   268, -1069, -3045, -4688, -5052, -3515, 
+           0,  4949, 10253, 14538, 16474, 15136, 10279,  2478, 
+       -6931, -16094, -23020, -26028, -24147, -17379, -6760,  5805, 
+       17908, 27120, 31509, 30054, 22885, 11282, -2568, -16010, 
+       -26457, -31915, -31388, -25068, -14285, -1213, 11585, 21691, 
+       27309, 27611, 22858, 14296,  3845, -6338, -14322, -18787, 
+       -19260, -16141, -10543, -3975,  2035,  6301,  8215,  7844, 
+        5839,  3203,   983,   -30,   467,  2220,  4489,  6269, 
+        6592,  4827,   908, -4585, -10519, -15440, -17934, -16985, 
+       -12277, -4339,  5493, 15322, 23069, 26935, 25812, 19575, 
+        9162, -3569, -16198, -26222, -31585, -31109, -24766, -13697, 
+       
+};
diff --git a/utils/iaxclient/lib/libiax2/src/dialtone.h b/utils/iaxclient/lib/libiax2/src/dialtone.h
new file mode 100644 (file)
index 0000000..09b8814
--- /dev/null
@@ -0,0 +1,105 @@
+/* dialtone.h: Generated from frequencies 350 and 440 
+   by gensound.  800 samples  */
+static short dialtone[800] = {
+           0,  9997, 19004, 26133, 30692, 32251, 30690, 26206, 
+       19286, 10657,  1206, -8116, -16396, -22848, -26895, -28221, 
+       -26797, -22878, -16960, -9723, -1954,  5545, 12044, 16954, 
+       19887, 20687, 19434, 16420, 12107,  7061,  1881, -2866, 
+       -6721, -9365, -10657, -10634, -9491, -7547, -5190, -2822, 
+        -801,   607,  1263,  1168,   454,  -633, -1784, -2669, 
+       -2993, -2548, -1247,   855,  3558,  6538,  9388, 11665, 
+       12955, 12933, 11408,  8370,  3996, -1349, -7152, -12797, 
+       -17635, -21060, -22583, -21895, -18914, -13807, -6985,   934, 
+        9180, 16913, 23309, 27654, 29422, 28342, 24429, 17998, 
+        9630,   123, -9589, -18538, -25813, -30667, -32588, -31360, 
+       -27088, -20185, -11332, -1411,  8594, 17694, 24997, 29805, 
+       31675, 30473, 26374, 19844, 11585,  2455, -6618, -14745, 
+       -21156, -25284, -26815, -25713, -22213, -16785, -10073, -2824, 
+        4203, 10318, 14969, 17794, 18653, 17628, 14998, 11197, 
+        6753,  2217, -1899, -5189, -7386, -8388, -8261, -7212, 
+       -5555, -3657, -1881,  -536,   169,   157,  -515, -1664, 
+       -3009, -4217, -4954, -4940, -3996, -2080,   697,  4081, 
+        7689, 11059, 13710, 15199, 15187, 13489, 10114,  5272, 
+        -630, -7031, -13263, -18632, -22491, -24320, -23794, -20823, 
+       -15582, -8498,  -218,  8457, 16651, 23507, 28276, 30407, 
+       29606, 25876, 19524, 11134,  1511, -8401, -17616, -25208, 
+       -30406, -32682, -31800, -27845, -21215, -12576, -2796,  7150, 
+       16278, 23700, 28713, 30868, 30015, 26312, 20199, 12351, 
+        3598, -5164, -13071, -19378, -23531, -25223, -24413, -21318, 
+       -16384, -10218, -3526,  2980,  8655, 12985, 15642, 16505, 
+       15661, 13381, 10073,  6228,  2348, -1110, -3796, -5495, 
+       -6152, -5863, -4853, -3434, -1954,  -744,   -62,   -60, 
+        -757, -2037, -3664, -5317, -6637, -7283, -6985, -5590, 
+       -3096,   334,  4390,  8631, 12544, 15605, 17339, 17393, 
+       15582, 11928,  6672,   258, -6705, -13506, -19403, -23711, 
+       -25879, -25558, -22653, -17341, -10061, -1480,  7570, 16185, 
+       23475, 28661, 31164, 30670, 27167, 20951, 12603,  2930, 
+       -7116, -16540, -24401, -29915, -32533, -32003, -28391, -22075, 
+       -13704, -4128,  5690, 14781, 22262, 27432, 29838, 29319, 
+       26014, 20339, 12940,  4614, -3777, -11401, -17540, -21660, 
+       -23463, -22908, -20199, -15755, -10150, -4044,  1898,  7079, 
+       11030, 13459, 14268, 13555, 11585,  8745,  5487,  2268, 
+        -511, -2559, -3716, -3975, -3468, -2440, -1206,  -101, 
+         578,   618,   -78, -1470, -3382, -5524, -7531, -9018, 
+       -9630, -9103, -7308, -4280,  -226,  4483,  9357, 13829, 
+       17329, 19352, 19524, 17659, 13788,  8177,  1302, -6184, 
+       -13528, -19945, -24710, -27240, -27167, -24381, -19058, -11646, 
+       -2830,  6539, 15528, 23219, 28806, 31685, 31520, 28282, 
+       22254, 14010,  4355, -5759, -15331, -23411, -29203, -32144, 
+       -31966, -28714, -22748, -14695, -5384,  4241, 13228, 20707, 
+       25981, 28600, 28391, 25479, 20256, 13337,  5482, -2482, 
+       -9761, -15668, -19694, -21556, -21215, -18865, -14902, -9864, 
+       -4366,   975,  5614,  9130, 11270, 11967, 11332,  9628, 
+        7223,  4536,  1976,  -113, -1495, -2071, -1882, -1102, 
+           0,  1102,  1882,  2071,  1495,   113, -1976, -4536, 
+       -7223, -9628, -11332, -11967, -11270, -9130, -5614,  -975, 
+        4366,  9864, 14902, 18865, 21215, 21556, 19694, 15668, 
+        9761,  2482, -5482, -13337, -20256, -25479, -28391, -28600, 
+       -25981, -20707, -13228, -4241,  5384, 14695, 22748, 28714, 
+       31966, 32144, 29203, 23411, 15331,  5759, -4355, -14010, 
+       -22254, -28282, -31520, -31685, -28806, -23219, -15528, -6539, 
+        2830, 11646, 19058, 24381, 27167, 27240, 24710, 19945, 
+       13528,  6184, -1302, -8177, -13788, -17659, -19524, -19352, 
+       -17329, -13829, -9357, -4483,   226,  4280,  7308,  9103, 
+        9630,  9018,  7531,  5524,  3382,  1470,    78,  -618, 
+        -578,   101,  1206,  2440,  3468,  3975,  3716,  2559, 
+         511, -2268, -5487, -8745, -11585, -13555, -14268, -13459, 
+       -11030, -7079, -1898,  4044, 10150, 15755, 20199, 22908, 
+       23463, 21660, 17540, 11401,  3777, -4614, -12940, -20339, 
+       -26014, -29319, -29838, -27432, -22262, -14781, -5690,  4128, 
+       13704, 22075, 28391, 32003, 32533, 29915, 24401, 16540, 
+        7116, -2930, -12603, -20951, -27167, -30670, -31164, -28661, 
+       -23475, -16185, -7570,  1480, 10061, 17341, 22653, 25558, 
+       25879, 23711, 19403, 13506,  6705,  -258, -6672, -11928, 
+       -15582, -17393, -17339, -15605, -12544, -8631, -4390,  -334, 
+        3096,  5590,  6985,  7283,  6637,  5317,  3664,  2037, 
+         757,    60,    62,   744,  1954,  3434,  4853,  5863, 
+        6152,  5495,  3796,  1110, -2348, -6228, -10073, -13381, 
+       -15661, -16505, -15642, -12985, -8655, -2980,  3526, 10218, 
+       16384, 21318, 24413, 25223, 23531, 19378, 13071,  5164, 
+       -3598, -12351, -20199, -26312, -30015, -30868, -28713, -23700, 
+       -16278, -7150,  2796, 12576, 21215, 27845, 31800, 32682, 
+       30406, 25208, 17616,  8401, -1511, -11134, -19524, -25876, 
+       -29606, -30407, -28276, -23507, -16651, -8457,   218,  8498, 
+       15582, 20823, 23794, 24320, 22491, 18632, 13263,  7031, 
+         630, -5272, -10114, -13489, -15187, -15199, -13710, -11059, 
+       -7689, -4081,  -697,  2080,  3996,  4940,  4954,  4217, 
+        3009,  1664,   515,  -157,  -169,   536,  1881,  3657, 
+        5555,  7212,  8261,  8388,  7386,  5189,  1899, -2217, 
+       -6753, -11197, -14998, -17628, -18653, -17794, -14969, -10318, 
+       -4203,  2824, 10073, 16785, 22213, 25713, 26815, 25284, 
+       21156, 14745,  6618, -2455, -11585, -19844, -26374, -30473, 
+       -31675, -29805, -24997, -17694, -8594,  1411, 11332, 20185, 
+       27088, 31360, 32588, 30667, 25813, 18538,  9589,  -123, 
+       -9630, -17998, -24429, -28342, -29422, -27654, -23309, -16913, 
+       -9180,  -934,  6985, 13807, 18914, 21895, 22583, 21060, 
+       17635, 12797,  7152,  1349, -3996, -8370, -11408, -12933, 
+       -12955, -11665, -9388, -6538, -3558,  -855,  1247,  2548, 
+        2993,  2669,  1784,   633,  -454, -1168, -1263,  -607, 
+         801,  2822,  5190,  7547,  9491, 10634, 10657,  9365, 
+        6721,  2866, -1881, -7061, -12107, -16420, -19434, -20687, 
+       -19887, -16954, -12044, -5545,  1954,  9723, 16960, 22878, 
+       26797, 28221, 26895, 22848, 16396,  8116, -1206, -10657, 
+       -19286, -26206, -30690, -32251, -30692, -26133, -19004, -9997, 
+       
+};
diff --git a/utils/iaxclient/lib/libiax2/src/frame.h b/utils/iaxclient/lib/libiax2/src/frame.h
new file mode 100644 (file)
index 0000000..9c1b2b6
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * libiax: An implementation of the Inter-Asterisk eXchange protocol
+ *
+ * Asterisk internal frame definitions.
+ * 
+ * Copyright (C) 1999, Mark Spencer
+ *
+ * Mark Spencer <markster@linux-support.net>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser General Public License.  Other components of
+ * Asterisk are distributed under The GNU General Public License
+ * only.
+ */
+
+#ifndef _LIBIAX_FRAME_H
+#define _LIBIAX_FRAME_H
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+
+/* Frame types */
+#define AST_FRAME_DTMF         1               /* A DTMF digit, subclass is the digit */
+#define AST_FRAME_VOICE                2               /* Voice data, subclass is AST_FORMAT_* */
+#define AST_FRAME_VIDEO                3               /* Video frame, maybe?? :) */
+#define AST_FRAME_CONTROL      4               /* A control frame, subclass is AST_CONTROL_* */
+#define AST_FRAME_NULL         5               /* An empty, useless frame */
+#define AST_FRAME_IAX          6               /* Inter Aterisk Exchange private frame type */
+#define AST_FRAME_TEXT         7               /* Text messages */
+#define AST_FRAME_IMAGE                8               /* Image Frames */
+#define AST_FRAME_HTML         9               /* HTML Frames */
+#define AST_FRAME_CNG           10             /* Comfort Noise frame (subclass is level of CNG in -dBov) */
+
+/* HTML subclasses */
+#define AST_HTML_URL           1               /* Sending a URL */
+#define AST_HTML_DATA          2               /* Data frame */
+#define AST_HTML_BEGIN         4               /* Beginning frame */
+#define AST_HTML_END           8               /* End frame */
+#define AST_HTML_LDCOMPLETE    16              /* Load is complete */
+#define AST_HTML_NOSUPPORT     17              /* Peer is unable to support HTML */
+#define AST_HTML_LINKURL       18              /* Send URL and track */
+#define AST_HTML_UNLINK                19              /* Request no more linkage */
+#define AST_HTML_LINKREJECT    20              /* Reject LINKURL */
+
+/* Data formats for capabilities and frames alike */
+/*! G.723.1 compression */
+#define AST_FORMAT_G723_1       (1 << 0)
+       /*! GSM compression */
+#define AST_FORMAT_GSM          (1 << 1)
+       /*! Raw mu-law data (G.711) */
+#define AST_FORMAT_ULAW         (1 << 2)
+       /*! Raw A-law data (G.711) */
+#define AST_FORMAT_ALAW         (1 << 3)
+       /*! ADPCM (G.726, 32kbps) */
+#define AST_FORMAT_G726         (1 << 4)
+       /*! ADPCM (IMA) */
+#define AST_FORMAT_ADPCM        (1 << 5)
+       /*! Raw 16-bit Signed Linear (8000 Hz) PCM */
+#define AST_FORMAT_SLINEAR      (1 << 6)
+       /*! LPC10, 180 samples/frame */
+#define AST_FORMAT_LPC10        (1 << 7)
+       /*! G.729A audio */
+#define AST_FORMAT_G729A        (1 << 8)
+       /*! SpeeX Free Compression */
+#define AST_FORMAT_SPEEX        (1 << 9)
+       /*! iLBC Free Compression */
+#define AST_FORMAT_ILBC         (1 << 10)
+       /*! Maximum audio format */
+#define AST_FORMAT_MAX_AUDIO    (1 << 15)
+       /*! JPEG Images */
+#define AST_FORMAT_JPEG         (1 << 16)
+       /*! PNG Images */
+#define AST_FORMAT_PNG          (1 << 17)
+       /*! H.261 Video */
+#define AST_FORMAT_H261         (1 << 18)
+       /*! H.263 Video */
+#define AST_FORMAT_H263         (1 << 19)
+       /*! H.263+ Video  */
+#define AST_FORMAT_H263p       (1 << 20)
+       /*! H.264 Video*/
+#define AST_FORMAT_H264                (1 << 21)
+       /*! MPEG4 Video*/
+#define AST_FORMAT_MPEG4       (1 << 22)
+       /*! Theora Video */
+#define AST_FORMAT_THEORA      (1 << 24)
+       /*! Max one */
+#define AST_FORMAT_MAX_VIDEO    (1 << 24)
+
+/* Control frame types */
+#define AST_CONTROL_HANGUP             1                       /* Other end has hungup */
+#define AST_CONTROL_RING               2                       /* Local ring */
+#define AST_CONTROL_RINGING    3                       /* Remote end is ringing */
+#define AST_CONTROL_ANSWER             4                       /* Remote end has answered */
+#define AST_CONTROL_BUSY               5                       /* Remote end is busy */
+#define AST_CONTROL_TAKEOFFHOOK 6                      /* Make it go off hook */
+#define AST_CONTROL_OFFHOOK            7                       /* Line is off hook */
+#define AST_CONTROL_CONGESTION 8                       /* Congestion (circuits busy) */
+#define AST_CONTROL_FLASH              9                       /* Flash hook */
+#define AST_CONTROL_WINK               10                      /* Wink */
+#define AST_CONTROL_OPTION             11                      /* Set an option */
+
+#define AST_FRIENDLY_OFFSET            64                      /* Reserved header space */
+
+struct ast_frame {
+        /*! Kind of frame */
+        int frametype;
+        /*! Subclass, frame dependent */
+        int subclass;
+        /*! Length of data */
+        int datalen;
+        /*! Number of 8khz samples in this frame */
+        int samples;
+        /*! Was the data malloc'd?  i.e. should we free it when we discard the f
+rame? */
+        int mallocd;
+        /*! How far into "data" the data really starts */
+        int offset;
+        /*! Optional source of frame for debugging */
+        char *src;
+        /*! Pointer to actual data */
+        void *data;
+        /*! Next/Prev for linking stand alone frames */
+        struct ast_frame *prev;
+       /*! Next/Prev for linking stand alone frames */
+        struct ast_frame *next;
+                                                                /* Unused except
+ if debugging is turned on, but left
+                                                                   in the struct
+ so that it can be turned on without
+                                                                   requiring a r
+ecompile of the whole thing */
+};
+
+
+
+#if defined(__cplusplus) || defined(c_plusplus)
+}
+#endif
+
+
+#endif
diff --git a/utils/iaxclient/lib/libiax2/src/iax-client.h b/utils/iaxclient/lib/libiax2/src/iax-client.h
new file mode 100644 (file)
index 0000000..673f937
--- /dev/null
@@ -0,0 +1,259 @@
+/*
+ * Asterisk -- A telephony toolkit for Linux.
+ *
+ * Implementation of Inter-Asterisk eXchange
+ *
+ * Copyright (C) 1999, Mark Spencer
+ *
+ * Mark Spencer <markster@linux-support.net>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser General Public License (LGPL)
+ */
+
+#ifndef _ASTERISK_IAX_CLIENT_H
+#define _ASTERISK_IAX_CLIENT_H
+
+#if defined(_MSC_VER)
+/* disable zero-sized array in struct/union warning */
+#pragma warning(disable:4200)
+#endif
+
+#ifdef WIN32
+#define socklen_t int
+#endif
+
+#include "frame.h"
+#include "iax2.h"
+#include "iax2-parser.h"
+
+#define MAXSTRLEN 80
+
+#define IAX_AUTHMETHOD_PLAINTEXT IAX_AUTH_PLAINTEXT
+#define IAX_AUTHMETHOD_MD5       IAX_AUTH_MD5
+
+extern char iax_errstr[];
+
+struct iax_session;
+
+
+#define IAX_EVENT_CONNECT       0      /* Connect a new call */
+#define IAX_EVENT_ACCEPT        1      /* Accept a call */
+#define IAX_EVENT_HANGUP        2      /* Hang up a call */
+#define IAX_EVENT_REJECT        3      /* Rejected call */
+#define IAX_EVENT_VOICE         4      /* Voice Data */
+#define IAX_EVENT_DTMF          5      /* A DTMF Tone */
+#define IAX_EVENT_TIMEOUT       6      /* Connection timeout...  session
+                                          will be a pointer to free()'d
+                                          memory! */
+#define IAX_EVENT_LAGRQ         7      /* Lag request -- Internal use only */
+#define IAX_EVENT_LAGRP         8      /* Lag Measurement.  See event.lag */
+#define IAX_EVENT_RINGA         9      /* Announce we/they are ringing */
+#define IAX_EVENT_PING          10      /* Ping -- internal use only */
+#define IAX_EVENT_PONG          11      /* Pong -- internal use only */
+#define IAX_EVENT_BUSY          12      /* Report a line busy */
+#define IAX_EVENT_ANSWER        13      /* Answer the line */
+
+#define IAX_EVENT_IMAGE         14      /* Send/Receive an image */
+#define IAX_EVENT_AUTHRQ        15      /* Authentication request */
+#define IAX_EVENT_AUTHRP        16      /* Authentication reply */
+
+#define IAX_EVENT_REGREQ        17      /* Registration request */
+#define IAX_EVENT_REGACK        18      /* Registration reply */
+#define IAX_EVENT_URL           19      /* URL received */
+#define IAX_EVENT_LDCOMPLETE    20      /* URL loading complete */
+
+#define IAX_EVENT_TRANSFER      21      /* Transfer has taken place */
+
+#define IAX_EVENT_DPREQ         22      /* Dialplan request */
+#define IAX_EVENT_DPREP         23      /* Dialplan reply */
+#define IAX_EVENT_DIAL          24      /* Dial on a TBD call */
+
+#define IAX_EVENT_QUELCH        25      /* Quelch Audio */
+#define IAX_EVENT_UNQUELCH      26      /* Unquelch Audio */
+
+#define IAX_EVENT_UNLINK        27      /* Unlink */
+#define IAX_EVENT_LINKREJECT    28      /* Link Rejection */
+#define IAX_EVENT_TEXT          29      /* Text Frame :-) */
+#define IAX_EVENT_REGREJ        30      /* Registration reply */
+#define IAX_EVENT_LINKURL       31      /* Unlink */
+#define IAX_EVENT_CNG           32      /* Comfort-noise (almost silence) */
+#define IAX_EVENT_POKE          33
+#define IAX_EVENT_VIDEO         34      /* Send/receive video */
+
+
+/* moved from iax.c to support attended transfer */
+#define IAX_EVENT_REREQUEST     999
+#define IAX_EVENT_TXREPLY       1000
+#define IAX_EVENT_TXREJECT      1001
+#define IAX_EVENT_TXACCEPT      1002
+#define IAX_EVENT_TXREADY       1003
+
+/*
+ * Null event. We use it to notify back the caller that a frame has been
+ * received and is queued for delivery
+ * Applciations should simply ignore it
+ */
+#define IAX_EVENT_NULL          65535
+
+#define IAX_SCHEDULE_FUZZ 0  /* ms of fuzz to drop */
+
+#if defined(WIN32)  ||  defined(_WIN32_WCE)
+#if defined(_MSC_VER)
+typedef int (__stdcall *iax_sendto_t)(SOCKET, const void *, size_t, int,
+               const struct sockaddr *, socklen_t);
+typedef int (__stdcall *iax_recvfrom_t)(SOCKET, void *, size_t, int,
+               struct sockaddr *, socklen_t *);
+#else
+typedef int PASCAL (*iax_sendto_t)(SOCKET, const char *, int, int,
+               const struct sockaddr *, int);
+typedef int PASCAL (*iax_recvfrom_t)(SOCKET, char *, int, int,
+               struct sockaddr *, int *);
+#endif
+#else
+typedef int (*iax_sendto_t)(int, const void *, size_t, int,
+               const struct sockaddr *, socklen_t);
+typedef int (*iax_recvfrom_t)(int, void *, size_t, int,
+               struct sockaddr *, socklen_t *);
+#endif
+
+struct iax_event {
+       int etype;                   /* Type of event */
+       int subclass;                /* Subclass data (event specific) */
+       unsigned int ts;             /* Timestamp */
+       struct iax_session *session; /* Applicable session */
+       int datalen;                 /* Length of raw data */
+       struct iax_ies ies;          /* IE's for IAX2 frames */
+       unsigned char data[0];       /* Raw data if applicable */
+};
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/* All functions return 0 on success and -1 on failure unless otherwise
+   specified */
+
+/* Called to initialize IAX structures and sockets.  Returns actual
+   portnumber (which it will try preferred portno first, but if not
+   take what it can get */
+extern int iax_init(int preferredportno);
+
+/* Get filedescriptor for IAX to use with select or gtk_input_add */
+extern int iax_get_fd(void);
+
+/* Find out how many milliseconds until the next scheduled event */
+extern int iax_time_to_next_event(void);
+
+/* Generate a new IAX session */
+extern struct iax_session *iax_session_new(void);
+
+/* Return exactly one iax event (if there is one pending).  If blocking is
+   non-zero, IAX will block until some event is received */
+extern struct iax_event *iax_get_event(int blocking);
+
+
+extern int iax_auth_reply(struct iax_session *session, char *password,
+               char *challenge, int methods);
+
+/* Free an event */
+extern void iax_event_free(struct iax_event *event);
+
+struct sockaddr_in;
+
+/* Front ends for sending events */
+extern int iax_send_dtmf(struct iax_session *session, char digit);
+extern int iax_send_voice(struct iax_session *session, int format, unsigned char *data, int datalen, int samples);
+extern int iax_send_cng(struct iax_session *session, int level, unsigned char *data, int datalen);
+extern int iax_send_image(struct iax_session *session, int format, unsigned char *data, int datalen);
+extern int iax_send_url(struct iax_session *session, const char *url, int link);
+extern int iax_send_text(struct iax_session *session, const char *text);
+extern int iax_send_ping(struct iax_session *session);
+extern int iax_load_complete(struct iax_session *session);
+extern int iax_reject(struct iax_session *session, char *reason);
+extern int iax_busy(struct iax_session *session);
+extern int iax_congestion(struct iax_session *session);
+extern int iax_hangup(struct iax_session *session, char *byemsg);
+extern int iax_call(struct iax_session *session, const char *cidnum, const char *cidname, const char *ich, const char *lang, int wait, int format, int capability);
+extern int iax_accept(struct iax_session *session, int format);
+extern int iax_answer(struct iax_session *session);
+extern int iax_sendurl(struct iax_session *session, char *url);
+extern int iax_send_unlink(struct iax_session *session);
+extern int iax_send_link_reject(struct iax_session *session);
+extern int iax_ring_announce(struct iax_session *session);
+extern struct sockaddr_in iax_get_peer_addr(struct iax_session *session);
+extern int iax_register(struct iax_session *session, const char *hostname, const char *peer, const char *secret, int refresh);
+extern int iax_unregister(struct iax_session *session, const char *hostname, const char *peer, const char *secret, const char *reason);
+extern int iax_lag_request(struct iax_session *session);
+extern int iax_dial(struct iax_session *session, char *number); /* Dial on a TBD call */
+extern int iax_dialplan_request(struct iax_session *session, char *number); /* Request dialplan status for number */
+extern int iax_quelch(struct iax_session *session);
+extern int iax_unquelch(struct iax_session * session);
+extern int iax_transfer(struct iax_session *session, const char *number);
+extern int iax_quelch_moh(struct iax_session *session, int MOH);
+extern int iax_send_video(struct iax_session *session, int format, unsigned char *data, int datalen, int fullframe);
+extern int iax_send_video_trunk(struct iax_session *session, int format, char *data, int datalen, int fullframe, int ntrunk);
+
+extern void iax_destroy(struct iax_session  * session);
+
+extern void iax_enable_debug(void);
+extern void iax_disable_debug(void);
+
+extern struct timeval iax_tvnow(void);
+
+/* For attended transfer, application create a new session,
+ * make a call on the new session.
+ * On answer of the new session, call iax_setup_transfer and wait for
+ * IAX_EVENT_TXREADY when both sides are completed succefully or
+ * IAX_EVENT_TXREJECT for either side.
+ * If there are music on hold the it will be stopped by this library.
+ */
+extern int iax_setup_transfer(struct iax_session *s0, struct iax_session *s1);
+
+struct iax_netstat {
+       int jitter;
+       int losspct;
+       int losscnt;
+       int packets;
+       int delay;
+       int dropped;
+       int ooo;
+};
+/* fills in rtt, and an iax_netstat structure for each of local/remote directions of call */
+extern int iax_get_netstats(struct iax_session *s, int *rtt, struct iax_netstat *local, struct iax_netstat *remote);
+
+
+extern void iax_set_private(struct iax_session *s, void *pvt);
+extern void *iax_get_private(struct iax_session *s);
+extern void iax_set_sendto(struct iax_session *s, iax_sendto_t sendto);
+
+/* to use application networking instead of internal, set call this instead of iax_init,
+ * and pass in sendto and recvfrom replacements.  blocking reads may not be implemented */
+extern void iax_set_networking(iax_sendto_t st, iax_recvfrom_t rf);
+
+/* destroy an iax session */
+extern void iax_session_destroy(struct iax_session **session);
+
+/* To control use of jitter buffer for video event */
+int iax_video_bypass_jitter(struct iax_session*, int );
+
+/* Handle externally received frames */
+struct iax_event *iax_net_process(unsigned char *buf, int len, struct sockaddr_in *sin);
+extern unsigned int iax_session_get_capability(struct iax_session *s);
+extern char iax_pref_codec_add(struct iax_session *session, unsigned int format);
+extern void iax_pref_codec_del(struct iax_session *session, unsigned int format);
+extern int iax_pref_codec_get(struct iax_session *session, unsigned int *array, int len);
+
+/* Fine tune jitterbuffer */
+extern void iax_set_jb_target_extra( long value );
+
+/* Portable 'decent' random number generation */
+extern void iax_seed_random(void);
+extern int iax_random(void);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* _ASTERISK_IAX_CLIENT_H */
diff --git a/utils/iaxclient/lib/libiax2/src/iax.c b/utils/iaxclient/lib/libiax2/src/iax.c
new file mode 100644 (file)
index 0000000..50364cc
--- /dev/null
@@ -0,0 +1,3517 @@
+ /*
+ * libiax: An implementation of Inter-Asterisk eXchange
+ *
+ * Copyright (C) 2001, Linux Support Services, Inc.
+ *
+ * Mark Spencer <markster@linux-support.net>
+ * Frik Strecker <frik@gatherworks.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if defined(WIN32)  ||  defined(_WIN32_WCE)
+#undef __STRICT_ANSI__ //for strdup with ms
+#include "winpoop.h"
+#if defined(_WIN32_WCE)
+#define strdup _strdup
+#else
+#include <process.h>
+#include <fcntl.h>
+#include <io.h>
+#include <errno.h>
+#endif
+#include <string.h>
+#include <time.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <limits.h>
+
+#if !defined(_WIN32_WCE)
+#include <sys/timeb.h>
+#endif
+
+#define        snprintf _snprintf
+
+#if defined(_MSC_VER)
+#define        close           closesocket
+#if !defined(_WIN32_WCE)
+#define inline      __inline
+#endif
+#endif
+
+#else // !#if defined(WIN32)  ||  defined(_WIN32_WCE)
+#include <netdb.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/time.h>   // gettimeofday
+#ifndef HAVE_GETTIMEOFDAY
+#define HAVE_GETTIMEOFDAY 1
+#endif
+#include <stdlib.h>
+
+#ifdef __GNUC__
+#ifndef __USE_SVID
+#define __USE_SVID
+#endif
+#endif
+
+#include <string.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/select.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <time.h>
+
+#if !defined(MACOSX) && !defined(__OpenBSD__)
+#include <malloc.h>
+#if !defined(SOLARIS)
+#include <error.h>
+#endif
+#endif
+
+#endif // #if defined(WIN32)  ||  defined(_WIN32_WCE) yes or no
+
+#ifndef _MSC_VER
+#endif
+
+#include "jitterbuf.h"
+#include "iax-client.h"
+#include "md5.h"
+
+/* Define socket options for IAX2 sockets, based on platform
+ * availability of flags */
+#if defined(WIN32)  ||  defined(_WIN32_WCE)
+#define IAX_SOCKOPTS 0
+#else
+#ifdef MACOSX
+#define IAX_SOCKOPTS MSG_DONTWAIT
+#else
+#if defined(SOLARIS) || defined(__OpenBSD__)
+#define IAX_SOCKOPTS MSG_DONTWAIT
+#else  /* Linux and others */
+#define IAX_SOCKOPTS MSG_DONTWAIT | MSG_NOSIGNAL
+#endif
+#endif
+#endif
+
+
+#ifdef SNOM_HACK
+/* The snom phone seems to improperly execute memset in some cases */
+#include "../../snom_phonecore2/include/snom_memset.h"
+#endif
+
+/* Voice TS Prediction causes libiax2 to clean up the timestamps on
+ * outgoing frames.  It works best with either continuous voice, or
+ * callers who call iax_send_cng to indicate DTX for silence */
+#define USE_VOICE_TS_PREDICTION
+
+#define MIN_RETRY_TIME 10
+#define MAX_RETRY_TIME 4000
+#define MEMORY_SIZE 1000
+
+#define TRANSFER_NONE  0
+#define TRANSFER_BEGIN 1
+#define TRANSFER_READY 2
+#define TRANSFER_REL   3
+
+/* Video frames bypass jitterbuffer */
+static int video_bypass_jitterbuffer = 0;
+
+/* To use or not to use the jitterbuffer */
+static int iax_use_jitterbuffer = 1;
+
+/* UDP Socket (file descriptor) */
+static int netfd = -1;
+
+/* Max timeouts */
+static const int maxretries = 10;
+
+/* configurable jitterbuffer options */
+static long jb_target_extra = -1;
+
+/* external global networking replacements */
+static iax_sendto_t   iax_sendto = (iax_sendto_t) sendto;
+static iax_recvfrom_t iax_recvfrom = (iax_recvfrom_t) recvfrom;
+
+/* ping interval (seconds) */
+static int ping_time = 10;
+static void send_ping(void *session);
+
+struct iax_session {
+       /* Private data */
+       void *pvt;
+       /* session-local Sendto function */
+       iax_sendto_t sendto;
+       /* Is voice quelched (e.g. hold) */
+       int quelch;
+       /* Codec Pref Order */
+       char codec_order[32];
+       /* Codec Pref Order Index*/
+       int codec_order_len;
+       /* Last received voice format */
+       int voiceformat;
+       /* Last transmitted voice format */
+       int svoiceformat;
+       /* Last received video format */
+       int videoformat;
+       /* Last transmitted video format */
+       int svideoformat;
+       /* Per session capability */
+       int capability;
+       /* Last received timestamp */
+       unsigned int last_ts;
+       /* Last transmitted timestamp */
+       unsigned int lastsent;
+       /* Timestamp of the last transmitted video frame */
+       unsigned int lastvsent;
+#ifdef USE_VOICE_TS_PREDICTION
+       /* Next predicted voice ts */
+       unsigned int nextpred;
+       /* True if the last voice we transmitted was not silence/CNG */
+       int notsilenttx;
+#endif
+       /* Our last measured ping time */
+       unsigned int pingtime;
+       /* Address of peer */
+       struct sockaddr_in peeraddr;
+       /* Our call number */
+       int callno;
+       /* Peer's call number */
+       int peercallno;
+       /* Our next outgoing sequence number */
+       unsigned char oseqno;
+       /* Next sequence number they have not yet acknowledged */
+       unsigned char rseqno;
+       /* Our last received incoming sequence number */
+       unsigned char iseqno;
+       /* Last acknowledged sequence number */
+       unsigned char aseqno;
+       /* Last sequence number we VNAKd */
+       unsigned char lastvnak;
+       /* Time value that we base our transmission on */
+       struct timeval offset;
+       /* Time value we base our delivery on */
+       struct timeval rxcore;
+       /* Current link state */
+       int state;
+       /* Unregister reason */
+       char unregreason[MAXSTRLEN];
+       /* Expected Username */
+       char username[MAXSTRLEN];
+       /* Expected Secret */
+       char secret[MAXSTRLEN];
+       /* Refresh if applicable */
+       int refresh;
+
+       /* ping scheduler id */
+       int pingid;
+
+       /* Transfer stuff */
+       struct sockaddr_in transfer;
+       int transferring;
+       int transfercallno;
+       int transferid;
+       int transferpeer;       /* for attended transfer */
+       int transfer_moh;       /* for music on hold while performing attended transfer */
+
+       jitterbuf *jb;
+
+       struct iax_netstat remote_netstats;
+
+       /* For linking if there are multiple connections */
+       struct iax_session *next;
+};
+
+char iax_errstr[256];
+
+
+#define IAXERROR snprintf(iax_errstr, sizeof(iax_errstr),
+
+#ifdef DEBUG_SUPPORT
+
+#ifdef DEBUG_DEFAULT
+static int debug = 1;
+#else
+static int debug = 0;
+#endif
+
+void iax_enable_debug(void)
+{
+       debug = 1;
+}
+
+void iax_disable_debug(void)
+{
+       debug = 0;
+}
+
+void iax_enable_jitterbuffer(void)
+{
+       iax_use_jitterbuffer = 1;
+}
+
+void iax_disable_jitterbuffer(void)
+{
+       iax_use_jitterbuffer = 0;
+}
+
+void iax_set_private(struct iax_session *s, void *ptr)
+{
+       s->pvt = ptr;
+}
+
+void *iax_get_private(struct iax_session *s)
+{
+       return s->pvt;
+}
+
+void iax_set_sendto(struct iax_session *s, iax_sendto_t ptr)
+{
+       s->sendto = ptr;
+}
+
+/* This is a little strange, but to debug you call DEBU(G "Hello World!\n"); */
+#if defined(WIN32)  ||  defined(_WIN32_WCE)
+#define G __FILE__, __LINE__,
+#else
+#define G __FILE__, __LINE__, __PRETTY_FUNCTION__,
+#endif
+
+#define DEBU __debug
+#if defined(WIN32)  ||  defined(_WIN32_WCE)
+static int __debug(const char *file, int lineno, const char *fmt, ...)
+{
+       va_list args;
+       va_start(args, fmt);
+       if (debug) {
+               fprintf(stderr, "%s line %d: ", file, lineno);
+               vfprintf(stderr, fmt, args);
+       }
+       va_end(args);
+       return 0;
+}
+#else
+static int __debug(const char *file, int lineno, const char *func, const char *fmt, ...)
+{
+       va_list args;
+       va_start(args, fmt);
+       if (debug) {
+               fprintf(stderr, "%s line %d in %s: ", file, lineno, func);
+               vfprintf(stderr, fmt, args);
+       }
+       va_end(args);
+       return 0;
+}
+#endif
+#else /* No debug support */
+
+#if defined(WIN32)  ||  defined(_WIN32_WCE)
+#define        DEBU
+#else
+#define DEBU(fmt...) \
+    do {} while(0)
+#endif
+#define G
+#endif
+
+void iax_seed_random()
+{
+#if defined(HAVE_SRANDOMDEV)
+       srandomdev();
+#elif defined(HAVE_SRANDOM)
+       srandom((unsigned int)time(0));
+#elif defined(HAVE_SRAND48)
+       srand48((long int)time(0));
+#else
+       srand((unsigned int)time(0));
+#endif
+}
+
+int iax_random()
+{
+#if defined(HAVE_RANDOM)
+       return (int)random();
+#elif defined(HAVE_LRAND48)
+       return (int)lrand48();
+#else
+       return rand();
+#endif
+}
+
+typedef void (*sched_func)(void *);
+
+struct iax_sched {
+       /* These are scheduled things to be delivered */
+       struct timeval when;
+       /* If event is non-NULL then we're delivering an event */
+       struct iax_event *event;
+       /* If frame is non-NULL then we're transmitting a frame */
+       struct iax_frame *frame;
+       /* If func is non-NULL then we should call it */
+       sched_func func;
+       /* and pass it this argument */
+       void *arg;
+       /* Easy linking */
+       struct iax_sched *next;
+};
+
+static struct iax_sched *schedq = NULL;
+static struct iax_session *sessions = NULL;
+static int callnums = 1;
+
+unsigned int iax_session_get_capability(struct iax_session *s)
+{
+       return s->capability;
+}
+
+static int inaddrcmp(struct sockaddr_in *sin1, struct sockaddr_in *sin2)
+{
+       return (sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) || (sin1->sin_port != sin2->sin_port);
+}
+
+static int iax_sched_add(struct iax_event *event, struct iax_frame *frame, sched_func func, void *arg, int ms)
+{
+
+       /* Schedule event to be delivered to the client
+          in ms milliseconds from now, or a reliable frame to be retransmitted */
+       struct iax_sched *sched, *cur, *prev = NULL;
+
+       if (!event && !frame && !func) {
+               DEBU(G "No event, no frame, no func?  what are we scheduling?\n");
+               return -1;
+       }
+
+       //fprintf(stderr, "scheduling event %d ms from now\n", ms);
+       sched = (struct iax_sched*)malloc(sizeof(struct iax_sched));
+       if (sched) {
+               memset(sched, 0, sizeof(struct iax_sched));
+               sched->when = iax_tvnow();
+               sched->when.tv_sec += (ms / 1000);
+               ms = ms % 1000;
+               sched->when.tv_usec += (ms * 1000);
+               if (sched->when.tv_usec > 1000000) {
+                       sched->when.tv_usec -= 1000000;
+                       sched->when.tv_sec++;
+               }
+               sched->event = event;
+               sched->frame = frame;
+               sched->func = func;
+               sched->arg = arg;
+               /* Put it in the list, in order */
+               cur = schedq;
+               while(cur && ((cur->when.tv_sec < sched->when.tv_sec) ||
+                                        ((cur->when.tv_usec <= sched->when.tv_usec) &&
+                                         (cur->when.tv_sec == sched->when.tv_sec)))) {
+                               prev = cur;
+                               cur = cur->next;
+               }
+               sched->next = cur;
+               if (prev) {
+                       prev->next = sched;
+               } else {
+                       schedq = sched;
+               }
+               return 0;
+       } else {
+               DEBU(G "Out of memory!\n");
+               return -1;
+       }
+}
+
+static int iax_sched_del(struct iax_event *event, struct iax_frame *frame, sched_func func, void *arg, int all)
+{
+       struct iax_sched *cur, *tmp, *prev = NULL;
+
+       cur = schedq;
+       while (cur) {
+               if (cur->event == event && cur->frame == frame && cur->func == func && cur->arg == arg) {
+                       if (prev)
+                               prev->next = cur->next;
+                       else
+                               schedq = cur->next;
+                       tmp = cur;
+                       cur = cur->next;
+                       free(tmp);
+                       if (!all)
+                               return -1;
+               } else {
+                       prev = cur;
+                       cur = cur->next;
+               }
+       }
+       return 0;
+}
+
+
+int iax_time_to_next_event(void)
+{
+       struct timeval tv;
+       struct iax_sched *cur = schedq;
+       int ms, min = 999999999;
+
+       /* If there are no pending events, we don't need to timeout */
+       if (!cur)
+               return -1;
+       tv = iax_tvnow();
+       while(cur) {
+               ms = (cur->when.tv_sec - tv.tv_sec) * 1000 +
+                    (cur->when.tv_usec - tv.tv_usec) / 1000;
+               if (ms < min)
+                       min = ms;
+               cur = cur->next;
+       }
+       if (min < 0)
+               min = 0;
+       return min;
+}
+
+struct iax_session *iax_session_new(void)
+{
+       struct iax_session *s;
+       s = calloc(1, sizeof(struct iax_session));
+       if (s) {
+               jb_conf jbconf;
+
+               /* Initialize important fields */
+               s->voiceformat = -1;
+               s->svoiceformat = -1;
+               s->videoformat = -1;
+               /* Default pingtime to 100 ms -- should cover most decent net connections */
+               s->pingtime = 100;
+               /* XXX Not quite right -- make sure it's not in use, but that won't matter
+                  unless you've had at least 65k calls.  XXX */
+               s->callno = callnums++;
+               if (callnums > 32767)
+                       callnums = 1;
+               s->peercallno = 0;
+               s->lastvnak = -1;
+               s->transferpeer = 0; /* for attended transfer */
+               s->next = sessions;
+               s->sendto = iax_sendto;
+               s->pingid = -1;
+
+#ifdef USE_VOICE_TS_PREDICTION
+               s->nextpred = 0;
+#endif
+
+               s->jb = jb_new();
+               if ( !s->jb )
+               {
+                       free(s);
+                       return 0;
+               }
+               jbconf.max_jitterbuf = 0;
+               jbconf.resync_threshold = 1000;
+               jbconf.max_contig_interp = 0;
+               jbconf.target_extra = jb_target_extra;
+               jb_setconf(s->jb, &jbconf);
+
+               sessions = s;
+       }
+       return s;
+}
+
+static int iax_session_valid(struct iax_session *session)
+{
+       /* Return -1 on a valid iax session pointer, 0 on a failure */
+       struct iax_session *cur = sessions;
+       while(cur) {
+               if (session == cur)
+                       return -1;
+               cur = cur->next;
+       }
+       return 0;
+}
+
+int iax_get_netstats(struct iax_session *session, int *rtt, struct iax_netstat *local, struct iax_netstat *remote)
+{
+       jb_info stats;
+
+       if(!iax_session_valid(session)) return -1;
+
+       *rtt = session->pingtime;
+
+       *remote = session->remote_netstats;
+
+       jb_getinfo(session->jb, &stats);
+
+       local->jitter = stats.jitter;
+       /* XXX: should be short-term loss pct.. */
+       if(stats.frames_in == 0) stats.frames_in = 1;
+       local->losspct = stats.losspct/1000;
+       local->losscnt = stats.frames_lost;
+       local->packets = stats.frames_in;
+       local->delay = stats.current - stats.min;
+       local->dropped = stats.frames_dropped;
+       local->ooo = stats.frames_ooo;
+
+       return 0;
+}
+
+#ifdef USE_VOICE_TS_PREDICTION
+static void add_ms(struct timeval *tv, int ms)
+{
+       tv->tv_usec += ms * 1000;
+       if (tv->tv_usec > 999999) {
+               tv->tv_sec += tv->tv_usec / 1000000;
+               tv->tv_usec %= 1000000;
+       }
+
+       if (tv->tv_usec < 0) {
+               tv->tv_sec += (tv->tv_usec / 1000000 - 1);
+               tv->tv_usec = (tv->tv_usec % 1000000) + 1000000;
+       }
+}
+#endif
+
+static int calc_timestamp(struct iax_session *session, unsigned int ts, struct ast_frame *f)
+{
+       int ms;
+       struct timeval tv;
+       int voice = 0;
+       int video = 0;
+       int genuine = 0;
+
+       if ( f && f->frametype == AST_FRAME_VOICE )
+       {
+               voice = 1;
+       } else if ( f && f->frametype == AST_FRAME_VIDEO )
+       {
+               video = 1;
+       } else if (!f || f->frametype == AST_FRAME_IAX)
+       {
+               genuine = 1;
+       }
+
+       /* If this is the first packet we're sending, get our
+          offset now. */
+       if (!session->offset.tv_sec && !session->offset.tv_usec)
+               session->offset = iax_tvnow();
+
+       /* If the timestamp is specified, just use their specified
+          timestamp no matter what.  Usually this is done for
+          special cases.  */
+       if (ts)
+       {
+               if ( f && session )
+                       session->lastsent = ts;
+               return ts;
+       }
+
+       /* Otherwise calculate the timestamp from the current time */
+       tv = iax_tvnow();
+
+       /* Calculate the number of milliseconds since we sent the first packet */
+       ms = (tv.tv_sec - session->offset.tv_sec) * 1000 +
+                (tv.tv_usec - session->offset.tv_usec) / 1000;
+
+       if (ms < 0)
+               ms = 0;
+
+       if(voice) {
+#ifdef USE_VOICE_TS_PREDICTION
+               /* If we haven't most recently sent silence, and we're
+                * close in time, use predicted time */
+               if(session->notsilenttx && abs(ms - session->nextpred) <= 240) {
+                       /* Adjust our txcore, keeping voice and non-voice
+                        * synchronized */
+                       add_ms(&session->offset, (int)(ms - session->nextpred)/10);
+
+                       if(!session->nextpred)
+                               session->nextpred = ms;
+                       ms = session->nextpred;
+               } else {
+                       /* in this case, just use the actual time, since
+                        * we're either way off (shouldn't happen), or we're
+                        * ending a silent period -- and seed the next predicted
+                        * time.  Also, round ms to the next multiple of
+                        * frame size (so our silent periods are multiples
+                        * of frame size too) */
+                       int diff = ms % (f->samples / 8);
+                       if(diff)
+                               ms += f->samples/8 - diff;
+                       session->nextpred = ms;
+               }
+               session->notsilenttx = 1;
+#else
+               if(ms <= session->lastsent)
+                       ms = session->lastsent + 3;
+#endif
+       } else if ( video ) {
+               /*
+                * IAX2 draft 03 says that timestamps MUST be in order.
+                * It does not say anything about several frames having the same timestamp
+                * When transporting video, we can have a frame that spans multiple iax packets
+                * (so called slices), so it would make sense to use the same timestamp for all of
+                * them
+                * We do want to make sure that frames don't go backwards though
+                */
+               if ( (unsigned int)ms < session->lastsent )
+                       ms = session->lastsent;
+       } else {
+               /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking)
+                  if appropriate unless it's a genuine frame */
+               if (genuine) {
+                       if ((unsigned int)ms <= session->lastsent)
+                               ms = session->lastsent + 3;
+               } else if (abs(ms - session->lastsent) <= 240) {
+                       ms = session->lastsent + 3;
+               }
+
+       }
+
+       /* Record the last sent packet for future reference */
+       /* unless an AST_FRAME_IAX */
+       if (!genuine)
+               session->lastsent = ms;
+
+#ifdef USE_VOICE_TS_PREDICTION
+       /* set next predicted ts based on 8khz samples */
+       if(voice)
+           session->nextpred += f->samples / 8;
+#endif
+
+       return ms;
+}
+
+static unsigned char get_n_bits_at(unsigned char *data, int n, int bit)
+{
+       int byte = bit / 8;       /* byte containing first bit */
+       int rem = 8 - (bit % 8);  /* remaining bits in first byte */
+       unsigned char ret = 0;
+
+       if (n <= 0 || n > 8)
+               return 0;
+
+       if (rem < n) {
+               ret = (data[byte] << (n - rem));
+               ret |= (data[byte + 1] >> (8 - n + rem));
+       } else {
+               ret = (data[byte] >> (rem - n));
+       }
+
+       return (ret & (0xff >> (8 - n)));
+}
+
+static int speex_get_wb_sz_at(unsigned char *data, int len, int bit)
+{
+       static int SpeexWBSubModeSz[] = {
+               0, 36, 112, 192,
+               352, 0, 0, 0 };
+       int off = bit;
+       unsigned char c;
+
+       /* skip up to two wideband frames */
+       if (((len * 8 - off) >= 5) &&
+               get_n_bits_at(data, 1, off)) {
+               c = get_n_bits_at(data, 3, off + 1);
+               off += SpeexWBSubModeSz[c];
+
+               if (((len * 8 - off) >= 5) &&
+                       get_n_bits_at(data, 1, off)) {
+                       c = get_n_bits_at(data, 3, off + 1);
+                       off += SpeexWBSubModeSz[c];
+
+                       if (((len * 8 - off) >= 5) &&
+                               get_n_bits_at(data, 1, off)) {
+                               /* too many in a row */
+                               DEBU(G "\tCORRUPT too many wideband streams in a row\n");
+                               return -1;
+                       }
+               }
+
+       }
+       return off - bit;
+}
+
+static int speex_get_samples(unsigned char *data, int len)
+{
+       static int SpeexSubModeSz[] = {
+               0, 43, 119, 160,
+               220, 300, 364, 492,
+               79, 0, 0, 0,
+               0, 0, 0, 0 };
+       static int SpeexInBandSz[] = {
+               1, 1, 4, 4,
+               4, 4, 4, 4,
+               8, 8, 16, 16,
+               32, 32, 64, 64 };
+       int bit = 0;
+       int cnt = 0;
+       int off = 0;
+       unsigned char c;
+
+       DEBU(G "speex_get_samples(%d)\n", len);
+       while ((len * 8 - bit) >= 5) {
+               /* skip wideband frames */
+               off = speex_get_wb_sz_at(data, len, bit);
+               if (off < 0)  {
+                       DEBU(G "\tERROR reading wideband frames\n");
+                       break;
+               }
+               bit += off;
+
+               if ((len * 8 - bit) < 5) {
+                       DEBU(G "\tERROR not enough bits left after wb\n");
+                       break;
+               }
+
+               /* get control bits */
+               c = get_n_bits_at(data, 5, bit);
+               DEBU(G "\tCONTROL: %d at %d\n", c, bit);
+               bit += 5;
+
+               if (c == 15) {
+                       DEBU(G "\tTERMINATOR\n");
+                       break;
+               } else if (c == 14) {
+                       /* in-band signal; next 4 bits contain signal id */
+                       c = get_n_bits_at(data, 4, bit);
+                       bit += 4;
+                       DEBU(G "\tIN-BAND %d bits\n", SpeexInBandSz[c]);
+                       bit += SpeexInBandSz[c];
+               } else if (c == 13) {
+                       /* user in-band; next 5 bits contain msg len */
+                       c = get_n_bits_at(data, 5, bit);
+                       bit += 5;
+                       DEBU(G "\tUSER-BAND %d bytes\n", c);
+                       bit += c * 8;
+               } else if (c > 8) {
+                       DEBU(G "\tUNKNOWN sub-mode %d\n", c);
+                       break;
+               } else {
+                       /* skip number bits for submode (less the 5 control bits) */
+                       DEBU(G "\tSUBMODE %d %d bits\n", c, SpeexSubModeSz[c]);
+                       bit += SpeexSubModeSz[c] - 5;
+
+                       cnt += 160; /* new frame */
+               }
+       }
+       DEBU(G "\tSAMPLES: %d\n", cnt);
+       return cnt;
+}
+
+static inline int get_interp_len(int format)
+{
+       return (format == AST_FORMAT_ILBC) ? 30 : 20;
+}
+
+static int get_sample_cnt(struct iax_event *e)
+{
+       int cnt = 0;
+
+       /*
+        * In the case of zero length frames, do not return a cnt of 0
+        */
+       if ( e->datalen == 0 ) {
+               return get_interp_len( e->subclass ) * 8;
+       }
+
+       switch (e->subclass) {
+       case AST_FORMAT_SPEEX:
+               cnt = speex_get_samples(e->data, e->datalen);
+               break;
+       case AST_FORMAT_G723_1:
+               cnt = 240;              /* FIXME Not always the case */
+               break;
+       case AST_FORMAT_ILBC:
+               cnt = 240 * (e->datalen / 50);
+               break;
+       case AST_FORMAT_GSM:
+               cnt = 160 * (e->datalen / 33);
+               break;
+       case AST_FORMAT_G729A:
+               cnt = 160 * (e->datalen / 20);
+               break;
+       case AST_FORMAT_SLINEAR:
+               cnt = e->datalen / 2;
+               break;
+       case AST_FORMAT_LPC10:
+               cnt = 22 * 8 + (((char *)(e->data))[7] & 0x1) * 8;
+               break;
+       case AST_FORMAT_ULAW:
+       case AST_FORMAT_ALAW:
+               cnt = e->datalen;
+               break;
+       case AST_FORMAT_ADPCM:
+       case AST_FORMAT_G726:
+               cnt = e->datalen * 2;
+               break;
+       default:
+               return 0;
+       }
+       return cnt;
+}
+
+static int iax_xmit_frame(struct iax_frame *f)
+{
+       int res;
+#ifdef DEBUG_SUPPORT
+       if (debug) {
+               struct ast_iax2_full_hdr *h = (struct ast_iax2_full_hdr *)f->data;
+
+               if (ntohs(h->scallno) & IAX_FLAG_FULL)
+                       iax_showframe(f, NULL, 0, f->transfer ?
+                                                                               &(f->session->transfer) :
+                                                                               &(f->session->peeraddr),
+                                                                               f->datalen - sizeof(struct ast_iax2_full_hdr));
+       }
+#endif
+       /* Send the frame raw */
+       res = f->session->sendto(netfd, (const char *) f->data, f->datalen,
+                       IAX_SOCKOPTS, f->transfer ?
+                       (struct sockaddr *)&(f->session->transfer) :
+                       (struct sockaddr *)&(f->session->peeraddr),
+                       sizeof(f->session->peeraddr));
+       return res;
+}
+
+static int iax_reliable_xmit(struct iax_frame *f)
+{
+       struct iax_frame *fc;
+       struct ast_iax2_full_hdr *fh;
+       fh = (struct ast_iax2_full_hdr *) f->data;
+       if (!fh->type) {
+               return -2;
+       }
+       fc = (struct iax_frame *)malloc(sizeof(struct iax_frame));
+       if (fc) {
+               /* Make a copy of the frame */
+               memcpy(fc, f, sizeof(struct iax_frame));
+               /* And a copy of the data if applicable */
+               if (!fc->data || !fc->datalen) {
+                       IAXERROR "No frame data?");
+                       DEBU(G "No frame data?\n");
+                       return -1;
+               } else {
+                       fc->data = (char *)malloc(fc->datalen);
+                       if (!fc->data) {
+                               DEBU(G "Out of memory\n");
+                               IAXERROR "Out of memory\n");
+                               return -1;
+                       }
+                       memcpy(fc->data, f->data, f->datalen);
+                       iax_sched_add(NULL, fc, NULL, NULL, fc->retrytime);
+                       return iax_xmit_frame(fc);
+               }
+       } else
+               return -1;
+}
+
+void iax_set_networking(iax_sendto_t st, iax_recvfrom_t rf)
+{
+       iax_sendto = st;
+       iax_recvfrom = rf;
+}
+
+void iax_set_jb_target_extra( long value )
+{
+       /* store in jb_target_extra, a static global */
+       jb_target_extra = value ;
+}
+
+int iax_init(int preferredportno)
+{
+       int portno = preferredportno;
+
+       if (iax_recvfrom == (iax_recvfrom_t)recvfrom)
+       {
+               struct sockaddr_in sin;
+               socklen_t sinlen;
+               int flags;
+               int bufsize = 128 * 1024;
+
+               if (netfd > -1)
+               {
+                       /* Okay, just don't do anything */
+                       DEBU(G "Already initialized.");
+                       return 0;
+               }
+               netfd = (int)socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
+               if (netfd < 0)
+               {
+                       DEBU(G "Unable to allocate UDP socket\n");
+                       IAXERROR "Unable to allocate UDP socket\n");
+                       return -1;
+               }
+
+               if (preferredportno == 0)
+                       preferredportno = IAX_DEFAULT_PORTNO;
+
+               if (preferredportno < 0)
+                       preferredportno = 0;
+
+               sin.sin_family = AF_INET;
+               sin.sin_addr.s_addr = 0;
+               sin.sin_port = htons((short)preferredportno);
+               if (bind(netfd, (struct sockaddr *) &sin, sizeof(sin)) < 0)
+               {
+#if defined(WIN32)  ||  defined(_WIN32_WCE)
+                       if (WSAGetLastError() == WSAEADDRINUSE)
+#else
+                       if (errno == EADDRINUSE)
+#endif
+                       {
+                               /*the port is already in use, so bind to a free port chosen by the IP stack*/
+                               DEBU(G "Unable to bind to preferred port - port is in use. Trying to bind to a free one");
+                               sin.sin_port = htons((short)0);
+                               if (bind(netfd, (struct sockaddr *) &sin, sizeof(sin)) < 0)
+                               {
+                                       IAXERROR "Unable to bind UDP socket\n");
+                                       return -1;
+                               }
+                       } else
+                       {
+                               IAXERROR "Unable to bind UDP socket\n");
+                               return -1;
+                       }
+               }
+
+               sinlen = sizeof(sin);
+               if (getsockname(netfd, (struct sockaddr *) &sin, &sinlen) < 0)
+               {
+                       close(netfd);
+                       netfd = -1;
+                       DEBU(G "Unable to figure out what I'm bound to.");
+                       IAXERROR "Unable to determine bound port number.");
+                       return -1;
+               }
+#if defined(WIN32)  ||  defined(_WIN32_WCE)
+               flags = 1;
+               if (ioctlsocket(netfd,FIONBIO,(unsigned long *) &flags))
+               {
+                       closesocket(netfd);
+                       netfd = -1;
+                       DEBU(G "Unable to set non-blocking mode.");
+                       IAXERROR "Unable to set non-blocking mode.");
+                       return -1;
+               }
+
+#else
+               if ((flags = fcntl(netfd, F_GETFL)) < 0)
+               {
+                       close(netfd);
+                       netfd = -1;
+                       DEBU(G "Unable to retrieve socket flags.");
+                       IAXERROR "Unable to retrieve socket flags.");
+                       return -1;
+               }
+               if (fcntl(netfd, F_SETFL, flags | O_NONBLOCK) < 0)
+               {
+                       close(netfd);
+                       netfd = -1;
+                       DEBU(G "Unable to set non-blocking mode.");
+                       IAXERROR "Unable to set non-blocking mode.");
+                       return -1;
+               }
+#endif
+               /* Mihai: increase UDP socket buffers to avoid packet loss. */
+               if (setsockopt(netfd, SOL_SOCKET, SO_RCVBUF, (char *)&bufsize,
+                                       sizeof(bufsize)) < 0)
+               {
+                       DEBU(G "Unable to set receive buffer size.");
+                       IAXERROR "Unable to set receive buffer size.");
+               }
+
+               /* set send buffer size too */
+               if (setsockopt(netfd, SOL_SOCKET, SO_SNDBUF, (char *)&bufsize,
+                                       sizeof(bufsize)) < 0)
+               {
+                       DEBU(G "Unable to set send buffer size.");
+                       IAXERROR "Unable to set send buffer size.");
+               }
+
+               portno = ntohs(sin.sin_port);
+               DEBU(G "Started on port %d\n", portno);
+       }
+
+       iax_seed_random();
+       callnums = 1 + (int)(32767.0 * (iax_random() / (RAND_MAX + 1.0)));
+
+       return portno;
+}
+
+static void destroy_session(struct iax_session *session);
+
+static void convert_reply(char *out, unsigned char *in)
+{
+       int x;
+       for (x=0;x<16;x++)
+               sprintf(out + (x << 1), "%2.2x", (int)in[x]);
+}
+
+static unsigned char compress_subclass(int subclass)
+{
+       int x;
+       int power=-1;
+       /* If it's 128 or smaller, just return it */
+       if (subclass < IAX_FLAG_SC_LOG)
+               return subclass;
+       /* Otherwise find its power */
+       for (x = 0; x < IAX_MAX_SHIFT; x++) {
+               if (subclass & (1 << x)) {
+                       if (power > -1) {
+                               DEBU(G "Can't compress subclass %d\n", subclass);
+                               return 0;
+                       } else
+                               power = x;
+               }
+       }
+       return power | IAX_FLAG_SC_LOG;
+}
+
+static int iax_send(struct iax_session *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final, int fullframe)
+{
+       /* Queue a packet for delivery on a given private structure.  Use "ts" for
+          timestamp, or calculate if ts is 0.  Send immediately without retransmission
+          or delayed, with retransmission */
+       struct ast_iax2_full_hdr *fh;
+       struct ast_iax2_mini_hdr *mh;
+       struct ast_iax2_video_hdr *vh;
+       //unsigned char buf[5120]; //fd: changed max packet size[5120];
+       unsigned char buf[32 * 1024]; //Mihai: let's see if this is where it crashes
+
+       struct iax_frame *fr;
+       int res;
+       int sendmini=0;
+       unsigned int lastsent;
+       unsigned int fts;
+
+       if (!pvt)
+       {
+               IAXERROR "No private structure for packet?\n");
+               return -1;
+       }
+
+       /* this must come before the next call to calc_timestamp() since
+        calc_timestamp() will change lastsent to the returned value */
+       lastsent = pvt->lastsent;
+
+       /* Calculate actual timestamp */
+       fts = calc_timestamp(pvt, ts, f);
+
+       if (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L))
+               /* High two bits are the same on timestamp, or sending on a trunk */ &&
+               (f->frametype == AST_FRAME_VOICE)
+               /* is a voice frame */ &&
+               (f->subclass == pvt->svoiceformat)
+               /* is the same type */ )
+       {
+               /* Force immediate rather than delayed transmission */
+               now = 1;
+               /* Mark that mini-style frame is appropriate */
+               sendmini = 1;
+       }
+
+       /* Bitmask taken from chan_iax2.c... I must ask Mark Spencer for this? I think not... */
+       if ( f->frametype == AST_FRAME_VIDEO )
+       {
+               /* Check if the timestamp has rolled over or if the video codec has changed */
+               if ( ((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
+                    (f->subclass == pvt->svideoformat)
+                  )
+               {
+                       /* send a mini video frame immediately */
+                       now = 1;
+                       sendmini = 1;
+               } else
+               {
+                       /* we want to send a fullframe and be able to retransmit it */
+                       now = 0;
+                       sendmini = 0;
+               }
+               pvt->lastvsent = fts;
+       }
+
+       /* if requested, force a full frame */
+       if ( fullframe )
+       {
+               now = 0;
+               sendmini = 0;
+       }
+       
+       /* Allocate an iax_frame */
+       if (now)
+       {
+               fr = (struct iax_frame *) buf;
+       } else
+       {
+               fr = iax_frame_new(DIRECTION_OUTGRESS, f->datalen);
+               if ( fr == NULL )
+               {
+                       IAXERROR "Out of memory\n");
+                       return -1;
+               }
+       }
+       
+       /* Copy our prospective frame into our immediate or retransmitted wrapper */
+       iax_frame_wrap(fr, f);
+
+       fr->ts = fts;
+       if (!fr->ts)
+       {
+               IAXERROR "timestamp is 0?\n");
+               if (!now)
+                       iax_frame_free(fr);
+               return -1;
+       }
+
+       fr->callno = pvt->callno;
+       fr->transfer = transfer;
+       fr->final = final;
+       fr->session = pvt;
+       if (!sendmini)
+       {
+               /* We need a full frame */
+               if (seqno > -1)
+                       fr->oseqno = seqno;
+               else
+                       fr->oseqno = pvt->oseqno++;
+               fr->iseqno = pvt->iseqno;
+               fh = (struct ast_iax2_full_hdr *)(((char *)fr->af.data) - sizeof(struct ast_iax2_full_hdr));
+               fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
+               fh->ts = htonl(fr->ts);
+               fh->oseqno = fr->oseqno;
+               if (transfer)
+               {
+                       fh->iseqno = 0;
+               } else
+                       fh->iseqno = fr->iseqno;
+                       /* Keep track of the last thing we've acknowledged */
+               pvt->aseqno = fr->iseqno;
+               fh->type = fr->af.frametype & 0xFF;
+               if (f->frametype == AST_FRAME_VIDEO)
+                       fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
+               else
+                       fh->csub = compress_subclass(fr->af.subclass);
+               if (transfer)
+               {
+                       fr->dcallno = pvt->transfercallno;
+               } else
+                       fr->dcallno = pvt->peercallno;
+               fh->dcallno = htons(fr->dcallno);
+               fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
+               fr->data = fh;
+               fr->retries = maxretries;
+               /* Retry after 2x the ping time has passed */
+               fr->retrytime = pvt->pingtime * 2;
+               if (fr->retrytime < MIN_RETRY_TIME)
+                       fr->retrytime = MIN_RETRY_TIME;
+               if (fr->retrytime > MAX_RETRY_TIME)
+                       fr->retrytime = MAX_RETRY_TIME;
+               /* Acks' don't get retried */
+               if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
+                       fr->retries = -1;
+               if (f->frametype == AST_FRAME_VOICE)
+               {
+                       pvt->svoiceformat = f->subclass;
+               }
+               else if (f->frametype == AST_FRAME_VIDEO)
+               {
+                       pvt->svideoformat = f->subclass & ~0x1;
+               }
+               if (now)
+               {
+                       res = iax_xmit_frame(fr);
+               } else
+                       res = iax_reliable_xmit(fr);
+       } else
+       {
+               if (fr->af.frametype == AST_FRAME_VIDEO)
+               {
+                       /* Video frame have no sequence number */
+                       fr->oseqno = -1;
+                       fr->iseqno = -1;
+                       vh = (struct ast_iax2_video_hdr *)(((char* )fr->af.data) - sizeof(struct ast_iax2_video_hdr));
+                       vh->zeros = 0;
+                       vh->callno = htons(0x8000 | fr->callno);
+                       vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
+                       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
+                       fr->data = vh;
+                       fr->retries = -1;
+                       res = iax_xmit_frame(fr);
+               } else
+               {
+                       /* Mini-frames have no sequence number */
+                       fr->oseqno = -1;
+                       fr->iseqno = -1;
+                       /* Mini frame will do */
+                       mh = (struct ast_iax2_mini_hdr *)(((char *)fr->af.data) - sizeof(struct ast_iax2_mini_hdr));
+                       mh->callno = htons(fr->callno);
+                       mh->ts = htons(fr->ts & 0xFFFF);
+                       fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
+                       fr->data = mh;
+                       fr->retries = -1;
+                       res = iax_xmit_frame(fr);
+               }
+       }
+       if( !now && fr!=NULL )
+               iax_frame_free( fr );
+       return res;
+}
+
+#if 0
+static int iax_predestroy(struct iax_session *pvt)
+{
+       if (!pvt) {
+               return -1;
+       }
+       if (!pvt->alreadygone) {
+               /* No more pings or lagrq's */
+               if (pvt->pingid > -1)
+                       ast_sched_del(sched, pvt->pingid);
+               if (pvt->lagid > -1)
+                       ast_sched_del(sched, pvt->lagid);
+               if (pvt->autoid > -1)
+                       ast_sched_del(sched, pvt->autoid);
+               if (pvt->initid > -1)
+                       ast_sched_del(sched, pvt->initid);
+               pvt->pingid = -1;
+               pvt->lagid = -1;
+               pvt->autoid = -1;
+               pvt->initid = -1;
+               pvt->alreadygone = 1;
+       }
+       return 0;
+}
+#endif
+
+static int __send_command(struct iax_session *i, char type, int command,
+               unsigned int ts, unsigned char *data, int datalen, int seqno,
+               int now, int transfer, int final, int fullframe, int samples)
+{
+       struct ast_frame f;
+       f.frametype = type;
+       f.subclass = command;
+       f.datalen = datalen;
+       f.samples = samples;
+       f.mallocd = 0;
+       f.offset = 0;
+#ifdef __GNUC__
+       f.src = (char *) __FUNCTION__;
+#else
+       f.src = (char *) __FILE__;
+#endif
+       f.data = data;
+       return iax_send(i, &f, ts, seqno, now, transfer, final, fullframe);
+}
+
+static int send_command(struct iax_session *i, char type, int command, unsigned int ts, unsigned char *data, int datalen, int seqno)
+{
+       return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0, 0, 0);
+}
+
+static int send_command_video(struct iax_session *i, char type, int command, unsigned int ts, unsigned char *data, int datalen, int seqno, int fullframe)
+{
+       return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0, fullframe, 0);
+}
+
+static int send_command_final(struct iax_session *i, char type, int command, unsigned int ts, unsigned char *data, int datalen, int seqno)
+{
+#if 0
+       /* It is assumed that the callno has already been locked */
+       iax_predestroy(i);
+#endif
+       int r;
+       r = __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1, 0, 0);
+       if (r >= 0) destroy_session(i);
+       return r;
+}
+
+static int send_command_immediate(struct iax_session *i, char type, int command, unsigned int ts, unsigned char *data, int datalen, int seqno)
+{
+       return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0, 0, 0);
+}
+
+static int send_command_transfer(struct iax_session *i, char type, int command, unsigned int ts, unsigned char *data, int datalen)
+{
+       return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0, 0, 0);
+}
+
+static int send_command_samples(struct iax_session *i, char type, int command, unsigned int ts, unsigned char *data, int datalen, int seqno, int samples)
+{
+       return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0, 0, samples);
+}
+
+
+int iax_transfer(struct iax_session *session, const char *number)
+{
+       static int res;                         //Return Code
+       struct iax_ie_data ied;                 //IE Data Structure (Stuff To Send)
+
+       // Clear The Memory Used For IE Buffer
+       memset(&ied, 0, sizeof(ied));
+
+       // Copy The Transfer Destination Into The IE Structure
+       iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, number);
+
+       // Send The Transfer Command - Asterisk Will Handle The Rest!
+       res = send_command(session, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
+
+       // Return Success
+       return 0;
+}
+
+static void stop_transfer(struct iax_session *session)
+{
+       struct iax_sched *sch;
+
+       sch = schedq;
+       while(sch) {
+               if (sch->frame && (sch->frame->session == session))
+                                       sch->frame->retries = -1;
+               sch = sch->next;
+       }
+}      /* stop_transfer */
+
+static void complete_transfer(struct iax_session *session, int peercallno, int xfr2peer, int preserveSeq)
+{
+       jb_frame frame;
+
+       session->peercallno = peercallno;
+       /* Change from transfer to session now */
+       if (xfr2peer) {
+               memcpy(&session->peeraddr, &session->transfer, sizeof(session->peeraddr));
+               memset(&session->transfer, 0, sizeof(session->transfer));
+               session->transferring = TRANSFER_NONE;
+               session->transferpeer = 0;
+               session->transfer_moh = 0;
+               /* Force retransmission of a real voice packet, and reset all timing */
+               session->svoiceformat = -1;
+               session->voiceformat = 0;
+               session->svideoformat = -1;
+               session->videoformat = 0;
+       }
+
+       memset(&session->rxcore, 0, sizeof(session->rxcore));
+       memset(&session->offset, 0, sizeof(session->offset));
+
+       /* Reset jitterbuffer */
+       while(jb_getall(session->jb,&frame) == JB_OK)
+               iax_event_free((struct iax_event *)frame.data);
+
+       jb_reset(session->jb);
+
+       if (! preserveSeq)
+       {
+               /* Reset sequence numbers */
+               session->aseqno = 0;
+               session->oseqno = 0;
+               session->iseqno = 0;
+       }
+
+       session->lastsent = 0;
+       session->last_ts = 0;
+       session->pingtime = 30;
+       /* We have to dump anything we were going to (re)transmit now that we've been
+          transferred since they're all invalid and for the old host. */
+       stop_transfer(session);
+}      /* complete_transfer */
+
+int iax_setup_transfer(struct iax_session *org_session, struct iax_session *new_session)
+{
+       int res;
+       struct iax_ie_data ied0;
+       struct iax_ie_data ied1;
+
+       struct iax_session *s0 = org_session;
+       struct iax_session *s1 = new_session;
+
+       int transfer_id = 1 + (int)(32767.0 * (iax_random() / (RAND_MAX + 1.0)));
+
+       memset(&ied0, 0, sizeof(ied0));
+
+       memset(&ied1, 0, sizeof(ied1));
+
+       /* reversed setup */
+       iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &s1->peeraddr);
+       iax_ie_append_short(&ied0, IAX_IE_CALLNO, s1->peercallno);
+       iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transfer_id);
+
+       iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &s0->peeraddr);
+       iax_ie_append_short(&ied1, IAX_IE_CALLNO, s0->peercallno);
+       iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transfer_id);
+
+       s0->transfer = s1->peeraddr;
+       s1->transfer = s0->peeraddr;
+
+       s0->transferid = transfer_id;
+       s1->transferid = transfer_id;
+
+       s0->transfercallno = s0->peercallno;
+       s1->transfercallno = s1->peercallno;
+
+       s0->transferring = TRANSFER_BEGIN;
+       s1->transferring = TRANSFER_BEGIN;
+
+       s0->transferpeer = s1->callno;
+       s1->transferpeer = s0->callno;
+#ifdef DEBUG_SUPPORT
+       if (debug) {
+               DEBU(G "iax_setup_transfer(%d, %d) transfer_id=%d\n", s0->callno, s1->callno, transfer_id);
+               DEBU(G "\torg: callno=%d peercallno=%d peeraddr=%s peerport=%d\n", s0->callno, s0->peercallno, inet_ntoa(s0->peeraddr.sin_addr), ntohs(s0->peeraddr.sin_port));
+               DEBU(G "\tnew: callno=%d peercallno=%d peeraddr=%s peerport=%d\n", s1->callno, s1->peercallno, inet_ntoa(s1->peeraddr.sin_addr), ntohs(s1->peeraddr.sin_port));
+       }
+#endif
+
+       res = send_command(s0, AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
+       if (res < 0) {
+               return -1;
+       }
+
+       res = send_command(s1, AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
+       if (res < 0) {
+               return -1;
+       }
+
+       return 0;
+}
+
+static int iax_finish_transfer(struct iax_session *s, short new_peer)
+{
+       int res;
+       struct iax_ie_data ied;
+
+       memset(&ied, 0, sizeof(ied));
+
+       iax_ie_append_short(&ied, IAX_IE_CALLNO, new_peer);
+
+       res = send_command(s, AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied.buf, ied.pos, -1);
+
+       complete_transfer(s, new_peer, 0, 1);
+
+       return res;
+
+}
+
+static struct iax_session *iax_find_session2(short callno)
+{
+       struct iax_session *cur = sessions;
+
+       while(cur) {
+               if (callno == cur->callno && callno != 0)  {
+                       return cur;
+               }
+               cur = cur->next;
+       }
+
+       return NULL;
+}
+
+static int iax_handle_txready(struct iax_session *s)
+{
+       struct iax_session *s0, *s1;
+       short s0_org_peer, s1_org_peer;
+
+       if (s->transfer_moh) {
+               s->transfer_moh = 0;
+               iax_unquelch(s);
+       }
+
+       complete_transfer(s, s->peercallno, 0, 1);
+
+       s->transferring = TRANSFER_REL;
+
+       s0 = s;
+       s1 = iax_find_session2(s0->transferpeer);
+
+       if (s1 != NULL &&
+           s1->callno == s0->transferpeer &&
+           s0->transferring == TRANSFER_REL &&
+           s1->transferring == TRANSFER_REL) {
+
+               s0_org_peer = s0->peercallno;
+               s1_org_peer = s1->peercallno;
+
+               iax_finish_transfer(s0, s1_org_peer);
+               iax_finish_transfer(s1, s0_org_peer);
+               return 1;
+       }
+
+       return 0;
+}
+
+static void iax_handle_txreject(struct iax_session *s)
+{
+       struct iax_session *s0, *s1;
+
+       s0 = s;
+       s1 = iax_find_session2(s0->transferpeer);
+       if (s1 != NULL &&
+                s0->transferpeer == s1->callno &&
+                s1->transferring) {
+               if (s1->transfer_moh) {
+                       s1->transfer_moh = 0;
+                       send_command_immediate(s1, AST_FRAME_IAX, IAX_COMMAND_UNQUELCH, 0, NULL, 0, s1->iseqno);
+               }
+       }
+       if (s0->transfer_moh) {
+               s0->transfer_moh = 0;
+               send_command_immediate(s0, AST_FRAME_IAX, IAX_COMMAND_UNQUELCH, 0, NULL, 0, s0->iseqno);
+       }
+
+       memset(&s->transfer, 0, sizeof(s->transfer));
+       s->transferring = TRANSFER_NONE;
+       s->transferpeer = 0;
+       s->transfer_moh = 0;
+}
+
+static void destroy_session(struct iax_session *session)
+{
+       struct iax_session *cur, *prev=NULL;
+       struct iax_sched *curs, *prevs=NULL, *nexts=NULL;
+       int    loop_cnt=0;
+       curs = schedq;
+       while(curs) {
+               nexts = curs->next;
+               if (curs->frame && curs->frame->session == session) {
+                       /* Just mark these frames as if they've been sent */
+                       curs->frame->retries = -1;
+               } else if (curs->event && curs->event->session == session) {
+                       if (prevs)
+                               prevs->next = nexts;
+                       else
+                               schedq = nexts;
+                       if (curs->event)
+                               iax_event_free(curs->event);
+                       free(curs);
+               } else {
+                       prevs = curs;
+               }
+               curs = nexts;
+               loop_cnt++;
+       }
+
+       cur = sessions;
+       while(cur) {
+               if (cur == session) {
+                       jb_frame frame;
+
+                       if (prev)
+                               prev->next = session->next;
+                       else
+                               sessions = session->next;
+
+                       while(jb_getall(session->jb,&frame) == JB_OK)
+                               iax_event_free((struct iax_event *)frame.data);
+
+                       jb_destroy(session->jb);
+
+                       free(session);
+                       return;
+               }
+               prev = cur;
+               cur = cur->next;
+       }
+}
+
+static int iax_send_lagrp(struct iax_session *session, unsigned int ts);
+static int iax_send_pong(struct iax_session *session, unsigned int ts);
+
+static struct iax_event *handle_event(struct iax_event *event)
+{
+       /* We have a candidate event to be delievered.  Be sure
+          the session still exists. */
+       if (event)
+       {
+               if ( event->etype == IAX_EVENT_NULL ) return event;
+               if (iax_session_valid(event->session))
+               {
+                       /* Lag requests are never actually sent to the client, but
+                          other than that are handled as normal packets */
+                       switch(event->etype)
+                       {
+                               /* the user on the outside may need to look at the session so we will not free
+                                  it here anymore we will test for hangup event in iax_event_free and do it
+                                  there.
+                                */
+                       case IAX_EVENT_REJECT:
+                       case IAX_EVENT_HANGUP:
+                               /* Destroy this session -- it's no longer valid */
+                               destroy_session(event->session);
+                               return event;
+                       case IAX_EVENT_LAGRQ:
+                               event->etype = IAX_EVENT_LAGRP;
+                               iax_send_lagrp(event->session, event->ts);
+                               iax_event_free(event);
+                               break;
+                       case IAX_EVENT_PING:
+                               event->etype = IAX_EVENT_PONG;
+                               iax_send_pong(event->session, event->ts);
+                               iax_event_free(event);
+                               break;
+                       case IAX_EVENT_POKE:
+                               event->etype = IAX_EVENT_PONG;
+                               iax_send_pong(event->session, event->ts);
+                               destroy_session(event->session);
+                               iax_event_free(event);
+                               break;
+                       default:
+                               return event;
+                       }
+               } else
+                       iax_event_free(event);
+       }
+       return NULL;
+}
+
+static int iax2_vnak(struct iax_session *session)
+{
+       /* send vnak just once for a given sequence number */
+       if ( (unsigned char)(session->lastvnak - session->iseqno) < 128 )
+       {
+               return 0;
+       }
+
+       session->lastvnak = session->iseqno;
+       return send_command_immediate(session, AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, session->iseqno);
+}
+
+int iax_send_dtmf(struct iax_session *session, char digit)
+{
+       return send_command(session, AST_FRAME_DTMF, digit, 0, NULL, 0, -1);
+}
+
+int iax_send_voice(struct iax_session *session, int format, unsigned char *data, int datalen, int samples)
+{
+       /* Send a (possibly compressed) voice frame */
+       if (!session->quelch)
+               return send_command_samples(session, AST_FRAME_VOICE, format, 0, data, datalen, -1, samples);
+       return 0;
+}
+
+int iax_send_cng(struct iax_session *session, int level, unsigned char *data,
+               int datalen)
+{
+#ifdef USE_VOICE_TS_PREDICTION
+       session->notsilenttx = 0;
+#endif
+       return send_command(session, AST_FRAME_CNG, level, 0, data, datalen, -1);
+}
+
+int iax_send_image(struct iax_session *session, int format, unsigned char *data,
+               int datalen)
+{
+       /* Send an image frame */
+       return send_command(session, AST_FRAME_IMAGE, format, 0, data, datalen, -1);
+}
+
+int iax_send_video(struct iax_session *session, int format, unsigned char *data,
+               int datalen, int fullframe)
+{
+       if (!session->quelch)
+       {
+               int res = send_command_video(session, AST_FRAME_VIDEO, format,
+                               0, data, datalen, -1, fullframe);
+               return res;
+       }
+       return 0;
+}
+
+int iax_send_video_trunk(struct iax_session *session, int format,
+               char *data, int datalen, int fullframe, int ntrunk)
+{
+       static int my_lastts = 0;
+
+       if ( ntrunk == 0 )
+               my_lastts = calc_timestamp(session, 0, NULL);
+
+       if ( !session->quelch )
+       {
+               return send_command_video(session, AST_FRAME_VIDEO, format,
+                               my_lastts, (unsigned char *)data, datalen, -1,
+                               fullframe);
+       }
+       return 0;
+}
+
+int iax_video_bypass_jitter(struct iax_session *s, int mode)
+{
+       video_bypass_jitterbuffer = mode;
+       return 0;
+}
+
+int iax_register(struct iax_session *session, const char *server, const char *peer, const char *secret, int refresh)
+{
+       /* Send a registration request */
+       char tmp[256];
+       char *p;
+       int res;
+       int portno = IAX_DEFAULT_PORTNO;
+       struct iax_ie_data ied;
+       struct hostent *hp;
+
+       tmp[255] = '\0';
+       strncpy(tmp, server, sizeof(tmp) - 1);
+       p = strchr(tmp, ':');
+       if (p) {
+               *p = '\0';
+               portno = atoi(p+1);
+       }
+
+       memset(&ied, 0, sizeof(ied));
+       if (secret)
+               strncpy(session->secret, secret, sizeof(session->secret) - 1);
+       else
+               strcpy(session->secret, "");
+
+       memset(&session->unregreason, 0, sizeof(session->unregreason));
+
+       /* Connect first */
+       hp = gethostbyname(tmp);
+       if (!hp) {
+               snprintf(iax_errstr, sizeof(iax_errstr), "Invalid hostname: %s", tmp);
+               return -1;
+       }
+       memcpy(&session->peeraddr.sin_addr, hp->h_addr, sizeof(session->peeraddr.sin_addr));
+       session->peeraddr.sin_port = htons(portno);
+       session->peeraddr.sin_family = AF_INET;
+       strncpy(session->username, peer, sizeof(session->username) - 1);
+       session->refresh = refresh;
+       iax_ie_append_str(&ied, IAX_IE_USERNAME, peer);
+       iax_ie_append_short(&ied, IAX_IE_REFRESH, refresh);
+       res = send_command(session, AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
+       return res;
+}
+
+int iax_unregister(struct iax_session *session, const char *server, const char *peer, const char *secret, const char *reason)
+{
+       /* Send an unregistration request */
+       char tmp[256];
+       char *p;
+       int portno = IAX_DEFAULT_PORTNO;
+       struct iax_ie_data ied;
+       struct hostent *hp;
+
+       tmp[255] = '\0';
+       strncpy(tmp, server, sizeof(tmp) - 1);
+       p = strchr(tmp, ':');
+       if (p) {
+               *p = '\0';
+               portno = atoi(p+1);
+       }
+
+       memset(&ied, 0, sizeof(ied));
+       if (secret)
+               strncpy(session->secret, secret, sizeof(session->secret) - 1);
+       else
+               strcpy(session->secret, "");
+
+       if (reason && strlen(reason))
+               strncpy(session->unregreason, reason, sizeof(session->unregreason) - 1);
+       else
+               strcpy(session->unregreason, "Unspecified");
+
+       /* Connect first */
+       hp = gethostbyname(tmp);
+       if (!hp) {
+               snprintf(iax_errstr, sizeof(iax_errstr), "Invalid hostname: %s", tmp);
+               return -1;
+       }
+       memcpy(&session->peeraddr.sin_addr, hp->h_addr, sizeof(session->peeraddr.sin_addr));
+       session->peeraddr.sin_port = htons(portno);
+       session->peeraddr.sin_family = AF_INET;
+       strncpy(session->username, peer, sizeof(session->username) - 1);
+       iax_ie_append_str(&ied, IAX_IE_USERNAME, peer);
+       iax_ie_append_str(&ied, IAX_IE_CAUSE, session->unregreason);
+       return send_command(session, AST_FRAME_IAX, IAX_COMMAND_REGREL, 0, ied.buf, ied.pos, -1);
+}
+
+int iax_reject(struct iax_session *session, char *reason)
+{
+       struct iax_ie_data ied;
+       memset(&ied, 0, sizeof(ied));
+       iax_ie_append_str(&ied, IAX_IE_CAUSE, reason ? reason : "Unspecified");
+       return send_command_final(session, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
+}
+
+int iax_hangup(struct iax_session *session, char *byemsg)
+{
+       struct iax_ie_data ied;
+       iax_sched_del(NULL, NULL, send_ping, (void *) session, 1);
+       memset(&ied, 0, sizeof(ied));
+       iax_ie_append_str(&ied, IAX_IE_CAUSE, byemsg ? byemsg : "Normal clearing");
+       return send_command_final(session, AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
+}
+
+int iax_sendurl(struct iax_session *session, char *url)
+{
+       return send_command(session, AST_FRAME_HTML, AST_HTML_URL, 0,
+                       (unsigned char *)url, (int)strlen(url), -1);
+}
+
+int iax_ring_announce(struct iax_session *session)
+{
+       return send_command(session, AST_FRAME_CONTROL, AST_CONTROL_RINGING, 0, NULL, 0, -1);
+}
+
+int iax_lag_request(struct iax_session *session)
+{
+       return send_command(session, AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
+}
+
+int iax_busy(struct iax_session *session)
+{
+       return send_command(session, AST_FRAME_CONTROL, AST_CONTROL_BUSY, 0, NULL, 0, -1);
+}
+
+int iax_congestion(struct iax_session *session)
+{
+       return send_command(session, AST_FRAME_CONTROL, AST_CONTROL_CONGESTION, 0, NULL, 0, -1);
+}
+
+
+int iax_accept(struct iax_session *session, int format)
+{
+       struct iax_ie_data ied;
+       memset(&ied, 0, sizeof(ied));
+       iax_ie_append_int(&ied, IAX_IE_FORMAT, format);
+       return send_command(session, AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied.buf, ied.pos, -1);
+}
+
+int iax_answer(struct iax_session *session)
+{
+       return send_command(session, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
+}
+
+int iax_load_complete(struct iax_session *session)
+{
+       return send_command(session, AST_FRAME_HTML, AST_HTML_LDCOMPLETE, 0, NULL, 0, -1);
+}
+
+int iax_send_url(struct iax_session *session, const char *url, int link)
+{
+       return send_command(session, AST_FRAME_HTML,
+                       link ? AST_HTML_LINKURL : AST_HTML_URL, 0,
+                       (unsigned char *)url, (int)strlen(url), -1);
+}
+
+int iax_send_text(struct iax_session *session, const char *text)
+{
+       return send_command(session, AST_FRAME_TEXT, 0, 0,
+                       (unsigned char *)text, (int)strlen(text) + 1, -1);
+}
+
+int iax_send_unlink(struct iax_session *session)
+{
+       return send_command(session, AST_FRAME_HTML, AST_HTML_UNLINK, 0, NULL, 0, -1);
+}
+
+int iax_send_link_reject(struct iax_session *session)
+{
+       return send_command(session, AST_FRAME_HTML, AST_HTML_LINKREJECT, 0, NULL, 0, -1);
+}
+
+static int iax_send_pong(struct iax_session *session, unsigned int ts)
+{
+        struct iax_ie_data ied;
+       jb_info stats;
+
+        memset(&ied, 0, sizeof(ied));
+
+       jb_getinfo(session->jb, &stats);
+
+       iax_ie_append_int(&ied,IAX_IE_RR_JITTER, stats.jitter);
+       /* XXX: should be short-term loss pct.. */
+       if(stats.frames_in == 0) stats.frames_in = 1;
+       iax_ie_append_int(&ied,IAX_IE_RR_LOSS,
+                       ((0xff & (stats.losspct/1000)) << 24 |
+                        (stats.frames_lost & 0x00ffffff)));
+       iax_ie_append_int(&ied,IAX_IE_RR_PKTS, stats.frames_in);
+       iax_ie_append_short(&ied,IAX_IE_RR_DELAY,
+                       (unsigned short)(stats.current - stats.min));
+       iax_ie_append_int(&ied,IAX_IE_RR_DROPPED, stats.frames_dropped);
+       iax_ie_append_int(&ied,IAX_IE_RR_OOO, stats.frames_ooo);
+
+       return send_command(session, AST_FRAME_IAX, IAX_COMMAND_PONG, ts, ied.buf, ied.pos, -1);
+}
+
+/* external API; deprecated since we send pings ourselves now (finally) */
+int iax_send_ping(struct iax_session *session)
+{
+       return send_command(session, AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
+}
+
+/* scheduled ping sender; sends ping, then reschedules */
+static void send_ping(void *s)
+{
+       struct iax_session *session = (struct iax_session *)s;
+
+       /* important, eh? */
+       if(!iax_session_valid(session)) return;
+
+       send_command(session, AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
+       session->pingid = iax_sched_add(NULL,NULL, send_ping, (void *)session, ping_time * 1000);
+       return;
+}
+
+static int iax_send_lagrp(struct iax_session *session, unsigned int ts)
+{
+       return send_command(session, AST_FRAME_IAX, IAX_COMMAND_LAGRP, ts, NULL, 0, -1);
+}
+
+static int iax_send_txcnt(struct iax_session *session)
+{
+       struct iax_ie_data ied;
+       memset(&ied, 0, sizeof(ied));
+       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, session->transferid);
+       return send_command_transfer(session, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
+}
+
+static int iax_send_txrej(struct iax_session *session)
+{
+       struct iax_ie_data ied;
+       memset(&ied, 0, sizeof(ied));
+       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, session->transferid);
+       return send_command_transfer(session, AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, ied.buf, ied.pos);
+}
+
+static int iax_send_txaccept(struct iax_session *session)
+{
+       struct iax_ie_data ied;
+       memset(&ied, 0, sizeof(ied));
+       iax_ie_append_int(&ied, IAX_IE_TRANSFERID, session->transferid);
+       return send_command_transfer(session, AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, ied.buf, ied.pos);
+}
+
+static int iax_send_txready(struct iax_session *session)
+{
+       struct iax_ie_data ied;
+       memset(&ied, 0, sizeof(ied));
+       /* see asterisk chan_iax2.c */
+       iax_ie_append_short(&ied, IAX_IE_CALLNO, session->callno);
+       return send_command(session, AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied.buf, ied.pos, -1);
+}
+
+int iax_auth_reply(struct iax_session *session, char *password, char *challenge, int methods)
+{
+       char reply[16];
+       struct MD5Context md5;
+       char realreply[256];
+       struct iax_ie_data ied;
+       memset(&ied, 0, sizeof(ied));
+       if ((methods & IAX_AUTH_MD5) && challenge) {
+               MD5Init(&md5);
+               MD5Update(&md5, (const unsigned char *) challenge,
+                               (unsigned int)strlen(challenge));
+               MD5Update(&md5, (const unsigned char *) password,
+                               (unsigned int)strlen(password));
+               MD5Final((unsigned char *) reply, &md5);
+               memset(realreply, 0, sizeof(realreply));
+               convert_reply(realreply, (unsigned char *) reply);
+               iax_ie_append_str(&ied, IAX_IE_MD5_RESULT, realreply);
+       } else {
+               iax_ie_append_str(&ied, IAX_IE_PASSWORD, password);
+       }
+       return send_command(session, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
+}
+
+static int iax_regauth_reply(struct iax_session *session, char *password, char *challenge, int methods)
+{
+       char reply[16];
+       struct MD5Context md5;
+       char realreply[256];
+       struct iax_ie_data ied;
+       memset(&ied, 0, sizeof(ied));
+       iax_ie_append_str(&ied, IAX_IE_USERNAME, session->username);
+       if ((methods & IAX_AUTHMETHOD_MD5) && challenge) {
+               MD5Init(&md5);
+               MD5Update(&md5, (const unsigned char *) challenge,
+                               (unsigned int)strlen(challenge));
+               MD5Update(&md5, (const unsigned char *) password,
+                               (unsigned int)strlen(password));
+               MD5Final((unsigned char *) reply, &md5);
+               memset(realreply, 0, sizeof(realreply));
+               convert_reply(realreply, (unsigned char *) reply);
+               iax_ie_append_str(&ied, IAX_IE_MD5_RESULT, realreply);
+       } else {
+               iax_ie_append_str(&ied, IAX_IE_PASSWORD, password);
+       }
+       if (strlen(session->unregreason)) {             /* Non-zero unregreason length indicates REGREL */
+               iax_ie_append_str(&ied, IAX_IE_CAUSE, session->unregreason);
+               return send_command(session, AST_FRAME_IAX, IAX_COMMAND_REGREL, 0, ied.buf, ied.pos, -1);
+       } else {
+               iax_ie_append_short(&ied, IAX_IE_REFRESH, session->refresh);
+               return send_command(session, AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
+       }
+}
+
+
+int iax_dial(struct iax_session *session, char *number)
+{
+       struct iax_ie_data ied;
+       memset(&ied, 0, sizeof(ied));
+       iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, number);
+       return send_command(session, AST_FRAME_IAX, IAX_COMMAND_DIAL, 0, ied.buf, ied.pos, -1);
+}
+
+int iax_quelch(struct iax_session *session)
+{
+       return send_command(session, AST_FRAME_IAX, IAX_COMMAND_QUELCH, 0, NULL, 0, -1);
+}
+
+int iax_unquelch(struct iax_session *session)
+{
+       return send_command(session, AST_FRAME_IAX, IAX_COMMAND_UNQUELCH, 0, NULL, 0, -1);
+}
+
+int iax_dialplan_request(struct iax_session *session, char *number)
+{
+       struct iax_ie_data ied;
+       memset(&ied, 0, sizeof(ied));
+       iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, number);
+       return send_command(session, AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
+}
+
+static inline int which_bit(unsigned int i)
+{
+       char x;
+       for(x = 0; x < 32; x++) {
+               if ((1U << x) == i) {
+                       return x + 1;
+               }
+       }
+       return 0;
+}
+
+char iax_pref_codec_add(struct iax_session *session, unsigned int format)
+{
+       int diff = (int) 'A';
+       session->codec_order[session->codec_order_len++] = (which_bit(format)) + diff;
+       session->codec_order[session->codec_order_len] = '\0';
+       return session->codec_order[session->codec_order_len-1];
+}
+
+
+void iax_pref_codec_del(struct iax_session *session, unsigned int format)
+{
+       int diff = (int) 'A';
+       int x;
+       char old[32];
+       char remove = which_bit(format) + diff;
+
+       strncpy(old, session->codec_order, sizeof(old));
+       session->codec_order_len = 0;
+
+       for (x = 0;  x < (int) strlen(old);  x++) {
+               if (old[x] != remove) {
+                       session->codec_order[session->codec_order_len++] = old[x];
+               }
+       }
+       session->codec_order[session->codec_order_len] = '\0';
+}
+
+int iax_pref_codec_get(struct iax_session *session, unsigned int *array, int len)
+{
+       int diff = (int) 'A';
+       int x;
+
+       for (x = 0; x < session->codec_order_len && x < len; x++) {
+               array[x] = (1 << (session->codec_order[x] - diff - 1));
+       }
+
+       return x;
+}
+
+int iax_call(struct iax_session *session, const char *cidnum, const char *cidname, const char *ich, const char *lang, int wait, int formats, int capabilities)
+{
+       char tmp[256]="";
+       char *part1, *part2;
+       int res;
+       int portno;
+       char *username, *hostname, *secret, *context, *exten, *dnid;
+       struct iax_ie_data ied;
+       struct hostent *hp;
+       /* We start by parsing up the temporary variable which is of the form of:
+          [user@]peer[:portno][/exten[@context]] */
+       if (!ich) {
+               IAXERROR "Invalid IAX Call Handle\n");
+               DEBU(G "Invalid IAX Call Handle\n");
+               return -1;
+       }
+       memset(&ied, 0, sizeof(ied));
+       strncpy(tmp, ich, sizeof(tmp) - 1);
+       iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
+       if (cidnum)
+               iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, cidnum);
+       if (cidname)
+               iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, cidname);
+
+       if (session->codec_order_len) {
+               iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, session->codec_order);
+       }
+
+       session->capability = capabilities;
+       session->pingid = iax_sched_add(NULL,NULL, send_ping, (void *)session, 2 * 1000);
+
+       /* XXX We should have a preferred format XXX */
+       iax_ie_append_int(&ied, IAX_IE_FORMAT, formats);
+       iax_ie_append_int(&ied, IAX_IE_CAPABILITY, capabilities);
+       if (lang)
+               iax_ie_append_str(&ied, IAX_IE_LANGUAGE, lang);
+
+       /* Part 1 is [user[:password]@]peer[:port] */
+       part1 = strtok(tmp, "/");
+
+       /* Part 2 is exten[@context] if it is anything all */
+       part2 = strtok(NULL, "/");
+
+       if (strchr(part1, '@')) {
+               username = strtok(part1, "@");
+               hostname = strtok(NULL, "@");
+       } else {
+               username = NULL;
+               hostname = part1;
+       }
+
+       if (username && strchr(username, ':')) {
+               username = strtok(username, ":");
+               secret = strtok(NULL, ":");
+       } else
+               secret = NULL;
+
+       if(username)
+               strncpy(session->username, username, sizeof(session->username) - 1);
+
+       if(secret)
+               strncpy(session->secret, secret, sizeof(session->secret) - 1);
+
+       if (strchr(hostname, ':')) {
+               strtok(hostname, ":");
+               portno = atoi(strtok(NULL, ":"));
+       } else {
+               portno = IAX_DEFAULT_PORTNO;
+       }
+       if (part2) {
+               exten = strtok(part2, "@");
+               dnid = exten;
+               context = strtok(NULL, "@");
+       } else {
+               exten = NULL;
+               dnid = NULL;
+               context = NULL;
+       }
+       if (username)
+               iax_ie_append_str(&ied, IAX_IE_USERNAME, username);
+       if (exten && strlen(exten))
+               iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, exten);
+       if (dnid && strlen(dnid))
+               iax_ie_append_str(&ied, IAX_IE_DNID, dnid);
+       if (context && strlen(context))
+               iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
+
+       /* Setup host connection */
+       hp = gethostbyname(hostname);
+       if (!hp) {
+               snprintf(iax_errstr, sizeof(iax_errstr), "Invalid hostname: %s", hostname);
+               return -1;
+       }
+       memcpy(&session->peeraddr.sin_addr, hp->h_addr, sizeof(session->peeraddr.sin_addr));
+       session->peeraddr.sin_port = htons(portno);
+       session->peeraddr.sin_family = AF_INET;
+       res = send_command(session, AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
+       if (res < 0)
+               return res;
+       if (wait) {
+               DEBU(G "Waiting not yet implemented\n");
+               return -1;
+       }
+       return res;
+}
+
+static int calc_rxstamp(struct iax_session *session)
+{
+       struct timeval tv;
+       int ms;
+
+       if (!session->rxcore.tv_sec && !session->rxcore.tv_usec) {
+               session->rxcore = iax_tvnow();
+       }
+       tv = iax_tvnow();
+
+       ms = (tv.tv_sec - session->rxcore.tv_sec) * 1000 +
+                (tv.tv_usec - session->rxcore.tv_usec) / 1000;
+               return ms;
+}
+
+#ifdef notdef_cruft
+static int match(struct sockaddr_in *sin, short callno, short dcallno, struct iax_session *cur)
+{
+       if ((cur->peeraddr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
+               (cur->peeraddr.sin_port == sin->sin_port)) {
+               /* This is the main host */
+               if ((cur->peercallno == callno) ||
+                       ((dcallno == cur->callno) && !cur->peercallno)) {
+                       /* That's us.  Be sure we keep track of the peer call number */
+                       cur->peercallno = callno;
+                       return 1;
+               }
+       }
+       if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
+           (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
+               /* We're transferring */
+               if (dcallno == cur->callno)
+                       return 1;
+       }
+       return 0;
+}
+#endif
+
+/* splitted match into 2 passes otherwise causing problem of matching
+   up the wrong session using the dcallno and the peercallno because
+   during a transfer (2 IAX channels on the same client/system) the
+   same peercallno (from two different asterisks) exist in more than
+   one session.
+ */
+static int forward_match(struct sockaddr_in *sin, short callno, short dcallno, struct iax_session *cur)
+{
+       if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
+               (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
+               /* We're transferring */
+               if (dcallno == cur->callno)
+               {
+                       return 1;
+               }
+       }
+
+       if ((cur->peeraddr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
+               (cur->peeraddr.sin_port == sin->sin_port)) {
+               if (dcallno == cur->callno && dcallno != 0)  {
+                       /* That's us.  Be sure we keep track of the peer call number */
+                       if (cur->peercallno == 0) {
+                               cur->peercallno = callno;
+                       }
+                       else if ( cur->peercallno != callno ) 
+                       {
+                               // print a warning when the callno's don't match
+                               fprintf( stderr, "WARNING: peercallno does not match callno"
+                                       ", peercallno => %d, callno => %d, dcallno => %d",
+                                       cur->peercallno, callno, dcallno ) ;
+                               return 0 ;
+                       }
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+static int reverse_match(struct sockaddr_in *sin, short callno, struct iax_session *cur)
+{
+       if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
+               (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
+               /* We're transferring */
+               if (callno == cur->peercallno)  {
+                       return 1;
+               }
+       }
+       if ((cur->peeraddr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
+               (cur->peeraddr.sin_port == sin->sin_port)) {
+               if (callno == cur->peercallno)  {
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+static struct iax_session *iax_find_session(struct sockaddr_in *sin,
+               short callno,
+               short dcallno,
+               int makenew)
+{
+       struct iax_session *cur = sessions;
+       while(cur) {
+               if (forward_match(sin, callno, dcallno, cur)) {
+                       return cur;
+               }
+               cur = cur->next;
+       }
+
+       cur = sessions;
+       while(cur) {
+               if (reverse_match(sin, callno, cur)) {
+                       return cur;
+               }
+               cur = cur->next;
+       }
+
+       if (makenew && !dcallno) {
+               cur = iax_session_new();
+               cur->peercallno = callno;
+               cur->peeraddr.sin_addr.s_addr = sin->sin_addr.s_addr;
+               cur->peeraddr.sin_port = sin->sin_port;
+               cur->peeraddr.sin_family = AF_INET;
+               cur->pingid = iax_sched_add(NULL,NULL, send_ping, (void *)cur, 2 * 1000);
+               DEBU(G "Making new session, peer callno %d, our callno %d\n", callno, cur->callno);
+       } else {
+               DEBU(G "No session, peer = %d, us = %d\n", callno, dcallno);
+       }
+       return cur;
+}
+
+#ifdef EXTREME_DEBUG
+static int display_time(int ms)
+{
+       static int oldms = -1;
+       if (oldms < 0) {
+               DEBU(G "First measure\n");
+               oldms = ms;
+               return 0;
+       }
+       DEBU(G "Time from last frame is %d ms\n", ms - oldms);
+       oldms = ms;
+       return 0;
+}
+#endif
+
+/* From chan_iax2/steve davies:  need to get permission from steve or digium, I guess */
+static long unwrap_timestamp(long ts, long last)
+{
+       int x;
+
+       if ( (ts & 0xFFFF0000) == (last & 0xFFFF0000) ) {
+               x = ts - last;
+               if (x < -50000) {
+                       /* Sudden big jump backwards in timestamp:
+                          What likely happened here is that miniframe
+                          timestamp has circled but we haven't gotten the
+                          update from the main packet. We'll just pretend
+                          that we did, and update the timestamp
+                          appropriately. */
+                       ts = ( (last & 0xFFFF0000) + 0x10000) | (ts & 0xFFFF);
+                       DEBU(G "schedule_delivery: pushed forward timestamp\n");
+               }
+               if (x > 50000) {
+                       /* Sudden apparent big jump forwards in timestamp:
+                          What's likely happened is this is an old miniframe
+                          belonging to the previous top-16-bit timestamp that
+                          has turned up out of order. Adjust the timestamp
+                          appropriately. */
+                       ts = ( (last & 0xFFFF0000) - 0x10000) | (ts & 0xFFFF);
+                       DEBU(G "schedule_delivery: pushed back timestamp\n");
+               }
+       }
+       else if ( (ts & 0xFFFF8000L) == (last & 0xFFFF8000L) ) {
+               x = ts - last;
+               if (x < -50000) {
+                       /* Sudden big jump backwards in timestamp:
+                          What likely happened here is that miniframe
+                          timestamp has circled but we haven't gotten the
+                          update from the main packet. We'll just pretend
+                          that we did, and update the timestamp
+                          appropriately. */
+                       ts = ( (last & 0xFFFF8000L) + 0x10000) | (ts & 0xFFFF);
+                       DEBU(G "schedule_delivery: pushed forward timestamp\n");
+               }
+               if (x > 50000) {
+                       /* Sudden apparent big jump forwards in timestamp:
+                        * What's likely happened is this is an old miniframe
+                        * belonging to the previous top-16-bit timestamp that
+                        * has turned up out of order. Adjust the timestamp
+                        * appropriately. */
+                       ts = ( (last & 0xFFFF8000L) - 0x10000) | (ts & 0xFFFF);
+                       DEBU(G "schedule_delivery: pushed back timestamp\n");
+               }
+       }
+       return ts;
+}
+
+
+static struct iax_event *schedule_delivery(struct iax_event *e, unsigned int ts, int updatehistory)
+{
+       /*
+        * This is the core of the IAX jitterbuffer delivery mechanism:
+        * Dynamically adjust the jitterbuffer and decide how long to wait
+        * before delivering the packet.
+        */
+
+#ifdef EXTREME_DEBUG
+       DEBU(G "[%p] We are at %d, packet is for %d\n", e->session, calc_rxstamp(e->session), ts);
+#endif
+
+       /* insert into jitterbuffer */
+       /* TODO: Perhaps we could act immediately if it's not droppable and late */
+       if ( !iax_use_jitterbuffer ||
+                       (e->etype == IAX_EVENT_VIDEO &&
+                        video_bypass_jitterbuffer) )
+       {
+               iax_sched_add(e, NULL, NULL, NULL, 0);
+               return NULL;
+       } else
+       {
+               int type = JB_TYPE_CONTROL;
+               int len = 0;
+
+               if(e->etype == IAX_EVENT_VOICE)
+               {
+                       type = JB_TYPE_VOICE;
+                       /* The frame time only has an effect for voice */
+                       len = get_sample_cnt(e) / 8;
+               } else if(e->etype == IAX_EVENT_VIDEO)
+               {
+                       type = JB_TYPE_VIDEO;
+               } else if(e->etype == IAX_EVENT_CNG)
+               {
+                       type = JB_TYPE_SILENCE;
+               }
+
+               /* unwrap timestamp */
+               ts = unwrap_timestamp(ts,e->session->last_ts);
+
+               /* move forward last_ts if it's greater. We do this _after_
+                * unwrapping, because asterisk _still_ has cases where it
+                * doesn't send full frames when it ought to */
+               if(ts > e->session->last_ts)
+               {
+                       e->session->last_ts = ts;
+               }
+
+               if(jb_put(e->session->jb, e, type, len, ts,
+                                       calc_rxstamp(e->session)) == JB_DROP)
+               {
+                       iax_event_free(e);
+               }
+       }
+
+       return NULL;
+}
+
+static int uncompress_subclass(unsigned char csub)
+{
+       /* If the SC_LOG flag is set, return 2^csub otherwise csub */
+       if (csub & IAX_FLAG_SC_LOG)
+               return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
+       else
+               return csub;
+}
+
+static void iax_handle_vnak(struct iax_session *session, struct ast_iax2_full_hdr *fh)
+{
+       struct iax_sched *sch, *list, *l, *tmp;
+
+       /*
+        * According to the IAX2 02 draft, we MUST immediately retransmit all frames
+        * with higher sequence number than the VNAK's iseqno
+        * However, it seems that the right thing to do would be to retransmit
+        * frames with sequence numbers higher OR EQUAL to VNAK's iseqno.
+        */
+       sch = schedq;
+       list = NULL;
+       while ( sch != NULL )
+       {
+               if ( sch->frame != NULL &&
+                    sch->frame->session == session
+                  )
+               {
+                       /*
+                        * We want to check if our frame's oseqno is greater or equal than
+                        * the VNAK's iseqno, but we need to take into account sequence
+                        * number wrap-arounds
+                        * session->rseqno is our last acknowledged sequence number, so
+                        * we use that as a base
+                        */
+                       if ( (unsigned char)(fh->iseqno - session->rseqno) <= (unsigned char)(sch->frame->oseqno - session->rseqno) )
+                       {
+                               /*
+                                * We cannot retransmit immediately, since the frames are ordered by retransmit time
+                                * We need to collect them and orrange them in ascending order of their oseqno
+                                */
+                               tmp = (struct iax_sched *)calloc(1, sizeof(struct iax_sched));
+                               tmp->frame = sch->frame;
+
+                               if ( list == NULL ||
+                                    (list->frame->oseqno - session->rseqno) > (tmp->frame->oseqno - session->rseqno)
+                                  )
+                               {
+                                       tmp->next = list;
+                                       list = tmp;
+                               } else
+                               {
+                                       l = list;
+                                       while ( l != NULL )
+                                       {
+                                               if ( l->next == NULL ||
+                                                    (l->next->frame->oseqno - session->rseqno) > (tmp->frame->oseqno - session->rseqno)
+                                                  )
+                                               {
+                                                       tmp->next = l->next;
+                                                       l->next = tmp;
+                                                       break;
+                                               }
+                                               l = l->next;
+                                       }
+                               }
+                       }
+               }
+               sch = sch->next;
+       }
+
+       /* Transmit collected frames and free the space */
+       while ( list != NULL )
+       {
+               tmp = list;
+               iax_xmit_frame(tmp->frame);
+               list = list->next;
+               free(tmp);
+       }
+}
+
+static struct iax_event *iax_header_to_event(struct iax_session *session, struct ast_iax2_full_hdr *fh, int datalen, struct sockaddr_in *sin)
+{
+       struct iax_event *e;
+       struct iax_sched *sch;
+       unsigned int ts;
+       int subclass;
+       int nowts;
+       int updatehistory = 1;
+       ts = ntohl(fh->ts);
+
+       if (fh->type==AST_FRAME_VIDEO)
+               subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
+       else
+               subclass = uncompress_subclass(fh->csub);
+
+       /* don't run last_ts backwards; i.e. for retransmits and the like */
+       if (ts > session->last_ts &&
+           (fh->type == AST_FRAME_IAX &&
+            subclass != IAX_COMMAND_ACK &&
+            subclass != IAX_COMMAND_PONG &&
+            subclass != IAX_COMMAND_LAGRP))
+       {
+               session->last_ts = ts;
+       }
+
+#ifdef DEBUG_SUPPORT
+       if (debug)
+               iax_showframe(NULL, fh, 1, sin, datalen);
+#endif
+
+       /* Get things going with it, timestamp wise, if we
+          haven't already. */
+
+       /* Handle implicit ACKing unless this is an INVAL, and only if this is
+               from the real peer, not the transfer peer */
+       if ( !inaddrcmp(sin, &session->peeraddr) &&
+            ( subclass != IAX_COMMAND_INVAL ||
+              fh->type != AST_FRAME_IAX
+            )
+          )
+       {
+               unsigned char x;
+               /* XXX This code is not very efficient.  Surely there is a better way which still
+                       properly handles boundary conditions? XXX */
+               /* First we have to qualify that the ACKed value is within our window */
+               for (x=session->rseqno; x != session->oseqno; x++)
+                       if (fh->iseqno == x)
+                               break;
+               if ((x != session->oseqno) || (session->oseqno == fh->iseqno))
+               {
+                       /* The acknowledgement is within our window.  Time to acknowledge everything
+                               that it says to */
+                       for (x=session->rseqno; x != fh->iseqno; x++)
+                       {
+                               /* Ack the packet with the given timestamp */
+                               DEBU(G "Cancelling transmission of packet %d\n", x);
+                               sch = schedq;
+                               while(sch)
+                               {
+                                       if ( sch->frame &&
+                                            sch->frame->session == session &&
+                                            sch->frame->oseqno == x
+                                          )
+                                               sch->frame->retries = -1;
+                                       sch = sch->next;
+                               }
+                       }
+                       /* Note how much we've received acknowledgement for */
+                       session->rseqno = fh->iseqno;
+               } else
+                       DEBU(G "Received iseqno %d not within window %d->%d\n", fh->iseqno, session->rseqno, session->oseqno);
+       }
+
+       /* Check where we are */
+       if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
+                       ((fh->type != AST_FRAME_VOICE) && (fh->type != AST_FRAME_VIDEO)))
+               updatehistory = 0;
+       if ((session->iseqno != fh->oseqno) &&
+               (session->iseqno ||
+                       ((subclass != IAX_COMMAND_TXREADY) &&
+                       (subclass != IAX_COMMAND_TXREL) &&
+                       (subclass != IAX_COMMAND_TXCNT) &&
+                       (subclass != IAX_COMMAND_TXACC)) ||
+                       (fh->type != AST_FRAME_IAX)))
+       {
+               if (
+                       ((subclass != IAX_COMMAND_ACK) &&
+                       (subclass != IAX_COMMAND_INVAL) &&
+                       (subclass != IAX_COMMAND_TXREADY) &&
+                       (subclass != IAX_COMMAND_TXREL) &&
+                       (subclass != IAX_COMMAND_TXCNT) &&
+                       (subclass != IAX_COMMAND_TXACC) &&
+                       (subclass != IAX_COMMAND_VNAK)) ||
+                       (fh->type != AST_FRAME_IAX))
+               {
+                       /* If it's not an ACK packet, it's out of order. */
+                       DEBU(G "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
+                               session->iseqno, fh->oseqno, fh->type, subclass);
+                       
+                       /* 
+                        * Check if session->iseqno > fh->oseqno, accounting for possible wrap around
+                        * This is correct if the two values are not equal (which, in this case, is guaranteed)
+                        */
+                       if ( (unsigned char)(session->iseqno - fh->oseqno) < 128 )
+                       {
+                               /* If we've already seen it, ack it XXX There's a border condition here XXX */
+                               if ((fh->type != AST_FRAME_IAX) ||
+                                               ((subclass != IAX_COMMAND_ACK) && (subclass != IAX_COMMAND_INVAL)))
+                               {
+                                       DEBU(G "Acking anyway\n");
+                                       /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if
+                                               we have anything to send, we'll retransmit and get an ACK back anyway XXX */
+                                       send_command_immediate(session, AST_FRAME_IAX, IAX_COMMAND_ACK, ts, NULL, 0,fh->iseqno);
+                               }
+                       } else
+                       {
+                               /* Send a VNAK requesting retransmission */
+                               iax2_vnak(session);
+                       }
+                       return NULL;
+               }
+       } else
+       {
+               /* Increment unless it's an ACK or VNAK */
+               if (((subclass != IAX_COMMAND_ACK) &&
+                       (subclass != IAX_COMMAND_INVAL) &&
+                       (subclass != IAX_COMMAND_TXCNT) &&
+                       (subclass != IAX_COMMAND_TXACC) &&
+                       (subclass != IAX_COMMAND_VNAK)) ||
+                       (fh->type != AST_FRAME_IAX))
+                       session->iseqno++;
+       }
+
+       e = (struct iax_event *)malloc(sizeof(struct iax_event) + datalen + 1);
+
+       if (e) {
+               memset(e, 0, sizeof(struct iax_event) + datalen);
+               /* Set etype to some unknown value so do not inavertently
+                  sending IAX_EVENT_CONNECT event, which is 0 to application.
+                */
+               e->etype = -1;
+               e->session = session;
+               switch(fh->type) {
+               case AST_FRAME_DTMF:
+                       e->etype = IAX_EVENT_DTMF;
+                       e->subclass = subclass;
+                       /*
+                        We want the DTMF event deliver immediately so all I/O can be
+                        terminate quickly in an IVR system.
+                       e = schedule_delivery(e, ts, updatehistory); */
+                       break;
+               case AST_FRAME_VOICE:
+                       e->etype = IAX_EVENT_VOICE;
+                       e->subclass = subclass;
+                       e->ts = ts;
+                       session->voiceformat = subclass;
+                       if (datalen) {
+                               memcpy(e->data, fh->iedata, datalen);
+                               e->datalen = datalen;
+                       }
+                       e = schedule_delivery(e, ts, updatehistory);
+                       break;
+               case AST_FRAME_CNG:
+                       e->etype = IAX_EVENT_CNG;
+                       e->subclass = subclass;
+                       if (datalen) {
+                               memcpy(e->data, fh->iedata, datalen);
+                               e->datalen = datalen;
+                       }
+                       e = schedule_delivery(e, ts, updatehistory);
+                       break;
+               case AST_FRAME_IAX:
+                       /* Parse IE's */
+                       if (datalen) {
+                               memcpy(e->data, fh->iedata, datalen);
+                               e->datalen = datalen;
+                       }
+                       if (iax_parse_ies(&e->ies, e->data, e->datalen)) {
+                               IAXERROR "Unable to parse IE's");
+                               free(e);
+                               e = NULL;
+                               break;
+                       }
+                       switch(subclass) {
+                       case IAX_COMMAND_NEW:
+                               /* This is a new, incoming call */
+                               /* save the capability for validation */
+                               session->capability = e->ies.capability;
+                               if (e->ies.codec_prefs) {
+                                       strncpy(session->codec_order,
+                                                       e->ies.codec_prefs,
+                                                       sizeof(session->codec_order));
+                                       session->codec_order_len =
+                                               (int)strlen(session->codec_order);
+                               }
+                               e->etype = IAX_EVENT_CONNECT;
+                               e = schedule_delivery(e, ts, updatehistory);
+                               break;
+                       case IAX_COMMAND_AUTHREQ:
+                               /* This is a request for a call */
+                               e->etype = IAX_EVENT_AUTHRQ;
+                               if (strlen(session->username) && !strcmp(e->ies.username, session->username) &&
+                                       strlen(session->secret)) {
+                                               /* Hey, we already know this one */
+                                               iax_auth_reply(session, session->secret, e->ies.challenge, e->ies.authmethods);
+                                               free(e);
+                                               e = NULL;
+                                               break;
+                               }
+                               e = schedule_delivery(e, ts, updatehistory);
+                               break;
+                       case IAX_COMMAND_HANGUP:
+                               e->etype = IAX_EVENT_HANGUP;
+                               e = schedule_delivery(e, ts, updatehistory);
+                               break;
+                       case IAX_COMMAND_INVAL:
+                               e->etype = IAX_EVENT_HANGUP;
+                               e = schedule_delivery(e, ts, updatehistory);
+                               break;
+                       case IAX_COMMAND_REJECT:
+                               e->etype = IAX_EVENT_REJECT;
+                               e = schedule_delivery(e, ts, updatehistory);
+                               break;
+                       case IAX_COMMAND_ACK:
+                               free(e);
+                               e = NULL;
+                               break;
+                       case IAX_COMMAND_VNAK:
+                               iax_handle_vnak(session, fh);
+                               free(e);
+                               e = NULL;
+                               break;
+                       case IAX_COMMAND_LAGRQ:
+                               /* Pass this along for later handling */
+                               e->etype = IAX_EVENT_LAGRQ;
+                               e->ts = ts;
+                               e = schedule_delivery(e, ts, updatehistory);
+                               break;
+                       case IAX_COMMAND_POKE:
+                               e->etype = IAX_EVENT_POKE;
+                               e->ts = ts;
+                               break;
+                       case IAX_COMMAND_PING:
+                               /* PINGS and PONGS don't get scheduled; */
+                               e->etype = IAX_EVENT_PING;
+                               e->ts = ts;
+                               break;
+                       case IAX_COMMAND_PONG:
+                               e->etype = IAX_EVENT_PONG;
+                               /* track weighted average of ping time */
+                               session->pingtime = ((2 * session->pingtime) + (calc_timestamp(session,0,NULL) - ts)) / 3;
+                               session->remote_netstats.jitter = e->ies.rr_jitter;
+                               session->remote_netstats.losspct = e->ies.rr_loss >> 24;;
+                               session->remote_netstats.losscnt = e->ies.rr_loss & 0xffffff;
+                               session->remote_netstats.packets = e->ies.rr_pkts;
+                               session->remote_netstats.delay = e->ies.rr_delay;
+                               session->remote_netstats.dropped = e->ies.rr_dropped;
+                               session->remote_netstats.ooo = e->ies.rr_ooo;
+                               break;
+                       case IAX_COMMAND_ACCEPT:
+                               if (e->ies.format & session->capability) {
+                                       e->etype = IAX_EVENT_ACCEPT;
+                               }
+                               else {
+                                       struct iax_ie_data ied;
+                                       /* Although this should not happen, we
+                                        * added this to make sure the
+                                        * negotiation protocol is enforced.
+                                        * For lack of event to notify the
+                                        * application we use the defined
+                                        * REJECT event.
+                                        */
+                                       memset(&ied, 0, sizeof(ied));
+                                       iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unable to negotiate codec");
+                                       send_command_final(session, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
+                                       e->etype = IAX_EVENT_REJECT;
+                               }
+                               e = schedule_delivery(e, ts, updatehistory);
+                               break;
+                       case IAX_COMMAND_REGACK:
+                               e->etype = IAX_EVENT_REGACK;
+                               e = schedule_delivery(e, ts, updatehistory);
+                               break;
+                       case IAX_COMMAND_REGAUTH:
+                               iax_regauth_reply(session, session->secret, e->ies.challenge, e->ies.authmethods);
+                               free(e);
+                               e = NULL;
+                               break;
+                       case IAX_COMMAND_REGREJ:
+                               e->etype = IAX_EVENT_REGREJ;
+                               e = schedule_delivery(e, ts, updatehistory);
+                               break;
+                       case IAX_COMMAND_LAGRP:
+                               e->etype = IAX_EVENT_LAGRP;
+                               nowts = calc_timestamp(session, 0, NULL);
+                               e->ts = nowts - ts;
+                               /* Can't call schedule_delivery since timestamp is non-normal */
+                               break;;
+                       case IAX_COMMAND_TXREQ:
+                               /* added check for defensive programming
+                                * - in case the asterisk server
+                                * or another client does not send the
+                                *  apparent transfer address
+                                */
+                               if (e->ies.apparent_addr != NULL) {
+                                       /* so a full voice frame is sent on the
+                                          next voice output */
+                                       session->svoiceformat = -1;
+                                       session->transfer = *e->ies.apparent_addr;
+                                       session->transfer.sin_family = AF_INET;
+                                       session->transfercallno = e->ies.callno;
+                                       session->transferring = TRANSFER_BEGIN;
+                                       session->transferid = e->ies.transferid;
+                                       iax_send_txcnt(session);
+                               }
+                               free(e);
+                               e = NULL;
+                               break;
+                       case IAX_COMMAND_DPREP:
+                               /* Received dialplan reply */
+                               e->etype = IAX_EVENT_DPREP;
+                               /* Return immediately, makes no sense to schedule */
+                               break;
+                       case IAX_COMMAND_TXCNT:
+                               if (session->transferring)  {
+                                       session->transfer = *sin;
+                                       iax_send_txaccept(session);
+                               }
+                               free(e);
+                               e = NULL;
+                               break;
+                       case IAX_COMMAND_TXACC:
+                               if (session->transferring) {
+                                       stop_transfer(session);
+                                       session->transferring = TRANSFER_READY;
+                                       iax_send_txready(session);
+                               }
+                               free(e);
+                               e = NULL;
+                               break;
+                       case IAX_COMMAND_TXREL:
+                               /* Release the transfer */
+                               send_command_immediate(session, AST_FRAME_IAX, IAX_COMMAND_ACK, ts, NULL, 0, fh->iseqno);
+                               if (session->transferring) {
+                                       complete_transfer(session, e->ies.callno, 1, 0);
+                               }
+                               else {
+                                       complete_transfer(session, session->peercallno, 0, 1);
+                               }
+                               e->etype = IAX_EVENT_TRANSFER;
+                               /* notify that asterisk no longer sitting between peers */
+                               e = schedule_delivery(e, ts, updatehistory);
+                               break;
+                       case IAX_COMMAND_QUELCH:
+                               e->etype = IAX_EVENT_QUELCH;
+                               session->quelch = 1;
+                               break;
+                       case IAX_COMMAND_UNQUELCH:
+                               e->etype = IAX_EVENT_UNQUELCH;
+                               session->quelch = 0;
+                               break;
+                       case IAX_COMMAND_TXREJ:
+                               e->etype = IAX_EVENT_TXREJECT;
+                               iax_handle_txreject(session);
+                               break;
+
+                       case IAX_COMMAND_TXREADY:
+                               send_command_immediate(session, AST_FRAME_IAX, IAX_COMMAND_ACK, ts, NULL, 0, fh->iseqno);
+                               if (iax_handle_txready(session)) {
+                                       e->etype = IAX_EVENT_TXREADY;
+                               }
+                               else {
+                                       free(e);
+                                       e = NULL;
+                               }
+                               break;
+                       default:
+                               DEBU(G "Don't know what to do with IAX command %d\n", subclass);
+                               free(e);
+                               e = NULL;
+                       }
+                       break;
+               case AST_FRAME_CONTROL:
+                       switch(subclass) {
+                       case AST_CONTROL_ANSWER:
+                               e->etype = IAX_EVENT_ANSWER;
+                               e = schedule_delivery(e, ts, updatehistory);
+                               break;
+                       case AST_CONTROL_CONGESTION:
+                       case AST_CONTROL_BUSY:
+                               e->etype = IAX_EVENT_BUSY;
+                               e = schedule_delivery(e, ts, updatehistory);
+                               break;
+                       case AST_CONTROL_RINGING:
+                               e->etype = IAX_EVENT_RINGA;
+                               e = schedule_delivery(e, ts, updatehistory);
+                               break;
+                       default:
+                               DEBU(G "Don't know what to do with AST control %d\n", subclass);
+                               free(e);
+                               return NULL;
+                       }
+                       break;
+               case AST_FRAME_IMAGE:
+                       e->etype = IAX_EVENT_IMAGE;
+                       e->subclass = subclass;
+                       if (datalen) {
+                               memcpy(e->data, fh->iedata, datalen);
+                       }
+                       e = schedule_delivery(e, ts, updatehistory);
+                       break;
+               case AST_FRAME_VIDEO:
+                       e->etype = IAX_EVENT_VIDEO;
+                       e->subclass = subclass;
+                       e->ts = ts;
+                       session->videoformat = e->subclass;
+                       memcpy(e->data, fh->iedata, datalen);
+                       e->datalen = datalen;
+                       e = schedule_delivery(e, ts, updatehistory);
+                       break;
+               case AST_FRAME_TEXT:
+                       e->etype = IAX_EVENT_TEXT;
+                       if (datalen) {
+                               memcpy(e->data, fh->iedata, datalen);
+                               e->datalen = datalen;
+                       }
+                       e = schedule_delivery(e, ts, updatehistory);
+                       break;
+
+               case AST_FRAME_HTML:
+                       switch(fh->csub) {
+                       case AST_HTML_LINKURL:
+                               e->etype = IAX_EVENT_LINKURL;
+                               /* Fall through */
+                       case AST_HTML_URL:
+                               if (e->etype == -1)
+                                       e->etype = IAX_EVENT_URL;
+                               e->subclass = fh->csub;
+                               e->datalen = datalen;
+                               if (datalen) {
+                                       memcpy(e->data, fh->iedata, datalen);
+                               }
+                               e = schedule_delivery(e, ts, updatehistory);
+                               break;
+                       case AST_HTML_LDCOMPLETE:
+                               e->etype = IAX_EVENT_LDCOMPLETE;
+                               e = schedule_delivery(e, ts, updatehistory);
+                               break;
+                       case AST_HTML_UNLINK:
+                               e->etype = IAX_EVENT_UNLINK;
+                               e = schedule_delivery(e, ts, updatehistory);
+                               break;
+                       case AST_HTML_LINKREJECT:
+                               e->etype = IAX_EVENT_LINKREJECT;
+                               e = schedule_delivery(e, ts, updatehistory);
+                               break;
+                       default:
+                               DEBU(G "Don't know how to handle HTML type %d frames\n", fh->csub);
+                               free(e);
+                               return NULL;
+                       }
+                       break;
+               default:
+                       DEBU(G "Don't know what to do with frame type %d\n", fh->type);
+                       free(e);
+                       return NULL;
+               }
+       } else
+               DEBU(G "Out of memory\n");
+
+       /* Already ack'd iax frames */
+       if (session->aseqno != session->iseqno) {
+               send_command_immediate(session, AST_FRAME_IAX, IAX_COMMAND_ACK, ts, NULL, 0, fh->iseqno);
+       }
+       return e;
+}
+
+/* Some parts taken from iax_miniheader_to_event and from from chan_iax2.c. We must inform Mark Spencer? */
+static struct iax_event *iax_videoheader_to_event(struct iax_session *session,
+               struct ast_iax2_video_hdr *vh, int datalen)
+{
+       struct iax_event * e;
+
+       if ( session->videoformat <= 0 )
+       {
+               DEBU(G "No last video format received on session %d\n",
+                               session->callno);
+               return 0;
+       }
+
+       e = (struct iax_event *)malloc(sizeof(struct iax_event) + datalen);
+
+       if ( !e )
+       {
+               DEBU(G "Out of memory\n");
+               return 0;
+       }
+
+       e->etype = IAX_EVENT_VIDEO;
+       e->session = session;
+       e->subclass = session->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
+       e->datalen = datalen;
+       memcpy(e->data, vh->data, e->datalen);
+       e->ts = (session->last_ts & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
+
+       return schedule_delivery(e, e->ts, 1);
+}
+
+static struct iax_event *iax_miniheader_to_event(struct iax_session *session,
+               struct ast_iax2_mini_hdr *mh, int datalen)
+{
+       struct iax_event * e;
+
+       if ( session->voiceformat <= 0 )
+       {
+               DEBU(G "No last format received on session %d\n", session->callno);
+               return 0;
+       }
+
+       e = (struct iax_event *)malloc(sizeof(struct iax_event) + datalen);
+
+       if ( !e )
+       {
+               DEBU(G "Out of memory\n");
+               return 0;
+       }
+
+       e->etype = IAX_EVENT_VOICE;
+       e->session = session;
+       e->subclass = session->voiceformat;
+       e->datalen = datalen;
+       memcpy(e->data, mh->data, datalen);
+       e->ts = (session->last_ts & 0xFFFF0000) | ntohs(mh->ts);
+
+       return schedule_delivery(e, e->ts, 1);
+}
+
+void iax_destroy(struct iax_session *session)
+{
+       destroy_session(session);
+}
+
+static struct iax_event *iax_net_read(void)
+{
+       unsigned char buf[65536];
+       int res;
+       struct sockaddr_in sin;
+       socklen_t sinlen;
+       struct iax_event *event;
+
+       sinlen = sizeof(sin);
+       res = iax_recvfrom(netfd, (char *)buf, sizeof(buf), 0, (struct sockaddr *) &sin, &sinlen);
+       if (res < 0) {
+#if defined(_WIN32_WCE)
+               if (WSAGetLastError() != WSAEWOULDBLOCK) {
+                       DEBU(G "Error on read: %d\n", WSAGetLastError());
+                       IAXERROR "Read error on network socket: ???");
+               }
+#elif defined(WIN32)  ||  defined(_WIN32_WCE)
+               if (WSAGetLastError() != WSAEWOULDBLOCK) {
+                       DEBU(G "Error on read: %d\n", WSAGetLastError());
+                       IAXERROR "Read error on network socket: %s", strerror(errno));
+               }
+#else
+               if (errno != EAGAIN) {
+                       DEBU(G "Error on read: %s\n", strerror(errno));
+                       IAXERROR "Read error on network socket: %s", strerror(errno));
+               }
+#endif
+               return NULL;
+       }
+       event = iax_net_process(buf, res, &sin);
+       if ( event == NULL )
+       {
+               // We have received a frame. The corresponding event is queued
+               // We need to motify the entire stack of calling functions so they
+               // don't go to sleep thinking there are no more frames to process
+               // TODO: this is buttugly from a design point of view. Basically we
+               // change libiax2 behavior to accomodate iaxclient.
+               // There must be a way to do it better.
+               event = (struct iax_event *)malloc(sizeof(struct iax_event));
+               if ( event != NULL ) event->etype = IAX_EVENT_NULL;
+       }
+       return event;
+}
+
+static struct iax_session *iax_txcnt_session(struct ast_iax2_full_hdr *fh, int datalen,
+                               struct sockaddr_in *sin, short callno, short dcallno)
+{
+       int subclass = uncompress_subclass(fh->csub);
+       unsigned char buf[ 65536 ]; /* allocated on stack with same size as iax_net_read() */
+       struct iax_ies ies;
+       struct iax_session *cur;
+
+       if ((fh->type != AST_FRAME_IAX) || (subclass != IAX_COMMAND_TXCNT) || (!datalen)) {
+               return NULL; /* special handling for TXCNT only */
+       }
+       memcpy(buf, fh->iedata, datalen);       /* prepare local buf for iax_parse_ies() */
+
+       if (iax_parse_ies(&ies, buf, datalen)) {
+               return NULL;    /* Unable to parse IE's */
+       }
+       if (!ies.transferid) {
+               return NULL;    /* TXCNT without proper IAX_IE_TRANSFERID */
+       }
+       for( cur=sessions; cur; cur=cur->next ) {
+               if ((cur->transferring) && (cur->transferid == (int) ies.transferid) &&
+                       (cur->callno == dcallno) && (cur->transfercallno == callno)) {
+                       /* We're transferring ---
+                        *  skip address/port checking which would fail while
+                        *  remote peer behind symmetric NAT, verify
+                        *  transferid instead
+                        */
+                       cur->transfer.sin_addr.s_addr = sin->sin_addr.s_addr; /* setup for further handling */
+                       cur->transfer.sin_port = sin->sin_port;
+                       break;
+               }
+       }
+       return cur;
+}
+
+struct iax_event *iax_net_process(unsigned char *buf, int len, struct sockaddr_in *sin)
+{
+       struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)buf;
+       struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)buf;
+       struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)buf;
+       struct iax_session *session;
+
+       if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
+               /* Full size header */
+               if ((size_t)len < sizeof(struct ast_iax2_full_hdr)) {
+                       DEBU(G "Short header received from %s\n", inet_ntoa(sin->sin_addr));
+                       IAXERROR "Short header received from %s\n", inet_ntoa(sin->sin_addr));
+                       return NULL;
+               }
+               /* We have a full header, process appropriately */
+               session = iax_find_session(sin,
+                               ntohs(fh->scallno) & ~IAX_FLAG_FULL,
+                               ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, 1);
+               if (!session)
+                       session = iax_txcnt_session(fh,
+                                       len - sizeof(struct ast_iax2_full_hdr),
+                                       sin, ntohs(fh->scallno) & ~IAX_FLAG_FULL,
+                                       ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS);
+               if (session)
+                       return iax_header_to_event(session, fh, len - sizeof(struct ast_iax2_full_hdr), sin);
+               DEBU(G "No session?\n");
+               return NULL;
+       } else {
+               if ((size_t)len < sizeof(struct ast_iax2_mini_hdr)) {
+                       DEBU(G "Short header received from %s\n", inet_ntoa(sin->sin_addr));
+                       IAXERROR "Short header received from %s\n", inet_ntoa(sin->sin_addr));
+                       return NULL;
+               }
+               /* Miniature, voice frame */
+               if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000))
+               {
+                       session = iax_find_session(sin, ntohs(vh->callno) & ~0x8000, 0, 0);
+
+                       if (session)
+                               return iax_videoheader_to_event(session, vh,
+                                               len - sizeof(struct ast_iax2_video_hdr));
+               } else {
+                       /* audio frame */
+                       session = iax_find_session(sin, ntohs(fh->scallno), 0, 0);
+                       if (session)
+                               return iax_miniheader_to_event(session, mh,
+                                               len - sizeof(struct ast_iax2_mini_hdr));
+               }
+               DEBU(G "No session?\n");
+               return NULL;
+       }
+}
+
+static struct iax_sched *iax_get_sched(struct timeval tv)
+{
+       struct iax_sched *cur, *prev=NULL;
+       cur = schedq;
+       /* Check the event schedule first. */
+       while(cur) {
+               if ((tv.tv_sec > cur->when.tv_sec) ||
+                   ((tv.tv_sec == cur->when.tv_sec) &&
+                       (tv.tv_usec >= cur->when.tv_usec))) {
+                               /* Take it out of the event queue */
+                               if (prev) {
+                                       prev->next = cur->next;
+                               } else {
+                                       schedq = cur->next;
+                               }
+                               return cur;
+               }
+               cur = cur->next;
+       }
+       return NULL;
+}
+
+struct iax_event *iax_get_event(int blocking)
+{
+       struct iax_event *event;
+       struct iax_frame *frame;
+       struct timeval tv;
+       struct iax_sched *cur;
+       struct iax_session *session;
+
+       tv = iax_tvnow();
+
+       while((cur = iax_get_sched(tv)))
+       {
+               event = cur->event;
+               frame = cur->frame;
+               if (event)
+               {
+                       /* See if this is an event we need to handle */
+                       event = handle_event(event);
+                       if (event)
+                       {
+                               free(cur);
+                               return event;
+                       }
+               } else if(frame)
+               {
+                       /* It's a frame, transmit it and schedule a retry */
+                       if (frame->retries < 0)
+                       {
+                               /* It's been acked.  No need to send it.   Destroy the old
+                                  frame. If final, destroy the session. */
+                               if (frame->final)
+                                       destroy_session(frame->session);
+                               if (frame->data)
+                                       free(frame->data);
+                               free(frame);
+                       } else if (frame->retries == 0)
+                       {
+                               if (frame->transfer)
+                               {
+                                       /* Send a transfer reject since we weren't able to connect */
+                                       iax_send_txrej(frame->session);
+                                       if (frame->data)
+                                               free(frame->data);
+                                       free(frame);
+                                       free(cur);
+                                       break;
+                               } else
+                               {
+                                       /* We haven't been able to get an ACK on this packet. If a
+                                          final frame, destroy the session, otherwise, pass up timeout */
+                                       if (frame->final)
+                                       {
+                                               destroy_session(frame->session);
+                                               if (frame->data)
+                                                       free(frame->data);
+                                               free(frame);
+                                       } else
+                                       {
+                                               event = (struct iax_event *)malloc(sizeof(struct iax_event));
+                                               if (event)
+                                               {
+                                                       event->etype = IAX_EVENT_TIMEOUT;
+                                                       event->session = frame->session;
+                                                       if (frame->data)
+                                                               free(frame->data);
+                                                       free(frame);
+                                                       free(cur);
+                                                       return handle_event(event);
+                                               }
+                                       }
+                               }
+                       } else
+                       {
+                               struct ast_iax2_full_hdr *fh;
+                               /* Decrement remaining retries */
+                               frame->retries--;
+                               /* Multiply next retry time by 4, not above MAX_RETRY_TIME though */
+                               frame->retrytime *= 4;
+                               /* Keep under 1000 ms if this is a transfer packet */
+                               if (!frame->transfer)
+                               {
+                                       if (frame->retrytime > MAX_RETRY_TIME)
+                                               frame->retrytime = MAX_RETRY_TIME;
+                               } else if (frame->retrytime > 1000)
+                                       frame->retrytime = 1000;
+                               fh = (struct ast_iax2_full_hdr *)(frame->data);
+                               fh->dcallno = htons(IAX_FLAG_RETRANS | frame->dcallno);
+                               iax_xmit_frame(frame);
+                               /* Schedule another retransmission */
+                               DEBU(G "Scheduling retransmission %d\n", frame->retries);
+                               iax_sched_add(NULL, frame, NULL, NULL, frame->retrytime);
+                       }
+               } else if (cur->func)
+               {
+                   cur->func(cur->arg);
+               }
+               free(cur);
+       }
+
+       /* get jitterbuffer-scheduled events */
+       for ( session = sessions; session; session = session->next )
+       {
+               int ret;
+               long now;
+               long next;
+               jb_frame frame;
+
+               now = (tv.tv_sec - session->rxcore.tv_sec) * 1000 +
+                     (tv.tv_usec - session->rxcore.tv_usec) / 1000;
+
+               if ( now <= (next = jb_next(session->jb)) )
+                       continue;
+
+               /* interp len no longer hardcoded, now determined by get_interp_len */
+               ret = jb_get(session->jb,&frame,now,get_interp_len(session->voiceformat));
+
+               switch(ret) {
+               case JB_OK:
+                       event = (struct iax_event *)frame.data;
+                       event = handle_event(event);
+                       if (event) {
+                               return event;
+                       }
+                       break;
+               case JB_INTERP:
+                       /* create an interpolation frame */
+                       //fprintf(stderr, "Making Interpolation frame\n");
+                       event = (struct iax_event *)malloc(sizeof(struct iax_event));
+                       if (event) {
+                               event->etype    = IAX_EVENT_VOICE;
+                               event->subclass = session->voiceformat;
+                               /* XXX: ??? applications probably ignore this anyway */
+                               event->ts       = now;
+                               event->session  = session;
+                               event->datalen  = 0;
+                               event = handle_event(event);
+                               if(event)
+                                       return event;
+                       }
+                       break;
+               case JB_DROP:
+                       iax_event_free((struct iax_event *)frame.data);
+                       break;
+               case JB_NOFRAME:
+               case JB_EMPTY:
+                       /* do nothing */
+                       break;
+               default:
+                       /* shouldn't happen */
+                       break;
+               }
+       }
+
+       /* Now look for networking events */
+       if (blocking) {
+               /* Block until there is data if desired */
+               fd_set fds;
+               int nextEventTime;
+
+               FD_ZERO(&fds);
+               FD_SET(netfd, &fds);
+
+               nextEventTime = iax_time_to_next_event();
+
+               if(nextEventTime < 0) select(netfd + 1, &fds, NULL, NULL, NULL);
+               else
+               {
+                       struct timeval nextEvent;
+
+                       nextEvent.tv_sec = nextEventTime / 1000;
+                       nextEvent.tv_usec = (nextEventTime % 1000) * 1000;
+
+                       select(netfd + 1, &fds, NULL, NULL, &nextEvent);
+               }
+
+       }
+       event = iax_net_read();
+
+       return handle_event(event);
+}
+
+struct sockaddr_in iax_get_peer_addr(struct iax_session *session)
+{
+       return session->peeraddr;
+}
+
+void iax_session_destroy(struct iax_session **session)
+{
+       destroy_session(*session);
+       *session = NULL;
+}
+
+void iax_event_free(struct iax_event *event)
+{
+       /* We gave the user a chance to play with the session now we need to
+        * destroy it if you are not calling this function on every event you
+        * read you are now going to leak sessions as well as events!
+        */
+       switch(event->etype) {
+       case IAX_EVENT_REJECT:
+       case IAX_EVENT_HANGUP:
+               /* Destroy this session -- it's no longer valid */
+               if (event->session) { /* maybe the user did it already */
+                       destroy_session(event->session);
+               }
+               break;
+       }
+       free(event);
+}
+
+int iax_get_fd(void)
+{
+       /* Return our network file descriptor. The client can select on this
+        * (probably with other things, or can add it to a network add sort
+        * of gtk_input_add for example */
+       return netfd;
+}
+
+int iax_quelch_moh(struct iax_session *session, int MOH)
+{
+       struct iax_ie_data ied;                 //IE Data Structure (Stuff To Send)
+       memset(&ied, 0, sizeof(ied));
+
+       // You can't quelch the quelched
+       if (session->quelch == 1)
+               return -1;
+
+       if (MOH) {
+               iax_ie_append(&ied, IAX_IE_MUSICONHOLD);
+               session->transfer_moh = 1;
+       }
+
+       return send_command(session, AST_FRAME_IAX, IAX_COMMAND_QUELCH, 0, ied.buf, ied.pos, -1);
+}
+
+struct timeval iax_tvnow(void)
+{
+       struct timeval tv;
+
+#ifdef HAVE_GETTIMEOFDAY
+       gettimeofday(&tv, 0);
+#elif defined(_MSC_VER)
+       struct _timeb curSysTime;
+
+       _ftime(&curSysTime);
+       tv.tv_sec = (long)curSysTime.time;
+       tv.tv_usec = curSysTime.millitm * 1000;
+#else
+#error no gettimeofday or equivalent available
+#endif
+       return tv;
+}
diff --git a/utils/iaxclient/lib/libiax2/src/iax.h b/utils/iaxclient/lib/libiax2/src/iax.h
new file mode 100644 (file)
index 0000000..8a0e3fe
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * libIAX
+ *
+ * Implementation of Inter-IAXerisk eXchange
+ * 
+ * Copyright (C) 1999, Mark Spencer
+ *
+ * Mark Spencer <markster@linux-support.net>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License
+ */
+#ifndef _IAX_H
+#define _IAX_H
+
+/* Max version of IAX protocol we support */
+#define IAX_PROTO_VERSION 1
+
+#define IAX_MAX_CALLS 32768
+
+#define IAX_FLAG_FULL          0x8000
+
+#define IAX_FLAG_SC_LOG                0x80
+
+#define IAX_MAX_SHIFT          0x1F
+
+/* Maximum size of an IAX frame (max size of UDP frame) */
+#define IAX_MAX_BUF_SIZE 65536
+
+/* Subclass for IAX_FRAME_IAX */
+#define IAX_COMMAND_NEW                1
+#define IAX_COMMAND_PING       2
+#define IAX_COMMAND_PONG       3
+#define IAX_COMMAND_ACK                4
+#define IAX_COMMAND_HANGUP     5
+#define IAX_COMMAND_REJECT     6
+#define IAX_COMMAND_ACCEPT     7
+#define IAX_COMMAND_AUTHREQ    8
+#define IAX_COMMAND_AUTHREP    9
+#define IAX_COMMAND_INVAL      10
+#define IAX_COMMAND_LAGRQ      11
+#define IAX_COMMAND_LAGRP      12
+#define IAX_COMMAND_REGREQ     13      /* Registration request */
+#define IAX_COMMAND_REGAUTH    14      /* Registration authentication required */
+#define IAX_COMMAND_REGACK     15      /* Registration accepted */
+#define IAX_COMMAND_REGREJ     16      /* Registration rejected */
+#define IAX_COMMAND_REGREL     17      /* Force release of registration */
+#define IAX_COMMAND_VNAK       18      /* If we receive voice before valid first voice frame, send this */
+#define IAX_COMMAND_DPREQ      19      /* Request status of a dialplan entry */
+#define IAX_COMMAND_DPREP      20      /* Request status of a dialplan entry */
+#define IAX_COMMAND_DIAL       21      /* Request a dial on channel brought up TBD */
+#define IAX_COMMAND_TXREQ      22      /* Transfer Request */
+#define IAX_COMMAND_TXCNT      23      /* Transfer Connect */
+#define IAX_COMMAND_TXACC      24      /* Transfer Accepted */
+#define IAX_COMMAND_TXREADY    25      /* Transfer ready */
+#define IAX_COMMAND_TXREL      26      /* Transfer release */
+#define IAX_COMMAND_TXREJ      27      /* Transfer reject */
+#define IAX_COMMAND_QUELCH     28      /* Stop audio/video transmission */
+#define IAX_COMMAND_UNQUELCH 29        /* Resume audio/video transmission */
+
+#define IAX_DEFAULT_REG_EXPIRE         60
+
+#define IAX_DEFAULT_PORTNO             5036
+
+/* Full frames are always delivered reliably */
+struct iax_full_hdr {
+       short callno;                   /* Source call number -- high bit must be 1 */
+       short dcallno;                  /* Destination call number */
+       unsigned int ts;                /* 32-bit timestamp in milliseconds */
+       unsigned short seqno;   /* Packet number */
+       char type;                              /* Frame type */
+       unsigned char csub;             /* Compressed subclass */
+       char data[0];
+};
+
+/* Mini header is used only for voice frames -- delivered unreliably */
+struct iax_mini_hdr {
+       short callno;                   /* Source call number -- high bit must be 0 */
+       unsigned short ts;              /* 16-bit Timestamp (high 16 bits from last IAX_full_hdr) */
+                                                       /* Frametype implicitly VOICE_FRAME */
+                                                       /* subclass implicit from last IAX_full_hdr */
+       char data[0];
+};
+
+#endif
diff --git a/utils/iaxclient/lib/libiax2/src/iax2-parser.c b/utils/iaxclient/lib/libiax2/src/iax2-parser.c
new file mode 100644 (file)
index 0000000..78fcb07
--- /dev/null
@@ -0,0 +1,822 @@
+/*
+ * Asterisk -- A telephony toolkit for Linux.
+ *
+ * Implementation of Inter-Asterisk eXchange
+ * 
+ * Copyright (C) 2003-2004, Digium
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License
+ */
+
+#if defined(WIN32)  ||  defined(_WIN32_WCE)
+#include "winpoop.h"
+#define snprintf _snprintf
+#else
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
+
+#ifndef _MSC_VER
+#include <unistd.h>
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "frame.h"
+#include "iax2.h"
+#include "iax2-parser.h"
+
+static int frames = 0;
+static int iframes = 0;
+static int oframes = 0;
+
+#ifdef ALIGN32
+static unsigned int get_uint32(unsigned char *p)
+{
+  return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
+}
+
+static unsigned short get_uint16(unsigned char *p)
+{
+  return (p[0] << 8) | p[1] ;
+}
+
+#else
+#define get_uint32(p) (*((unsigned int *)(p)))
+#define get_uint16(p) (*((unsigned short *)(p)))
+#endif
+
+
+static void internaloutput(const char *str)
+{
+       //printf(str);
+}
+
+static void internalerror(const char *str)
+{
+       fprintf(stderr, "WARNING: %s", str);
+}
+
+static void (*outputf)(const char *str) = internaloutput;
+static void (*errorf)(const char *str) = internalerror;
+
+static void dump_addr(char *output, int maxlen, void *value, int len)
+{
+       struct sockaddr_in sin;
+       if (len == sizeof(sin)) {
+               memcpy(&sin, value, len);
+               snprintf(output, maxlen, "IPV4 %s:%d", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
+       } else {
+               snprintf(output, maxlen, "Invalid Address");
+       }
+}
+
+static void dump_string(char *output, int maxlen, void *value, int len)
+{
+       maxlen--;
+       if (maxlen > len)
+               maxlen = len;
+       strncpy(output,(const char *)value, maxlen);
+       output[maxlen] = '\0';
+}
+
+static void dump_int(char *output, int maxlen, void *value, int len)
+{
+       if (len == (int)sizeof(unsigned int))
+               snprintf(output, maxlen, "%lu", (unsigned long)ntohl(get_uint32(value)));
+       else
+               snprintf(output, maxlen, "Invalid INT");
+}
+
+static void dump_short(char *output, int maxlen, void *value, int len)
+{
+       if (len == (int)sizeof(unsigned short))
+               snprintf(output, maxlen, "%d", ntohs(get_uint16(value)));
+       else
+               snprintf(output, maxlen, "Invalid SHORT");
+}
+
+static void dump_byte(char *output, int maxlen, void *value, int len)
+{
+       if (len == (int)sizeof(unsigned char))
+               snprintf(output, maxlen, "%d", *((unsigned char *)value));
+       else
+               snprintf(output, maxlen, "Invalid BYTE");
+}
+
+static void dump_samprate(char *output, int maxlen, void *value, int len)
+{
+       char tmp[256]="";
+       int sr;
+       if (len == (int)sizeof(unsigned short)) {
+               sr = ntohs(*((unsigned short *)value));
+               if (sr & IAX_RATE_8KHZ)
+                       strcat(tmp, ",8khz");
+               if (sr & IAX_RATE_11KHZ)
+                       strcat(tmp, ",11.025khz");
+               if (sr & IAX_RATE_16KHZ)
+                       strcat(tmp, ",16khz");
+               if (sr & IAX_RATE_22KHZ)
+                       strcat(tmp, ",22.05khz");
+               if (sr & IAX_RATE_44KHZ)
+                       strcat(tmp, ",44.1khz");
+               if (sr & IAX_RATE_48KHZ)
+                       strcat(tmp, ",48khz");
+               if (strlen(tmp))
+                       strncpy(output, &tmp[1], maxlen - 1);
+               else
+                       strncpy(output, "None specified!\n", maxlen - 1);
+       } else
+               snprintf(output, maxlen, "Invalid SHORT");
+
+}
+
+static void dump_prov_ies(char *output, int maxlen, unsigned char *iedata, int len);
+static void dump_prov(char *output, int maxlen, void *value, int len)
+{
+       dump_prov_ies(output, maxlen, (unsigned char *)value, len);
+}
+
+static struct iax2_ie {
+       int ie;
+       char *name;
+       void (*dump)(char *output, int maxlen, void *value, int len);
+} ies[] = {
+       { IAX_IE_CALLED_NUMBER, "CALLED NUMBER", dump_string },
+       { IAX_IE_CALLING_NUMBER, "CALLING NUMBER", dump_string },
+       { IAX_IE_CALLING_ANI, "ANI", dump_string },
+       { IAX_IE_CALLING_NAME, "CALLING NAME", dump_string },
+       { IAX_IE_CALLED_CONTEXT, "CALLED CONTEXT", dump_string },
+       { IAX_IE_USERNAME, "USERNAME", dump_string },
+       { IAX_IE_PASSWORD, "PASSWORD", dump_string },
+       { IAX_IE_CAPABILITY, "CAPABILITY", dump_int },
+       { IAX_IE_FORMAT, "FORMAT", dump_int },
+       { IAX_IE_LANGUAGE, "LANGUAGE", dump_string },
+       { IAX_IE_VERSION, "VERSION", dump_short },
+       { IAX_IE_ADSICPE, "ADSICPE", dump_short },
+       { IAX_IE_DNID, "DNID", dump_string },
+       { IAX_IE_AUTHMETHODS, "AUTHMETHODS", dump_short },
+       { IAX_IE_CHALLENGE, "CHALLENGE", dump_string },
+       { IAX_IE_MD5_RESULT, "MD5 RESULT", dump_string },
+       { IAX_IE_RSA_RESULT, "RSA RESULT", dump_string },
+       { IAX_IE_APPARENT_ADDR, "APPARENT ADDRESS", dump_addr },
+       { IAX_IE_REFRESH, "REFRESH", dump_short },
+       { IAX_IE_DPSTATUS, "DIALPLAN STATUS", dump_short },
+       { IAX_IE_CALLNO, "CALL NUMBER", dump_short },
+       { IAX_IE_CAUSE, "CAUSE", dump_string },
+       { IAX_IE_IAX_UNKNOWN, "UNKNOWN IAX CMD", dump_byte },
+       { IAX_IE_MSGCOUNT, "MESSAGE COUNT", dump_short },
+       { IAX_IE_AUTOANSWER, "AUTO ANSWER REQ" },
+       { IAX_IE_TRANSFERID, "TRANSFER ID", dump_int },
+       { IAX_IE_RDNIS, "REFERRING DNIS", dump_string },
+       { IAX_IE_PROVISIONING, "PROVISIONING", dump_prov },
+       { IAX_IE_AESPROVISIONING, "AES PROVISIONG" },
+       { IAX_IE_DATETIME, "DATE TIME", dump_int },
+       { IAX_IE_DEVICETYPE, "DEVICE TYPE", dump_string },
+       { IAX_IE_SERVICEIDENT, "SERVICE IDENT", dump_string },
+       { IAX_IE_FIRMWAREVER, "FIRMWARE VER", dump_short },
+       { IAX_IE_FWBLOCKDESC, "FW BLOCK DESC", dump_int },
+       { IAX_IE_FWBLOCKDATA, "FW BLOCK DATA" },
+       { IAX_IE_PROVVER, "PROVISIONG VER", dump_int },
+       { IAX_IE_CALLINGPRES, "CALLING PRESNTN", dump_byte },
+       { IAX_IE_CALLINGTON, "CALLING TYPEOFNUM", dump_byte },
+       { IAX_IE_CALLINGTNS, "CALLING TRANSITNET", dump_short },
+       { IAX_IE_SAMPLINGRATE, "SAMPLINGRATE", dump_samprate },
+       { IAX_IE_CODEC_PREFS, "CODEC_PREFS", dump_string },
+       { IAX_IE_RR_JITTER, "RR_JITTER", dump_int },
+       { IAX_IE_RR_LOSS, "RR_LOSS", dump_int },
+       { IAX_IE_RR_PKTS, "RR_PKTS", dump_int },
+       { IAX_IE_RR_DELAY, "RR_DELAY", dump_short },
+       { IAX_IE_RR_DROPPED, "RR_DROPPED", dump_int },
+       { IAX_IE_RR_OOO, "RR_OOO", dump_int },
+};
+
+const char *iax_ie2str(int ie)
+{
+       int x;
+       for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) {
+               if (ies[x].ie == ie)
+                       return ies[x].name;
+       }
+       return "Unknown IE";
+}
+
+
+static void dump_prov_ies(char *output, int maxlen, unsigned char *iedata, int len)
+{
+       int ielen;
+       int ie;
+       int found;
+       char tmp[256];
+       if (len < 2)
+               return;
+       strcpy(output, "\n"); 
+       maxlen -= (int)strlen(output); output += strlen(output);
+       while(len > 2) {
+               ie = iedata[0];
+               ielen = iedata[1];
+               if (ielen + 2> len) {
+                       snprintf(tmp, (int)sizeof(tmp), "Total Prov IE length of %d bytes exceeds remaining prov frame length of %d bytes\n", ielen + 2, len);
+                       strncpy(output, tmp, maxlen - 1);
+                       maxlen -= (int)strlen(output); output += strlen(output);
+                       return;
+               }
+               found = 0;
+               if (!found) {
+                       snprintf(tmp, (int)sizeof(tmp), "       Unknown Prov IE %03d  : Present\n", ie);
+                       strncpy(output, tmp, maxlen - 1);
+                       maxlen -= (int)strlen(output); output += strlen(output);
+               }
+               iedata += (2 + ielen);
+               len -= (2 + ielen);
+       }
+}
+
+static void dump_ies(unsigned char *iedata, int len)
+{
+       int ielen;
+       int ie;
+       int x;
+       int found;
+       char interp[1024];
+       char tmp[1024];
+       if (len < 2)
+               return;
+       while(len > 2) {
+               ie = iedata[0];
+               ielen = iedata[1];
+               if (ielen + 2> len) {
+                       snprintf(tmp, (int)sizeof(tmp), "Total IE length of %d bytes exceeds remaining frame length of %d bytes\n", ielen + 2, len);
+                       outputf(tmp);
+                       return;
+               }
+               found = 0;
+               for (x=0;x<(int)sizeof(ies) / (int)sizeof(ies[0]); x++) {
+                       if (ies[x].ie == ie) {
+                               if (ies[x].dump) {
+                                       ies[x].dump(interp, (int)sizeof(interp), iedata + 2, ielen);
+                                       snprintf(tmp, (int)sizeof(tmp), "   %-15.15s : %s\n", ies[x].name, interp);
+                                       outputf(tmp);
+                               } else {
+                                       if (ielen)
+                                               snprintf(interp, (int)sizeof(interp), "%d bytes", ielen);
+                                       else
+                                               strcpy(interp, "Present");
+                                       snprintf(tmp, (int)sizeof(tmp), "   %-15.15s : %s\n", ies[x].name, interp);
+                                       outputf(tmp);
+                               }
+                               found++;
+                       }
+               }
+               if (!found) {
+                       snprintf(tmp, (int)sizeof(tmp), "   Unknown IE %03d  : Present\n", ie);
+                       outputf(tmp);
+               }
+               iedata += (2 + ielen);
+               len -= (2 + ielen);
+       }
+       outputf("\n");
+}
+
+void iax_showframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
+{
+       const char *frames[] = {
+               "(0?)",
+               "DTMF   ",
+               "VOICE  ",
+               "VIDEO  ",
+               "CONTROL",
+               "NULL   ",
+               "IAX    ",
+               "TEXT   ",
+               "IMAGE  " };
+       const char *iaxs[] = {
+               "(0?)",
+               "NEW    ",
+               "PING   ",
+               "PONG   ",
+               "ACK    ",
+               "HANGUP ",
+               "REJECT ",
+               "ACCEPT ",
+               "AUTHREQ",
+               "AUTHREP",
+               "INVAL  ",
+               "LAGRQ  ",
+               "LAGRP  ",
+               "REGREQ ",
+               "REGAUTH",
+               "REGACK ",
+               "REGREJ ",
+               "REGREL ",
+               "VNAK   ",
+               "DPREQ  ",
+               "DPREP  ",
+               "DIAL   ",
+               "TXREQ  ",
+               "TXCNT  ",
+               "TXACC  ",
+               "TXREADY",
+               "TXREL  ",
+               "TXREJ  ",
+               "QUELCH ",
+               "UNQULCH",
+               "POKE",
+               "PAGE",
+               "MWI",
+               "UNSUPPORTED",
+               "TRANSFER",
+               "PROVISION",
+               "FWDOWNLD",
+               "FWDATA"
+       };
+       const char *cmds[] = {
+               "(0?)",
+               "HANGUP ",
+               "RING   ",
+               "RINGING",
+               "ANSWER ",
+               "BUSY   ",
+               "TKOFFHK ",
+               "OFFHOOK ",
+               "CONGESTION ",
+               "FLASH ",
+               "WINK ",
+               "OPTION "
+        };
+       struct ast_iax2_full_hdr *fh;
+       char retries[20];
+       char class2[20];
+       char subclass2[20];
+       const char *clas;
+       const char *subclass;
+       char tmp[256];
+
+       if (f) {
+               fh = (struct ast_iax2_full_hdr *)f->data;
+               snprintf(retries, (int)sizeof(retries), "%03d", f->retries);
+       } else {
+               fh = fhi;
+               if (ntohs(fh->dcallno) & IAX_FLAG_RETRANS)
+                       strcpy(retries, "Yes");
+               else
+                       strcpy(retries, " No");
+       }
+       if (!(ntohs(fh->scallno) & IAX_FLAG_FULL)) {
+               /* Don't mess with mini-frames */
+               return;
+       }
+       if (fh->type >= (int)(sizeof(frames)/sizeof(char *))) {
+               snprintf(class2, (int)sizeof(class2), "(%d?)", fh->type);
+               clas = class2;
+       } else {
+               clas = frames[(int)fh->type];
+       }
+       if (fh->type == AST_FRAME_DTMF) {
+               sprintf(subclass2, "%c", fh->csub);
+               subclass = subclass2;
+       } else if (fh->type == AST_FRAME_IAX) {
+               if (fh->csub >= (int)sizeof(iaxs)/(int)sizeof(iaxs[0])) {
+                       snprintf(subclass2, (int)sizeof(subclass2), "(%d?)", fh->csub);
+                       subclass = subclass2;
+               } else {
+                       subclass = iaxs[(int)fh->csub];
+               }
+       } else if (fh->type == AST_FRAME_CONTROL) {
+               if (fh->csub >= (int)(sizeof(cmds)/sizeof(char *))) {
+                       snprintf(subclass2, (int)sizeof(subclass2), "(%d?)", fh->csub);
+                       subclass = subclass2;
+               } else {
+                       subclass = cmds[(int)fh->csub];
+               }
+       } else {
+               snprintf(subclass2, (int)sizeof(subclass2), "%d", fh->csub);
+               subclass = subclass2;
+       }
+snprintf(tmp, (int)sizeof(tmp), 
+"%s-Frame Retry[%s] -- OSeqno: %3.3d ISeqno: %3.3d Type: %s Subclass: %s\n",
+       (rx ? "Rx" : "Tx"),
+       retries, fh->oseqno, fh->iseqno, clas, subclass);
+       outputf(tmp);
+snprintf(tmp, (int)sizeof(tmp), 
+"   Timestamp: %05lums  SCall: %5.5d  DCall: %5.5d [%s:%d]\n",
+       (unsigned long)ntohl(fh->ts),
+       ntohs(fh->scallno) & ~IAX_FLAG_FULL, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS,
+               inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
+       outputf(tmp);
+       if (fh->type == AST_FRAME_IAX)
+               dump_ies(fh->iedata, datalen);
+}
+
+int iax_ie_append_raw(struct iax_ie_data *ied, unsigned char ie, const void *data, int datalen)
+{
+       char tmp[256];
+       if (datalen > ((int)sizeof(ied->buf) - ied->pos)) {
+               snprintf(tmp, (int)sizeof(tmp), "Out of space for ie '%s' (%d), need %d have %d\n", iax_ie2str(ie), ie, datalen, (int)sizeof(ied->buf) - ied->pos);
+               errorf(tmp);
+               return -1;
+       }
+       ied->buf[ied->pos++] = ie;
+       ied->buf[ied->pos++] = datalen;
+       memcpy(ied->buf + ied->pos, data, datalen);
+       ied->pos += datalen;
+       return 0;
+}
+
+int iax_ie_append_addr(struct iax_ie_data *ied, unsigned char ie, struct sockaddr_in *sin)
+{
+       return iax_ie_append_raw(ied, ie, sin, (int)sizeof(struct sockaddr_in));
+}
+
+int iax_ie_append_int(struct iax_ie_data *ied, unsigned char ie, unsigned int value) 
+{
+       unsigned int newval;
+       newval = htonl(value);
+       return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
+}
+
+int iax_ie_append_short(struct iax_ie_data *ied, unsigned char ie, unsigned short value) 
+{
+       unsigned short newval;
+       newval = htons(value);
+       return iax_ie_append_raw(ied, ie, &newval, (int)sizeof(newval));
+}
+
+int iax_ie_append_str(struct iax_ie_data *ied, unsigned char ie, const char *str)
+{
+       return iax_ie_append_raw(ied, ie, str, (int)strlen(str));
+}
+
+int iax_ie_append_byte(struct iax_ie_data *ied, unsigned char ie, unsigned char dat)
+{
+       return iax_ie_append_raw(ied, ie, &dat, 1);
+}
+
+int iax_ie_append(struct iax_ie_data *ied, unsigned char ie) 
+{
+       return iax_ie_append_raw(ied, ie, NULL, 0);
+}
+
+void iax_set_output(void (*func)(const char *))
+{
+       outputf = func;
+}
+
+void iax_set_error(void (*func)(const char *))
+{
+       errorf = func;
+}
+
+int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
+{
+       /* Parse data into information elements */
+       int len;
+       int ie;
+       char tmp[256];
+       memset(ies, 0, (int)sizeof(struct iax_ies));
+       ies->msgcount = -1;
+       ies->firmwarever = -1;
+       ies->calling_ton = -1;
+       ies->calling_tns = -1;
+       ies->calling_pres = -1;
+       ies->samprate = IAX_RATE_8KHZ;
+       while(datalen >= 2) {
+               ie = data[0];
+               len = data[1];
+               if (len > datalen - 2) {
+                       errorf("Information element length exceeds message size\n");
+                       return -1;
+               }
+               switch(ie) {
+               case IAX_IE_CALLED_NUMBER:
+                       ies->called_number = (char *) data + 2;
+                       break;
+               case IAX_IE_CALLING_NUMBER:
+                       ies->calling_number = (char *) data + 2;
+                       break;
+               case IAX_IE_CALLING_ANI:
+                       ies->calling_ani = (char *) data + 2;
+                       break;
+               case IAX_IE_CALLING_NAME:
+                       ies->calling_name = (char *) data + 2;
+                       break;
+               case IAX_IE_CALLED_CONTEXT:
+                       ies->called_context = (char *) data + 2;
+                       break;
+               case IAX_IE_USERNAME:
+                       ies->username = (char *) data + 2;
+                       break;
+               case IAX_IE_PASSWORD:
+                       ies->password = (char *) data + 2;
+                       break;
+               case IAX_IE_CAPABILITY:
+                       if (len != (int)sizeof(unsigned int)) {
+                               snprintf(tmp, (int)sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
+                               errorf(tmp);
+                       } else
+                               ies->capability = ntohl(get_uint32(data + 2));
+                       break;
+               case IAX_IE_FORMAT:
+                       if (len != (int)sizeof(unsigned int)) {
+                               snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
+                               errorf(tmp);
+                       } else
+                               ies->format = ntohl(get_uint32(data + 2));
+                       break;
+               case IAX_IE_LANGUAGE:
+                       ies->language = (char *) data + 2;
+                       break;
+               case IAX_IE_CODEC_PREFS:
+                       ies->codec_prefs = (char *) data + 2;
+                       break;
+               case IAX_IE_VERSION:
+                       if (len != (int)sizeof(unsigned short)) {
+                               snprintf(tmp, (int)sizeof(tmp),  "Expecting version to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
+                               errorf(tmp);
+                       } else
+                               ies->version = ntohs(get_uint16(data + 2));
+                       break;
+               case IAX_IE_ADSICPE:
+                       if (len != (int)sizeof(unsigned short)) {
+                               snprintf(tmp, (int)sizeof(tmp), "Expecting adsicpe to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
+                               errorf(tmp);
+                       } else
+                               ies->adsicpe = ntohs(get_uint16(data + 2));
+                       break;
+               case IAX_IE_SAMPLINGRATE:
+                       if (len != (int)sizeof(unsigned short)) {
+                               snprintf(tmp, (int)sizeof(tmp), "Expecting samplingrate to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
+                               errorf(tmp);
+                       } else
+                               ies->samprate = ntohs(get_uint16(data + 2));
+                       break;
+               case IAX_IE_DNID:
+                       ies->dnid = (char *) data + 2;
+                       break;
+               case IAX_IE_RDNIS:
+                       ies->rdnis = (char *) data + 2;
+                       break;
+               case IAX_IE_AUTHMETHODS:
+                       if (len != (int)sizeof(unsigned short))  {
+                               snprintf(tmp, (int)sizeof(tmp), "Expecting authmethods to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
+                               errorf(tmp);
+                       } else
+                               ies->authmethods = ntohs(get_uint16(data + 2));
+                       break;
+               case IAX_IE_CHALLENGE:
+                       ies->challenge = (char *) data + 2;
+                       break;
+               case IAX_IE_MD5_RESULT:
+                       ies->md5_result = (char *) data + 2;
+                       break;
+               case IAX_IE_RSA_RESULT:
+                       ies->rsa_result = (char *) data + 2;
+                       break;
+               case IAX_IE_APPARENT_ADDR:
+                       ies->apparent_addr = ((struct sockaddr_in *)(data + 2));
+                       break;
+               case IAX_IE_REFRESH:
+                       if (len != (int)sizeof(unsigned short)) {
+                               snprintf(tmp, (int)sizeof(tmp),  "Expecting refresh to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
+                               errorf(tmp);
+                       } else
+                               ies->refresh = ntohs(get_uint16(data + 2));
+                       break;
+               case IAX_IE_DPSTATUS:
+                       if (len != (int)sizeof(unsigned short)) {
+                               snprintf(tmp, (int)sizeof(tmp),  "Expecting dpstatus to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
+                               errorf(tmp);
+                       } else
+                               ies->dpstatus = ntohs(get_uint16(data + 2));
+                       break;
+               case IAX_IE_CALLNO:
+                       if (len != (int)sizeof(unsigned short)) {
+                               snprintf(tmp, (int)sizeof(tmp),  "Expecting callno to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
+                               errorf(tmp);
+                       } else
+                               ies->callno = ntohs(get_uint16(data + 2));
+                       break;
+               case IAX_IE_CAUSE:
+                       ies->cause = (char *) data + 2;
+                       break;
+               case IAX_IE_CAUSECODE:
+                       if (len != 1) {
+                               snprintf(tmp, (int)sizeof(tmp), "Expecting causecode to be single byte but was %d\n", len);
+                               errorf(tmp);
+                       } else {
+                               ies->causecode = data[2];
+                       }
+                       break;
+               case IAX_IE_IAX_UNKNOWN:
+                       if (len == 1)
+                               ies->iax_unknown = data[2];
+                       else {
+                               snprintf(tmp, (int)sizeof(tmp), "Expected single byte Unknown command, but was %d long\n", len);
+                               errorf(tmp);
+                       }
+                       break;
+               case IAX_IE_MSGCOUNT:
+                       if (len != (int)sizeof(unsigned short)) {
+                               snprintf(tmp, (int)sizeof(tmp), "Expecting msgcount to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
+                               errorf(tmp);
+                       } else
+                               ies->msgcount = ntohs(get_uint16(data + 2));    
+                       break;
+               case IAX_IE_AUTOANSWER:
+                       ies->autoanswer = 1;
+                       break;
+               case IAX_IE_MUSICONHOLD:
+                       ies->musiconhold = 1;
+                       break;
+               case IAX_IE_TRANSFERID:
+                       if (len != (int)sizeof(unsigned int)) {
+                               snprintf(tmp, (int)sizeof(tmp), "Expecting transferid to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
+                               errorf(tmp);
+                       } else
+                               ies->transferid = ntohl(get_uint32(data + 2));
+                       break;
+               case IAX_IE_DATETIME:
+                       if (len != (int)sizeof(unsigned int)) {
+                               snprintf(tmp, (int)sizeof(tmp), "Expecting date/time to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
+                               errorf(tmp);
+                       } else
+                               ies->datetime = ntohl(get_uint32(data + 2));
+                       break;
+               case IAX_IE_FIRMWAREVER:
+                       if (len != (int)sizeof(unsigned short)) {
+                               snprintf(tmp, (int)sizeof(tmp), "Expecting firmwarever to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
+                               errorf(tmp);
+                       } else
+                               ies->firmwarever = ntohs(get_uint16(data + 2)); 
+                       break;
+               case IAX_IE_DEVICETYPE:
+                       ies->devicetype = (char *) data + 2;
+                       break;
+               case IAX_IE_SERVICEIDENT:
+                       ies->serviceident = (char *) data + 2;
+                       break;
+               case IAX_IE_FWBLOCKDESC:
+                       if (len != (int)sizeof(unsigned int)) {
+                               snprintf(tmp, (int)sizeof(tmp), "Expected block desc to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
+                               errorf(tmp);
+                       } else
+                               ies->fwdesc = ntohl(get_uint32(data + 2));
+                       break;
+               case IAX_IE_FWBLOCKDATA:
+                       ies->fwdata = data + 2;
+                       ies->fwdatalen = len;
+                       break;
+               case IAX_IE_PROVVER:
+                       if (len != (int)sizeof(unsigned int)) {
+                               snprintf(tmp, (int)sizeof(tmp), "Expected provisioning version to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
+                               errorf(tmp);
+                       } else {
+                               ies->provverpres = 1;
+                               ies->provver = ntohl(get_uint32(data + 2));
+                       }
+                       break;
+               case IAX_IE_CALLINGPRES:
+                       if (len == 1)
+                               ies->calling_pres = data[2];
+                       else {
+                               snprintf(tmp, (int)sizeof(tmp), "Expected single byte callingpres, but was %d long\n", len);
+                               errorf(tmp);
+                       }
+                       break;
+               case IAX_IE_CALLINGTON:
+                       if (len == 1)
+                               ies->calling_ton = data[2];
+                       else {
+                               snprintf(tmp, (int)sizeof(tmp), "Expected single byte callington, but was %d long\n", len);
+                               errorf(tmp);
+                       }
+                       break;
+               case IAX_IE_CALLINGTNS:
+                       if (len != (int)sizeof(unsigned short)) {
+                               snprintf(tmp, (int)sizeof(tmp), "Expecting callingtns to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
+                               errorf(tmp);
+                       } else
+                               ies->calling_tns = ntohs(get_uint16(data + 2)); 
+                       break;
+               case IAX_IE_RR_JITTER:
+                       if (len != (int)sizeof(unsigned int)) {
+                               snprintf(tmp, (int)sizeof(tmp), "Expected jitter rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
+                               errorf(tmp);
+                       } else {
+                               ies->rr_jitter = ntohl(get_uint32(data + 2));
+                       }
+                       break;
+               case IAX_IE_RR_LOSS:
+                       if (len != (int)sizeof(unsigned int)) {
+                               snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
+                               errorf(tmp);
+                       } else {
+                               ies->rr_loss = ntohl(get_uint32(data + 2));
+                       }
+                       break;
+               case IAX_IE_RR_PKTS:
+                       if (len != (int)sizeof(unsigned int)) {
+                               snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
+                               errorf(tmp);
+                       } else {
+                               ies->rr_pkts = ntohl(get_uint32(data + 2));
+                       }
+                       break;
+               case IAX_IE_RR_DELAY:
+                       if (len != (int)sizeof(unsigned short)) {
+                               snprintf(tmp, (int)sizeof(tmp), "Expected loss rr to be %d bytes long but was %d\n", (int)sizeof(unsigned short), len);
+                               errorf(tmp);
+                       } else {
+                               ies->rr_delay = ntohs(get_uint16(data + 2));
+                       }
+                       break;
+               case IAX_IE_RR_DROPPED:
+                       if (len != (int)sizeof(unsigned int)) {
+                               snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
+                               errorf(tmp);
+                       } else {
+                               ies->rr_dropped = ntohl(get_uint32(data + 2));
+                       }
+                       break;
+               case IAX_IE_RR_OOO:
+                       if (len != (int)sizeof(unsigned int)) {
+                               snprintf(tmp, (int)sizeof(tmp), "Expected packets rr to be %d bytes long but was %d\n", (int)sizeof(unsigned int), len);
+                               errorf(tmp);
+                       } else {
+                               ies->rr_ooo = ntohl(get_uint32(data + 2));
+                       }
+                       break;
+               default:
+                       snprintf(tmp, (int)sizeof(tmp), "Ignoring unknown information element '%s' (%d) of length %d\n", iax_ie2str(ie), ie, len);
+                       outputf(tmp);
+               }
+               /* Overwrite information element with 0, to null terminate previous portion */
+               data[0] = 0;
+               datalen -= (len + 2);
+               data += (len + 2);
+       }
+       /* Null-terminate last field */
+       *data = '\0';
+       if (datalen) {
+               errorf("Invalid information element contents, strange boundary\n");
+               return -1;
+       }
+       return 0;
+}
+
+void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f)
+{
+       fr->af.frametype = f->frametype;
+       fr->af.subclass = f->subclass;
+       fr->af.mallocd = 0;                             /* Our frame is static relative to the container */
+       fr->af.datalen = f->datalen;
+       fr->af.samples = f->samples;
+       fr->af.offset = AST_FRIENDLY_OFFSET;
+       fr->af.src = f->src;
+       fr->af.data = fr->afdata;
+       if (fr->af.datalen) 
+               memcpy(fr->af.data, f->data, fr->af.datalen);
+}
+
+struct iax_frame *iax_frame_new(int direction, int datalen)
+{
+       struct iax_frame *fr;
+       fr = (struct iax_frame *)malloc((int)sizeof(struct iax_frame) + datalen);
+       if (fr) {
+               fr->direction = direction;
+               fr->retrans = -1;
+               frames++;
+               if (fr->direction == DIRECTION_INGRESS)
+                       iframes++;
+               else
+                       oframes++;
+       }
+       return fr;
+}
+
+void iax_frame_free(struct iax_frame *fr)
+{
+       /* Note: does not remove from scheduler! */
+       if (fr->direction == DIRECTION_INGRESS)
+               iframes--;
+       else if (fr->direction == DIRECTION_OUTGRESS)
+               oframes--;
+       else {
+               errorf("Attempt to double free frame detected\n");
+               return;
+       }
+       fr->direction = 0;
+       free(fr);
+       frames--;
+}
+
+int iax_get_frames(void) { return frames; }
+int iax_get_iframes(void) { return iframes; }
+int iax_get_oframes(void) { return oframes; }
diff --git a/utils/iaxclient/lib/libiax2/src/iax2-parser.h b/utils/iaxclient/lib/libiax2/src/iax2-parser.h
new file mode 100644 (file)
index 0000000..8238b2f
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Asterisk -- A telephony toolkit for Linux.
+ *
+ * Implementation of Inter-Asterisk eXchange
+ * 
+ * Copyright (C) 2003, Digium
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License
+ */
+#ifndef _IAX2_PARSER_H
+#define _IAX2_PARSER_H
+
+struct iax_ies {
+       char *called_number;
+       char *calling_number;
+       char *calling_ani;
+       char *calling_name;
+       int calling_ton;
+       int calling_tns;
+       int calling_pres;
+       char *called_context;
+       char *username;
+       char *password;
+       unsigned int capability;
+       unsigned int format;
+       char *codec_prefs;
+       char *language;
+       int version;
+       unsigned short adsicpe;
+       char *dnid;
+       char *rdnis;
+       unsigned int authmethods;
+       char *challenge;
+       char *md5_result;
+       char *rsa_result;
+       struct sockaddr_in *apparent_addr;
+       unsigned short refresh;
+       unsigned short dpstatus;
+       unsigned short callno;
+       char *cause;
+       unsigned char causecode;
+       unsigned char iax_unknown;
+       int msgcount;
+       int autoanswer;
+       int musiconhold;
+       unsigned int transferid;
+       unsigned int datetime;
+       char *devicetype;
+       char *serviceident;
+       int firmwarever;
+       unsigned int fwdesc;
+       unsigned char *fwdata;
+       unsigned char fwdatalen;
+       unsigned int provver;
+       unsigned short samprate;
+       unsigned int provverpres;
+       unsigned int rr_jitter;
+       unsigned int rr_loss;
+       unsigned int rr_pkts;
+       unsigned short rr_delay;
+       unsigned int rr_dropped;
+       unsigned int rr_ooo;
+};
+
+#define DIRECTION_INGRESS 1
+#define DIRECTION_OUTGRESS 2
+
+struct iax_frame {
+#ifdef LIBIAX
+       struct iax_session *session;
+       struct iax_event *event;
+#endif
+
+       /* /Our/ call number */
+       unsigned short callno;
+       /* /Their/ call number */
+       unsigned short dcallno;
+       /* Start of raw frame (outgoing only) */
+       void *data;
+       /* Length of frame (outgoing only) */
+       int datalen;
+       /* How many retries so far? */
+       int retries;
+       /* Outgoing relative timestamp (ms) */
+       unsigned int ts;
+       /* How long to wait before retrying */
+       int retrytime;
+       /* Are we received out of order?  */
+       int outoforder;
+       /* Have we been sent at all yet? */
+       int sentyet;
+       /* Outgoing Packet sequence number */
+       int oseqno;
+       /* Next expected incoming packet sequence number */
+       int iseqno;
+       /* Non-zero if should be sent to transfer peer */
+       int transfer;
+       /* Non-zero if this is the final message */
+       int final;
+       /* Ingress or outgres */
+       int direction;
+       /* Retransmission ID */
+       int retrans;
+       /* Easy linking */
+       struct iax_frame *next;
+       struct iax_frame *prev;
+       /* Actual, isolated frame header */
+       struct ast_frame af;
+       unsigned char unused[AST_FRIENDLY_OFFSET];
+       unsigned char afdata[0];        /* Data for frame */
+};
+
+struct iax_ie_data {
+       unsigned char buf[1024];
+       int pos;
+};
+
+/* Choose a different function for output */
+extern void iax_set_output(void (*output)(const char *data));
+/* Choose a different function for errors */
+extern void iax_set_error(void (*output)(const char *data));
+extern void iax_showframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen);
+
+extern const char *iax_ie2str(int ie);
+
+extern int iax_ie_append_raw(struct iax_ie_data *ied, unsigned char ie, const void *data, int datalen);
+extern int iax_ie_append_addr(struct iax_ie_data *ied, unsigned char ie, struct sockaddr_in *sin);
+extern int iax_ie_append_int(struct iax_ie_data *ied, unsigned char ie, unsigned int value);
+extern int iax_ie_append_short(struct iax_ie_data *ied, unsigned char ie, unsigned short value);
+extern int iax_ie_append_str(struct iax_ie_data *ied, unsigned char ie, const char *str);
+extern int iax_ie_append_byte(struct iax_ie_data *ied, unsigned char ie, unsigned char dat);
+extern int iax_ie_append(struct iax_ie_data *ied, unsigned char ie);
+extern int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen);
+
+extern int iax_get_frames(void);
+extern int iax_get_iframes(void);
+extern int iax_get_oframes(void);
+
+extern void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f);
+extern struct iax_frame *iax_frame_new(int direction, int datalen);
+extern void iax_frame_free(struct iax_frame *fr);
+#endif
diff --git a/utils/iaxclient/lib/libiax2/src/iax2.h b/utils/iaxclient/lib/libiax2/src/iax2.h
new file mode 100644 (file)
index 0000000..1f9ae38
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * Asterisk -- A telephony toolkit for Linux.
+ *
+ * Implementation of Inter-Asterisk eXchange
+ * 
+ * Copyright (C) 2003, Digium
+ *
+ * Mark Spencer <markster@linux-support.net>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License
+ */
+#ifndef _IAX2_H
+#define _IAX2_H
+
+/* Max version of IAX protocol we support */
+#define IAX_PROTO_VERSION 2
+
+#define IAX_MAX_CALLS 32768
+
+#define IAX_FLAG_FULL          0x8000
+
+#define IAX_FLAG_RETRANS       0x8000
+
+#define IAX_FLAG_SC_LOG                0x80
+
+#define IAX_MAX_SHIFT          0x1F
+
+#define IAX_WINDOW                     64
+
+/* Subclass for AST_FRAME_IAX */
+#define IAX_COMMAND_NEW                1
+#define IAX_COMMAND_PING       2
+#define IAX_COMMAND_PONG       3
+#define IAX_COMMAND_ACK                4
+#define IAX_COMMAND_HANGUP     5
+#define IAX_COMMAND_REJECT     6
+#define IAX_COMMAND_ACCEPT     7
+#define IAX_COMMAND_AUTHREQ    8
+#define IAX_COMMAND_AUTHREP    9
+#define IAX_COMMAND_INVAL      10
+#define IAX_COMMAND_LAGRQ      11
+#define IAX_COMMAND_LAGRP      12
+#define IAX_COMMAND_REGREQ     13      /* Registration request */
+#define IAX_COMMAND_REGAUTH    14      /* Registration authentication required */
+#define IAX_COMMAND_REGACK     15      /* Registration accepted */
+#define IAX_COMMAND_REGREJ     16      /* Registration rejected */
+#define IAX_COMMAND_REGREL     17      /* Force release of registration */
+#define IAX_COMMAND_VNAK       18      /* If we receive voice before valid first voice frame, send this */
+#define IAX_COMMAND_DPREQ      19      /* Request status of a dialplan entry */
+#define IAX_COMMAND_DPREP      20      /* Request status of a dialplan entry */
+#define IAX_COMMAND_DIAL       21      /* Request a dial on channel brought up TBD */
+#define IAX_COMMAND_TXREQ      22      /* Transfer Request */
+#define IAX_COMMAND_TXCNT      23      /* Transfer Connect */
+#define IAX_COMMAND_TXACC      24      /* Transfer Accepted */
+#define IAX_COMMAND_TXREADY    25      /* Transfer ready */
+#define IAX_COMMAND_TXREL      26      /* Transfer release */
+#define IAX_COMMAND_TXREJ      27      /* Transfer reject */
+#define IAX_COMMAND_QUELCH     28      /* Stop audio/video transmission */
+#define IAX_COMMAND_UNQUELCH 29        /* Resume audio/video transmission */
+#define IAX_COMMAND_POKE    30  /* Like ping, but does not require an open connection */
+#define IAX_COMMAND_PAGE       31      /* Paging description */
+#define IAX_COMMAND_MWI        32      /* Stand-alone message waiting indicator */
+#define IAX_COMMAND_UNSUPPORT  33      /* Unsupported message received */
+#define IAX_COMMAND_TRANSFER   34      /* Request remote transfer */
+#define IAX_COMMAND_PROVISION  35      /* Provision device */
+#define IAX_COMMAND_FWDOWNL    36      /* Download firmware */
+#define IAX_COMMAND_FWDATA     37      /* Firmware Data */
+
+#define IAX_DEFAULT_REG_EXPIRE  60     /* By default require re-registration once per minute */
+
+#define IAX_LINGER_TIMEOUT             10 /* How long to wait before closing bridged call */
+
+#define IAX_DEFAULT_PORTNO             4569
+
+/* IAX Information elements */
+#define IAX_IE_CALLED_NUMBER           1               /* Number/extension being called - string */
+#define IAX_IE_CALLING_NUMBER          2               /* Calling number - string */
+#define IAX_IE_CALLING_ANI                     3               /* Calling number ANI for billing  - string */
+#define IAX_IE_CALLING_NAME                    4               /* Name of caller - string */
+#define IAX_IE_CALLED_CONTEXT          5               /* Context for number - string */
+#define IAX_IE_USERNAME                                6               /* Username (peer or user) for authentication - string */
+#define IAX_IE_PASSWORD                                7               /* Password for authentication - string */
+#define IAX_IE_CAPABILITY                      8               /* Actual codec capability - unsigned int */
+#define IAX_IE_FORMAT                          9               /* Desired codec format - unsigned int */
+#define IAX_IE_LANGUAGE                                10              /* Desired language - string */
+#define IAX_IE_VERSION                         11              /* Protocol version - short */
+#define IAX_IE_ADSICPE                         12              /* CPE ADSI capability - short */
+#define IAX_IE_DNID                                    13              /* Originally dialed DNID - string */
+#define IAX_IE_AUTHMETHODS                     14              /* Authentication method(s) - short */
+#define IAX_IE_CHALLENGE                       15              /* Challenge data for MD5/RSA - string */
+#define IAX_IE_MD5_RESULT                      16              /* MD5 challenge result - string */
+#define IAX_IE_RSA_RESULT                      17              /* RSA challenge result - string */
+#define IAX_IE_APPARENT_ADDR           18              /* Apparent address of peer - struct sockaddr_in */
+#define IAX_IE_REFRESH                         19              /* When to refresh registration - short */
+#define IAX_IE_DPSTATUS                                20              /* Dialplan status - short */
+#define IAX_IE_CALLNO                          21              /* Call number of peer - short */
+#define IAX_IE_CAUSE                           22              /* Cause - string */
+#define IAX_IE_IAX_UNKNOWN                     23              /* Unknown IAX command - byte */
+#define IAX_IE_MSGCOUNT                                24              /* How many messages waiting - short */
+#define IAX_IE_AUTOANSWER                      25              /* Request auto-answering -- none */
+#define IAX_IE_MUSICONHOLD                     26              /* Request musiconhold with QUELCH -- none or string */
+#define IAX_IE_TRANSFERID                      27              /* Transfer Request Identifier -- int */
+#define IAX_IE_RDNIS                           28              /* Referring DNIS -- string */
+#define IAX_IE_PROVISIONING                    29              /* Provisioning info */
+#define IAX_IE_AESPROVISIONING                 30              /* AES Provisioning info */
+#define IAX_IE_DATETIME                                31              /* Date/Time */
+#define IAX_IE_DEVICETYPE                       32              /* Device Type -- string */
+#define IAX_IE_SERVICEIDENT                     33              /* Service Identifier -- string */
+#define IAX_IE_FIRMWAREVER                      34              /* Firmware revision -- u16 */
+#define IAX_IE_FWBLOCKDESC                      35              /* Firmware block description -- u32 */
+#define IAX_IE_FWBLOCKDATA                      36              /* Firmware block of data -- raw */
+#define IAX_IE_PROVVER                          37              /* Provisioning Version (u32) */
+#define IAX_IE_CALLINGPRES                      38              /* Calling presentation (u8) */
+#define IAX_IE_CALLINGTON                       39              /* Calling type of number (u8) */
+#define IAX_IE_CALLINGTNS                       40              /* Calling transit network select (u16) */
+#define IAX_IE_SAMPLINGRATE                     41              /* Supported sampling rates (u16) */
+#define IAX_IE_CAUSECODE                        42              /* Hangup cause (u8) */
+#define IAX_IE_ENCRYPTION                       43              /* Encryption format (u16) */
+#define IAX_IE_ENCKEY                           44              /* Encryption key (raw) */
+#define IAX_IE_CODEC_PREFS          45      /* Codec Negotiation */
+
+#define IAX_IE_RR_JITTER                        46              /* Received jitter (as in RFC1889) u32 */
+#define IAX_IE_RR_LOSS                          47              /* Received loss (high byte loss pct, low 24 bits loss count, as in rfc1889 */
+#define IAX_IE_RR_PKTS                          48              /* Received frames (total frames received) u32 */
+#define IAX_IE_RR_DELAY                         49              /* Max playout delay for received frames (in ms) u16 */
+#define IAX_IE_RR_DROPPED                       50              /* Dropped frames (presumably by jitterbuf) u32 */
+#define IAX_IE_RR_OOO                           51              /* Frames received Out of Order u32 */
+
+
+
+#define IAX_AUTH_PLAINTEXT                     (1 << 0)
+#define IAX_AUTH_MD5                           (1 << 1)
+#define IAX_AUTH_RSA                           (1 << 2)
+
+#define IAX_META_TRUNK                         1               /* Trunk meta-message */
+#define IAX_META_VIDEO                         2               /* Video frame */
+
+#define IAX_RATE_8KHZ                          (1 << 0) /* 8khz sampling (default if absent) */
+#define IAX_RATE_11KHZ                         (1 << 1) /* 11.025khz sampling */
+#define IAX_RATE_16KHZ                         (1 << 2) /* 16khz sampling */
+#define IAX_RATE_22KHZ                         (1 << 3) /* 22.05khz sampling */
+#define IAX_RATE_44KHZ                         (1 << 4) /* 44.1khz sampling */
+#define IAX_RATE_48KHZ                         (1 << 5) /* 48khz sampling */
+
+#define IAX_DPSTATUS_EXISTS                    (1 << 0)
+#define IAX_DPSTATUS_CANEXIST          (1 << 1)
+#define IAX_DPSTATUS_NONEXISTANT       (1 << 2)
+#define IAX_DPSTATUS_IGNOREPAT         (1 << 14)
+#define IAX_DPSTATUS_MATCHMORE         (1 << 15)
+
+#if defined(_MSC_VER)
+#pragma pack(push,1)
+#define __PACKED
+#else
+#define __PACKED __attribute__ ((__packed__))
+#endif
+
+/* Full frames are always delivered reliably */
+struct ast_iax2_full_hdr {
+       unsigned short scallno; /* Source call number -- high bit must be 1 */
+       unsigned short dcallno; /* Destination call number -- high bit is 1 if retransmission */
+       unsigned int ts;                /* 32-bit timestamp in milliseconds (from 1st transmission) */
+       unsigned char oseqno;   /* Packet number (outgoing) */
+       unsigned char iseqno;   /* Packet number (next incoming expected) */
+       char type;                              /* Frame type */
+       unsigned char csub;             /* Compressed subclass */
+       unsigned char iedata[0];
+} __PACKED;
+
+/* Mini header is used only for voice frames -- delivered unreliably */
+struct ast_iax2_mini_hdr {
+       unsigned short callno;  /* Source call number -- high bit must be 0, rest must be non-zero */
+       unsigned short ts;              /* 16-bit Timestamp (high 16 bits from last ast_iax2_full_hdr) */
+                                                       /* Frametype implicitly VOICE_FRAME */
+                                                       /* subclass implicit from last ast_iax2_full_hdr */
+       unsigned char data[0];
+} __PACKED;
+
+struct ast_iax2_meta_hdr {
+       unsigned short zeros;                   /* Zeros field -- must be zero */
+       unsigned char metacmd;                  /* Meta command */
+       unsigned char cmddata;                  /* Command Data */
+       unsigned char data[0];
+} __PACKED;
+
+struct ast_iax2_video_hdr {
+       unsigned short zeros;                   /* Zeros field -- must be zero */
+       unsigned short callno;                  /* Video call number */
+       unsigned short ts;                              /* Timestamp and mark if present */
+       unsigned char data[0];
+} __PACKED;
+
+struct ast_iax2_meta_trunk_hdr {
+       unsigned int ts;                                /* 32-bit timestamp for all messages */
+       unsigned char data[0];
+} __PACKED;
+
+struct ast_iax2_meta_trunk_entry {
+       unsigned short callno;                  /* Call number */
+       unsigned short len;                             /* Length of data for this callno */
+} __PACKED;
+
+#define IAX_FIRMWARE_MAGIC 0x69617879
+
+struct ast_iax2_firmware_header {
+       unsigned int magic;             /* Magic number */
+       unsigned short version;         /* Software version */
+       unsigned char devname[16];      /* Device */
+       unsigned int datalen;           /* Data length of file beyond header */
+       unsigned char chksum[16];       /* Checksum of all data */
+       unsigned char data[0];
+} __PACKED;
+
+
+#if defined(_MSC_VER)
+#pragma pack(pop)
+#endif
+
+#undef __PACKED
+
+#endif
diff --git a/utils/iaxclient/lib/libiax2/src/jitterbuf.c b/utils/iaxclient/lib/libiax2/src/jitterbuf.c
new file mode 100644 (file)
index 0000000..0d45024
--- /dev/null
@@ -0,0 +1,833 @@
+/*
+ * jitterbuf: an application-independent jitterbuffer
+ *
+ * Copyrights:
+ * Copyright (C) 2004-2005, Horizon Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License
+ *
+ * Copyright on this file is disclaimed to Digium for inclusion in Asterisk
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include "jitterbuf.h"
+
+/* define these here, just for ancient compiler systems */
+#define JB_LONGMAX 2147483647L
+#define JB_LONGMIN (-JB_LONGMAX - 1L)
+
+/* MS VC can't do __VA_ARGS__ */
+#if (defined(WIN32)  ||  defined(_WIN32_WCE))  &&  defined(_MSC_VER)
+#define jb_warn if (warnf) warnf
+#define jb_err if (errf) errf
+#define jb_dbg if (dbgf) dbgf
+
+#ifdef DEEP_DEBUG
+  #define jb_dbg2 if (dbgf) dbgf
+#else
+  #define jb_dbg2 if (0) dbgf
+#endif
+
+#else
+
+#define jb_warn(...) (warnf ? warnf(__VA_ARGS__) : (void)0)
+#define jb_err(...) (errf ? errf(__VA_ARGS__) : (void)0)
+#define jb_dbg(...) (dbgf ? dbgf(__VA_ARGS__) : (void)0)
+
+#ifdef DEEP_DEBUG
+#define jb_dbg2(...) (dbgf ? dbgf(__VA_ARGS__) : (void)0)
+#else
+#define jb_dbg2(...) ((void)0)
+#endif
+
+#endif
+
+static jb_output_function_t warnf, errf, dbgf;
+
+void jb_setoutput(jb_output_function_t err, jb_output_function_t warn, jb_output_function_t dbg)
+{
+       errf = err;
+       warnf = warn;
+       dbgf = dbg;
+}
+
+static void increment_losspct(jitterbuf *jb)
+{
+       jb->info.losspct = (100000 + 499 * jb->info.losspct)/500;
+}
+
+static void decrement_losspct(jitterbuf *jb)
+{
+       jb->info.losspct = (499 * jb->info.losspct)/500;
+}
+
+void jb_reset(jitterbuf *jb)
+{
+       /* only save settings */
+       jb_conf s = jb->info.conf;
+       memset(jb, 0, sizeof(*jb));
+       jb->info.conf = s;
+
+       /* initialize length, using the configured value */
+       jb->info.current = jb->info.target = jb->info.conf.target_extra;
+       jb->info.silence_begin_ts = -1;
+}
+
+jitterbuf * jb_new()
+{
+       jitterbuf *jb;
+
+       if (!(jb = (jitterbuf *)malloc(sizeof(*jb))))
+               return NULL;
+
+       jb->info.conf.target_extra = JB_TARGET_EXTRA;
+
+       jb_reset(jb);
+
+       jb_dbg2("jb_new() = %x\n", jb);
+       return jb;
+}
+
+void jb_destroy(jitterbuf *jb)
+{
+       jb_frame *frame;
+       jb_dbg2("jb_destroy(%x)\n", jb);
+
+       /* free all the frames on the "free list" */
+       frame = jb->free;
+       while (frame != NULL) {
+               jb_frame *next = frame->next;
+               free(frame);
+               frame = next;
+       }
+
+       /* free ourselves! */
+       free(jb);
+}
+
+
+
+#if 0
+static int longcmp(const void *a, const void *b)
+{
+       return *(long *)a - *(long *)b;
+}
+#endif
+
+/* simple history manipulation */
+/* maybe later we can make the history buckets variable size, or something? */
+/* drop parameter determines whether we will drop outliers to minimize
+ * delay */
+static int history_put(jitterbuf *jb, long ts, long now, long ms)
+{
+       long delay = now - (ts - jb->info.resync_offset);
+       long threshold = 2 * jb->info.jitter + jb->info.conf.resync_threshold;
+       long kicked;
+
+       /* don't add special/negative times to history */
+       if (ts <= 0)
+               return 0;
+
+       /* check for drastic change in delay */
+       if (jb->info.conf.resync_threshold != -1) {
+               if (abs(delay - jb->info.last_delay) > threshold) {
+                       jb->info.cnt_delay_discont++;
+                       if (jb->info.cnt_delay_discont > 3) {
+                               /* resync the jitterbuffer */
+                               jb->info.cnt_delay_discont = 0;
+                               jb->hist_ptr = 0;
+                               jb->hist_maxbuf_valid = 0;
+
+                               jb_warn("Resyncing the jb. last_delay %ld, this delay %ld, threshold %ld, new offset %ld\n", jb->info.last_delay, delay, threshold, ts - now);
+                               jb->info.resync_offset = ts - now;
+                               jb->info.last_delay = delay = 0; /* after resync, frame is right on time */
+                       } else {
+                               return -1;
+                       }
+               } else {
+                       jb->info.last_delay = delay;
+                       jb->info.cnt_delay_discont = 0;
+               }
+       }
+
+       kicked = jb->history[jb->hist_ptr % JB_HISTORY_SZ];
+
+       jb->history[(jb->hist_ptr++) % JB_HISTORY_SZ] = delay;
+
+       /* optimization; the max/min buffers don't need to be recalculated,
+        * if this packet's entry doesn't change them. This happens if this
+        * packet is not involved, _and_ any packet that got kicked out of
+        * the history is also not involved. We do a number of comparisons,
+        * but it's probably still worthwhile, because it will usually
+        * succeed, and should be a lot faster than going through all 500
+        * packets in history */
+       if (!jb->hist_maxbuf_valid)
+               return 0;
+
+       /* don't do this until we've filled history
+        * (reduces some edge cases below) */
+       if (jb->hist_ptr < JB_HISTORY_SZ)
+               goto invalidate;
+
+       /* if the new delay would go into min */
+       if (delay < jb->hist_minbuf[JB_HISTORY_MAXBUF_SZ-1])
+               goto invalidate;
+
+       /* or max.. */
+       if (delay > jb->hist_maxbuf[JB_HISTORY_MAXBUF_SZ-1])
+               goto invalidate;
+
+       /* or the kicked delay would be in min */
+       if (kicked <= jb->hist_minbuf[JB_HISTORY_MAXBUF_SZ-1])
+               goto invalidate;
+
+       if (kicked >= jb->hist_maxbuf[JB_HISTORY_MAXBUF_SZ-1])
+               goto invalidate;
+
+       /* if we got here, we don't need to invalidate, 'cause this delay didn't
+        * affect things */
+       return 0;
+       /* end optimization */
+
+
+invalidate:
+       jb->hist_maxbuf_valid = 0;
+       return 0;
+}
+
+static void history_calc_maxbuf(jitterbuf *jb)
+{
+       int i,j;
+
+       if (jb->hist_ptr == 0)
+               return;
+
+
+       /* initialize maxbuf/minbuf to the latest value */
+       for (i=0;i<JB_HISTORY_MAXBUF_SZ;i++) {
+               /*
+                * jb->hist_maxbuf[i] = jb->history[(jb->hist_ptr-1) % JB_HISTORY_SZ];
+                * jb->hist_minbuf[i] = jb->history[(jb->hist_ptr-1) % JB_HISTORY_SZ];
+                */
+               jb->hist_maxbuf[i] = JB_LONGMIN;
+               jb->hist_minbuf[i] = JB_LONGMAX;
+       }
+
+       /* use insertion sort to populate maxbuf */
+       /* we want it to be the top "n" values, in order */
+
+       /* start at the beginning, or JB_HISTORY_SZ frames ago */
+       i = (jb->hist_ptr > JB_HISTORY_SZ) ? (jb->hist_ptr - JB_HISTORY_SZ) : 0;
+
+       for (;i<jb->hist_ptr;i++) {
+               long toins = jb->history[i % JB_HISTORY_SZ];
+
+               /* if the maxbuf should get this */
+               if (toins > jb->hist_maxbuf[JB_HISTORY_MAXBUF_SZ-1])  {
+
+                       /* insertion-sort it into the maxbuf */
+                       for (j=0;j<JB_HISTORY_MAXBUF_SZ;j++) {
+                               /* found where it fits */
+                               if (toins > jb->hist_maxbuf[j]) {
+                                       /* move over */
+                                       memmove(jb->hist_maxbuf + j + 1, jb->hist_maxbuf + j, (JB_HISTORY_MAXBUF_SZ - (j + 1)) * sizeof(jb->hist_maxbuf[0]));
+                                       /* insert */
+                                       jb->hist_maxbuf[j] = toins;
+
+                                       break;
+                               }
+                       }
+               }
+
+               /* if the minbuf should get this */
+               if (toins < jb->hist_minbuf[JB_HISTORY_MAXBUF_SZ-1])  {
+
+                       /* insertion-sort it into the maxbuf */
+                       for (j=0;j<JB_HISTORY_MAXBUF_SZ;j++) {
+                               /* found where it fits */
+                               if (toins < jb->hist_minbuf[j]) {
+                                       /* move over */
+                                       memmove(jb->hist_minbuf + j + 1, jb->hist_minbuf + j, (JB_HISTORY_MAXBUF_SZ - (j + 1)) * sizeof(jb->hist_minbuf[0]));
+                                       /* insert */
+                                       jb->hist_minbuf[j] = toins;
+
+                                       break;
+                               }
+                       }
+               }
+
+               if (0) {
+                       int k;
+                       fprintf(stderr, "toins = %ld\n", toins);
+                       fprintf(stderr, "maxbuf =");
+                       for (k=0;k<JB_HISTORY_MAXBUF_SZ;k++)
+                               fprintf(stderr, "%ld ", jb->hist_maxbuf[k]);
+                       fprintf(stderr, "\nminbuf =");
+                       for (k=0;k<JB_HISTORY_MAXBUF_SZ;k++)
+                               fprintf(stderr, "%ld ", jb->hist_minbuf[k]);
+                       fprintf(stderr, "\n");
+               }
+       }
+
+       jb->hist_maxbuf_valid = 1;
+}
+
+static void history_get(jitterbuf *jb)
+{
+       long max, min, jitter;
+       int index;
+       int count;
+
+       if (!jb->hist_maxbuf_valid)
+               history_calc_maxbuf(jb);
+
+       /* count is how many items in history we're examining */
+       count = (jb->hist_ptr < JB_HISTORY_SZ) ? jb->hist_ptr : JB_HISTORY_SZ;
+
+       /* index is the "n"ths highest/lowest that we'll look for */
+       index = count * JB_HISTORY_DROPPCT / 100;
+
+       /* sanity checks for index */
+       if (index > (JB_HISTORY_MAXBUF_SZ - 1))
+               index = JB_HISTORY_MAXBUF_SZ - 1;
+
+
+       if (index < 0) {
+               jb->info.min = 0;
+               jb->info.jitter = 0;
+               return;
+       }
+
+       max = jb->hist_maxbuf[index];
+       min = jb->hist_minbuf[index];
+
+       jitter = max - min;
+
+       /* these debug stmts compare the difference between looking at the absolute jitter, and the
+        * values we get by throwing away the outliers */
+       /*
+       fprintf(stderr, "[%d] min=%d, max=%d, jitter=%d\n", index, min, max, jitter);
+       fprintf(stderr, "[%d] min=%d, max=%d, jitter=%d\n", 0, jb->hist_minbuf[0], jb->hist_maxbuf[0], jb->hist_maxbuf[0]-jb->hist_minbuf[0]);
+       */
+
+       jb->info.min = min;
+       jb->info.jitter = jitter;
+}
+
+/* returns 1 if frame was inserted into head of queue, 0 otherwise */
+static int queue_put(jitterbuf *jb, void *data, const enum jb_frame_type type, long ms, long ts)
+{
+       jb_frame *frame;
+       jb_frame *p;
+       int head = 0;
+       long resync_ts = ts - jb->info.resync_offset;
+
+       if ((frame = jb->free)) {
+               jb->free = frame->next;
+       } else if (!(frame = (jb_frame *)malloc(sizeof(*frame)))) {
+               jb_err("cannot allocate frame\n");
+               return 0;
+       }
+
+       jb->info.frames_cur++;
+
+       frame->data = data;
+       frame->ts = resync_ts;
+       frame->ms = ms;
+       frame->type = type;
+
+       /*
+        * frames are a circular list, jb-frames points to to the lowest ts,
+        * jb->frames->prev points to the highest ts
+        */
+
+       if (!jb->frames) {  /* queue is empty */
+               jb->frames = frame;
+               frame->next = frame;
+               frame->prev = frame;
+               head = 1;
+       } else if (resync_ts < jb->frames->ts) {
+               frame->next = jb->frames;
+               frame->prev = jb->frames->prev;
+
+               frame->next->prev = frame;
+               frame->prev->next = frame;
+
+               /* frame is out of order */
+               jb->info.frames_ooo++;
+
+               jb->frames = frame;
+               head = 1;
+       } else {
+               p = jb->frames;
+
+               /* frame is out of order */
+               if (resync_ts < p->prev->ts) jb->info.frames_ooo++;
+
+               while (resync_ts < p->prev->ts && p->prev != jb->frames)
+                       p = p->prev;
+
+               frame->next = p;
+               frame->prev = p->prev;
+
+               frame->next->prev = frame;
+               frame->prev->next = frame;
+       }
+       return head;
+}
+
+static long queue_next(jitterbuf *jb)
+{
+       if (jb->frames)
+               return jb->frames->ts;
+       else
+               return -1;
+}
+
+static long queue_last(jitterbuf *jb)
+{
+       if (jb->frames)
+               return jb->frames->prev->ts;
+       else
+               return -1;
+}
+
+static jb_frame *_queue_get(jitterbuf *jb, long ts, int all)
+{
+       jb_frame *frame;
+       frame = jb->frames;
+
+       if (!frame)
+               return NULL;
+
+       /*jb_warn("queue_get: ASK %ld FIRST %ld\n", ts, frame->ts); */
+
+       if (all || ts >= frame->ts) {
+               /* remove this frame */
+               frame->prev->next = frame->next;
+               frame->next->prev = frame->prev;
+
+               if (frame->next == frame)
+                       jb->frames = NULL;
+               else
+                       jb->frames = frame->next;
+
+
+               /* insert onto "free" single-linked list */
+               frame->next = jb->free;
+               jb->free = frame;
+
+               jb->info.frames_cur--;
+
+               /* we return the frame pointer, even though it's on free list,
+                * but caller must copy data */
+               return frame;
+       }
+
+       return NULL;
+}
+
+static jb_frame *queue_get(jitterbuf *jb, long ts)
+{
+       return _queue_get(jb,ts,0);
+}
+
+static jb_frame *queue_getall(jitterbuf *jb)
+{
+       return _queue_get(jb,0,1);
+}
+
+#if 0
+/* some diagnostics */
+static void jb_dbginfo(jitterbuf *jb)
+{
+       if (dbgf == NULL)
+               return;
+
+       jb_dbg("\njb info: fin=%ld fout=%ld flate=%ld flost=%ld fdrop=%ld fcur=%ld\n",
+               jb->info.frames_in, jb->info.frames_out, jb->info.frames_late, jb->info.frames_lost, jb->info.frames_dropped, jb->info.frames_cur);
+
+       jb_dbg("jitter=%ld current=%ld target=%ld min=%ld sil=%d len=%d len/fcur=%ld\n",
+               jb->info.jitter, jb->info.current, jb->info.target, jb->info.min, jb->info.silence_begin_ts, jb->info.current - jb->info.min,
+               jb->info.frames_cur ? (jb->info.current - jb->info.min)/jb->info.frames_cur : -8);
+       if (jb->info.frames_in > 0)
+               jb_dbg("jb info: Loss PCT = %ld%%, Late PCT = %ld%%\n",
+               jb->info.frames_lost * 100/(jb->info.frames_in + jb->info.frames_lost),
+               jb->info.frames_late * 100/jb->info.frames_in);
+       jb_dbg("jb info: queue %d -> %d.  last_ts %d (queue len: %d) last_ms %d\n",
+               queue_next(jb),
+               queue_last(jb),
+               jb->info.next_voice_ts,
+               queue_last(jb) - queue_next(jb),
+               jb->info.last_voice_ms);
+}
+#endif
+
+#ifdef DEEP_DEBUG
+static void jb_chkqueue(jitterbuf *jb)
+{
+       int i=0;
+       jb_frame *p = jb->frames;
+
+       if (!p) {
+               return;
+       }
+
+       do {
+               if (p->next == NULL)  {
+                       jb_err("Queue is BROKEN at item [%d]", i);
+               }
+               i++;
+               p=p->next;
+       } while (p->next != jb->frames);
+}
+
+static void jb_dbgqueue(jitterbuf *jb)
+{
+       int i=0;
+       jb_frame *p = jb->frames;
+
+       jb_dbg("queue: ");
+
+       if (!p) {
+               jb_dbg("EMPTY\n");
+               return;
+       }
+
+       do {
+               jb_dbg("[%d]=%ld ", i++, p->ts);
+               p=p->next;
+       } while (p->next != jb->frames);
+
+       jb_dbg("\n");
+}
+#endif
+
+enum jb_return_code jb_put(jitterbuf *jb, void *data, const enum jb_frame_type type, long ms, long ts, long now)
+{
+       jb_dbg2("jb_put(%x,%x,%ld,%ld,%ld)\n", jb, data, ms, ts, now);
+
+       jb->info.frames_in++;
+
+       if (type == JB_TYPE_VOICE) {
+               /* presently, I'm only adding VOICE frames to history and drift
+                * calculations; mostly because with the IAX integrations, I'm
+                * sending retransmitted control frames with their awkward
+                * timestamps through
+                */
+               if (history_put(jb,ts,now,ms))
+                       return JB_DROP;
+       }
+
+       /* if put into head of queue, caller needs to reschedule */
+       if (queue_put(jb,data,type,ms,ts)) {
+               return JB_SCHED;
+       }
+
+       return JB_OK;
+}
+
+
+static enum jb_return_code _jb_get(jitterbuf *jb, jb_frame *frameout, long now, long interpl)
+{
+       jb_frame *frame;
+       long diff;
+
+       /*if ((now - jb_next(jb)) > 2 * jb->info.last_voice_ms) jb_warn("SCHED: %ld", (now - jb_next(jb))); */
+       /* get jitter info */
+       history_get(jb);
+
+
+       /* target */
+       jb->info.target = jb->info.jitter + jb->info.min + jb->info.conf.target_extra;
+
+       /* if a hard clamp was requested, use it */
+       if ((jb->info.conf.max_jitterbuf) && ((jb->info.target - jb->info.min) > jb->info.conf.max_jitterbuf)) {
+               jb_dbg("clamping target from %d to %d\n", (jb->info.target - jb->info.min), jb->info.conf.max_jitterbuf);
+               jb->info.target = jb->info.min + jb->info.conf.max_jitterbuf;
+       }
+
+       diff = jb->info.target - jb->info.current;
+
+       /* jb_warn("diff = %d lms=%d last = %d now = %d\n", diff,  */
+       /*      jb->info.last_voice_ms, jb->info.last_adjustment, now); */
+
+       /* let's work on non-silent case first */
+       if (!jb->info.silence_begin_ts) {
+               /* we want to grow */
+               if ((diff > 0) &&
+                       /* we haven't grown in the delay length */
+                       (((jb->info.last_adjustment + JB_ADJUST_DELAY) < now) ||
+                       /* we need to grow more than the "length" we have left */
+                       (diff > queue_last(jb) - queue_next(jb)) ) ) {
+                       /* grow by interp frame length */
+                       jb->info.current += interpl;
+                       jb->info.next_voice_ts += interpl;
+                       jb->info.last_voice_ms = interpl;
+                       jb->info.last_adjustment = now;
+                       jb->info.cnt_contig_interp++;
+                       /* assume silence instead of continuing to interpolate */
+                       if (jb->info.conf.max_contig_interp && jb->info.cnt_contig_interp >= jb->info.conf.max_contig_interp) {
+                               jb->info.silence_begin_ts = jb->info.next_voice_ts - jb->info.current;
+                       }
+                       jb_dbg("G");
+                       return JB_INTERP;
+               }
+
+               frame = queue_get(jb, jb->info.next_voice_ts - jb->info.current);
+
+               /* not a voice frame; just return it. */
+               if (frame && frame->type != JB_TYPE_VOICE) {
+                       /* track start of silence */
+                       if (frame->type == JB_TYPE_SILENCE) {
+                               jb->info.silence_begin_ts = frame->ts;
+                               jb->info.cnt_contig_interp = 0;
+                       }
+
+                       *frameout = *frame;
+                       jb->info.frames_out++;
+                       jb_dbg("o");
+                       return JB_OK;
+               }
+
+               /* voice frame is later than expected */
+               if (frame && frame->ts + jb->info.current < jb->info.next_voice_ts) {
+                       if (frame->ts + jb->info.current > jb->info.next_voice_ts - jb->info.last_voice_ms) {
+                               /* either we interpolated past this frame in the last jb_get */
+                               /* or the frame is still in order, but came a little too quick */
+                               *frameout = *frame;
+                               /* reset expectation for next frame */
+                               jb->info.next_voice_ts = frame->ts + jb->info.current + frame->ms;
+                               jb->info.frames_out++;
+                               decrement_losspct(jb);
+                               jb->info.cnt_contig_interp = 0;
+                               jb_dbg("v");
+                               return JB_OK;
+                       } else {
+                               /* voice frame is late */
+                               *frameout = *frame;
+                               jb->info.frames_out++;
+                               decrement_losspct(jb);
+                               jb->info.frames_late++;
+                               jb->info.frames_lost--;
+                               jb_dbg("l");
+                               /*jb_warn("\nlate: wanted=%ld, this=%ld, next=%ld\n", jb->info.next_voice_ts - jb->info.current, frame->ts, queue_next(jb));
+                                 jb_warninfo(jb); */
+                               return JB_DROP;
+                       }
+               }
+
+               /* keep track of frame sizes, to allow for variable sized-frames */
+               if (frame && frame->ms > 0) {
+                       jb->info.last_voice_ms = frame->ms;
+               }
+
+               /* we want to shrink; shrink at 1 frame / 500ms */
+               /* unless we don't have a frame, then shrink 1 frame */
+               /* every 80ms (though perhaps we can shrink even faster */
+               /* in this case) */
+               if (diff < -jb->info.conf.target_extra &&
+                               ((!frame && jb->info.last_adjustment + 80 < now) ||
+                                (jb->info.last_adjustment + 500 < now))) {
+
+                       jb->info.last_adjustment = now;
+                       jb->info.cnt_contig_interp = 0;
+
+                       if (frame) {
+                               *frameout = *frame;
+                               /* shrink by frame size we're throwing out */
+                               jb->info.current -= frame->ms;
+                               jb->info.frames_out++;
+                               decrement_losspct(jb);
+                               jb->info.frames_dropped++;
+                               jb_dbg("s");
+                               return JB_DROP;
+                       } else {
+                               /* shrink by last_voice_ms */
+                               jb->info.current -= jb->info.last_voice_ms;
+                               jb->info.frames_lost++;
+                               increment_losspct(jb);
+                               jb_dbg("S");
+                               return JB_NOFRAME;
+                       }
+               }
+
+               /* lost frame */
+               if (!frame) {
+                       /* this is a bit of a hack for now, but if we're close to
+                        * target, and we find a missing frame, it makes sense to
+                        * grow, because the frame might just be a bit late;
+                        * otherwise, we presently get into a pattern where we return
+                        * INTERP for the lost frame, then it shows up next, and we
+                        * throw it away because it's late */
+                       /* I've recently only been able to replicate this using
+                        * iaxclient talking to app_echo on asterisk.  In this case,
+                        * my outgoing packets go through asterisk's (old)
+                        * jitterbuffer, and then might get an unusual increasing delay
+                        * there if it decides to grow?? */
+                       /* Update: that might have been a different bug, that has been fixed..
+                        * But, this still seemed like a good idea, except that it ended up making a single actual
+                        * lost frame get interpolated two or more times, when there was "room" to grow, so it might
+                        * be a bit of a bad idea overall */
+                       /*if (diff > -1 * jb->info.last_voice_ms) {
+                               jb->info.current += jb->info.last_voice_ms;
+                               jb->info.last_adjustment = now;
+                               jb_warn("g");
+                               return JB_INTERP;
+                       } */
+                       jb->info.frames_lost++;
+                       increment_losspct(jb);
+                       jb->info.next_voice_ts += interpl;
+                       jb->info.last_voice_ms = interpl;
+                       jb->info.cnt_contig_interp++;
+                       /* assume silence instead of continuing to interpolate */
+                       if (jb->info.conf.max_contig_interp && jb->info.cnt_contig_interp >= jb->info.conf.max_contig_interp) {
+                               jb->info.silence_begin_ts = jb->info.next_voice_ts - jb->info.current;
+                       }
+                       jb_dbg("L");
+                       return JB_INTERP;
+               }
+
+               /* normal case; return the frame, increment stuff */
+               *frameout = *frame;
+               jb->info.next_voice_ts += frame->ms;
+               jb->info.frames_out++;
+               jb->info.cnt_contig_interp = 0;
+               decrement_losspct(jb);
+               jb_dbg("v");
+               return JB_OK;
+       } else {
+               /* TODO: after we get the non-silent case down, we'll make the
+                * silent case -- basically, we'll just grow and shrink faster
+                * here, plus handle next_voice_ts a bit differently */
+
+               /* to disable silent special case altogether, just uncomment this: */
+               /* jb->info.silence_begin_ts = 0; */
+
+               /* shrink interpl len every 10ms during silence */
+               if (diff < -jb->info.conf.target_extra &&
+                       jb->info.last_adjustment + 10 <= now) {
+                       jb->info.current -= interpl;
+                       jb->info.last_adjustment = now;
+               }
+
+               frame = queue_get(jb, now - jb->info.current);
+               if (!frame) {
+                       return JB_NOFRAME;
+               } else if (frame->type != JB_TYPE_VOICE) {
+                       /* normal case; in silent mode, got a non-voice frame */
+                       *frameout = *frame;
+                       jb->info.frames_out++;
+                       return JB_OK;
+               }
+               if (frame->ts < jb->info.silence_begin_ts) {
+                       /* voice frame is late */
+                       *frameout = *frame;
+                       jb->info.frames_out++;
+                       decrement_losspct(jb);
+                       jb->info.frames_late++;
+                       jb->info.frames_lost--;
+                       jb_dbg("l");
+                       /*jb_warn("\nlate: wanted=%ld, this=%ld, next=%ld\n", jb->info.next_voice_ts - jb->info.current, frame->ts, queue_next(jb));
+                         jb_warninfo(jb); */
+                       return JB_DROP;
+               } else {
+                       /* voice frame */
+                       /* try setting current to target right away here */
+                       jb->info.current = jb->info.target;
+                       jb->info.silence_begin_ts = 0;
+                       jb->info.next_voice_ts = frame->ts + jb->info.current + frame->ms;
+                       jb->info.last_voice_ms = frame->ms;
+                       jb->info.frames_out++;
+                       decrement_losspct(jb);
+                       *frameout = *frame;
+                       jb_dbg("V");
+                       return JB_OK;
+               }
+       }
+}
+
+long jb_next(jitterbuf *jb)
+{
+       if (jb->info.silence_begin_ts) {
+               if (jb->frames) {
+                       long next = queue_next(jb);
+                       history_get(jb);
+                       /* shrink during silence */
+                       if (jb->info.target - jb->info.current < -jb->info.conf.target_extra)
+                               return jb->info.last_adjustment + 10;
+                       return next + jb->info.target;
+               }
+               else
+                       return JB_LONGMAX;
+       } else {
+               return jb->info.next_voice_ts;
+       }
+}
+
+enum jb_return_code jb_get(jitterbuf *jb, jb_frame *frameout, long now, long interpl)
+{
+       enum jb_return_code ret = _jb_get(jb, frameout, now, interpl);
+#if 0
+       static int lastts=0;
+       int thists = ((ret == JB_OK) || (ret == JB_DROP)) ? frameout->ts : 0;
+       jb_warn("jb_get(%x,%x,%ld) = %d (%d)\n", jb, frameout, now, ret, thists);
+       if (thists && thists < lastts) jb_warn("XXXX timestamp roll-back!!!\n");
+       lastts = thists;
+#endif
+       return ret;
+}
+
+enum jb_return_code jb_getall(jitterbuf *jb, jb_frame *frameout)
+{
+       jb_frame *frame;
+       frame = queue_getall(jb);
+
+       if (!frame) {
+               return JB_NOFRAME;
+       }
+
+       *frameout = *frame;
+       return JB_OK;
+}
+
+
+enum jb_return_code jb_getinfo(jitterbuf *jb, jb_info *stats)
+{
+       history_get(jb);
+
+       *stats = jb->info;
+
+       return JB_OK;
+}
+
+enum jb_return_code jb_setconf(jitterbuf *jb, jb_conf *conf)
+{
+       /* take selected settings from the struct */
+
+       jb->info.conf.max_jitterbuf = conf->max_jitterbuf;
+       jb->info.conf.resync_threshold = conf->resync_threshold;
+       jb->info.conf.max_contig_interp = conf->max_contig_interp;
+
+       /* -1 indicates use of the default JB_TARGET_EXTRA value */
+       jb->info.conf.target_extra = ( conf->target_extra == -1 )
+               ? JB_TARGET_EXTRA
+               : conf->target_extra
+               ;
+
+       /* update these to match new target_extra setting */
+       jb->info.current = jb->info.conf.target_extra;
+       jb->info.target = jb->info.conf.target_extra;
+
+       return JB_OK;
+}
+
+
diff --git a/utils/iaxclient/lib/libiax2/src/jitterbuf.h b/utils/iaxclient/lib/libiax2/src/jitterbuf.h
new file mode 100644 (file)
index 0000000..9c9225b
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * jitterbuf: an application-independent jitterbuffer
+ *
+ * Copyrights:
+ * Copyright (C) 2004-2005, Horizon Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License
+ *
+ * Copyright on this file is disclaimed to Digium for inclusion in Asterisk
+ */
+
+#ifndef _JITTERBUF_H_
+#define _JITTERBUF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* configuration constants */
+       /* Number of historical timestamps to use in calculating jitter and drift */
+#define JB_HISTORY_SZ          500
+       /* what percentage of timestamps should we drop from the history when we examine it;
+        * this might eventually be something made configurable */
+#define JB_HISTORY_DROPPCT     3
+       /* the maximum droppct we can handle (say it was configurable). */
+#define JB_HISTORY_DROPPCT_MAX 4
+       /* the size of the buffer we use to keep the top and botton timestamps for dropping */
+#define JB_HISTORY_MAXBUF_SZ   JB_HISTORY_SZ * JB_HISTORY_DROPPCT_MAX / 100
+       /* amount of additional jitterbuffer adjustment  */
+#define JB_TARGET_EXTRA 40
+       /* ms between growing and shrinking; may not be honored if jitterbuffer runs out of space */
+#define JB_ADJUST_DELAY 40
+
+enum jb_return_code {
+       /* return codes */
+       JB_OK,            /* 0 */
+       JB_EMPTY,         /* 1 */
+       JB_NOFRAME,       /* 2 */
+       JB_INTERP,        /* 3 */
+       JB_DROP,          /* 4 */
+       JB_SCHED          /* 5 */
+};
+
+enum jb_frame_type {
+/* frame types */
+       JB_TYPE_CONTROL,  /* 0            */
+       JB_TYPE_VOICE,    /* 1            */
+       JB_TYPE_VIDEO,    /* 2 - reserved */
+       JB_TYPE_SILENCE   /* 3            */
+};
+
+typedef struct jb_conf {
+       /* settings */
+       long max_jitterbuf;     /* defines a hard clamp to use in setting the jitter buffer delay */
+       long resync_threshold;  /* the jb will resync when delay increases to (2 * jitter) + this param */
+       long max_contig_interp; /* the max interp frames to return in a row */
+       long target_extra;      /* amount of additional jitterbuffer adjustment, overrides JB_TARGET_EXTRA */
+} jb_conf;
+
+typedef struct jb_info {
+       jb_conf conf;
+
+       /* statistics */
+       long frames_in;         /* number of frames input to the jitterbuffer.*/
+       long frames_out;        /* number of frames output from the jitterbuffer.*/
+       long frames_late;       /* number of frames which were too late, and dropped.*/
+       long frames_lost;       /* number of missing frames.*/
+       long frames_dropped;    /* number of frames dropped (shrinkage) */
+       long frames_ooo;        /* number of frames received out-of-order */
+       long frames_cur;        /* number of frames presently in jb, awaiting delivery.*/
+       long jitter;            /* jitter measured within current history interval*/
+       long min;               /* minimum lateness within current history interval */
+       long current;           /* the present jitterbuffer adjustment */
+       long target;            /* the target jitterbuffer adjustment */
+       long losspct;           /* recent lost frame percentage (* 1000) */
+       long next_voice_ts;     /* the ts of the next frame to be read from the jb - in receiver's time */
+       long last_voice_ms;     /* the duration of the last voice frame */
+       long silence_begin_ts;  /* the time of the last CNG frame, when in silence */
+       long last_adjustment;   /* the time of the last adjustment */
+       long last_delay;        /* the last now added to history */
+       long cnt_delay_discont; /* the count of discontinuous delays */
+       long resync_offset;     /* the amount to offset ts to support resyncs */
+       long cnt_contig_interp; /* the number of contiguous interp frames returned */
+} jb_info;
+
+typedef struct jb_frame {
+       void *data;               /* the frame data */
+       long ts;                  /* the relative delivery time expected */
+       long ms;                  /* the time covered by this frame, in sec/8000 */
+       enum jb_frame_type type;  /* the type of frame */
+       struct jb_frame *next, *prev;
+} jb_frame;
+
+typedef struct jitterbuf {
+       jb_info info;
+
+       /* history */
+       long history[JB_HISTORY_SZ];            /* history */
+       int  hist_ptr;                          /* points to index in history for next entry */
+       long hist_maxbuf[JB_HISTORY_MAXBUF_SZ]; /* a sorted buffer of the max delays (highest first) */
+       long hist_minbuf[JB_HISTORY_MAXBUF_SZ]; /* a sorted buffer of the min delays (lowest first) */
+       int  hist_maxbuf_valid;                 /* are the "maxbuf"/minbuf valid? */
+
+       jb_frame *frames;               /* queued frames */
+       jb_frame *free;                 /* free frames (avoid malloc?) */
+} jitterbuf;
+
+
+/* new jitterbuf */
+jitterbuf *            jb_new(void);
+
+/* destroy jitterbuf */
+void                   jb_destroy(jitterbuf *jb);
+
+/* reset jitterbuf */
+/* NOTE:  The jitterbuffer should be empty before you call this, otherwise
+ * you will leak queued frames, and some internal structures */
+void                   jb_reset(jitterbuf *jb);
+
+/* queue a frame data=frame data, timings (in ms): ms=length of frame (for voice), ts=ts (sender's time)
+ * now=now (in receiver's time) return value is one of
+ * JB_OK: Frame added. Last call to jb_next() still valid
+ * JB_DROP: Drop this frame immediately
+ * JB_SCHED: Frame added. Call jb_next() to get a new time for the next frame
+ */
+enum jb_return_code jb_put(jitterbuf *jb, void *data, const enum jb_frame_type type, long ms, long ts, long now);
+
+/* get a frame for time now (receiver's time)  return value is one of
+ * JB_OK:  You've got frame!
+ * JB_DROP: Here's an audio frame you should just drop.  Ask me again for this time..
+ * JB_NOFRAME: There's no frame scheduled for this time.
+ * JB_INTERP: Please interpolate an interpl-length frame for this time (either we need to grow, or there was a lost frame)
+ * JB_EMPTY: The jb is empty.
+ */
+enum jb_return_code jb_get(jitterbuf *jb, jb_frame *frame, long now, long interpl);
+
+/* unconditionally get frames from jitterbuf until empty */
+enum jb_return_code jb_getall(jitterbuf *jb, jb_frame *frameout);
+
+/* when is the next frame due out, in receiver's time (0=EMPTY)
+ * This value may change as frames are added (esp non-audio frames) */
+long                   jb_next(jitterbuf *jb);
+
+/* get jitterbuf info: only "statistics" may be valid */
+enum jb_return_code jb_getinfo(jitterbuf *jb, jb_info *stats);
+
+/* set jitterbuf conf */
+enum jb_return_code jb_setconf(jitterbuf *jb, jb_conf *conf);
+
+typedef                        void (*jb_output_function_t)(const char *fmt, ...);
+extern void jb_setoutput(jb_output_function_t err, jb_output_function_t warn, jb_output_function_t dbg);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/utils/iaxclient/lib/libiax2/src/md5.c b/utils/iaxclient/lib/libiax2/src/md5.c
new file mode 100644 (file)
index 0000000..401216e
--- /dev/null
@@ -0,0 +1,285 @@
+/* MD5 checksum routines used for authentication.  Not covered by GPL, but
+   in the public domain as per the copyright below */
+
+#ifdef FREEBSD
+# include <machine/endian.h>
+#elif defined(LINUX)  
+# include <endian.h>
+# include <features.h>
+# include <sys/types.h>
+#elif defined(SOLARIS)
+  /* each solaris is different -- this won't work on 2.6 or 2.7 */
+# include <sys/isa_defs.h> /* Defines either _LITTLE_ENDIAN or _BIG_ENDIAN */
+#  define __BIG_ENDIAN         4321
+#  define __LITTLE_ENDIAN      1234
+#  define BIG_ENDIAN           4321
+#  define LITTLE_ENDIAN                1234
+#  ifdef _LITTLE_ENDIAN
+#    define __BYTE_ORDER       __LITTLE_ENDIAN
+#    define BYTE_ORDER         LITTLE_ENDIAN
+#  else
+#    define __BYTE_ORDER       __BIG_ENDIAN
+#    define BYTE_ORDER         BIG_ENDIAN
+#  endif
+#endif
+
+#if __BYTE_ORDER == __BIG_ENDIAN || BYTE_ORDER == BIG_ENDIAN
+# define HIGHFIRST 1
+#elif __BYTE_ORDER == __LITTLE_ENDIAN || BYTE_ORDER == LITLE_ENDIAN
+# undef HIGHFIRST
+#else
+# error "Please fix <bits/endian.h>"
+#endif
+
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest.  This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+#include <string.h>            /* for memcpy() */
+#include "md5.h"
+
+#ifndef HIGHFIRST
+#define byteReverse(buf, len)  /* Nothing */
+#else
+void byteReverse(uint8_t *buf, unsigned int longs);
+
+#ifndef ASM_MD5
+/*
+ * Note: this code is harmless on little-endian machines.
+ */
+void byteReverse(uint8_t *buf, unsigned int longs)
+{
+    uint32_t t;
+    do {
+       t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
+           ((unsigned) buf[1] << 8 | buf[0]);
+       *(uint32_t *) buf = t;
+       buf += 4;
+    } while (--longs);
+}
+#endif
+#endif
+
+/*
+ * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void MD5Init(struct MD5Context *ctx)
+{
+    ctx->buf[0] = 0x67452301;
+    ctx->buf[1] = 0xefcdab89;
+    ctx->buf[2] = 0x98badcfe;
+    ctx->buf[3] = 0x10325476;
+
+    ctx->bits[0] = 0;
+    ctx->bits[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void MD5Update(struct MD5Context *ctx, uint8_t const *buf, unsigned int len)
+{
+    uint32_t t;
+
+    /* Update bitcount */
+
+    t = ctx->bits[0];
+    if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t)
+       ctx->bits[1]++;         /* Carry from low to high */
+    ctx->bits[1] += len >> 29;
+
+    t = (t >> 3) & 0x3f;       /* Bytes already in shsInfo->data */
+
+    /* Handle any leading odd-sized chunks */
+
+    if (t) {
+       uint8_t *p = (uint8_t *) ctx->in + t;
+
+       t = 64 - t;
+       if (len < t) {
+           memcpy(p, buf, len);
+           return;
+       }
+       memcpy(p, buf, t);
+       byteReverse(ctx->in, 16);
+       MD5Transform(ctx->buf, (uint32_t *) ctx->in);
+       buf += t;
+       len -= t;
+    }
+    /* Process data in 64-byte chunks */
+
+    while (len >= 64) {
+       memcpy(ctx->in, buf, 64);
+       byteReverse(ctx->in, 16);
+       MD5Transform(ctx->buf, (uint32_t *) ctx->in);
+       buf += 64;
+       len -= 64;
+    }
+
+    /* Handle any remaining bytes of data. */
+
+    memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern 
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void MD5Final(uint8_t digest[16], struct MD5Context *ctx)
+{
+    unsigned int count;
+    uint8_t *p;
+
+    /* Compute number of bytes mod 64 */
+    count = (ctx->bits[0] >> 3) & 0x3F;
+
+    /* Set the first char of padding to 0x80.  This is safe since there is
+       always at least one byte free */
+    p = ctx->in + count;
+    *p++ = 0x80;
+
+    /* Bytes of padding needed to make 64 bytes */
+    count = 64 - 1 - count;
+
+    /* Pad out to 56 mod 64 */
+    if (count < 8) {
+       /* Two lots of padding:  Pad the first block to 64 bytes */
+       memset(p, 0, count);
+       byteReverse(ctx->in, 16);
+       MD5Transform(ctx->buf, (uint32_t *) ctx->in);
+
+       /* Now fill the next block with 56 bytes */
+       memset(ctx->in, 0, 56);
+    } else {
+       /* Pad block to 56 bytes */
+       memset(p, 0, count - 8);
+    }
+    byteReverse(ctx->in, 14);
+
+    /* Append length in bits and transform */
+    ((uint32_t *) ctx->in)[14] = ctx->bits[0];
+    ((uint32_t *) ctx->in)[15] = ctx->bits[1];
+
+    MD5Transform(ctx->buf, (uint32_t *) ctx->in);
+    byteReverse((uint8_t *) ctx->buf, 4);
+    memcpy(digest, ctx->buf, 16);
+    memset(ctx, 0, sizeof(ctx));       /* In case it's sensitive */
+}
+
+#ifndef ASM_MD5
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+       ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data.  MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void MD5Transform(uint32_t buf[4], uint32_t const in[16])
+{
+    uint32_t a, b, c, d;
+
+    a = buf[0];
+    b = buf[1];
+    c = buf[2];
+    d = buf[3];
+
+    MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+    MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+    MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
+    MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+    MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+    MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+    MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+    MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+    MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+    MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+    MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+    MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+    MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+    MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+    MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+    MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+    MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+    MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+    MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+    MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+    MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+    MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
+    MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+    MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+    MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+    MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+    MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+    MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+    MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+    MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+    MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+    MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+    MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+    MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+    MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+    MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+    MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+    MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+    MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+    MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+    MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+    MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+    MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+    MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+    MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+    MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+    MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+    MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+    MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+    MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+    MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+    MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+    MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+    MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+    MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+    MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+    MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+    MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+    MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+    MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+    MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+    MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+    MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+    MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+    buf[0] += a;
+    buf[1] += b;
+    buf[2] += c;
+    buf[3] += d;
+}
+
+#endif
diff --git a/utils/iaxclient/lib/libiax2/src/md5.h b/utils/iaxclient/lib/libiax2/src/md5.h
new file mode 100644 (file)
index 0000000..81c9e30
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef MD5_H
+#define MD5_H
+
+#ifndef _MSC_VER
+#include <inttypes.h>
+#else
+typedef unsigned int uint32_t;
+typedef unsigned char uint8_t;
+#endif
+
+struct MD5Context {
+       uint32_t buf[4];
+       uint32_t bits[2];
+       uint8_t in[64];
+};
+
+void MD5Init(struct MD5Context *context);
+void MD5Update(struct MD5Context *context, uint8_t const *buf, unsigned int len);
+void MD5Final(uint8_t digest[16], struct MD5Context *context);
+void MD5Transform(uint32_t buf[4], uint32_t const in[16]);
+
+/*
+ * This is needed to make RSAREF happy on some MS-DOS compilers.
+ */
+typedef struct MD5Context MD5_CTX;
+
+#endif /* !MD5_H */
diff --git a/utils/iaxclient/lib/libiax2/src/miniphone.c b/utils/iaxclient/lib/libiax2/src/miniphone.c
new file mode 100644 (file)
index 0000000..ab0dd84
--- /dev/null
@@ -0,0 +1,776 @@
+/*
+ * Miniphone: A simple, command line telephone
+ *
+ * IAX Support for talking to Asterisk and other Gnophone clients
+ *
+ * Copyright (C) 1999, Linux Support Services, Inc.
+ *
+ * Mark Spencer <markster@linux-support.net>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <iax-client.h>
+#include <linux/soundcard.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/signal.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <gsm.h>
+#include <miniphone.h>
+#include <time.h>
+
+#include "busy.h"
+#include "dialtone.h"
+#include "answer.h"
+#include "ringtone.h"
+#include "ring10.h"
+#include "options.h"
+
+#define FRAME_SIZE 160
+
+static char callerid[80];
+
+struct peer {
+       int time;
+       gsm gsmin;
+       gsm gsmout;
+
+       struct iax_session *session;
+       struct peer *next;
+};
+
+static char *audiodev = "/dev/dsp";
+static int audiofd = -1;
+static struct peer *peers;
+static int answered_call = 0;
+
+static struct peer *find_peer(struct iax_session *);
+static int audio_setup(char *);
+static void sighandler(int);
+static void parse_args(FILE *, unsigned char *);
+void do_iax_event(FILE *);
+void call(FILE *, char *);
+void answer_call(void);
+void reject_call(void);
+static void handle_event(FILE *, struct iax_event *e, struct peer *p);
+void parse_cmd(FILE *, int, char **);
+void issue_prompt(FILE *);
+void dump_array(FILE *, char **);
+
+struct sound {
+       short *data;
+       int datalen;
+       int samplen;
+       int silencelen;
+       int repeat;
+};
+
+static int cursound = -1;
+
+static int sampsent = 0;
+static int offset = 0;
+static int silencelen = 0;
+static int nosound = 0;
+
+static int offhook = 0;
+static int ringing = 0;
+
+static int writeonly = 0;
+
+static struct iax_session *registry = NULL;
+static struct timeval regtime;
+
+#define TONE_NONE     -1
+#define TONE_RINGTONE 0
+#define TONE_BUSY     1
+#define TONE_CONGEST  2
+#define TONE_RINGER   3
+#define TONE_ANSWER   4
+#define TONE_DIALTONE  5
+
+#define OUTPUT_NONE    0
+#define OUTPUT_SPEAKER 1
+#define OUTPUT_HANDSET 2
+#define OUTPUT_BOTH    3
+
+static struct sound sounds[] = {
+       { ringtone, sizeof(ringtone)/2, 16000, 32000, 1 },
+       { busy, sizeof(busy)/2, 4000, 4000, 1 },
+       { busy, sizeof(busy)/2, 2000, 2000, 1 },
+       { ring10, sizeof(ring10)/2, 16000, 32000, 1 },
+       { answer, sizeof(answer)/2, 2200, 0, 0 },
+       { dialtone, sizeof(dialtone)/2, 8000, 0, 1 },
+};
+
+static char *help[] = {
+"Welcome to the miniphone telephony client, the commands are as follows:\n",
+"Help\t\t-\tDisplays this screen.",
+"Help <Command>\t-\tInqueries specific information on a command.",
+"Dial <Number>\t-\tDials the number supplied in the first arguement",
+"Status\t\t-\tLists the current sessions and their current status.",
+"Quit\t\t-\tShuts down the client.",
+"",
+0
+};
+
+static short silence[FRAME_SIZE];
+
+static struct peer *most_recent_answer;
+static struct iax_session *newcall = 0;
+
+static struct peer *find_peer(struct iax_session *session)
+{
+       struct peer *cur = peers;
+       while(cur) {
+               if (cur->session == session)
+                       return cur;
+               cur = cur->next;
+       }
+       return NULL;
+}
+
+static int audio_setup(char *dev)
+{
+       int fd; 
+       int fmt = AFMT_S16_LE;
+       int channels = 1;
+       int speed = 8000;
+       int fragsize = (40 << 16) | 6;
+       if ( (fd = open(dev, O_RDWR | O_NONBLOCK)) < 0) {
+               fprintf(stderr, "Unable to open audio device %s: %s\n", dev, strerror(errno));
+               return -1;
+       }
+       if (ioctl(fd, SNDCTL_DSP_SETFMT, &fmt) || (fmt != AFMT_S16_LE)) {
+               fprintf(stderr, "Unable to set in signed linear format.\n");
+               return -1;
+       }
+       if (ioctl(fd, SNDCTL_DSP_SETDUPLEX, 0)) {
+               fprintf(stderr, "Unable to set full duplex operation.\n");
+               writeonly = 1;
+               /* return -1; */
+       }
+       if (ioctl(fd, SNDCTL_DSP_CHANNELS, &channels) || (channels != 1)) {
+               fprintf(stderr, "Unable to set to mono\n");
+               return -1;
+       }
+       if (ioctl(fd, SNDCTL_DSP_SPEED, &speed) || (speed != 8000)) {
+               fprintf(stderr, "Unable to set speed to 8000 hz\n");
+               return -1;
+       }
+       if (ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &fragsize)) {
+               fprintf(stderr, "Unable to set fragment size...\n");
+               return -1;
+       }
+
+       return fd;
+}
+
+static int send_sound(int soundfd)
+{
+       /* Send FRAME_SIZE samples of whatever */
+       short myframe[FRAME_SIZE];
+       short *frame = NULL;
+       int total = FRAME_SIZE;
+       int amt=0;
+       int res;
+       int myoff;
+       audio_buf_info abi;
+       if (cursound > -1) {
+               res = ioctl(soundfd, SNDCTL_DSP_GETOSPACE ,&abi);
+               if (res) {
+                       fprintf(stderr,"Unable to read output space\n");
+                       return -1;
+               }
+               /* Calculate how many samples we can send, max */
+               if (total > (abi.fragments * abi.fragsize / 2)) 
+                       total = abi.fragments * abi.fragsize / 2;
+               res = total;
+               if (sampsent < sounds[cursound].samplen) {
+                       myoff=0;
+                       while(total) {
+                               amt = total;
+                               if (amt > (sounds[cursound].datalen - offset)) 
+                                       amt = sounds[cursound].datalen - offset;
+                               memcpy(myframe + myoff, sounds[cursound].data + offset, amt * 2);
+                               total -= amt;
+                               offset += amt;
+                               sampsent += amt;
+                               myoff += amt;
+                               if (offset >= sounds[cursound].datalen)
+                                       offset = 0;
+                       }
+                       /* Set it up for silence */
+                       if (sampsent >= sounds[cursound].samplen) 
+                               silencelen = sounds[cursound].silencelen;
+                       frame = myframe;
+               } else {
+                       if (silencelen > 0) {
+                               frame = silence;
+                               silencelen -= res;
+                       } else {
+                               if (sounds[cursound].repeat) {
+                                       /* Start over */
+                                       sampsent = 0;
+                                       offset = 0;
+                               } else {
+                                       cursound = -1;
+                                       nosound = 0;
+                               }
+                       }
+               }
+#if 0
+               if (frame)
+                       printf("res is %d, frame[0] is %d\n", res, frame[0]);
+#endif         
+               res = write(soundfd, frame, res * 2);
+               if (res > 0)
+                       return 0;
+               return res;
+       }
+       return 0;
+}
+
+static int iax_regtimeout(int timeout)
+{
+       if (timeout) {
+               gettimeofday(&regtime, NULL);
+               regtime.tv_sec += timeout;
+       } else {
+               regtime.tv_usec = 0;
+               regtime.tv_sec = 0;
+       }
+       return 0;
+}
+
+static int check_iax_register(void)
+{
+       int res;
+       if (strlen(regpeer) && strlen(server)) {
+               registry = iax_session_new();
+       
+               res = iax_register(registry, server,regpeer,regsecret, refresh);
+       
+               if (res) {
+                       fprintf(stderr, "Failed registration: %s\n", iax_errstr);
+                       return -1;
+               }
+               iax_regtimeout(5 * refresh / 6);
+       } else {
+               iax_regtimeout(0);
+               refresh = 60;
+       }
+       return 0;
+}
+
+static int check_iax_timeout(void)
+{
+       struct timeval tv;
+       int ms;
+       if (!regtime.tv_usec || !regtime.tv_sec)
+               return -1;
+       gettimeofday(&tv, NULL);
+       if ((tv.tv_usec >= regtime.tv_usec) && (tv.tv_sec >= regtime.tv_sec)) {
+               check_iax_register();
+               /* Have it check again soon */
+               return 100;
+       }
+       ms = (regtime.tv_sec - tv.tv_sec) * 1000 + (regtime.tv_usec - tv.tv_usec) / 1000;
+       return ms;
+}
+
+static int gentone(int sound, int uninterruptible)
+{
+       cursound = sound;
+       sampsent = 0;
+       offset = 0;
+       silencelen = 0;
+       nosound = uninterruptible;
+       printf("Sending tone %d\n", sound);
+       return 0;
+}
+
+void
+sighandler(int sig)
+{
+       if(sig == SIGHUP) {
+               puts("rehashing!");
+       } else if(sig == SIGINT) {
+               static int prev = 0;
+               int cur;
+               
+               if ( (cur = time(0))-prev <= 5) {
+                       printf("Terminating!\n");
+                       exit(0);
+               } else {
+                       prev = cur;
+                       printf("Press interrupt key again in the next %d seconds to really terminate\n", 5-(cur-prev));
+               }
+       }
+}
+
+void
+parse_args(FILE *f, unsigned char *cmd)
+{
+       static char *argv[MAXARGS];
+       unsigned char *parse = cmd;
+       int argc = 0, t = 0;
+
+       // Don't mess with anything that doesn't exist...
+       if(!*parse)
+               return;
+
+       bzero(argv, sizeof(argv));
+       while(*parse) {
+               if(*parse < 33 || *parse > 128) {
+                       *parse = 0, t++;
+                       if(t > MAXARG) {
+                               fprintf(f, "Warning: Argument exceeds maximum argument size, command ignored!\n");
+                               return;
+                       }
+               } else if(t || !argc) {
+                       if(argc == MAXARGS) {
+                               fprintf(f, "Warning: Command ignored, too many arguments\n");
+                               return;
+                       }
+                       argv[argc++] = parse;
+                       t = 0;
+               }
+
+               parse++;
+       }
+
+       if(argc)
+               parse_cmd(f, argc, argv);
+}
+
+int
+main(int argc, char *argv[])
+{
+       int port;
+       int netfd;
+       int c, h=0, m, regm;
+       FILE *f;
+       int fd = STDIN_FILENO;
+       char rcmd[RBUFSIZE];
+       fd_set readfd;
+       fd_set writefd;
+       struct timeval timer;
+       struct timeval *timerptr = NULL;
+       gsm_frame fo;
+
+       load_options();
+
+       if (!strlen(callerid))
+               gethostname(callerid, sizeof(callerid));
+
+       signal(SIGHUP, sighandler);
+       signal(SIGINT, sighandler);
+
+       if ( !(f = fdopen(fd, "w+"))) {
+               fprintf(stderr, "Unable to create file on fd %d\n", fd);
+               return -1;
+       }
+
+       if ( (audiofd = audio_setup(audiodev)) == -1) {
+               fprintf(stderr, "Fatal error: failed to open sound device");
+               return -1;
+       }
+
+       if ( (port = iax_init(0) < 0)) {
+               fprintf(stderr, "Fatal error: failed to initialize iax with port %d\n", port);
+               return -1;
+       }
+
+       iax_set_formats(AST_FORMAT_GSM);
+       netfd = iax_get_fd();
+
+       check_iax_register();
+
+       fprintf(f, "Text Based Telephony Client.\n\n");
+       issue_prompt(f);
+
+       timer.tv_sec = 0;
+       timer.tv_usec = 0;
+
+       while(1) {
+               FD_ZERO(&readfd);
+               FD_ZERO(&writefd);
+               FD_SET(fd, &readfd);
+                       if(fd > h)
+                               h = fd;
+               if(answered_call && !writeonly) {
+                       FD_SET(audiofd, &readfd);
+                               if(audiofd > h)
+                                       h = audiofd;
+               }
+               if (cursound > -1) {
+                       FD_SET(audiofd, &writefd);
+                       if (audiofd > h)
+                               h = audiofd;
+               }
+               FD_SET(netfd, &readfd);
+               if(netfd > h)
+                       h = netfd;
+
+               if ( (c = select(h+1, &readfd, &writefd, 0, timerptr)) >= 0) {
+                       if(FD_ISSET(fd, &readfd)) {
+                               if ( ( fgets(&*rcmd, 256, f))) {
+                                       rcmd[strlen(rcmd)-1] = 0;
+                                       parse_args(f, &*rcmd);
+                               } else fprintf(f, "Fatal error: failed to read data!\n");
+
+                               issue_prompt(f);
+                       }
+                       if(answered_call) {
+                               if(FD_ISSET(audiofd, &readfd)) {
+                               static int ret, rlen = 0;
+                                       static short rbuf[FRAME_SIZE];
+
+                                       if ( (ret = read(audiofd, rbuf + rlen, 2 * (FRAME_SIZE-rlen))) == -1) {
+                                               puts("Failed to read audio.");
+                                               return -1;
+                                       }
+                                       rlen += ret/2;
+                                       if(rlen == FRAME_SIZE) {
+                                               rlen = 0;
+
+                                               if(!most_recent_answer->gsmout)
+                                                       most_recent_answer->gsmout = gsm_create();
+
+                                               gsm_encode(most_recent_answer->gsmout, rbuf, fo);
+                                               if(iax_send_voice(most_recent_answer->session,
+                                               AST_FORMAT_GSM, (char *)fo, sizeof(fo)) == -1)
+                                                       puts("Failed to send voice!");
+                                       }
+                               }
+                       }
+                       do_iax_event(f);
+                       m = iax_time_to_next_event();
+                       if(m > -1) {
+                               timerptr = &timer;
+                               timer.tv_sec = m /1000;
+                               timer.tv_usec = (m % 1000) * 1000;
+                       } else 
+                               timerptr = 0;
+                       regm = check_iax_timeout();
+                       if (!timerptr || (m > regm)) {
+                               timerptr = &timer;
+                               timer.tv_sec = regm /1000;
+                               timer.tv_usec = (regm % 1000) * 1000;
+                       }
+                       if (FD_ISSET(audiofd, &writefd)) {
+                               send_sound(audiofd);
+                       }
+               } else {
+                       if(errno == EINTR)
+                               continue;
+                       fprintf(stderr, "Fatal error in select(): %s\n", strerror(errno));
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+void
+do_iax_event(FILE *f) {
+       int sessions = 0;
+       struct iax_event *e = 0;
+       struct peer *peer;
+
+       while ( (e = iax_get_event(0))) {
+               peer = find_peer(e->session);
+               if(peer) {
+                       handle_event(f, e, peer);
+               } else if (e->session == registry) {
+                       fprintf(stderr, "Registration complete: %s (%d)\n",
+                               (e->event.regreply.status == IAX_REG_SUCCESS) ? "Success" : "Failed",
+                               e->event.regreply.status);
+                       registry = NULL;
+               } else {
+                       if(e->etype != IAX_EVENT_CONNECT) {
+                               fprintf(stderr, "Huh? This is an event for a non-existant session?\n");
+                               continue;
+                       }
+                       sessions++;
+
+                       if(sessions >= MAX_SESSIONS) {
+                               fprintf(f, "Missed a call... too many sessions open.\n");
+                       }
+
+
+                       if(e->event.connect.callerid && e->event.connect.dnid)
+                               fprintf(f, "Call from '%s' for '%s'", e->event.connect.callerid, 
+                               e->event.connect.dnid);
+                       else if(e->event.connect.dnid) {
+                               fprintf(f, "Call from '%s'", e->event.connect.dnid);
+                       } else if(e->event.connect.callerid) {
+                               fprintf(f, "Call from '%s'", e->event.connect.callerid);
+                       } else printf("Call from");
+                       fprintf(f, " (%s)\n", inet_ntoa(iax_get_peer_addr(e->session).sin_addr));
+
+                       if(most_recent_answer) {
+                               fprintf(f, "Incoming call ignored, there's already a call waiting for answer... \
+please accept or reject first\n");
+                               iax_reject(e->session, "Too many calls, we're busy!");
+                       } else {
+                               if ( !(peer = malloc(sizeof(struct peer)))) {
+                                       fprintf(f, "Warning: Unable to allocate memory!\n");
+                                       return;
+                               }
+
+                               peer->time = time(0);
+                               peer->session = e->session;
+                               if (peer->gsmin)
+                                       free(peer->gsmin);
+                               peer->gsmin = 0;
+                               if (peer->gsmout)
+                                       free(peer->gsmout);
+                               peer->gsmout = 0;
+
+                               peer->next = peers;
+                               peers = peer;
+
+                               iax_accept(peer->session);
+                               iax_ring_announce(peer->session);
+                               most_recent_answer = peer;
+                               ringing = 1;
+                               gentone(TONE_RINGER, 0);
+                               fprintf(f, "Incoming call!\n");
+                       }
+                       issue_prompt(f);
+               }
+               iax_event_free(e);
+       }
+}
+
+void
+call(FILE *f, char *num)
+{
+       struct peer *peer;
+
+       if(!newcall)
+               newcall = iax_session_new();
+       else {
+               fprintf(f, "Already attempting to call somewhere, please cancel first!\n");
+               return;
+       }
+
+       if ( !(peer = malloc(sizeof(struct peer)))) {
+               fprintf(f, "Warning: Unable to allocate memory!\n");
+               return;
+       }
+
+       peer->time = time(0);
+       peer->session = newcall;
+       peer->gsmin = 0;
+       peer->gsmout = 0;
+
+       peer->next = peers;
+       peers = peer;
+
+       most_recent_answer = peer;
+
+       offhook = 1;
+       
+       iax_call(peer->session, callerid, num, NULL, 10);
+}
+
+void
+answer_call(void)
+{
+       if(most_recent_answer)
+               iax_answer(most_recent_answer->session);
+       printf("Answering call!\n");
+       answered_call = 1;
+       offhook = 1;
+       ringing = 0;
+       gentone(TONE_ANSWER, 1);
+}
+
+void
+reject_call(void)
+{
+       iax_reject(most_recent_answer->session, "Call rejected manually.");
+       most_recent_answer = 0;
+       ringing = 0;
+       gentone(TONE_NONE, 1);
+}
+
+void
+handle_event(FILE *f, struct iax_event *e, struct peer *p)
+{
+       short fr[FRAME_SIZE];
+       int len;
+
+       switch(e->etype) {
+               case IAX_EVENT_HANGUP:
+                       iax_hangup(most_recent_answer->session, "Byeee!");
+                       fprintf(f, "Call disconnected by peer\n");
+                       free(most_recent_answer);
+                       most_recent_answer = 0;
+                       answered_call = 0;
+                       peers = 0;
+                       newcall = 0;
+                       if (offhook)
+                               gentone(TONE_CONGEST, 0);
+                       break;
+
+               case IAX_EVENT_REJECT:
+                       fprintf(f, "Authentication was rejected\n");
+                       break;
+               case IAX_EVENT_ACCEPT:
+                       fprintf(f, "Accepted...\n");
+                       issue_prompt(f);
+                       break;
+               case IAX_EVENT_RINGA:
+                       fprintf(f, "Ringing...\n");
+                       issue_prompt(f);
+                       gentone(TONE_RINGTONE, 0);
+                       break;
+               case IAX_EVENT_ANSWER:
+                       answer_call();
+                       gentone(TONE_ANSWER, 1);
+                       break;
+               case IAX_EVENT_VOICE:
+                       switch(e->event.voice.format) {
+                               case AST_FORMAT_GSM:
+                                       if(e->event.voice.datalen % 33) {
+                                               fprintf(stderr, "Weird gsm frame, not a multiple of 33.\n");
+                                               break;
+                                       }
+
+                                       if (!p->gsmin)
+                                               p->gsmin = gsm_create();
+
+                                       len = 0;
+                                       while(len < e->event.voice.datalen) {
+                                               if(gsm_decode(p->gsmin, e->event.voice.data + len, fr)) {
+                                                       fprintf(stderr, "Bad GSM data\n");
+                                                       break;
+                                               } else {
+                                                       int res;
+
+                                                       res = write(audiofd, fr, sizeof(fr));
+                                                       if (res < 0) 
+                                                               fprintf(f, "Write failed: %s\n", strerror(errno));
+                                               }
+                                               len += 33;
+                                       }
+                                       break;
+                               default :
+                                       fprintf(f, "Don't know how to handle that format %d\n", e->event.voice.format);
+                       }
+                       break;
+               default:
+                       fprintf(f, "Unknown event: %d\n", e->etype);
+       }
+}
+
+void
+dump_call(void)
+{
+        if(most_recent_answer)
+        {
+               printf("Dumping call!\n");
+            iax_hangup(most_recent_answer->session,"");
+            free(most_recent_answer);
+        }
+        answered_call = 0;
+        most_recent_answer = 0;
+        answered_call = 0;
+        peers = 0;
+        newcall = 0;
+               offhook = 0;
+               ringing = 0;
+               gentone(TONE_NONE, 0);
+}                                                                               
+
+void
+parse_cmd(FILE *f, int argc, char **argv)
+{
+       if(!strcasecmp(argv[0], "HELP")) {
+               if(argc == 1)
+                       dump_array(f, help);
+               else if(argc == 2) {
+                       if(!strcasecmp(argv[1], "HELP"))
+                               fprintf(f, "Help <Command>\t-\tDisplays general help or specific help on command if supplied an arguement\n");
+                       else if(!strcasecmp(argv[1], "QUIT"))
+                               fprintf(f, "Quit\t\t-\tShuts down the miniphone\n");
+                       else fprintf(f, "No help available on %s\n", argv[1]);
+               } else {
+                       fprintf(f, "Too many arguements for command help.\n");
+               }
+       } else if(!strcasecmp(argv[0], "STATUS")) {
+               if(argc == 1) {
+                       int c = 0;
+                       struct peer *peerptr = peers;
+
+                       if(!peerptr)
+                               fprintf(f, "No session matches found.\n");
+                       else while(peerptr) {
+                               fprintf(f, "Listing sessions:\n\n");
+                               fprintf(f, "Session %d\n", ++c);
+                               fprintf(f, "Session existed for %d seconds\n", (int)time(0)-peerptr->time);
+                               if(answered_call)
+                                       fprintf(f, "Call answered.\n");
+                               else fprintf(f, "Call ringing.\n");
+
+                               peerptr = peerptr->next;
+                       }
+               } else fprintf(f, "Too many arguments for command status.\n");
+       } else if(!strcasecmp(argv[0], "ANSWER")) {
+               if(argc > 1)
+                       fprintf(f, "Too many arguements for command answer\n");
+               else answer_call();
+       } else if(!strcasecmp(argv[0], "REJECT")) {
+               if(argc > 1)
+                       fprintf(f, "Too many arguements for command reject\n");
+               else {
+                       fprintf(f, "Rejecting current phone call.\n");
+                       reject_call();
+               }
+       } else if (!strcasecmp(argv[0], "DUMP")) {
+               dump_call();
+       } else if (!strcasecmp(argv[0], "HANGUP")) {
+               dump_call();
+       } else if(!strcasecmp(argv[0], "CALL")) {
+               if(argc > 2)
+                       fprintf(f, "Too many arguements for command call\n");
+               else {
+                       call(f, argv[1]);
+               }
+       } else if(!strcasecmp(argv[0], "QUIT")) {
+               if(argc > 1)
+                       fprintf(f, "Too many arguements for command quit\n");
+               else {
+                       fprintf(f, "Good bye!\n");
+                       exit(1);
+               }
+       } else fprintf(f, "Unknown command of %s\n", argv[0]);
+}
+
+void
+issue_prompt(FILE *f)
+{
+       fprintf(f, "TeleClient> ");
+       fflush(f);
+}
+
+void
+dump_array(FILE *f, char **array) {
+       while(*array)
+               fprintf(f, "%s\n", *array++);
+}
diff --git a/utils/iaxclient/lib/libiax2/src/miniphone.h b/utils/iaxclient/lib/libiax2/src/miniphone.h
new file mode 100644 (file)
index 0000000..6e3677a
--- /dev/null
@@ -0,0 +1,6 @@
+#define RBUFSIZE 256
+#define MAXARGS 10
+#define MAXARG 256
+#define MAX_SESSIONS 4
+
+extern void parse_cmd(FILE *, int, char **);
diff --git a/utils/iaxclient/lib/libiax2/src/options.c b/utils/iaxclient/lib/libiax2/src/options.c
new file mode 100644 (file)
index 0000000..a01e3f8
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Snomphone: IAX software for SNOM 100 Phone
+ *
+ * IAX Support for talking to Asterisk and other Gnophone clients
+ *
+ * Copyright (C) 1999, Linux Support Services, Inc.
+ *
+ * Mark Spencer <markster@linux-support.net>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License
+ */
+
+#define CONFIG_FILE "/etc/miniphone.conf"
+#define USER_FILE "%s/.miniphone-conf"
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+char regpeer[256];
+char regsecret[256];
+char server[256];
+int refresh = 60;
+char context[256];
+char language[256];
+
+#define TYPE_STRING 0
+#define TYPE_INT    1
+
+struct opt {
+       char *name;
+       void *where;
+       int len;
+       int type;
+};
+
+static struct opt opts[] =  {
+       { "regpeer", regpeer, sizeof(regpeer), TYPE_STRING },
+       { "regsecret", regsecret, sizeof(regsecret), TYPE_STRING },
+       { "server", server, sizeof(server), TYPE_STRING },
+       { "context", context, sizeof(context), TYPE_STRING },
+       { "language", language, sizeof(language), TYPE_STRING },
+       { "refresh", &refresh, sizeof(refresh), TYPE_INT },
+};
+
+static int __load_options(char *filename)
+{
+       FILE *f;
+       int lineno = 0;
+       char buf[256];
+       char *var, *value;
+       int x;
+       char *c;
+       f = fopen(filename, "r");
+       if (!f) {
+               fprintf(stderr, "Failed to open '%s': %s\n", filename, strerror(errno));
+               return -1;
+       }
+       while(!feof(f)) {
+               fgets(buf, sizeof(buf), f);
+               if (!feof(f)) {
+                       /* Ditch comments */
+                       if ((c = strchr(buf, '#')))
+                               *c = 0;
+                       lineno++;
+                       /* Strip CR */
+                       buf[strlen(buf)-1] = '\0';
+                       if (strlen(buf)) {
+                               var = strtok(buf, "=");
+                               value = strtok(NULL, "=");
+                               if (!var || !value) {
+                                       fprintf(stderr, "Syntax error line %d\n", lineno);
+                                       continue;
+                               }
+                               for (x=0;x<sizeof(opts) / sizeof(opts[0]); x++) {
+                                       if (!strcasecmp(var, opts[x].name)) {
+                                               switch(opts[x].type) {
+                                               case TYPE_STRING:
+                                                       strncpy((char *)opts[x].where, value, opts[x].len);
+                                                       break;
+                                               case TYPE_INT:
+                                                       if (sscanf(value, "%i", (int *)opts[x].where) != 1) {
+                                                               fprintf(stderr, "Not a number at line %d\n", lineno);
+                                                       }
+                                                       break;
+                                               default:
+                                                       fprintf(stderr, "Don't know what to do about type %d\n", opts[x].type);
+                                               }
+                                               break;
+                                       }
+                               }
+                               if (!(x < sizeof(opts) / sizeof(opts[0]))) {
+                                       fprintf(stderr, "Dunno keyword '%s'\n", var);
+                                       continue;
+                               }
+                       }
+               }
+       }
+       fclose(f);
+       return 0;
+}
+
+int load_options(void)
+{
+       char fn[256];
+       __load_options(CONFIG_FILE);
+       if (getenv("HOME")) {
+               snprintf(fn, sizeof(fn), USER_FILE, getenv("HOME"));
+               __load_options(fn);
+       }
+       return 0;
+}
+
+static int __save_options(char *filename)
+{
+       FILE *f;
+       f = fopen(filename, "w");
+       if (!f) {
+               fprintf(stderr, "Failed to open '%s': %s\n", filename, strerror(errno));
+               return -1;
+       }
+       fclose(f);
+       return 0;
+}
+
+int save_options(void)
+{
+       char fn[256];
+       if (getenv("HOME")) {
+               snprintf(fn, sizeof(fn), USER_FILE, getenv("HOME"));
+               return __save_options(fn);
+       } else
+               return __save_options(CONFIG_FILE);
+       
+}
diff --git a/utils/iaxclient/lib/libiax2/src/options.h b/utils/iaxclient/lib/libiax2/src/options.h
new file mode 100644 (file)
index 0000000..b9f791d
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Snomphone: IAX software for SNOM 100 Phone
+ *
+ * IAX Support for talking to Asterisk and other Gnophone clients
+ *
+ * Copyright (C) 1999, Linux Support Services, Inc.
+ *
+ * Mark Spencer <markster@linux-support.net>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License
+ */
+
+extern char regpeer[256];
+extern char regsecret[256];
+extern char regpeer[256];
+extern char server[256];
+extern int refresh;
+extern char context[256];
+extern char language[256];
+
+int save_options(void);
+int load_options(void);
diff --git a/utils/iaxclient/lib/libiax2/src/ring10.h b/utils/iaxclient/lib/libiax2/src/ring10.h
new file mode 100644 (file)
index 0000000..13fce37
--- /dev/null
@@ -0,0 +1,1752 @@
+/*
+  * Signed 16-bit audio data
+  *
+  * Source: /home/markster/ring10.raw
+  *
+  * Copyright (C) 1999, Mark Spencer and Linux Support Services
+  *
+  * Distributed under the terms of the GNU General Public License
+  *
+  */
+
+static signed short ring10[] = {
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 0x82a0, 0x8dc7, 0x607e, 0xc0c6, 0x2bd3, 
+0x8df5, 0x828d, 0x0716, 0xaca6, 0xcefe, 0x41df, 0xd185, 0x8aa3, 0x8b1a, 0x789b, 
+0x82a2, 0x804f, 0x7ea8, 0x8113, 0x7f7d, 0x7fff, 0x801e, 0x801d, 0x7f32, 0x82ec, 
+0x83e1, 0x7fb0, 0x7f71, 0x80de, 0x7f3d, 0x7fe3, 0x81b4, 0x7c37, 0x8553, 0x7b29, 
+0x7ede, 0xde6e, 0x0e64, 0xf9f4, 0x015e, 0x00f6, 0xfe56, 0x0019, 0xf8bb, 0xfd90, 
+0x08cc, 0x05ab, 0xfd0b, 0xf9c6, 0xf875, 0xf789, 0xfc74, 0x032e, 0xf97a, 0xf4bb, 
+0x0212, 0x006e, 0x03df, 0x17c5, 0x0f50, 0xfb23, 0xfdbd, 0xf7cf, 0xdf5b, 0xe2d3, 
+0xf111, 0xef27, 0x11c5, 0x33a4, 0x168d, 0x0145, 0x0494, 0xe85c, 0xdac3, 0xf0c7, 
+0xeea8, 0x0023, 0x3036, 0x252a, 0xffb7, 0x01d1, 0xf637, 0xd506, 0xe8eb, 0xf5ff, 
+0xe5ca, 0x1ec5, 0x3fa4, 0x0e3c, 0x1570, 0x2b37, 0xea23, 0xca43, 0xf392, 0xdf0e, 
+0xde40, 0x2e7c, 0x276f, 0x035c, 0x2ccc, 0x1acf, 0xcf4a, 0xeb5b, 0x0fb1, 0xe01a, 
+0x0c69, 0x3a97, 0xfb54, 0x0751, 0x20f1, 0xdce9, 0xd2a2, 0x19b3, 0x096f, 0xf1b6, 
+0x38de, 0x1f70, 0xf32b, 0x2569, 0x0650, 0xc3d7, 0xf1ad, 0x1aa5, 0xe87e, 0x0c7f, 
+0x406d, 0xffaa, 0x0ba8, 0x2e02, 0xe545, 0xcebb, 0x10fc, 0x0102, 0xded8, 0x2b7c, 
+0x2053, 0xec6f, 0x266e, 0x1770, 0xcb63, 0xf18e, 0x2015, 0xe6ef, 0xfe64, 0x3700, 
+0xf628, 0xfb00, 0x2e43, 0xee48, 0xcd4a, 0x1867, 0x0ec3, 0xdd77, 0x2291, 0x1c80, 
+0xe325, 0x19b7, 0x1719, 0xcb88, 0xeded, 0x258c, 0xe7e8, 0xf0c6, 0x2d21, 0xf3d5, 
+0xf494, 0x290d, 0xef7b, 0xca28, 0x12c8, 0x0d8d, 0xd5f3, 0x171d, 0x1994, 0xe0c0, 
+0x1348, 0x1929, 0xcf9b, 0xe6fb, 0x20ae, 0xe921, 0xed2b, 0x2c54, 0xf96e, 0xf19f, 
+0x21b6, 0xf12e, 0xc8b4, 0x0907, 0x0964, 0xd049, 0x0eb8, 0x1fa6, 0xe6b5, 0x0cec, 
+0x16b6, 0xcd0c, 0xda57, 0x17c9, 0xe440, 0xe2a2, 0x2b4d, 0xffa2, 0xec7e, 0x1ee9, 
+0xf674, 0xbfcb, 0xf769, 0x0402, 0xcfe8, 0x104b, 0x2734, 0xe7e9, 0x07d9, 0x19f4, 
+0xd032, 0xd00b, 0x0e46, 0xe17d, 0xe2d8, 0x3456, 0x0781, 0xed01, 0x238d, 0xfa72, 
+0xbb51, 0xf543, 0x050b, 0xccd5, 0x1491, 0x3358, 0xedad, 0x10c4, 0x283b, 0xd051, 
+0xc9e9, 0x11f8, 0xe2cb, 0xe534, 0x43aa, 0x1090, 0xf11b, 0x3267, 0x02c3, 0xb72d, 
+0xf9ac, 0x0fbd, 0xce45, 0x1d7b, 0x4389, 0xef2e, 0x1593, 0x348e, 0xd0cb, 0xca8c, 
+0x1f61, 0xe981, 0xdef7, 0x4774, 0x15ae, 0xefab, 0x3b28, 0x0a9e, 0xb2f6, 0xf9e9, 
+0x1976, 0xcc08, 0x15ab, 0x4534, 0xee6c, 0x159b, 0x3753, 0xcf09, 0xc69a, 0x2270, 
+0xf15c, 0xdee6, 0x48ce, 0x1af4, 0xf169, 0x3da0, 0x0d68, 0xb573, 0xff9e, 0x20ba, 
+0xcbfe, 0x142d, 0x4879, 0xed49, 0x1434, 0x3d96, 0xd714, 0xca99, 0x298b, 0xf708, 
+0xd92c, 0x4632, 0x1acc, 0xea6e, 0x3d2c, 0x1412, 0xb534, 0xfbfa, 0x24f9, 0xcd72, 
+0x0df9, 0x48f8, 0xeb87, 0x0bca, 0x3dd5, 0xd6cc, 0xc015, 0x2605, 0xfa87, 0xd1a9, 
+0x40d0, 0x1c59, 0xe0de, 0x34f9, 0x14c6, 0xaf61, 0xf2a5, 0x23e6, 0xc929, 0x01be, 
+0x4423, 0xe53b, 0x0182, 0x3c3a, 0xd758, 0xbb9d, 0x1fa9, 0xf454, 0xc611, 0x36e8, 
+0x18f7, 0xdac9, 0x2e8a, 0x126d, 0xac14, 0xead6, 0x2215, 0xc990, 0xf9f5, 0x43cb, 
+0xea01, 0xfcbf, 0x38fd, 0xd9f3, 0xb7cd, 0x1bc4, 0xfd41, 0xca56, 0x31e3, 0x1d4b, 
+0xdca2, 0x2a9f, 0x1c24, 0xb8aa, 0xeb59, 0x25d5, 0xd2d0, 0xfa10, 0x44fa, 0xefe0, 
+0xfced, 0x3ef4, 0xe9a1, 0xbdf0, 0x19ac, 0x0198, 0xca6f, 0x2f04, 0x25b6, 0xe187, 
+0x29ba, 0x250a, 0xbe42, 0xe40e, 0x24ef, 0xd75d, 0xf476, 0x44f8, 0xf719, 0xf7a1, 
+0x3c94, 0xf20e, 0xbcdf, 0x16a3, 0x07e8, 0xc8d4, 0x2a3e, 0x2b3f, 0xdf4e, 0x235d, 
+0x2c92, 0xc2c7, 0xdf39, 0x2873, 0xd790, 0xea2a, 0x47fd, 0xfd0e, 0xf0e3, 0x3bd8, 
+0xf4e9, 0xb265, 0x0c2c, 0x0751, 0xc302, 0x29bb, 0x37bd, 0xe138, 0x1e0c, 0x2d09, 
+0xbddb, 0xd246, 0x24c4, 0xd87a, 0xe5df, 0x4ff6, 0x08d6, 0xf0d8, 0x3d61, 0xf8bf, 
+0xaede, 0x0a36, 0x0df3, 0xc0f5, 0x23ec, 0x3e92, 0xe3d7, 0x1cad, 0x348e, 0xc0d6, 
+0xcd4e, 0x265c, 0xd9b6, 0xdf83, 0x510e, 0x0c41, 0xeece, 0x4153, 0xfeeb, 0xa9f6, 
+0x04b3, 0x12a4, 0xbf2f, 0x20d1, 0x42f4, 0xe1b1, 0x1b1e, 0x3980, 0xc2b4, 0xcb50, 
+0x2b74, 0xded0, 0xd835, 0x4e7a, 0x0b46, 0xe555, 0x4015, 0x0517, 0xaa54, 0x0504, 
+0x1932, 0xbc34, 0x1a77, 0x48b1, 0xe0bb, 0x149b, 0x3ba7, 0xc34a, 0xc481, 0x2bc2, 
+0xe401, 0xd20e, 0x4f53, 0x1389, 0xe3b7, 0x418b, 0x0a15, 0xa70d, 0x0024, 0x1f9f, 
+0xbf65, 0x142d, 0x4a81, 0xe0ca, 0x1152, 0x4325, 0xcb03, 0xc18a, 0x2b95, 0xeb45, 
+0xcf92, 0x4c54, 0x18ad, 0xe08b, 0x3f12, 0x1264, 0xa9fc, 0xfd97, 0x246f, 0xbf86, 
+0x0ce2, 0x4e7c, 0xe4f3, 0x0c20, 0x44e0, 0xd069, 0xbdcb, 0x2b8e, 0xf32d, 0xcad4, 
+0x464f, 0x1e76, 0xdf62, 0x3b07, 0x17ea, 0xaafb, 0xf5a0, 0x2835, 0xc7c2, 0x0842, 
+0x4d2b, 0xe634, 0x03ef, 0x42bc, 0xd7f2, 0xbb73, 0x2662, 0xf892, 0xc8b3, 0x3e30, 
+0x1f20, 0xdcca, 0x354a, 0x1c6b, 0xaf75, 0xf0f7, 0x2963, 0xc908, 0xfdbf, 0x4c3c, 
+0xebe5, 0x00e3, 0x44c4, 0xdf15, 0xb9e9, 0x243b, 0x00e9, 0xcb76, 0x3b53, 0x248e, 
+0xdc27, 0x2fcb, 0x22e5, 0xb66c, 0xec96, 0x2b19, 0xd0ef, 0xf97b, 0x48ae, 0xecc0, 
+0xf8b4, 0x411d, 0xe769, 0xb9f7, 0x1c41, 0x0022, 0xc369, 0x2ced, 0x23ac, 0xd8eb, 
+0x2522, 0x232a, 0xb611, 0xe19f, 0x2738, 0xd013, 0xece5, 0x434c, 0xf00e, 0xefcc, 
+0x3b79, 0xeb32, 0xb19c, 0x135e, 0x04ef, 0xc1b9, 0x27a8, 0x2992, 0xd7b3, 0x1ba5, 
+0x2481, 0xb8c5, 0xd97d, 0x246f, 0xd113, 0xe45d, 0x4486, 0xf7f7, 0xeb36, 0x395a, 
+0xf122, 0xaea5, 0x0c28, 0x05eb, 0xbde4, 0x2585, 0x36a2, 0xde67, 0x1b86, 0x2dac, 
+0xbd03, 0xd2b8, 0x2624, 0xd8b8, 0xe802, 0x521b, 0x0855, 0xefbc, 0x4048, 0xfad2, 
+0xafe2, 0x0fb1, 0x12b2, 0xc62c, 0x2c2a, 0x43f5, 0xe562, 0x1fcb, 0x3791, 0xc2ac, 
+0xd4d1, 0x2dfd, 0xde0a, 0xe53f, 0x5578, 0x0f49, 0xf2b6, 0x4609, 0x0105, 0xabf5, 
+0x09a8, 0x157e, 0xc286, 0x23e7, 0x425f, 0xe36a, 0x1d93, 0x3580, 0xbf80, 0xcaf2, 
+0x2a04, 0xf16e, 0xd92b, 0x0eaa, 0xf1a7, 0x1ddb, 0x5b52, 0x0665, 0xd2e3, 0x15f8, 
+0xf606, 0x9d42, 0xdba7, 0xf312, 0xd349, 0x21ed, 0x576a, 0x34e8, 0x2450, 0x2679, 
+0xdc01, 0xb506, 0xcb0f, 0xa454, 0xccf3, 0x2c13, 0x1673, 0xf8ca, 0x4ff1, 0x63ac, 
+0xec26, 0xd77c, 0xf1f9, 0xc268, 0xb11a, 0xdfe4, 0x02e7, 0x10f5, 0x3512, 0x19dd, 
+0x0edc, 0x3568, 0xf6f7, 0xbe10, 0xda93, 0xf4fe, 0xda03, 0xe293, 0x15dd, 0x15f3, 
+0x1ba5, 0x1521, 0x12e8, 0x23ab, 0x0fc3, 0xdb3e, 0xb671, 0xe960, 0xe13c, 0xc695, 
+0x1a81, 0x3d23, 0x1c56, 0x190d, 0x4234, 0x1970, 0xd784, 0xd86b, 0xb5e8, 0xc9f3, 
+0xeb89, 0xe344, 0x17ae, 0x5713, 0x37fc, 0xffe2, 0x36b3, 0x1dfe, 0xb963, 0xbf9c, 
+0xc9a1, 0xcc7b, 0xe409, 0x08a6, 0x2077, 0x3b4d, 0x3cba, 0x0553, 0x220e, 0x226e, 
+0xd219, 0xb7ec, 0xcb8b, 0xdf2a, 0xd0c7, 0xf5be, 0x2ff0, 0x42a6, 0x3c24, 0x25ae, 
+0x2d6d, 0x0d94, 0xde80, 0xb78b, 0xb12b, 0xdf7a, 0xde33, 0x0046, 0x47b1, 0x5170, 
+0x29c0, 0x2945, 0x3ab5, 0xf08f, 0xc806, 0xc229, 0xbbf4, 0xe40d, 0xf365, 0x0bfe, 
+0x448d, 0x5cd8, 0x1e52, 0x10ba, 0x3908, 0xefa4, 0xc243, 0xcf89, 0xd02d, 0xde92, 
+0xf8e0, 0x191e, 0x2f7b, 0x48e6, 0x1e38, 0x1074, 0x3785, 0xf8be, 0xbd1c, 0xc06b, 
+0xdc36, 0xdb97, 0xe3c0, 0x2042, 0x37c5, 0x36ff, 0x1b73, 0x2064, 0x2c9a, 0xefa2, 
+0xbf0c, 0xb7f0, 0xe221, 0xe243, 0xd998, 0x2263, 0x4bae, 0x3596, 0x18aa, 0x3763, 
+0x27d0, 0xdcc6, 0xcacc, 0xc06f, 0xd83d, 0xecfe, 0xeefa, 0x1ffa, 0x5052, 0x393f, 
+0x0af5, 0x3c9e, 0x316b, 0xd2df, 0xc575, 0xd3c8, 0xddd2, 0xdf98, 0xfbd7, 0x2929, 
+0x4879, 0x4052, 0x160c, 0x3708, 0x2b31, 0xdac6, 0xc0c3, 0xcfc0, 0xe71d, 0xddec, 
+0x0145, 0x3847, 0x457c, 0x356b, 0x214a, 0x3a5f, 0x1474, 0xd892, 0xc579, 0xc6a7, 
+0xe77a, 0xe4dc, 0x00ab, 0x3b89, 0x4eba, 0x290a, 0x16ea, 0x3dc6, 0x0956, 0xcc12, 
+0xc3bd, 0xc9e9, 0xe4be, 0xe60b, 0x0561, 0x3707, 0x4c82, 0x2444, 0x1406, 0x3a8e, 
+0xff5b, 0xc494, 0xbf9f, 0xcb26, 0xdfef, 0xe755, 0x1060, 0x334f, 0x40e5, 0x1f87, 
+0x16b9, 0x33e8, 0xfa6e, 0xc670, 0xb774, 0xcc17, 0xe18f, 0xdd0f, 0x102c, 0x3f0d, 
+0x4098, 0x1b95, 0x24b2, 0x315a, 0xe9d8, 0xc459, 0xb314, 0xc524, 0xe2a6, 0xe1cf, 
+0x100a, 0x44af, 0x455c, 0x1551, 0x264f, 0x2ab1, 0xd681, 0xb90c, 0xb4d6, 0xc68d, 
+0xddac, 0xef74, 0x1f57, 0x4357, 0x4192, 0x0e60, 0x1bcb, 0x20fd, 0xd477, 0xb435, 
+0xb3e3, 0xcdc3, 0xd9c4, 0xef97, 0x2384, 0x3b60, 0x34c9, 0x119d, 0x1f15, 0x0fb3, 
+0xd15d, 0xb30d, 0xa9e3, 0xd431, 0xdc02, 0xe98a, 0x2987, 0x4204, 0x290c, 0x1181, 
+0x2d0c, 0x0800, 0xcb55, 0xb8f5, 0xaaa6, 0xd49f, 0xe57c, 0xf063, 0x281c, 0x4c65, 
+0x2d19, 0x0cd2, 0x2ddb, 0xfefe, 0xc171, 0xbd4c, 0xb7c2, 0xd4c5, 0xe6f3, 0x0040, 
+0x2b86, 0x4b6d, 0x2ed1, 0x0ce3, 0x2d97, 0x01f9, 0xc2ad, 0xb8fc, 0xc53e, 0xe1cf, 
+0xea35, 0x0eb0, 0x38b8, 0x4a3b, 0x2a1e, 0x1457, 0x2a1e, 0xfbca, 0xcdf1, 0xbc93, 
+0xcc0b, 0xec27, 0xeb05, 0x144b, 0x4443, 0x496d, 0x2233, 0x2180, 0x30b2, 0xf03c, 
+0xcced, 0xbf0d, 0xcc55, 0xeec3, 0xf367, 0x186f, 0x45cd, 0x4e7d, 0x215a, 0x2485, 
+0x3122, 0xe7a8, 0xc40a, 0xbf85, 0xd4dd, 0xebe8, 0xf32b, 0x2121, 0x49bb, 0x4c61, 
+0x1af5, 0x1f88, 0x2c32, 0xe8c5, 0xc512, 0xc0b7, 0xdbf9, 0xe9ea, 0xf2f4, 0x2584, 
+0x43e2, 0x3e1b, 0x19cf, 0x28d2, 0x2442, 0xe27b, 0xc589, 0xbe8a, 0xdddc, 0xe567, 
+0xed4e, 0x27f2, 0x48cd, 0x3505, 0x0e88, 0x2cd5, 0x207d, 0xda54, 0xc1cf, 0xb8c1, 
+0xd925, 0xe569, 0xefd0, 0x2723, 0x4dd1, 0x38b2, 0x0de5, 0x2d90, 0x155b, 0xca06, 
+0xbab6, 0xbf37, 0xdd46, 0xe3fd, 0xfb50, 0x2e5d, 0x487b, 0x343e, 0x0abe, 0x25e9, 
+0x0f65, 0xcb83, 0xb474, 0xbc50, 0xe2ab, 0xe1df, 0xfd3e, 0x3672, 0x458b, 0x294e, 
+0x10fd, 0x2afa, 0x027f, 0xcae8, 0xb95b, 0xbc6f, 0xe536, 0xe3af, 0xfd1c, 0x3b18, 
+0x4cb1, 0x23ff, 0x13eb, 0x3353, 0xfb34, 0xc4aa, 0xb71a, 0xb9f2, 0xe1d7, 0xe97f, 
+0x058d, 0x3a0f, 0x4fcd, 0x2408, 0x11a3, 0x2fb9, 0xf271, 0xbb7f, 0xb447, 0xc317, 
+0xde44, 0xe56a, 0x110a, 0x3ccc, 0x494a, 0x1f80, 0x11af, 0x26a1, 0xeb09, 0xbcd0, 
+0xaf90, 0xc8d4, 0xe63f, 0xe47d, 0x1435, 0x3f4f, 0x3fbe, 0x17c7, 0x1a4f, 0x2393, 
+0xe191, 0xbfa1, 0xb0e4, 0xc7c9, 0xe2d9, 0xe363, 0x1625, 0x4320, 0x3da9, 0x11c4, 
+0x1e02, 0x1d1b, 0xd6be, 0xbe96, 0xb123, 0xc8a4, 0xe6ce, 0xef2e, 0x1c03, 0x4584, 
+0x3fd1, 0x1006, 0x20d8, 0x197b, 0xcf64, 0xb99e, 0xb693, 0xd396, 0xe8eb, 0xfb01, 
+0x2aca, 0x4b38, 0x3f87, 0x0de0, 0x1f2f, 0x1503, 0xd574, 0xba46, 0xb72d, 0xf07a, 
+0xfa16, 0xf608, 0x29c0, 0x3a7e, 0x42a7, 0x43ac, 0x2717, 0xec6f, 0xd732, 0xc1ac, 
+0xa146, 0xef37, 0x122b, 0x05c1, 0x5c67, 0x8e8c, 0x3d5e, 0x0043, 0x00d0, 0xb9ef, 
+0xa38d, 0xc8dd, 0xc921, 0x15c9, 0x5fe3, 0x531a, 0x477d, 0x5852, 0x1b9f, 0xb930, 
+0xd1b6, 0xde60, 0xbcce, 0xe7f7, 0x16b1, 0x2aeb, 0x4605, 0x3592, 0xfe8c, 0x0c1d, 
+0x1b24, 0xd084, 0xd667, 0x2736, 0x06f7, 0xdfa7, 0x1976, 0x0df9, 0xc5e8, 0x032b, 
+0x324e, 0xea0e, 0x1ab4, 0x46e4, 0xf72e, 0x0369, 0x0ef3, 0xbe35, 0xbd17, 0x10fd, 
+0xfb35, 0xeb3f, 0x4e43, 0x2da4, 0xfe31, 0x2f50, 0xf64c, 0xafd6, 0xe267, 0xfd01, 
+0xca77, 0x1087, 0x48c1, 0xfcf4, 0x1bb0, 0x31af, 0xd234, 0xc0cb, 0x054e, 0xec6b, 
+0xce29, 0x29db, 0x1bb4, 0xf0fd, 0x3608, 0x12eb, 0xbb40, 0xeaa8, 0x190f, 0xce00, 
+0xed59, 0x39ef, 0xf1f0, 0xfb2a, 0x3535, 0xe3b3, 0xbf33, 0x1a9b, 0x013b, 0xc2ab, 
+0x2976, 0x21e0, 0xd3d8, 0x1ca6, 0x14ae, 0xb242, 0xe538, 0x2958, 0xd98c, 0xf279, 
+0x4106, 0xf13e, 0xf68b, 0x3379, 0xe023, 0xb4a8, 0x104b, 0x0685, 0xcca4, 0x2e61, 
+0x2d96, 0xe2b8, 0x26ac, 0x2510, 0xc114, 0xd9e5, 0x1f91, 0xdbc9, 0xe515, 0x40bd, 
+0x0693, 0xff44, 0x3c5e, 0xf664, 0xb8dc, 0x0b37, 0x1314, 0xc29c, 0x161f, 0x3582, 
+0xe32e, 0x17c0, 0x2de6, 0xc7c1, 0xcfeb, 0x23a6, 0xe644, 0xe65f, 0x4256, 0xf765, 
+0xe698, 0x4148, 0xfbe1, 0xa6b4, 0x03fa, 0x1c92, 0xcb85, 0x1a54, 0x37af, 0xe830, 
+0x1b0b, 0x255d, 0xc13f, 0xd3d9, 0x205e, 0xde69, 0xe2ab, 0x48d5, 0x0931, 0xee2f, 
+0x3d79, 0x0658, 0xb36c, 0xf59e, 0x11f4, 0xd042, 0x110b, 0x2e1b, 0xe763, 0x2269, 
+0x3bda, 0xcefb, 0xd37b, 0x2d7f, 0xe9d7, 0xd48e, 0x3fd2, 0x0e86, 0xea62, 0x3cd5, 
+0x11e0, 0xc1dc, 0x08e0, 0x1f68, 0xd3f1, 0x1fc8, 0x3da6, 0xe12f, 0x1d62, 0x4060, 
+0xccb6, 0xd211, 0x316f, 0xf370, 0xe20e, 0x4657, 0x1280, 0xf30a, 0x3df0, 0x07fc, 
+0xb956, 0x023e, 0x1978, 0xcbba, 0x137d, 0x3ff7, 0xecbc, 0x1698, 0x3f29, 0xdf9f, 
+0xcc1c, 0x1bdc, 0xef17, 0xd3da, 0x346b, 0x1296, 0xeb25, 0x3885, 0x190f, 0xbf13, 
+0xfb71, 0x1df2, 0xc509, 0xffa2, 0x3a66, 0xe5fd, 0x04f6, 0x36be, 0xda99, 0xc67e, 
+0x1fc2, 0xef95, 0xcfa8, 0x39df, 0x0f1a, 0xd986, 0x2d7b, 0x0e88, 0xb2a2, 0xf40f, 
+0x1bd3, 0xc95c, 0x0511, 0x408d, 0xec48, 0x03d2, 0x3281, 0xd7a0, 0xb9a0, 0x13ab, 
+0xf02d, 0xc92c, 0x3af6, 0x26c0, 0xe5f8, 0x2de7, 0x18b9, 0xafd8, 0xddbf, 0x15bc, 
+0xc4d3, 0xf6dc, 0x4b73, 0xf89f, 0x018a, 0x3c4e, 0xdf11, 0xb20d, 0x12d7, 0xf511, 
+0xbf7e, 0x33aa, 0x286f, 0xe309, 0x3107, 0x1f74, 0xb1c3, 0xe10f, 0x1fd3, 0xc7d4, 
+0xef6e, 0x4b78, 0xf32f, 0xf8e5, 0x43cb, 0xe7da, 0xaf46, 0x115a, 0xfeb2, 0xbf7a, 
+0x2e9a, 0x2ed7, 0xde2f, 0x2807, 0x259c, 0xb09f, 0xd3d4, 0x2606, 0xd544, 0xeb3d, 
+0x5107, 0xfecf, 0xf63f, 0x4304, 0xedfe, 0xae0d, 0x0d7f, 0x0957, 0xc47d, 0x2f62, 
+0x3b51, 0xdfea, 0x2a01, 0x3390, 0xb825, 0xd3e9, 0x29f1, 0xd82e, 0xe2e3, 0x509a, 
+0x061c, 0xf530, 0x48b1, 0xf740, 0xabeb, 0x0d93, 0x0ed4, 0xbed0, 0x274e, 0x3e3b, 
+0xddc2, 0x2168, 0x35a1, 0xbbb0, 0xcedb, 0x2b94, 0xdd5b, 0xdd2d, 0x4e6a, 0x068d, 
+0xe741, 0x3eef, 0xfe34, 0xad12, 0x0bb7, 0x1a73, 0xbea5, 0x1c31, 0x4269, 0xdc1a, 
+0x1611, 0x37d6, 0xc048, 0xcaa3, 0x2f7e, 0xe59c, 0xd94c, 0x4ed8, 0x0af6, 0xe225, 
+0x3c84, 0xfd49, 0xa4b2, 0x048d, 0x1ed5, 0xc496, 0x1caa, 0x4641, 0xddd4, 0x1578, 
+0x37dc, 0xc13b, 0xcab7, 0x30dc, 0xfec0, 0xd462, 0x1387, 0x07dd, 0x14c1, 0x4b92, 
+0x0d74, 0xda49, 0x12de, 0x02fe, 0xb8fe, 0xeaae, 0x0363, 0xdab0, 0x23b0, 0x68fb, 
+0x3681, 0x1351, 0x29fc, 0xf22e, 0xb781, 0xd225, 0xc11d, 0xd7d8, 0x354d, 0x26b8, 
+0x09af, 0x60fa, 0x5f8c, 0xe302, 0xde80, 0xff6a, 0xbb95, 0xafec, 0x029f, 0x161d, 
+0x0fee, 0x3924, 0x2b6c, 0x1ed5, 0x24fe, 0xec7b, 0xc1fe, 0xe22b, 0xfbcd, 0xdc4d, 
+0xf3f7, 0x210f, 0x1d01, 0x1305, 0x1342, 0x1f6c, 0x0852, 0xfea5, 0xdd42, 0xc083, 
+0xf243, 0xde95, 0xd818, 0x23f7, 0x3eab, 0x0891, 0x1381, 0x52fd, 0xff10, 0xc983, 
+0xe091, 0xc3b8, 0xcafc, 0xe7d7, 0xfc8d, 0x2043, 0x559d, 0x2c2e, 0x0418, 0x4485, 
+0x0b4c, 0xb4e5, 0xc68e, 0xddbf, 0xd0b6, 0xdc81, 0x1e4b, 0x2d10, 0x365b, 0x2c50, 
+0x170a, 0x303e, 0x0a60, 0xcc89, 0xb88a, 0xdbc7, 0xe3e7, 0xcdd2, 0x0b38, 0x3c7e, 
+0x392b, 0x254c, 0x3272, 0x2fc9, 0xf0ee, 0xd4d8, 0xb5b4, 0xc03b, 0xdef0, 0xd8e9, 
+0x0edc, 0x533e, 0x46e4, 0x0fc4, 0x358a, 0x34b8, 0xd1c3, 0xbf29, 0xbb64, 0xbeea, 
+0xdb1c, 0xf31b, 0x17f1, 0x44fa, 0x4bfb, 0x0a36, 0x1fe2, 0x2ce9, 0xcf0d, 0xb605, 
+0xc6c6, 0xcc96, 0xcf30, 0xf9cd, 0x25fb, 0x36d1, 0x4086, 0x1499, 0x21d8, 0x287f, 
+0xde77, 0xb0fd, 0xba6d, 0xe0f5, 0xd3e4, 0xee77, 0x3561, 0x4077, 0x2baa, 0x1d38, 
+0x3753, 0x1587, 0xd2e2, 0xb252, 0xb44b, 0xe5a7, 0xdbb5, 0xe778, 0x3790, 0x55cb, 
+0x234e, 0x10ab, 0x42e9, 0x083e, 0xc15a, 0xc2a9, 0xbe30, 0xd7d1, 0xe76a, 0xfa22, 
+0x2b37, 0x53cb, 0x29a6, 0x0950, 0x4086, 0x0f68, 0xbba0, 0xb824, 0xcc9c, 0xd743, 
+0xd665, 0x06ae, 0x3597, 0x44f1, 0x2854, 0x19d4, 0x3395, 0xfe8f, 0xc1b9, 0xad2d, 
+0xc39d, 0xde05, 0xd850, 0x0bf2, 0x4266, 0x457f, 0x1d4b, 0x2284, 0x337f, 0xe442, 
+0xbc43, 0xb8ba, 0xc33a, 0xe0e4, 0xe8f8, 0x10b5, 0x4262, 0x4afc, 0x1744, 0x1d2b, 
+0x3125, 0xe2b5, 0xbcb6, 0xbdea, 0xccfd, 0xdfe5, 0xefed, 0x1bae, 0x3f5e, 0x451d, 
+0x167c, 0x1ea7, 0x2848, 0xdf70, 0xbb35, 0xbbfc, 0xd959, 0xe266, 0xec2b, 0x20e3, 
+0x435c, 0x3878, 0x0fee, 0x25e8, 0x1ba1, 0xdaf0, 0xc061, 0xb76f, 0xdd9c, 0xe727, 
+0xece4, 0x247e, 0x48ee, 0x303d, 0x099a, 0x320b, 0x19b9, 0xd0b8, 0xc508, 0xbe20, 
+0xd52c, 0xe430, 0xf5f1, 0x21d1, 0x4aae, 0x3670, 0x0bc4, 0x349a, 0x16c6, 0xc9e1, 
+0xbb8f, 0xc44e, 0xdbed, 0xde26, 0x03b2, 0x34c9, 0x4689, 0x30a8, 0x17ea, 0x33bd, 
+0x0b87, 0xcd79, 0xb9b9, 0xc3c1, 0xe227, 0xdffc, 0x07ae, 0x3deb, 0x4732, 0x25e8, 
+0x1ef9, 0x370f, 0xfb29, 0xcc78, 0xbf32, 0xc5c0, 0xe807, 0xe571, 0x074b, 0x4121, 
+0x4902, 0x1968, 0x206c, 0x3da5, 0xf467, 0xc9c7, 0xc240, 0xc6d8, 0xe2b1, 0xeca9, 
+0x0f7d, 0x3a80, 0x4ac1, 0x1bda, 0x1cdc, 0x3836, 0xee35, 0xc32e, 0xc0a2, 0xce3e, 
+0xdfd7, 0xe9c8, 0x162c, 0x3eb5, 0x48b0, 0x1a61, 0x1e8f, 0x2cf5, 0xe5c6, 0xbb80, 
+0xb378, 0xd228, 0xe3dd, 0xeba5, 0x2266, 0x46f5, 0x3e1f, 0x13fa, 0x26ea, 0x21ec, 
+0xd925, 0xbdc7, 0xb66d, 0xd76b, 0xe81e, 0xf025, 0x269d, 0x4d69, 0x3d40, 0x1027, 
+0x2c58, 0x1cc9, 0xd265, 0xbfd4, 0xbabe, 0xd919, 0xe822, 0xf931, 0x2bc9, 0x4c69, 
+0x3d20, 0x158d, 0x31ca, 0x1821, 0xce8a, 0xb8af, 0xba0f, 0xdfb6, 0xe677, 0xfd3b, 
+0x385e, 0x53d9, 0x3764, 0x14a8, 0x30af, 0x0a51, 0xcb95, 0xbad7, 0xbc48, 0xe366, 
+0xea7e, 0x06cf, 0x3f08, 0x53c7, 0x2fe0, 0x189d, 0x383f, 0x00fd, 0xc5f3, 0xbf0d, 
+0xc38f, 0xe4a3, 0xecee, 0x0ef5, 0x432c, 0x54a7, 0x2a15, 0x190d, 0x3675, 0xf7bc, 
+0xc3e0, 0xbc22, 0xc381, 0xe210, 0xec59, 0x15ed, 0x4300, 0x4fd8, 0x269c, 0x1bda, 
+0x324a, 0xed57, 0xbb9c, 0xb705, 0xceb8, 0xeb30, 0xed72, 0x1baa, 0x48ad, 0x4bd3, 
+0x1fde, 0x1ea9, 0x2826, 0xe505, 0xc2b3, 0xb577, 0xceec, 0xeeb9, 0xef73, 0x1fd5, 
+0x4c99, 0x41f7, 0x12c7, 0x24ad, 0x22eb, 0xd504, 0xbfe3, 0xba2a, 0xd063, 0xea6f, 
+0xf037, 0x1c9c, 0x4acf, 0x430c, 0x0b68, 0x200d, 0x1c9e, 0xcce4, 0xb9ad, 0xbc29, 
+0xd211, 0xe475, 0xfc21, 0x2910, 0x443b, 0x3a83, 0x0ef1, 0x2295, 0x15ac, 0xd00d, 
+0xb774, 0xbaff, 0xded3, 0xe41e, 0xf945, 0x331e, 0x49b7, 0x3276, 0x128d, 0x28c7, 
+0x08f2, 0xce8e, 0xbb2e, 0xb907, 0xe4c0, 0xe9f8, 0xf98a, 0x3323, 0x4a75, 0x2718, 
+0x0ddc, 0x3369, 0x0795, 0xc936, 0xc192, 0xc3cc, 0xe2b9, 0xe583, 0xfce9, 0x312f, 
+0x4951, 0x266f, 0x0ffe, 0x3698, 0x0679, 0xca63, 0xc301, 0xc844, 0xde4c, 0xe26e, 
+0x076e, 0x3283, 0x4507, 0x259a, 0x11af, 0x30ff, 0xfd1c, 0xc1b2, 0xb384, 0xc924, 
+0xe414, 0xde8f, 0x0781, 0x295f, 0x51b4, 0x5b09, 0x17c9, 0xf17b, 0xd9cd, 0xb11a, 
+0x8396, 0xbd98, 0x073f, 0x0598, 0x5258, 0x7bf8, 0x3dd3, 0x096d, 0xe7f8, 0xa966, 
+0x9271, 0xc3c7, 0xb173, 0xf5d9, 0x6db2, 0x3b89, 0x2231, 0x4aaf, 0x1c3b, 0xc115, 
+0xcb06, 0xd460, 0xbb98, 0x03f6, 0xf9d7, 0xecaf, 0x4aa5, 0x27cf, 0xcf8c, 0x0764, 
+0x3489, 0xd9cb, 0xf31b, 0x39b5, 0xebc3, 0xeb7f, 0x1192, 0xceee, 0xbd72, 0x16f9, 
+0x1b5a, 0xf888, 0x4a44, 0x34a8, 0xedd8, 0x18bb, 0xf8d6, 0xa74c, 0xd19c, 0x139c, 
+0xeaf7, 0x0d0b, 0x5317, 0x0e81, 0x0c44, 0x35bd, 0xe010, 0xb51d, 0x075b, 0xfc77, 
+0xc9ae, 0x2b95, 0x35a1, 0xf0e8, 0x2c61, 0x2481, 0xc370, 0xe826, 0x20b5, 0xd95a, 
+0xf832, 0x43e0, 0xf261, 0xf7ef, 0x414e, 0xf14b, 0xbf9e, 0x1c6c, 0x1380, 0xd3d1, 
+0x2650, 0x1f52, 0xd592, 0x1ddb, 0x2414, 0xc347, 0xebd1, 0x3e70, 0xf240, 0xeb89, 
+0x3d66, 0xf738, 0xe57b, 0x2fe8, 0xf22d, 0xbd68, 0x1e7b, 0x2466, 0xd858, 0x2613, 
+0x3122, 0xdc86, 0x16b9, 0x277b, 0xc324, 0xdb13, 0x2c78, 0xe8ab, 0xed0b, 0x49bb, 
+0x0342, 0xf02a, 0x3b6c, 0xf7d9, 0xb9c6, 0x0fd8, 0x1192, 0xc763, 0x12e5, 0x2738, 
+0xe26c, 0x1a89, 0x2a72, 0xcd72, 0xdca7, 0x27a9, 0xe962, 0xd98a, 0x271e, 0xf948, 
+0xe783, 0x29f0, 0x000e, 0xc137, 0x064c, 0x17e6, 0xcd48, 0x0efb, 0x329b, 0xdc50, 
+0xf9d6, 0x28fd, 0xd866, 0xc34b, 0x13df, 0xefa3, 0xdcbf, 0x3578, 0x09a7, 0xe33f, 
+0x2c3f, 0x02a6, 0xaa76, 0xf3eb, 0x1870, 0xc21d, 0x029e, 0x3d07, 0xedbb, 0x0a92, 
+0x33dc, 0xd94f, 0xc985, 0x15a5, 0xdf1c, 0xd3f5, 0x3f5e, 0x0fca, 0xe50f, 0x3b04, 
+0x1a3d, 0xb99b, 0xf6d1, 0x1c75, 0xcc21, 0x0987, 0x3e95, 0xed51, 0x0dcf, 0x3b32, 
+0xd980, 0xc6f7, 0x280e, 0xf587, 0xd3c2, 0x4871, 0x233c, 0xe02f, 0x3039, 0x183d, 
+0xaecf, 0xf137, 0x2776, 0xcc66, 0x0bf0, 0x5162, 0xeddf, 0x088c, 0x4536, 0xd457, 
+0xb205, 0x2315, 0xf51a, 0xc60d, 0x4281, 0x2682, 0xe5d9, 0x3aad, 0x1cab, 0xb02d, 
+0xf294, 0x20af, 0xbecb, 0x0084, 0x4c16, 0xeaf2, 0x054e, 0x449f, 0xdf02, 0xbd48, 
+0x25bf, 0xfda9, 0xcb15, 0x3a93, 0x1e9b, 0xddd4, 0x3408, 0x1f70, 0xb333, 0xf3df, 
+0x32ab, 0xd133, 0x014e, 0x52b2, 0xf138, 0xfe00, 0x4260, 0xe1f2, 0xbbac, 0x28bf, 
+0x0404, 0xcc81, 0x4649, 0x2e56, 0xdee8, 0x3677, 0x23ef, 0xabc0, 0xea62, 0x3159, 
+0xcf59, 0xfdcf, 0x575a, 0xf403, 0xfe40, 0x4759, 0xe094, 0xb225, 0x1ffa, 0xfefc, 
+0xc26f, 0x3a61, 0x2be1, 0xdb44, 0x2efe, 0x2504, 0xadcb, 0xe074, 0x2713, 0xc6d3, 
+0xecc2, 0x48d6, 0xea4d, 0xf2ec, 0x43a0, 0xe1fc, 0xaa5f, 0x1825, 0xffd7, 0xba38, 
+0x2bdb, 0x24a3, 0xce10, 0x1cd8, 0x1cfc, 0xab2e, 0xdc4d, 0x276d, 0xca22, 0xeb01, 
+0x4a08, 0xeb0e, 0xe94c, 0x3cd7, 0xe45f, 0xa6c6, 0x0f8c, 0x066f, 0xc2d2, 0x2a01, 
+0x2aea, 0xd9bf, 0x251a, 0x2933, 0xb64d, 0xd9b5, 0x26a1, 0xd2ba, 0xe822, 0x4af1, 
+0xfec7, 0xf323, 0x3fdf, 0xf78e, 0xb4c1, 0x0f7f, 0x0e1c, 0xc7ce, 0x25fb, 0x3129, 
+0xdeb5, 0x2268, 0x3385, 0xc266, 0xd9b6, 0x2efc, 0xddb0, 0xe00f, 0x45ac, 0x0168, 
+0xea8d, 0x3cd9, 0xfeda, 0xb603, 0x13c5, 0x166b, 0xc192, 0x1f5a, 0x3804, 0xda94, 
+0x15a3, 0x35b3, 0xc729, 0xd3ae, 0x2e68, 0xe359, 0xde70, 0x4764, 0x0725, 0xe6b1, 
+0x3882, 0xfed4, 0xad23, 0x0819, 0x16c2, 0xc15b, 0x1c91, 0x4358, 0xe49c, 0x1162, 
+0x35d1, 0xc8f8, 0xc74f, 0x2676, 0xe0e9, 0xd0d7, 0x4b09, 0x1cea, 0xedea, 0x3f3b, 
+0x11f4, 0xb09a, 0xfc73, 0x177b, 0xba40, 0x109f, 0x4fcb, 0xf285, 0x1d0f, 0x3dc2, 
+0xc588, 0xc98d, 0x329a, 0xfd8a, 0xcc33, 0x1573, 0x1810, 0x1532, 0x434e, 0x102d, 
+0xd555, 0x08d4, 0x0011, 0xb77c, 0xec37, 0x098c, 0xd4fc, 0x2033, 0x7926, 0x32be, 
+0xfe95, 0x28ab, 0xef9c, 0xa428, 0xcffc, 0xcbdf, 0xd07c, 0x3681, 0x2f87, 0x0680, 
+0x626e, 0x5e9c, 0xd624, 0xd9e4, 0x080a, 0xadfe, 0xa2f5, 0x12af, 0x142c, 0xffde, 
+0x3703, 0x3570, 0x269e, 0x24fb, 0xe8a1, 0xb7ec, 0xe753, 0xf82a, 0xce4d, 0x001a, 
+0x2e98, 0x1f84, 0x0eb8, 0x1beb, 0x2603, 0xfcff, 0xfd98, 0xd8c0, 0xc719, 0xfc52, 
+0xddd2, 0xe3ec, 0x2ee0, 0x4393, 0x042b, 0x1929, 0x569a, 0xef83, 0xc35d, 0xd9e5, 
+0xc6ce, 0xd1e0, 0xed86, 0x0b2a, 0x23b2, 0x504c, 0x20ad, 0x029d, 0x3b72, 0xf5a5, 
+0xad6b, 0xbe54, 0xddfc, 0xd162, 0xddcd, 0x2952, 0x324b, 0x3156, 0x1d3f, 0x12f5, 
+0x235b, 0xf27f, 0xc001, 0xb250, 0xdfdd, 0xe3f3, 0xd455, 0x14e4, 0x3c06, 0x3326, 
+0x1a60, 0x30e7, 0x24a0, 0xe2c3, 0xcd08, 0xb21c, 0xc75c, 0xdc66, 0xe088, 0x1e09, 
+0x54ef, 0x4197, 0x0dca, 0x356f, 0x22ce, 0xcaf2, 0xc0ce, 0xbc3d, 0xcfda, 0xe59b, 
+0xfe5c, 0x27b1, 0x4caa, 0x45a1, 0x0add, 0x274f, 0x1c6c, 0xcde6, 0xc343, 0xd011, 
+0xdf48, 0xe021, 0x0b0c, 0x335a, 0x3c8e, 0x345d, 0x0d86, 0x278e, 0x1b8f, 0xdc12, 
+0xbc28, 0xc6ff, 0xead3, 0xdba0, 0xfdee, 0x39b8, 0x3f03, 0x2143, 0x1858, 0x376b, 
+0x021b, 0xcaa8, 0xbb59, 0xc6f6, 0xef67, 0xe041, 0xf9ba, 0x3cd7, 0x4cfd, 0x168d, 
+0x1037, 0x3fec, 0xf71d, 0xbed3, 0xc8d6, 0xcbc6, 0xdd8f, 0xea8c, 0x09b1, 0x2e92, 
+0x4701, 0x1829, 0x091c, 0x3ad7, 0xfd4b, 0xb999, 0xbe68, 0xdc50, 0xdc39, 0xd663, 
+0x1009, 0x330e, 0x37f3, 0x1ad3, 0x1cca, 0x3476, 0xf66a, 0xc5e8, 0xbb6f, 0xd5e8, 
+0xe008, 0xd5ea, 0x10b5, 0x3f63, 0x3725, 0x1102, 0x2911, 0x3855, 0xe9cb, 0xc610, 
+0xc44b, 0xd547, 0xdd89, 0xe4aa, 0x195d, 0x4084, 0x3d9b, 0x10ab, 0x2a1f, 0x3667, 
+0xe38c, 0xc1a0, 0xc4c5, 0xdd94, 0xe21b, 0xe99c, 0x1f49, 0x4312, 0x3b69, 0x0f14, 
+0x2b3d, 0x2eaa, 0xdeab, 0xc00a, 0xc634, 0xe225, 0xe0e3, 0xf311, 0x2b9a, 0x44fd, 
+0x3881, 0x11ee, 0x2f2a, 0x2428, 0xdc87, 0xc347, 0xc2d0, 0xe6e0, 0xe5b0, 0xf196, 
+0x2d4e, 0x4a97, 0x3366, 0x1388, 0x3ae0, 0x1bf8, 0xd058, 0xc212, 0xc09b, 0xdbf3, 
+0xe25c, 0xfa1f, 0x3093, 0x4e94, 0x31f0, 0x12fe, 0x3bde, 0x11ad, 0xc841, 0xb8bd, 
+0xbe0b, 0xdd25, 0xdd7e, 0x0138, 0x3ac9, 0x4ccb, 0x2ba2, 0x1359, 0x3033, 0xfbc6, 
+0xc14d, 0xb543, 0xbd7e, 0xdcf8, 0xde2b, 0x0754, 0x388b, 0x409a, 0x1e0d, 0x134a, 
+0x2ba8, 0xeee4, 0xbe5b, 0xafaf, 0xbb90, 0xe059, 0xde74, 0x0736, 0x3d1c, 0x4310, 
+0x16f1, 0x1686, 0x2f2a, 0xe9de, 0xbe17, 0xb446, 0xc0ca, 0xdd27, 0xe1a0, 0x0ccd, 
+0x3c13, 0x4661, 0x1949, 0x196a, 0x2a50, 0xdf8d, 0xb6a7, 0xb25a, 0xc8aa, 0xdf0e, 
+0xe6dc, 0x19c8, 0x411d, 0x423f, 0x15db, 0x1a0d, 0x2316, 0xdf69, 0xba97, 0xb2a9, 
+0xd092, 0xe29a, 0xebf2, 0x2556, 0x4a3b, 0x3fb1, 0x16cb, 0x2603, 0x1c1b, 0xd67d, 
+0xbcf3, 0xb765, 0xdad1, 0xea4b, 0xf176, 0x27e4, 0x4d31, 0x3b4c, 0x0fab, 0x2ad5, 
+0x1a4d, 0xd10b, 0xbc49, 0xba78, 0xda1f, 0xe903, 0xffda, 0x308c, 0x4a2f, 0x38ce, 
+0x11cc, 0x299c, 0x105c, 0xcdc3, 0xba31, 0xc03e, 0xe616, 0xe849, 0xfec7, 0x37e1, 
+0x4e98, 0x3198, 0x12d8, 0x2aeb, 0x03e5, 0xcb29, 0xbccb, 0xc232, 0xe734, 0xeb9c, 
+0x07ed, 0x3d12, 0x4b48, 0x2515, 0x14e8, 0x330c, 0xfd19, 0xc86d, 0xc241, 0xca17, 
+0xe64b, 0xe918, 0x09ed, 0x3ba3, 0x4eee, 0x25e2, 0x167a, 0x38a6, 0xffcf, 0xcb0e, 
+0xc615, 0xd055, 0xe3d3, 0xeafc, 0x1602, 0x3e86, 0x49c2, 0x257e, 0x2166, 0x3bcd, 
+0xfc55, 0xc4ad, 0xbb87, 0xd6e3, 0xe7a1, 0xe64f, 0x1ddd, 0x4682, 0x4516, 0x1dee, 
+0x1dc5, 0x2b0d, 0xed86, 0xc590, 0xb97d, 0xd84f, 0xec06, 0xe368, 0x1c7f, 0x4cee, 
+0x3f07, 0x13c3, 0x289d, 0x28fb, 0xdcf0, 0xc5b7, 0xbdb7, 0xd4a7, 0xec46, 0xecd0, 
+0x1bda, 0x48cc, 0x4019, 0x0cd7, 0x23a7, 0x2698, 0xd5be, 0xbc3e, 0xb90e, 0xcc6c, 
+0xddf3, 0xf12b, 0x24f1, 0x4448, 0x3b5c, 0x118e, 0x2441, 0x1c2b, 0xd270, 0xb368, 
+0xb6c7, 0xdd46, 0xdf51, 0xefbb, 0x3138, 0x49d2, 0x3667, 0x1864, 0x2b86, 0x1073, 
+0xd35e, 0xbbf4, 0xb47a, 0xdfb4, 0xe8bb, 0xf6b2, 0x353a, 0x4fd4, 0x2e9f, 0x12a8, 
+0x323d, 0x07c8, 0xcb04, 0xc1fa, 0xbd57, 0xdf17, 0xe6e8, 0xfa82, 0x3052, 0x4c63, 
+0x2d83, 0x12bf, 0x3366, 0x0318, 0xc6dd, 0xbd85, 0xbc4f, 0xd9e1, 0xe604, 0x0814, 
+0x34df, 0x4a09, 0x2d9d, 0x148f, 0x2e79, 0xfba1, 0xc12c, 0xb277, 0xbf95, 0xdeb7, 
+0xe211, 0x10bc, 0x423c, 0x4956, 0x24f7, 0x1571, 0x2434, 0xebbb, 0xc333, 0xb587, 
+0xc733, 0xedc0, 0xebba, 0x0854, 0x3f2e, 0x6f7e, 0x4a81, 0x0e5e, 0x03fe, 0xcb43, 
+0xa313, 0xa8c3, 0xd5fe, 0x0fe0, 0x3ce3, 0x6922, 0x5cb3, 0x4541, 0x10b8, 0xc5c1, 
+0xb7c8, 0xca44, 0xca38, 0xd7f7, 0x38e7, 0x4e53, 0x1cb5, 0x3dfb, 0x3d19, 0x06ab, 
+0xeda0, 0xe9ef, 0xd83d, 0xf9bf, 0x0ebe, 0xca2a, 0x0a79, 0x510e, 0xf01d, 0xe7eb, 
+0x3be6, 0x1a2e, 0xf989, 0x353e, 0x099c, 0xe538, 0x16d7, 0xd697, 0xa93c, 0x0407, 
+0x1bee, 0xf75f, 0x46c6, 0x50e3, 0xf430, 0x1813, 0x169b, 0xaf5d, 0xc57c, 0x0fb5, 
+0xe638, 0xf7e9, 0x459c, 0x122e, 0x0654, 0x352e, 0xfc93, 0xc262, 0xf99c, 0x072c, 
+0xc8f1, 0x0bf2, 0x32cd, 0xf85b, 0x1790, 0x25c1, 0xde96, 0xd882, 0x18ea, 0xe834, 
+0xd77c, 0x3995, 0x1231, 0xeab1, 0x28e3, 0x0cfc, 0xc5ef, 0xf7bd, 0x18f1, 0xd03e, 
+0x057e, 0x320a, 0xe5e4, 0x07c7, 0x2d5d, 0xd88a, 0xc884, 0x2072, 0xfd6c, 0xd3d0, 
+0x2a59, 0x1066, 0xe564, 0x22a2, 0x047a, 0xb2ee, 0xeaad, 0x1c28, 0xcc6c, 0xf7e5, 
+0x3c36, 0xee88, 0xfbfb, 0x3085, 0xddf6, 0xb28a, 0x0aaf, 0xf456, 0xbc45, 0x223a, 
+0x21ed, 0xe31c, 0x2214, 0x1882, 0xb51a, 0xdbdc, 0x18ba, 0xc1ce, 0xe1c3, 0x397c, 
+0xed39, 0xf426, 0x3690, 0xe68c, 0xb498, 0x0e83, 0x00c5, 0xc494, 0x1ef7, 0x1b31, 
+0xdc33, 0x1f84, 0x1b7f, 0xb9c1, 0xdc07, 0x2246, 0xd5fb, 0xeaf7, 0x4a41, 0x042a, 
+0xed8c, 0x29a9, 0xf4c4, 0xbbf5, 0xffbd, 0x02b3, 0xd089, 0x2a98, 0x349a, 0xe5f4, 
+0x231d, 0x3682, 0xc042, 0xc757, 0x28ee, 0xe56b, 0xda47, 0x3eac, 0x0d7c, 0xfc17, 
+0x4512, 0x05d1, 0xbb63, 0x0fc8, 0x0da5, 0xb98f, 0x1ecc, 0x3aea, 0xdbbd, 0x1bd6, 
+0x4041, 0xd007, 0xd35e, 0x2aaf, 0xea38, 0xe711, 0x3e4a, 0xfa47, 0xef65, 0x3f02, 
+0xf730, 0xae98, 0x0fae, 0x1e19, 0xc953, 0x1ea3, 0x3db2, 0xe20d, 0x1043, 0x2d87, 
+0xc8ab, 0xca8a, 0x2270, 0xe769, 0xe021, 0x4751, 0x0a42, 0xed5b, 0x468e, 0x0a0e, 
+0xa823, 0xfc1e, 0x19ce, 0xc19e, 0x0fd8, 0x3c33, 0xe854, 0x1d91, 0x3f3f, 0xd03c, 
+0xd290, 0x2d60, 0xe292, 0xd443, 0x4229, 0x0590, 0xe446, 0x3c78, 0x0d2e, 0xbba0, 
+0x0b10, 0x1fdc, 0xccc6, 0x142f, 0x3174, 0xdc18, 0x1061, 0x371b, 0xd368, 0xd200, 
+0x2d59, 0xf1a5, 0xdc23, 0x3edd, 0x0fb6, 0xe812, 0x2f6f, 0x0a77, 0xb941, 0xfe00, 
+0x1d36, 0xcc9c, 0x11f2, 0x404a, 0xe70a, 0x0abc, 0x3965, 0xd3be, 0xbed2, 0x1fe7, 
+0xee09, 0xd03e, 0x3f07, 0x1799, 0xe33b, 0x342f, 0x1443, 0xb44b, 0xf906, 0x1979, 
+0xbeaf, 0x0a9f, 0x45b3, 0xe73c, 0x0a6f, 0x3e78, 0xd655, 0xc03d, 0x2087, 0xeb0b, 
+0xcf7a, 0x4395, 0x1915, 0xe1a6, 0x34d0, 0x134e, 0xac96, 0xeeeb, 0x1aa0, 0xc459, 
+0x0965, 0x4852, 0xe8bd, 0x0151, 0x3569, 0xd16f, 0xb855, 0x1c6f, 0xed54, 0xcabb, 
+0x428e, 0x1dfb, 0xdf3c, 0x323b, 0x15f0, 0xab84, 0xe597, 0x18a2, 0xc34f, 0x0120, 
+0x48dd, 0xedf1, 0x07d1, 0x3f6b, 0xd521, 0xb0ac, 0x1903, 0xf0c7, 0xc122, 0x3959, 
+0x22ad, 0xe010, 0x2ec7, 0x1837, 0xaaf6, 0xe170, 0x1e2b, 0xc7b9, 0xfdb5, 0x4c53, 
+0xebef, 0xfb34, 0x3ee4, 0xdef9, 0xb297, 0x1b34, 0xfd76, 0xc42a, 0x391e, 0x2b29, 
+0xde3f, 0x2dc8, 0x2491, 0xb2a5, 0xe544, 0x2b06, 0xcad8, 0xf507, 0x54ba, 0xf673, 
+0xfa92, 0x48ca, 0xe9a8, 0xafd3, 0x1ef7, 0x084a, 0xc383, 0x3a6e, 0x3354, 0xdbff, 
+0x2c3f, 0x2b2a, 0xb115, 0xe1c4, 0x348d, 0xd2d5, 0xf3b1, 0x5801, 0xf84b, 0xf5dc, 
+0x4897, 0xeba9, 0xac5a, 0x1d11, 0x0bb4, 0xbcd7, 0x32ed, 0x3809, 0xdc0a, 0x2aa8, 
+0x3035, 0xb63c, 0xddf9, 0x3359, 0xe1e6, 0xdc8c, 0x1666, 0xf007, 0x2428, 0x5dbe, 
+0x00c2, 0xd781, 0x22f0, 0xf405, 0xa1af, 0xed74, 0xf64b, 0xd808, 0x304e, 0x5c2f, 
+0x2e87, 0x2aaf, 0x32b5, 0xdc5e, 0xbf90, 0xd852, 0xad5b, 0xdde3, 0x38e2, 0x1923, 
+0x04d1, 0x62c4, 0x5bb8, 0xe529, 0xeaaf, 0xfd61, 0xc422, 0xc0df, 0xfa6b, 0x0d7b, 
+0x16ff, 0x3f3e, 0x1d78, 0x1a46, 0x3b1d, 0xf55f, 0xc829, 0xeeb5, 0x0157, 0xdd55, 
+0xf41a, 0x20b5, 0x1533, 0x2329, 0x1f7c, 0x1523, 0x1e43, 0x1419, 0xdc00, 0xbfc2, 
+0xfbcf, 0xe187, 0xd1ef, 0x2a18, 0x3c8b, 0x1862, 0x2179, 0x4380, 0x06a1, 0xdc67, 
+0xe0e4, 0xb854, 0xda4e, 0xf2b5, 0xe744, 0x1f54, 0x57ea, 0x2932, 0xfa55, 0x3961, 
+0x0fd9, 0xbac6, 0xcdda, 0xd258, 0xcf89, 0xe3ab, 0x0707, 0x1a3e, 0x3967, 0x30cc, 
+0x0264, 0x2d4f, 0x1e6c, 0xcc01, 0xb70b, 0xd1c4, 0xdac0, 0xca7b, 0xfba8, 0x26c2, 
+0x371b, 0x359b, 0x23c6, 0x2fb4, 0x0da1, 0xd9bd, 0xae9d, 0xb89c, 0xdb61, 0xcb90, 
+0x0132, 0x482d, 0x42cd, 0x1e49, 0x2e1f, 0x3691, 0xe7fa, 0xc93c, 0xba66, 0xbb0a, 
+0xe251, 0xe472, 0x0383, 0x3f08, 0x4cc8, 0x1215, 0x1c80, 0x3b71, 0xe4f3, 0xc431, 
+0xcbb0, 0xc403, 0xd2f9, 0xf12b, 0x1313, 0x2f50, 0x4774, 0x1313, 0x18c4, 0x4058, 
+0xed5d, 0xb643, 0xc25a, 0xd92a, 0xcdc3, 0xe267, 0x25f0, 0x37bf, 0x38e3, 0x1db0, 
+0x2909, 0x2dab, 0xe635, 0xb3fb, 0xb52f, 0xe71a, 0xdad1, 0xdbe5, 0x2dd4, 0x4a45, 
+0x2f11, 0x15fc, 0x375b, 0x1edc, 0xd95e, 0xc7dd, 0xb91d, 0xdb9a, 0xe8d2, 0xea7d, 
+0x243c, 0x50aa, 0x347a, 0x0b10, 0x3f2c, 0x24ae, 0xc984, 0xc48d, 0xccec, 0xd726, 
+0xda77, 0xf845, 0x2782, 0x491b, 0x3bb7, 0x1233, 0x3698, 0x200c, 0xcd29, 0xb25f, 
+0xc2ef, 0xdd85, 0xd457, 0xfe96, 0x3830, 0x43f0, 0x2e94, 0x1a60, 0x3369, 0x07e9, 
+0xcb4f, 0xb645, 0xba73, 0xdbb8, 0xdb8f, 0xffae, 0x3a33, 0x48d7, 0x2211, 0x15da, 
+0x362f, 0xfbd5, 0xc39a, 0xb7fb, 0xc2cf, 0xe1cd, 0xe2d2, 0x0604, 0x36c9, 0x495d, 
+0x209d, 0x15d2, 0x37e6, 0xf91a, 0xc431, 0xbe00, 0xccf7, 0xe3be, 0xe90a, 0x14f8, 
+0x3bed, 0x4775, 0x22c5, 0x1a55, 0x2eb8, 0xf7ab, 0xcbee, 0xbb0a, 0xd4b7, 0xea3e, 
+0xe43a, 0x18fd, 0x455e, 0x429e, 0x1d75, 0x27b4, 0x2e04, 0xeadd, 0xca0c, 0xb834, 
+0xcf7e, 0xebe8, 0xec12, 0x1d2b, 0x4ce6, 0x4388, 0x1410, 0x2882, 0x2863, 0xdbfa, 
+0xc201, 0xbc64, 0xd1a8, 0xe40d, 0xf23c, 0x21f6, 0x44ac, 0x3ed5, 0x105b, 0x1f33, 
+0x1ab9, 0xd393, 0xb879, 0xb8a2, 0xd559, 0xdf87, 0xf31b, 0x2555, 0x3b7c, 0x3066, 
+0x0f9b, 0x206c, 0x1043, 0xd352, 0xb6fe, 0xb4ae, 0xdacb, 0xdd79, 0xed28, 0x2944, 
+0x40cc, 0x26e3, 0x1073, 0x2c6d, 0x0a8e, 0xd1fe, 0xbe7c, 0xb79c, 0xdbb0, 0xe28f, 
+0xf1b8, 0x2782, 0x45d6, 0x288a, 0x146e, 0x3752, 0x08d7, 0xccea, 0xc003, 0xbd89, 
+0xda98, 0xe4f4, 0x0193, 0x3341, 0x4c65, 0x29eb, 0x1665, 0x385c, 0x0502, 0xcaf3, 
+0xbfdd, 0xc859, 0xe1b4, 0xe85f, 0x0f40, 0x394b, 0x49b1, 0x2907, 0x1adb, 0x324c, 
+0xf922, 0xc6e9, 0xb961, 0xcbdd, 0xe7b2, 0xe6bd, 0x11f6, 0x3fef, 0x46fb, 0x1df6, 
+0x1d0f, 0x2f40, 0xeef5, 0xc4a6, 0xb575, 0xcb9f, 0xe637, 0xea22, 0x1afc, 0x450f, 
+0x486c, 0x1ca2, 0x2081, 0x27c1, 0xe170, 0xbe81, 0xb610, 0xd4bd, 0xe951, 0xed82, 
+0x22d8, 0x4920, 0x44fd, 0x1967, 0x24be, 0x230d, 0xdd5b, 0xbd48, 0xb2b2, 0xd74f, 
+0xebd6, 0xf51e, 0x2d0e, 0x4f15, 0x406d, 0x18ea, 0x2d32, 0x1b37, 0xd68b, 0xc044, 
+0xb935, 0xdd2b, 0xe8ca, 0xf474, 0x309b, 0x54b6, 0x3c42, 0x14ba, 0x347b, 0x1910, 
+0xd0a8, 0xbcba, 0xb8c9, 0xdc46, 0xe9fe, 0xfff4, 0x3532, 0x5389, 0x3988, 0x14af, 
+0x3504, 0x102d, 0xc848, 0xb929, 0xbe6f, 0xdd0e, 0xe430, 0x059c, 0x3ba7, 0x4f58, 
+0x2e33, 0x10f0, 0x2a2f, 0xfdb9, 0xc2f6, 0xafbb, 0xbb99, 0xe4f6, 0xe5f2, 0x07f0, 
+0x3ce6, 0x4606, 0x2206, 0x1803, 0x2b80, 0xee52, 0xc24f, 0xb46d, 0xbb4a, 0xe32e, 
+0xe633, 0x0953, 0x4238, 0x4b00, 0x1a28, 0x1723, 0x280d, 0xe191, 0xbf29, 0xb512, 
+0xbb95, 0xe083, 0xee77, 0x11e1, 0x3d02, 0x4905, 0x18fb, 0x175c, 0x25d3, 0xdaba, 
+0xb4bd, 0xb51c, 0xcc2b, 0xe1c5, 0xed1f, 0x1d15, 0x42ae, 0x42e0, 0x12aa, 0x15c7, 
+0x1ce6, 0xdd86, 0xbb2e, 0xb339, 0xd4c6, 0xe6a3, 0xee5c, 0x246d, 0x4599, 0x378a, 
+0x117f, 0x247f, 0x1587, 0xd40f, 0xc211, 0xba12, 0xda04, 0xe9d2, 0xf097, 0x2593, 
+0x4a0d, 0x33f2, 0x0e58, 0x2f92, 0x1796, 0xd23e, 0xc5d1, 0xbd1d, 0xd6a8, 0xea03, 
+0xfd4b, 0x2b76, 0x4d07, 0x372b, 0x12c1, 0x3610, 0x1455, 0xc9fa, 0xc082, 0xc65f, 
+0xdbf3, 0xe5fa, 0x0864, 0x3695, 0x4d6d, 0x3441, 0x13be, 0x2f2f, 0x090c, 0xce34, 
+0xb830, 0xc505, 0xfada, 0xec81, 0xfb68, 0x2eba, 0x319e, 0x3ce2, 0x44fb, 0x1d01, 
+0xdd9d, 0xd66a, 0xb232, 0xa016, 0xf64b, 0xfff6, 0x09d5, 0x7376, 0x8570, 0x20f6, 
+0xfe82, 0xf200, 0x9a52, 0xa325, 0xc4f5, 0xcbde, 0x2c79, 0x67bb, 0x4c8f, 0x46a8, 
+0x523c, 0xf79d, 0xabd0, 0xda12, 0xcc15, 0xb71c, 0xf62d, 0x1e60, 0x327a, 0x4b18, 
+0x2770, 0xf598, 0x157f, 0x094e, 0xbe89, 0xebf7, 0x2a77, 0xf098, 0xe9ee, 0x28e2, 
+0xf32a, 0xc056, 0x237c, 0x271d, 0xe4a4, 0x3978, 0x35ba, 0xe536, 0x10f5, 0xfdaa, 
+0xa68b, 0xd3ea, 0x212f, 0xea07, 0x08a6, 0x5e96, 0x0ae2, 0x07c6, 0x37b6, 0xd70c, 
+0xb092, 0xfe7d, 0xf21a, 0xcad9, 0x34d2, 0x36e9, 0xf083, 0x37da, 0x22a5, 0xbc01, 
+0xdc00, 0x1395, 0xd553, 0xe5e3, 0x3bac, 0xfd08, 0xfe92, 0x3f5c, 0xee23, 0xbc45, 
+0x0d39, 0x0a9c, 0xc61a, 0x146f, 0x2951, 0xdb39, 0x171e, 0x293d, 0xc2e7, 0xdd20, 
+0x32b9, 0xe330, 0xd7b9, 0x3cc5, 0xf7d9, 0xdcad, 0x311b, 0xf1df, 0xb0b8, 0x105b, 
+0x1a8c, 0xca51, 0x1be5, 0x2f80, 0xd616, 0x11ca, 0x2652, 0xbc4e, 0xcb96, 0x21a7, 
+0xe4b4, 0xe253, 0x4487, 0x0196, 0xe674, 0x3516, 0xfb04, 0xb3bc, 0xfeb8, 0x1079, 
+0xc24e, 0x088e, 0x3298, 0xe80b, 0x14c1, 0x2ed3, 0xd1a8, 0xcf82, 0x2207, 0xee50, 
+0xcf02, 0x2dec, 0x08af, 0xe42a, 0x344d, 0x0fb2, 0xb971, 0xfa3f, 0x1df7, 0xd32e, 
+0x11cc, 0x3722, 0xda30, 0x07ac, 0x3d3f, 0xd7ab, 0xc34d, 0x271b, 0xfe76, 0xdbb3, 
+0x3d61, 0x18ed, 0xed9b, 0x3389, 0x0c14, 0xba7c, 0xf987, 0x187e, 0xcd50, 0x1066, 
+0x476b, 0xf480, 0x1314, 0x42bb, 0xe5fe, 0xc3be, 0x1389, 0xf39f, 0xd575, 0x3648, 
+0x1e47, 0xf2fa, 0x3e74, 0x234a, 0xbf4c, 0xf288, 0x221b, 0xc710, 0xfa3c, 0x5035, 
+0xfb9e, 0x0502, 0x44eb, 0xeee6, 0xc43e, 0x1d61, 0xfb1c, 0xc9de, 0x3c74, 0x2aae, 
+0xe190, 0x3674, 0x2619, 0xaff2, 0xe8b6, 0x2937, 0xc78c, 0xf5df, 0x540b, 0xfb05, 
+0x020b, 0x434b, 0xe0e6, 0xacc1, 0x10fc, 0xf91d, 0xbcee, 0x3592, 0x3566, 0xe36e, 
+0x337d, 0x30bf, 0xb32f, 0xd426, 0x2162, 0xc820, 0xe042, 0x4c56, 0xfe46, 0xf61f, 
+0x4a89, 0xf803, 0xad4d, 0x11a6, 0x0a6c, 0xb6d1, 0x253a, 0x3311, 0xd5a0, 0x2667, 
+0x3498, 0xb800, 0xd872, 0x2f83, 0xd41e, 0xe4e1, 0x5463, 0xf738, 0xea30, 0x492c, 
+0xf007, 0xaab2, 0x16ec, 0x11da, 0xc262, 0x2e37, 0x3e3b, 0xdd03, 0x22dd, 0x30e8, 
+0xb674, 0xd170, 0x2e2c, 0xdcd6, 0xe399, 0x56b9, 0x04f1, 0xea52, 0x4a44, 0xfd31, 
+0xa60d, 0x09bf, 0x162d, 0xbcc9, 0x1f55, 0x4352, 0xde68, 0x1cd9, 0x3c0d, 0xbf98, 
+0xc8d8, 0x2a1f, 0xdc64, 0xd503, 0x4d6c, 0x0785, 0xe7a8, 0x476e, 0xff01, 0xa5cd, 
+0x064f, 0x17bf, 0xbe55, 0x1800, 0x3b7b, 0xd4d9, 0x10f0, 0x3690, 0xbf8d, 0xc71e, 
+0x297a, 0xe393, 0xd729, 0x47fe, 0x0285, 0xda51, 0x391b, 0xfeb3, 0xa48e, 0xfbc3, 
+0x19a9, 0xc3a0, 0x108e, 0x3eae, 0xdebc, 0x0f12, 0x36a2, 0xc4c0, 0xbf91, 0x1e2f, 
+0xe5de, 0xd395, 0x4354, 0x10d5, 0xe319, 0x39c0, 0x0a87, 0xace4, 0xf7d2, 0x18b7, 
+0xc582, 0x0b6f, 0x3da5, 0xe290, 0x0dde, 0x3c3e, 0xcfe6, 0xc55b, 0x253d, 0xeca1, 
+0xcf94, 0x3b7a, 0x0f41, 0xdf74, 0x366b, 0x1370, 0xb644, 0xfb14, 0x1f1e, 0xc7c9, 
+0x07b4, 0x41e9, 0xe70d, 0x071d, 0x3d77, 0xdb66, 0xc478, 0x265f, 0xf916, 0xd180, 
+0x3ee6, 0x1beb, 0xdeb9, 0x31d9, 0x191a, 0xb479, 0xf52c, 0x2801, 0xccf7, 0x03d4, 
+0x4bd7, 0xedac, 0x016a, 0x3a65, 0xd6fc, 0xbe27, 0x2266, 0x07f4, 0xd0c6, 0x0dcf, 
+0x1281, 0x0eb0, 0x45e8, 0x1d9a, 0xd8e3, 0x05c1, 0x084a, 0xb5be, 0xdaec, 0x09a2, 
+0xe1b9, 0x11ee, 0x6086, 0x43d5, 0x17db, 0x2892, 0xfb50, 0xb60e, 0xc9f7, 0xc054, 
+0xc68d, 0x23e0, 0x2ffe, 0x062b, 0x4e99, 0x701f, 0xf80e, 0xd329, 0xff2c, 0xcb90, 
+0xa2d6, 0xed8c, 0x1910, 0x0699, 0x2f80, 0x3089, 0x1d1c, 0x374f, 0x03b2, 0xc14c, 
+0xd8b6, 0xfb3d, 0xd617, 0xe1a7, 0x22a2, 0x2021, 0x1a55, 0x1dcb, 0x2025, 0x150c, 
+0x0753, 0xe11c, 0xb5ad, 0xeb4f, 0xe450, 0xcc01, 0x1b1d, 0x3faa, 0x18aa, 0x0e6d, 
+0x4970, 0x17e5, 0xcba3, 0xd80b, 0xbb23, 0xc5d9, 0xe755, 0xf01c, 0x158e, 0x5028, 
+0x3e7d, 0xfcdb, 0x3482, 0x21eb, 0xbae5, 0xbfbe, 0xd2fb, 0xcfc4, 0xd821, 0x0aca, 
+0x27bb, 0x3924, 0x3d1e, 0x0e86, 0x271a, 0x205b, 0xd16c, 0xaf53, 0xc9df, 0xe377, 
+0xce6f, 0xfa21, 0x34f1, 0x4083, 0x3410, 0x259d, 0x319d, 0x06b6, 0xd9dc, 0xb750, 
+0xb2df, 0xde42, 0xd8e4, 0xfe96, 0x4970, 0x54f6, 0x25ba, 0x2520, 0x3c2e, 0xedea, 
+0xc061, 0xba0d, 0xba48, 0xde9c, 0xeb84, 0x0af2, 0x401e, 0x56b2, 0x1aa5, 0x0f66, 
+0x36cf, 0xe844, 0xb80e, 0xc1dd, 0xc246, 0xcece, 0xe9fe, 0x177a, 0x32d2, 0x4547, 
+0x1818, 0x0c52, 0x30b6, 0xec12, 0xaf1a, 0xb2f2, 0xcfa8, 0xd2b1, 0xdf9e, 0x2116, 
+0x3ab2, 0x35ab, 0x1b48, 0x247c, 0x25e1, 0xdedd, 0xb1e5, 0xaf2b, 0xdb4a, 0xe17b, 
+0xdfc7, 0x27da, 0x4f71, 0x34be, 0x0ed1, 0x2d58, 0x1ef5, 0xd091, 0xc1bb, 0xbe47, 
+0xd524, 0xeaee, 0xf469, 0x2112, 0x4cf4, 0x3d3e, 0x0aff, 0x304c, 0x281a, 0xcdc7, 
+0xbbed, 0xd088, 0xe04a, 0xdeea, 0xfee9, 0x2f94, 0x47fc, 0x3dff, 0x1a27, 0x31e9, 
+0x1deb, 0xd894, 0xbec6, 0xc6e8, 0xe5fc, 0xe340, 0x014d, 0x3cd1, 0x4e2f, 0x32bd, 
+0x1d0c, 0x372e, 0x0af1, 0xce88, 0xc502, 0xc97d, 0xe495, 0xeb9c, 0x0798, 0x374a, 
+0x4e4d, 0x2a7e, 0x16b3, 0x3ddd, 0x08ed, 0xc949, 0xc5ee, 0xce08, 0xdf28, 0xe8b7, 
+0x0fe9, 0x3689, 0x490a, 0x2817, 0x1714, 0x38c1, 0x0109, 0xc527, 0xc1af, 0xd087, 
+0xdced, 0xe41e, 0x12dc, 0x3476, 0x3cd2, 0x201b, 0x1cbb, 0x2e40, 0xf269, 0xc5fe, 
+0xb844, 0xcaac, 0xdf7f, 0xe02f, 0x0f09, 0x373a, 0x383b, 0x13eb, 0x21ef, 0x2cbc, 
+0xe41a, 0xc568, 0xb82e, 0xc319, 0xdca2, 0xe63b, 0x0f93, 0x3ca2, 0x4202, 0x11af, 
+0x2392, 0x2ac6, 0xd906, 0xb7d3, 0xb715, 0xce35, 0xdb89, 0xef49, 0x2213, 0x3ff6, 
+0x3f4b, 0x14d9, 0x2398, 0x1f27, 0xd7ab, 0xb866, 0xb50a, 0xd74b, 0xe11e, 0xf58b, 
+0x2ece, 0x467f, 0x3963, 0x1933, 0x2caa, 0x1426, 0xd5d8, 0xbe81, 0xb620, 0xdf76, 
+0xe789, 0xf65e, 0x349f, 0x505c, 0x3366, 0x16ea, 0x3646, 0x0f5a, 0xd18a, 0xc1b2, 
+0xb7f7, 0xdd2a, 0xeb2f, 0xfd79, 0x30f5, 0x516e, 0x31d6, 0x12af, 0x388a, 0x0be7, 
+0xca82, 0xbdf0, 0xbc89, 0xda3c, 0xe687, 0x06e8, 0x3695, 0x5204, 0x3323, 0x158c, 
+0x3447, 0x05f1, 0xca02, 0xb88d, 0xc1cf, 0xe381, 0xea5c, 0x110d, 0x40c6, 0x4e27, 
+0x2a69, 0x1e8c, 0x30b5, 0xf349, 0xc5eb, 0xb6f0, 0xc440, 0xe7cd, 0xebf2, 0x1281, 
+0x4308, 0x4ce7, 0x1f25, 0x1bf5, 0x2d5c, 0xe897, 0xc291, 0xb85f, 0xc6be, 0xe556, 
+0xf257, 0x1cc0, 0x442d, 0x4d14, 0x200a, 0x1f36, 0x26a6, 0xdf96, 0xbef2, 0xb898, 
+0xd0e1, 0xe9a1, 0xf513, 0x2536, 0x486a, 0x4666, 0x1bd4, 0x216e, 0x1a61, 0xd966, 
+0xbfd6, 0xb46f, 0xd414, 0xeb0f, 0xf5c1, 0x2917, 0x4b03, 0x3b01, 0x120a, 0x279d, 
+0x127b, 0xce60, 0xc0b2, 0xbaa1, 0xd93a, 0xea16, 0xf79d, 0x29e1, 0x4e28, 0x3952, 
+0x0c9b, 0x2918, 0x0da3, 0xc8e3, 0xbf5d, 0xbd5b, 0xd7be, 0xe6b5, 0xff78, 0x2bfe, 
+0x474e, 0x30ea, 0x0afb, 0x2996, 0x09da, 0xc618, 0xb66b, 0xc002, 0xde8f, 0xe009, 
+0x0068, 0x34b1, 0x479e, 0x290d, 0x1057, 0x2cf4, 0x0037, 0xc901, 0xba19, 0xc161, 
+0xe4c1, 0xe626, 0x06b7, 0x3bce, 0x46e6, 0x1fc6, 0x1c43, 0x37dd, 0xf4a3, 0xc6e9, 
+0xc0da, 0xc57a, 0xe45d, 0xe96e, 0x0b68, 0x3e09, 0x4c53, 0x1c9e, 0x1978, 0x350c, 
+0xec82, 0xc2fd, 0xc069, 0xc683, 0xdf64, 0xee42, 0x1619, 0x39da, 0x4685, 0x1dc8, 
+0x1c78, 0x2de4, 0xe52f, 0xbb56, 0xb88c, 0xd10f, 0xe424, 0xed39, 0x226e, 0x45c9, 
+0x4373, 0x1798, 0x1d16, 0x2213, 0xe050, 0xbf9c, 0xb315, 0xd32f, 0xe7c5, 0xec31, 
+0x23d2, 0x48dd, 0x38f4, 0x0de0, 0x25fc, 0x1996, 0xcef8, 0xbc82, 0xb55a, 0xd59c, 
+0xe89f, 0xefe0, 0x23a4, 0x4993, 0x37a4, 0x0c32, 0x2be5, 0x17d1, 0xcddd, 0xc07a, 
+0xb8e9, 0xd329, 0xe54b, 0xfb4e, 0x2cfc, 0x4d3a, 0x3bad, 0x0fee, 0x2b2b, 0x1047, 
+0xc712, 0xb4f7, 0xbbf0, 0xdc5f, 0xe2f3, 0xfef6, 0x224e, 0x4c36, 0x6c76, 0x2b5c, 
+0xfa57, 0xe594, 0xbdb1, 0x8b0a, 0xa7ca, 0x0160, 0x0786, 0x400c, 0x8424, 0x5796, 
+0x1be9, 0xf540, 0xbdf9, 0x9768, 0xc4df, 0xbd3d, 0xdd3d, 0x63d3, 0x4e65, 0x1fea, 
+0x4e57, 0x38bb, 0xd91b, 0xcd56, 0xe3ad, 0xbffd, 0xfbd6, 0x0607, 0xdb8e, 0x3ccb, 
+0x4192, 0xd6b0, 0xf73b, 0x42bf, 0xeff1, 0xe330, 0x3dbd, 0xfa84, 0xdccf, 0x13df, 
+0xde74, 0xb718, 0x0b45, 0x28d2, 0xfb25, 0x3fa0, 0x4276, 0xedb2, 0x1335, 0x0954, 
+0xadc9, 0xc6fc, 0x1522, 0xf53c, 0xfe45, 0x4b87, 0x18e7, 0x04a7, 0x3412, 0xee3f, 
+0xb321, 0xfd48, 0x04c9, 0xc508, 0x15a8, 0x372c, 0xeb2f, 0x165c, 0x2ca0, 0xce55, 
+0xd34d, 0x1c95, 0xe2fd, 0xdd7e, 0x3294, 0xf905, 0xe452, 0x34a4, 0x04d0, 0xbdd7, 
+0x0a01, 0x1d14, 0xce45, 0x0c02, 0x2888, 0xd716, 0x03dc, 0x2b4a, 0xd5cd, 0xd68c, 
+0x2ef2, 0xfc10, 0xda6f, 0x316f, 0x0773, 0xda8e, 0x2215, 0x0507, 0xb6f3, 0xfe70, 
+0x2a5d, 0xd6c8, 0x0b84, 0x4188, 0xe8c4, 0xfdd0, 0x2ec5, 0xd794, 0xc3a2, 0x2279, 
+0xf779, 0xd09d, 0x423d, 0x27fc, 0xe6f8, 0x2f40, 0x1b5a, 0xbc8b, 0xf157, 0x1fb4, 
+0xcaa0, 0xfa3a, 0x4232, 0xf922, 0x0ecb, 0x3f09, 0xe3ee, 0xc318, 0x1cef, 0xfdc1, 
+0xca4c, 0x2a22, 0x20f1, 0xe87d, 0x279c, 0x1afc, 0xbe72, 0xe720, 0x2220, 0xd1d4, 
+0xf6a7, 0x4e3e, 0xf5f4, 0xecca, 0x3b54, 0xf567, 0xb06f, 0x0a45, 0x0b98, 0xc973, 
+0x28f0, 0x2f21, 0xdfeb, 0x24a0, 0x2810, 0xaef4, 0xd207, 0x2ab3, 0xcd51, 0xdc82, 
+0x4ca3, 0xfdde, 0xef82, 0x40ab, 0xf143, 0xac33, 0x082b, 0xfdac, 0xb9b7, 0x28f3, 
+0x2b71, 0xd054, 0x2723, 0x3651, 0xb6cf, 0xd176, 0x2ba8, 0xd75d, 0xdb92, 0x450f, 
+0xfd8f, 0xec9c, 0x3e23, 0xf598, 0xaf02, 0x111a, 0x135a, 0xbd2d, 0x2334, 0x3d0a, 
+0xd3d8, 0x1768, 0x3bb0, 0xbab9, 0xc676, 0x311a, 0xe06f, 0xd889, 0x5018, 0x070b, 
+0xe756, 0x4942, 0xfd09, 0x9d71, 0x0bcc, 0x1bed, 0xb4ce, 0x1c66, 0x47ec, 0xdc5f, 
+0x1b74, 0x4238, 0xc481, 0xcf1b, 0x32f5, 0xe1ce, 0xda85, 0x4e4d, 0x0437, 0xe474, 
+0x4777, 0x07ed, 0xaff9, 0x127d, 0x24cd, 0xc370, 0x199d, 0x3e29, 0xd8bf, 0x14fd, 
+0x3d8b, 0xc8ea, 0xd1b6, 0x3766, 0xecd3, 0xda6f, 0x4fa7, 0x0ce7, 0xdddd, 0x4019, 
+0x0c05, 0xaedb, 0x0dbc, 0x2b4c, 0xcdd3, 0x1ddc, 0x470d, 0xe283, 0x1764, 0x40d4, 
+0xcabb, 0xcd66, 0x3585, 0xf1c2, 0xdda9, 0x4ffb, 0x11e4, 0xe28a, 0x415d, 0x12d2, 
+0xb486, 0x055e, 0x1fd4, 0xc66e, 0x12ca, 0x417e, 0xe4e2, 0x1229, 0x3e2a, 0xd10c, 
+0xc800, 0x29e0, 0xed4e, 0xd10c, 0x3fcc, 0x11a3, 0xe1f9, 0x3ad7, 0x16ca, 0xb727, 
+0x0155, 0x2400, 0xc8c6, 0x0c22, 0x40bf, 0xe1dc, 0x06e9, 0x3e89, 0xd924, 0xc59a, 
+0x27a2, 0xf22c, 0xcfad, 0x3f51, 0x14cd, 0xda51, 0x2f15, 0x1235, 0xae68, 0xedef, 
+0x1983, 0xc602, 0x06d9, 0x46e6, 0xe9de, 0x01cd, 0x3928, 0xd470, 0xb512, 0x15ff, 
+0xec31, 0xc9cd, 0x3f78, 0x243a, 0xe15e, 0x29ed, 0x1245, 0xaba1, 0xe5e9, 0x199e, 
+0xc296, 0xfe39, 0x4ac5, 0xeb5f, 0xfa56, 0x3c11, 0xd94f, 0xae50, 0x1511, 0xf001, 
+0xbde3, 0x36c2, 0x230d, 0xd7fe, 0x2c17, 0x1e3a, 0xaa06, 0xe31f, 0x226e, 0xc144, 
+0xf626, 0x4f4e, 0xeb1e, 0xf4dd, 0x3e8c, 0xdc0a, 0xaf47, 0x1e56, 0xfed8, 0xc48e, 
+0x3d56, 0x2b0f, 0xd682, 0x2918, 0x1dec, 0xa955, 0xe5bb, 0x2b6b, 0xc9b8, 0xfa77, 
+0x56f8, 0xf481, 0xfb61, 0x4479, 0xdf2e, 0xabca, 0x1c70, 0xffe7, 0xbc88, 0x3a59, 
+0x3826, 0xe054, 0x2f4b, 0x2c11, 0xb1dd, 0xe03e, 0x2b29, 0xc998, 0xf18d, 0x59ee, 
+0xf7ac, 0xf73d, 0x4d8e, 0xed67, 0xb1d8, 0x21a9, 0x1848, 0xccda, 0x07a8, 0xffcd, 
+0xfa23, 0x5aea, 0x3797, 0xd62f, 0x0ab0, 0x245e, 0xb225, 0xc27c, 0x09d2, 0xd863, 
+0xfe56, 0x5bb6, 0x4ddb, 0x2aa0, 0x3bda, 0x0b4a, 0xc172, 0xdcc2, 0xc178, 0xb04a, 
+0x211f, 0x3a69, 0xf99a, 0x3316, 0x7dfa, 0x1afe, 0xd954, 0x046d, 0xdf49, 0xb051, 
+0xdb3e, 0x09de, 0x0f9f, 0x347e, 0x2f84, 0x0af2, 0x3895, 0x1ade, 0xc5b6, 0xd468, 
+0xfe63, 0xe6d0, 0xddae, 0x14b5, 0x175e, 0x16c3, 0x1fae, 0x122e, 0x1fcb, 0x16f5, 
+0xef7f, 0xbe99, 0xdd8a, 0xf61b, 0xc6ce, 0x019a, 0x43c3, 0x2909, 0x1168, 0x39ad, 
+0x2f76, 0xde14, 0xddd2, 0xc963, 0xbd2a, 0xea45, 0xea62, 0x0266, 0x4616, 0x4e1c, 
+0x015e, 0x18de, 0x36f6, 0xcf20, 0xb656, 0xd210, 0xd017, 0xd8b3, 0xfb2f, 0x1950, 
+0x2b27, 0x3c69, 0x095e, 0x0ec5, 0x2d9c, 0xe85e, 0xb75b, 0xc4ac, 0xe1a3, 0xcfe0, 
+0xdf2a, 0x1a10, 0x3183, 0x376b, 0x1d4c, 0x237d, 0x185c, 0xe4f3, 0xbf7b, 0xab18, 
+0xcfc2, 0xd346, 0xe11c, 0x2903, 0x45ea, 0x24aa, 0x102b, 0x353d, 0x080f, 0xc677, 
+0xbdeb, 0xb32e, 0xd477, 0xe331, 0xef66, 0x2325, 0x4c5c, 0x27b3, 0xfaf5, 0x3106, 
+0x1252, 0xc709, 0xca81, 0xcbe5, 0xd04d, 0xdd4e, 0xfd3c, 0x1a5f, 0x3c21, 0x2935, 
+0x0252, 0x3750, 0x1e8e, 0xc8e4, 0xb83e, 0xd48f, 0xdc6e, 0xce04, 0x0585, 0x31bc, 
+0x360a, 0x2009, 0x14c2, 0x394e, 0x10a3, 0xc93d, 0xafa5, 0xd6b1, 0xef04, 0xcd94, 
+0x0467, 0x48be, 0x4051, 0x1437, 0x1fb5, 0x3cd3, 0xf79e, 0xcc8f, 0xc153, 0xcd1f, 
+0xeeb7, 0xe37c, 0x03cf, 0x4174, 0x4958, 0x1000, 0x1d3b, 0x4853, 0xf289, 0xbea9, 
+0xc9e2, 0xd4e7, 0xde7b, 0xe633, 0x1461, 0x3e75, 0x4911, 0x1b5a, 0x2106, 0x4059, 
+0xf467, 0xbf92, 0xc1f8, 0xd995, 0xdcf6, 0xe0ba, 0x1eb5, 0x4600, 0x4167, 0x1d25, 
+0x2ef9, 0x3639, 0xe56b, 0xc105, 0xc027, 0xd70a, 0xe1eb, 0xea01, 0x247e, 0x4c66, 
+0x3f10, 0x14c8, 0x3245, 0x3094, 0xdd32, 0xc132, 0xc147, 0xd9a1, 0xe18c, 0xeeb8, 
+0x2824, 0x4a69, 0x395c, 0x1015, 0x3040, 0x238d, 0xd48a, 0xc21b, 0xc53b, 0xdc6d, 
+0xe1ce, 0xf6ef, 0x2ad6, 0x46b7, 0x34da, 0x1114, 0x34eb, 0x1e8c, 0xd361, 0xbe8c, 
+0xc1c6, 0xe012, 0xdf71, 0xf81f, 0x3359, 0x4a06, 0x2d71, 0x1454, 0x38da, 0x0f58, 
+0xccf4, 0xbea1, 0xbbb5, 0xdb25, 0xe2c4, 0xfd77, 0x3627, 0x5121, 0x2c35, 0x15a0, 
+0x3989, 0x0018, 0xc03f, 0xbaf5, 0xc3cd, 0xe02b, 0xe6c9, 0x0e3d, 0x3eb5, 0x4d58, 
+0x26cb, 0x1318, 0x2fe0, 0xf891, 0xc27d, 0xb828, 0xc71e, 0xe21d, 0xe699, 0x15c5, 
+0x4058, 0x45ef, 0x2262, 0x1985, 0x28bc, 0xeca7, 0xc32c, 0xb7e4, 0xcfc1, 0xea07, 
+0xe4ac, 0x173a, 0x461c, 0x3eba, 0x15fa, 0x2087, 0x2703, 0xe29a, 0xc4b3, 0xb600, 
+0xc8f7, 0xe687, 0xe9ba, 0x15c4, 0x426b, 0x3e74, 0x0edd, 0x1f75, 0x23b8, 0xd925, 
+0xc0ab, 0xba1f, 0xcb2d, 0xe095, 0xeca2, 0x1990, 0x40e5, 0x3c5d, 0x1023, 0x24d2, 
+0x1ebd, 0xd280, 0xbab7, 0xba30, 0xd226, 0xe0d0, 0xf39a, 0x22d6, 0x4063, 0x34fc, 
+0x0f3b, 0x2825, 0x190f, 0xd310, 0xbcd9, 0xbd2e, 0xd80b, 0xdd5a, 0xf3ce, 0x2b22, 
+0x4783, 0x32fb, 0x13a4, 0x3361, 0x1484, 0xcf84, 0xc067, 0xc184, 0xdb6a, 0xe3e8, 
+0x0230, 0x3122, 0x4768, 0x320a, 0x16c1, 0x3427, 0x0aed, 0xc9bb, 0xba81, 0xc328, 
+0xe12c, 0xe1e3, 0x07e1, 0x3ec1, 0x4f67, 0x2ddc, 0x15f0, 0x2f32, 0xfe24, 0xc964, 
+0xbbfd, 0xc754, 0xe848, 0xe9ef, 0x1196, 0x41b3, 0x4b5f, 0x2760, 0x1f91, 0x35ce, 
+0xf3d5, 0xc722, 0xbfad, 0xcade, 0xe85a, 0xeaa5, 0x1660, 0x4809, 0x4c60, 0x1f11, 
+0x212f, 0x36b0, 0xefd1, 0xc764, 0xbc28, 0xc837, 0xe455, 0xec50, 0x1c88, 0x4b3c, 
+0x4de3, 0x2041, 0x28c6, 0x32d7, 0xe1ea, 0xbea7, 0xbd29, 0xd1a9, 0xe60c, 0xf02d, 
+0x2433, 0x4c51, 0x4811, 0x1816, 0x23ce, 0x292b, 0xdf35, 0xbcec, 0xb6b3, 0xd50d, 
+0xe49a, 0xee6a, 0x2b0c, 0x4b27, 0x39f9, 0x15f5, 0x29d8, 0x1859, 0xd36e, 0xc04c, 
+0xb5ab, 0xd4b0, 0xe461, 0xec0c, 0x2803, 0x4fb2, 0x371f, 0x0f49, 0x2de8, 0x1063, 
+0xc7dd, 0xbbcc, 0xb195, 0xcdad, 0xe2b5, 0xf6ed, 0x29d0, 0x4ac5, 0x31e4, 0x0aa9, 
+0x2acb, 0x0735, 0xbe72, 0xb39c, 0xb620, 0xd1d9, 0xdc5c, 0xfcdd, 0x307a, 0x46be, 
+0x2c7c, 0x0a2b, 0x22ab, 0xfca8, 0xc0ac, 0xafc4, 0xb815, 0xde74, 0xe13f, 0x0269, 
+0x370e, 0x4107, 0x21c4, 0x13c8, 0x26a3, 0xf061, 0xc3ac, 0xb5ad, 0xbbea, 0xe2b6, 
+0xe314, 0x03cd, 0x3a8a, 0x453e, 0x1c0b, 0x167a, 0x2afd, 0xe8ae, 0xc330, 0xbb1d, 
+0xbd71, 0xdff6, 0xea8c, 0x0cd6, 0x3cc1, 0x4b59, 0x1e08, 0x1762, 0x288a, 0xe327, 
+0xbcf5, 0xbc04, 0xcc41, 0xe3b8, 0xf214, 0x1f63, 0x40b7, 0x4556, 0x1932, 0x14e9, 
+0x22d4, 0xe5af, 0xc176, 0xbaf1, 0xd516, 0xeaa3, 0xed1a, 0x10a5, 0x4490, 0x6d0e, 
+0x387d, 0x06ad, 0xf979, 0xc011, 0x9e3c, 0xad92, 0xe582, 0x1234, 0x4531, 0x6a71, 
+0x4d3b, 0x3443, 0xfe14, 0xbf35, 0xb76f, 0xcbe7, 0xc8b4, 0xe9aa, 0x501f, 0x43d8, 
+0x1d18, 0x4560, 0x2e0d, 0xf4de, 0xea75, 0xe7b7, 0xd73f, 0x0fdc, 0x11cd, 0xd145, 
+0x29c3, 0x44d4, 0xdad6, 0xf4f0, 0x3e51, 0x092e, 0x07b6, 0x43ce, 0xfd5a, 0xf591, 
+0x1f19, 0xc2ea, 0xb2d7, 0x198e, 0x140f, 0xfa53, 0x5e12, 0x4564, 0xf1ae, 0x2e33, 
+0x0b49, 0xa4bb, 0xdaed, 0x1485, 0xdc90, 0x0cbf, 0x4f0d, 0x0854, 0x15b5, 0x3b75, 
+0xe6b5, 0xbe4e, 0x0981, 0xfc23, 0xc6c6, 0x22a2, 0x2984, 0xf1db, 0x27f9, 0x1ab0, 
+0xc60e, 0xe49e, 0x21a8, 0xd681, 0xe953, 0x41f4, 0xf337, 0xeb9d, 0x3560, 0xf514, 
+0xbd12, 0x135a, 0x1144, 0xc99f, 0x21e0, 0x2271, 0xd155, 0x1a35, 0x25a3, 0xbec7, 
+0xdc7d, 0x31ed, 0xe802, 0xe46d, 0x3ef6, 0xfc72, 0xeb7d, 0x2fc5, 0xecf1, 0xb132, 
+0x0d6d, 0x171d, 0xcaf3, 0x20be, 0x36cd, 0xdeff, 0x1430, 0x2c97, 0xc49c, 0xcab8, 
+0x247c, 0xe2b5, 0xd3f1, 0x3d93, 0x0c22, 0xee37, 0x3907, 0x01ea, 0xb32c, 0x07e5, 
+0x153f, 0xb7d0, 0x0a61, 0x333d, 0xdb8a, 0x1138, 0x3892, 0xcfca, 0xccd1, 0x2831, 
+0xeb12, 0xd73f, 0x357e, 0xfe1d, 0xe21b, 0x300a, 0xfded, 0xaf91, 0xffaf, 0x1ba1, 
+0xc5b1, 0x0c52, 0x3c73, 0xe33f, 0xfac8, 0x2338, 0xd7bc, 0xc7f4, 0x0f99, 0xe739, 
+0xd9e0, 0x3980, 0x0e6d, 0xe382, 0x335e, 0x15f9, 0xae82, 0xe698, 0x1c86, 0xca1d, 
+0xf6f1, 0x34d2, 0xf14d, 0x0fec, 0x3c9a, 0xdef1, 0xc8df, 0x20f3, 0xea68, 0xc50a, 
+0x33ef, 0x1185, 0xd7d4, 0x2ebc, 0x2178, 0xc1c1, 0xf72b, 0x2354, 0xd2eb, 0x0168, 
+0x30db, 0xe0a6, 0x05a6, 0x3bad, 0xdc09, 0xc45f, 0x276d, 0xfd11, 0xcf0a, 0x363e, 
+0x204b, 0xe4d0, 0x2851, 0x199c, 0xbc3c, 0xe9df, 0x1c38, 0xcf05, 0x03b3, 0x4c0e, 
+0xf6ee, 0x068d, 0x44a0, 0xe3e0, 0xb163, 0x17fa, 0xfdee, 0xc709, 0x37cd, 0x2e63, 
+0xea1c, 0x3531, 0x2ca0, 0xbf9e, 0xeeec, 0x2b06, 0xc5f7, 0xf1c8, 0x5385, 0xfc84, 
+0x0002, 0x49cb, 0xf52b, 0xbfbf, 0x204d, 0x04c6, 0xc649, 0x35e9, 0x30b9, 0xe658, 
+0x31b2, 0x2cb7, 0xb96b, 0xe5a8, 0x2f24, 0xd410, 0xf6ab, 0x5771, 0x04b9, 0xfc36, 
+0x3ec2, 0xecd7, 0xb28a, 0x1904, 0x0954, 0xc24d, 0x3764, 0x3ade, 0xddf2, 0x29ce, 
+0x3445, 0xb4d5, 0xd352, 0x2d79, 0xd037, 0xe09a, 0x535a, 0x01a5, 0xf095, 0x48ef, 
+0xf767, 0xa8aa, 0x11b3, 0x097b, 0xb15c, 0x2a36, 0x3db4, 0xd6cd, 0x24b8, 0x3712, 
+0xb430, 0xcdb4, 0x2b60, 0xd3aa, 0xe09b, 0x53eb, 0xfc4a, 0xea6b, 0x4b2a, 0xf90e, 
+0xa8c8, 0x1124, 0x129b, 0xbaac, 0x269d, 0x4030, 0xda96, 0x20e1, 0x3a2e, 0xbd1c, 
+0xd0d8, 0x3158, 0xdd88, 0xdee5, 0x57dc, 0x0a22, 0xeb70, 0x4be8, 0x027e, 0xa602, 
+0x0680, 0x1714, 0xbfed, 0x242e, 0x47b1, 0xe011, 0x1d8e, 0x3eca, 0xc029, 0xc616, 
+0x2e06, 0xe28f, 0xd4aa, 0x4f9e, 0x0f06, 0xe649, 0x438d, 0x0564, 0xa6f1, 0x02f6, 
+0x1bd3, 0xc020, 0x18b7, 0x4204, 0xd71b, 0x0fc8, 0x3e52, 0xc2b8, 0xbf78, 0x2bd7, 
+0xe6d3, 0xce7b, 0x47d7, 0x0a5d, 0xd7d4, 0x39c7, 0x074e, 0xa273, 0xfc77, 0x1fef, 
+0xbcf9, 0x0cec, 0x426a, 0xd4f2, 0x044f, 0x3d93, 0xc6ea, 0xbcdf, 0x2bd1, 0xed0b, 
+0xce10, 0x43d0, 0x0ca2, 0xd5d2, 0x35c4, 0x0c15, 0xa646, 0xfa2d, 0x2097, 0xc0dd, 
+0x0c2b, 0x439b, 0xdc9c, 0x059f, 0x3b30, 0xca4a, 0xbbcb, 0x2337, 0xe7a3, 0xc717, 
+0x3dae, 0x1491, 0xdc09, 0x3229, 0x0f3e, 0xac38, 0xf62a, 0x25d7, 0xcda9, 0xe86a, 
+0x0ccd, 0xe87d, 0x2a51, 0x46ee, 0xea42, 0xe40d, 0x22b1, 0xd631, 0xa84b, 0xf868, 
+0xe4f9, 0xdc35, 0x395d, 0x50be, 0x1fd6, 0x25ac, 0x1e57, 0xc641, 0xc358, 0xd0f2, 
+0xac56, 0xf1aa, 0x385d, 0x08e0, 0x0c0c, 0x6c90, 0x3d9a, 0xd534, 0xf575, 0xf32f, 
+0xb660, 0xc715, 0x00c3, 0x060a, 0x1cc0, 0x3bee, 0x0fef, 0x2648, 0x390e, 0xe520, 
+0xcaa4, 0xfc07, 0xfa8c, 0xcfc3, 0xff3b, 0x2146, 0x0eaa, 0x22f7, 0x21eb, 0x22a5, 
+0x2b3f, 0x140f, 0xd035, 0xce0d, 0x018b, 0xcdfd, 0xe402, 0x4024, 0x35a0, 0x11b4, 
+0x30f7, 0x48c6, 0xfc36, 0xe429, 0xd9e4, 0xb819, 0xe9ae, 0xecf6, 0xeaac, 0x339b, 
+0x5af6, 0x18c2, 0x0a7d, 0x49f9, 0xfaf8, 0xba8d, 0xd5ae, 0xd0dc, 0xd43b, 0xee6d, 
+0x117b, 0x23d1, 0x46ee, 0x29ad, 0x0339, 0x3a96, 0x1314, 0xc110, 0xbad0, 0xd9cf, 
+0xd706, 0xcd74, 0x0d91, 0x315e, 0x3f9c, 0x359b, 0x2190, 0x2aef, 0x0433, 0xcdb2, 
+0xa574, 0xc711, 0xe12e, 0xcf40, 0x197f, 0x5324, 0x3d77, 0x20a5, 0x375c, 0x2d03, 
+0xe262, 0xca54, 0xb0b0, 0xc640, 0xed6e, 0xe3a9, 0x14a7, 0x559a, 0x4789, 0x0af5, 
+0x2c0d, 0x3078, 0xd574, 0xc8f1, 0xc60c, 0xc4a3, 0xddbb, 0xf434, 0x12bf, 0x3a4f, 
+0x46b5, 0x0de9, 0x28f8, 0x3a3e, 0xd862, 0xb36e, 0xc4b9, 0xd290, 0xcc9e, 0xf150, 
+0x28e5, 0x36b7, 0x3727, 0x1942, 0x296a, 0x1f3b, 0xd304, 0xaa50, 0xb7e0, 0xe064, 
+0xcd60, 0xe774, 0x36d2, 0x4354, 0x256f, 0x16b9, 0x32a9, 0x04e9, 0xc94b, 0xbd89, 
+0xb4e8, 0xde63, 0xe6b3, 0xefc2, 0x2c99, 0x4d30, 0x244c, 0x0dd9, 0x4013, 0x0a25, 
+0xbf81, 0xc647, 0xc8d3, 0xd098, 0xddd7, 0x0729, 0x2f46, 0x49fe, 0x3186, 0x11dd, 
+0x33c9, 0x0a1a, 0xc455, 0xb4fe, 0xcbf9, 0xe01f, 0xd9c3, 0x0d63, 0x3ca9, 0x40e4, 
+0x2597, 0x1f85, 0x2fee, 0xf6c7, 0xc763, 0xb733, 0xcbd2, 0xe734, 0xe337, 0x11ef, 
+0x4379, 0x4377, 0x1865, 0x216c, 0x32c8, 0xee0c, 0xca47, 0xc04a, 0xd076, 0xe70b, 
+0xebed, 0x16a9, 0x3f81, 0x44ae, 0x16f6, 0x2266, 0x31f0, 0xe6d6, 0xc30d, 0xc333, 
+0xd87e, 0xe495, 0xf14b, 0x1f91, 0x3ab4, 0x3a37, 0x1822, 0x291b, 0x2bcf, 0xea2c, 
+0xc762, 0xbf57, 0xdd08, 0xe181, 0xec7b, 0x28f2, 0x456d, 0x366d, 0x1d72, 0x3891, 
+0x2266, 0xe229, 0xcd55, 0xbe26, 0xdad8, 0xe6b2, 0xf1ad, 0x2a59, 0x4ce7, 0x346f, 
+0x18da, 0x3eb3, 0x1a5c, 0xd0e6, 0xc45c, 0xbfe1, 0xd4d3, 0xe11f, 0x014a, 0x2f81, 
+0x4863, 0x3408, 0x1268, 0x31f4, 0x0ec8, 0xca3c, 0xb9fc, 0xc1dc, 0xdd52, 0xe093, 
+0x05ff, 0x33c3, 0x43d7, 0x2da7, 0x1671, 0x2bf0, 0x0034, 0xc97d, 0xb0c3, 0xbe5e, 
+0xe43b, 0xdb68, 0x0387, 0x3ae6, 0x3ee7, 0x1b43, 0x174b, 0x2d76, 0xf26e, 0xc68d, 
+0xb289, 0xbb76, 0xe0fe, 0xde57, 0x0305, 0x3b0e, 0x44f7, 0x17e8, 0x1ae0, 0x2e9e, 
+0xe6b9, 0xc23e, 0xb5b3, 0xbe35, 0xde8a, 0xe55c, 0x0e04, 0x3e2d, 0x4749, 0x1891, 
+0x1cce, 0x2c46, 0xe31a, 0xbc10, 0xb2be, 0xc7d4, 0xe1b0, 0xec58, 0x1b5f, 0x42a4, 
+0x4577, 0x18af, 0x206d, 0x2610, 0xe0cf, 0xbee7, 0xb63b, 0xd3ec, 0xe4ab, 0xed6c, 
+0x253f, 0x4a99, 0x42a8, 0x18da, 0x2a90, 0x2130, 0xd967, 0xc013, 0xb623, 0xd3d0, 
+0xe7d4, 0xf7c7, 0x2d1b, 0x4df4, 0x3dfe, 0x18d3, 0x2e94, 0x12e1, 0xceb7, 0xbc8b, 
+0xb721, 0xd9e6, 0xe7b6, 0xfe42, 0x37c7, 0x5256, 0x3916, 0x14fa, 0x2b19, 0x0829, 
+0xcbbc, 0xbc11, 0xba4e, 0xe0c8, 0xec3c, 0x04ba, 0x39d7, 0x4f48, 0x314f, 0x1b2a, 
+0x320f, 0xfbd4, 0xc7ad, 0xbe46, 0xbcb0, 0xdfec, 0xea9d, 0x0a76, 0x3eae, 0x51ce, 
+0x28b8, 0x15c7, 0x32b1, 0xf736, 0xc436, 0xbbe2, 0xc2bd, 0xe357, 0xecf4, 0x10c4, 
+0x40f6, 0x524e, 0x25cd, 0x19ce, 0x301e, 0xec1e, 0xbc6a, 0xbace, 0xd1d8, 0xe825, 
+0xec23, 0x1b1b, 0x4400, 0x482a, 0x1bce, 0x1896, 0x260d, 0xe7f6, 0xc325, 0xb5e4, 
+0xd101, 0xeabf, 0xea0d, 0x1d52, 0x47b3, 0x3cf0, 0x1282, 0x235d, 0x2050, 0xd9ae, 
+0xc4d9, 0xb970, 0xd086, 0xe87d, 0xea86, 0x1b23, 0x48b1, 0x3c02, 0x0e92, 0x2cb2, 
+0x2472, 0xd2cb, 0xbff8, 0xbc43, 0xce22, 0xe2d3, 0xf745, 0x2364, 0x47bb, 0x3e11, 
+0x1209, 0x2f53, 0x1fb0, 0xcfac, 0xba0d, 0xbeea, 0xd8e3, 0xde1c, 0xf854, 0x2f24, 
+0x49ea, 0x387f, 0x14be, 0x2de7, 0x1304, 0xd01b, 0xb948, 0xbc56, 0xe0d1, 0xe484, 
+0xff93, 0x3655, 0x488a, 0x2bf5, 0x16ba, 0x3637, 0x07aa, 0xcf32, 0xc24d, 0xc063, 
+0xe449, 0xe713, 0x01e8, 0x3b25, 0x4f83, 0x26c5, 0x1640, 0x3ab8, 0xff8c, 0xc83c, 
+0xbf7c, 0xc052, 0xdf32, 0xe807, 0x09ef, 0x390f, 0x4d01, 0x25f5, 0x19b1, 0x3685, 
+0xf201, 0xbb2e, 0xb561, 0xc59a, 0xdeac, 0xe81d, 0x110d, 0x2f0d, 0x5faf, 0x5bc4, 
+0x12fe, 0xf615, 0xda50, 0xa9ae, 0x886f, 0xcd18, 0x0718, 0x09f1, 0x5bb7, 0x7af7, 
+0x3e15, 0x0a73, 0xe799, 0xa715, 0x9c71, 0xc971, 0xb0a1, 0x07a7, 0x6f82, 0x3163, 
+0x2a82, 0x5398, 0x14c9, 0xbfc2, 0xd8b3, 0xd540, 0xc5ce, 0x0fda, 0xf099, 0xf1a7, 
+0x518e, 0x1c60, 0xcd84, 0x19da, 0x35b8, 0xd346, 0x03a1, 0x377b, 0xdf14, 0xefc5, 
+0x0c59, 0xc206, 0xc448, 0x2196, 0x11ee, 0xfe70, 0x4f48, 0x1fa8, 0xeb2d, 0x1d5b, 
+0xeaf2, 0x9f51, 0xdaef, 0x10e0, 0xe2b8, 0x140e, 0x4a7c, 0x0548, 0x11c6, 0x2b5c, 
+0xd063, 0xb9e9, 0x0c49, 0xee9f, 0xcd6b, 0x32da, 0x2204, 0xe702, 0x2c36, 0x195d, 
+0xbc4d, 0xef56, 0x1ea6, 0xd1a8, 0xfb24, 0x33f8, 0xe2fa, 0xffb5, 0x3ccd, 0xe4cb, 
+0xca25, 0x2563, 0x0355, 0xd2da, 0x2bb0, 0x137a, 0xd6ec, 0x2218, 0x1b95, 0xc3b7, 
+0xf854, 0x3722, 0xe6e8, 0xf671, 0x3596, 0xec18, 0xf030, 0x2d9c, 0xe6e7, 0xc2e9, 
+0x26d5, 0x1a49, 0xd733, 0x2bbd, 0x26a1, 0xdab2, 0x1ba0, 0x23f0, 0xc355, 0xe703, 
+0x2bce, 0xdc49, 0xf190, 0x496d, 0xfc6e, 0xf386, 0x3dfc, 0xf7e9, 0xbcff, 0x1444, 
+0x0996, 0xc579, 0x1fc6, 0x2a9c, 0xe722, 0x261f, 0x2af6, 0xc74c, 0xe3b8, 0x2a8b, 
+0xe105, 0xe8c4, 0x3bef, 0xfd9f, 0xefc2, 0x313f, 0xf888, 0xbeed, 0x0f0d, 0x10ba, 
+0xcf13, 0x2814, 0x3a0d, 0xdf51, 0x0dca, 0x2f8f, 0xccfa, 0xc831, 0x1d1f, 0xe940, 
+0xe8cf, 0x4a93, 0x0d52, 0xef83, 0x3c76, 0xfaba, 0xa5dd, 0x0126, 0x112f, 0xbdc7, 
+0x1a61, 0x422a, 0xe9fb, 0x1b1a, 0x3694, 0xc9c9, 0xce2b, 0x1ef2, 0xd732, 0xdc7b, 
+0x46da, 0xff7f, 0xe9fc, 0x46e1, 0x05ac, 0xaeb6, 0x0663, 0x159d, 0xc012, 0x1316, 
+0x34ba, 0xdd94, 0x12fd, 0x31f6, 0xc596, 0xcbff, 0x2ae2, 0xe4d5, 0xd6c1, 0x4927, 
+0x0b3d, 0xdd77, 0x3926, 0x07d1, 0xa2d2, 0xfb2e, 0x211d, 0xc317, 0x1769, 0x4b14, 
+0xe280, 0x1326, 0x411c, 0xc1e2, 0xbac5, 0x2cf6, 0xe603, 0xcb4b, 0x4ed8, 0x191b, 
+0xe401, 0x458d, 0x1545, 0xac87, 0x005f, 0x1e4a, 0xba9b, 0x0cc0, 0x467e, 0xe1cf, 
+0x11da, 0x478e, 0xd350, 0xc70d, 0x31c1, 0xf201, 0xce1e, 0x434c, 0x12d6, 0xdd0b, 
+0x3986, 0x1337, 0xaf6d, 0x006c, 0x2ca7, 0xc8ff, 0x0c23, 0x4bde, 0xe11d, 0x0318, 
+0x41ef, 0xd0e5, 0xbd29, 0x3042, 0xf8a0, 0xd014, 0x4ad2, 0x1b53, 0xda3d, 0x3aa3, 
+0x14be, 0xa4bb, 0xf7a1, 0x2b27, 0xc43a, 0x0948, 0x507e, 0xe296, 0x0297, 0x45db, 
+0xd510, 0xb990, 0x273a, 0xf430, 0xc750, 0x3f4c, 0x1a85, 0xdb6a, 0x3993, 0x1ab4, 
+0xadf3, 0xf5f6, 0x280d, 0xc5fc, 0xfe8a, 0x4668, 0xe58d, 0x011c, 0x457a, 0xdfc7, 
+0xbebe, 0x255e, 0xfae1, 0xcb02, 0x3a3a, 0x1b49, 0xd635, 0x2c90, 0x1a6d, 0xb0f1, 
+0xf0b7, 0x2851, 0xcb11, 0xfd3b, 0x4815, 0xe902, 0xf73a, 0x3af3, 0xde3a, 0xb633, 
+0x1a27, 0xfae7, 0xc8e7, 0x3373, 0x1efa, 0xdab3, 0x2af8, 0x1f54, 0xb3a4, 0xe5bd, 
+0x2010, 0xc657, 0xef33, 0x4332, 0xf32a, 0xf8bc, 0x3a43, 0xe716, 0xb380, 0x1025, 
+0xf94b, 0xbff8, 0x2cbe, 0x2722, 0xd958, 0x2238, 0x24de, 0xb4e0, 0xd8e0, 0x219f, 
+0xcbf4, 0xec3e, 0x4cc4, 0xf5db, 0xee65, 0x3cb1, 0xe88f, 0xad6b, 0x15fb, 0x0312, 
+0xbe65, 0x3207, 0x3441, 0xd731, 0x1ee6, 0x2923, 0xb321, 0xd7af, 0x26e1, 0xce3a, 
+0xeb73, 0x52d6, 0xfb3a, 0xed11, 0x3fa2, 0xeb93, 0xa537, 0x0fde, 0x078b, 0xbcc7, 
+0x2dd2, 0x39bf, 0xde73, 0x2216, 0x2ba5, 0xb204, 0xd113, 0x2873, 0xd059, 0xe433, 
+0x5331, 0x00f5, 0xede6, 0x41c9, 0xf3f8, 0xaa8c, 0x0f24, 0x06be, 0xb5e6, 0x29e9, 
+0x39f4, 0xda5d, 0x25b6, 0x2b84, 0xb07f, 0xd942, 0x36fe, 0xe8ec, 0xcdd1, 0x1733, 
+0x0849, 0x1aa1, 0x4558, 0xfb48, 0xd3ef, 0x11bd, 0xef48, 0xb142, 0xf697, 0xfdea, 
+0xd64a, 0x32a6, 0x6fed, 0x25f8, 0x0b17, 0x2a5c, 0xdff3, 0xaef4, 0xd4ec, 0xbcba, 
+0xe25d, 0x44cb, 0x234b, 0x1321, 0x73ba, 0x4da9, 0xced4, 0xe817, 0x007f, 0xa908, 
+0xb5df, 0x1df6, 0x1875, 0x0e2c, 0x3ec1, 0x2fcd, 0x272d, 0x2290, 0xe25c, 0xc07e, 
+0xf134, 0xfb4d, 0xd6f2, 0x0ad3, 0x3447, 0x223c, 0x13f1, 0x2272, 0x269f, 0x025a, 
+0x0161, 0xd722, 0xd224, 0x0308, 0xde38, 0xef78, 0x3c18, 0x42ed, 0x0555, 0x290a, 
+0x5400, 0xe6be, 0xca2d, 0xdae9, 0xc68f, 0xd7d0, 0xf47c, 0x10ed, 0x3184, 0x5941, 
+0x1cf6, 0x0891, 0x3a35, 0xeb6f, 0xae39, 0xc817, 0xe6f7, 0xd6ef, 0xebb0, 0x3372, 
+0x35f1, 0x34dd, 0x1e90, 0x16f7, 0x21a1, 0xf074, 0xc287, 0xb8c4, 0xe82d, 0xe6eb, 
+0xdb90, 0x1e19, 0x40af, 0x3208, 0x1a9a, 0x320f, 0x1b9a, 0xdeff, 0xcf46, 0xb4a3, 
+0xcbd7, 0xdf68, 0xe59a, 0x22fe, 0x55b5, 0x3892, 0x0be2, 0x396b, 0x1a98, 0xc635, 
+0xc146, 0xc092, 0xd361, 0xe7eb, 0x0383, 0x2879, 0x4c6a, 0x3c0d, 0x05ca, 0x2976, 
+0x14a9, 0xc798, 0xc116, 0xd2d8, 0xdd50, 0xdcd3, 0x0b09, 0x2bce, 0x3653, 0x2ab8, 
+0x0a52, 0x2aa9, 0x14b7, 0xd401, 0xb890, 0xcc60, 0xea88, 0xd5e4, 0xfe7d, 0x383b, 
+0x3ade, 0x1b88, 0x1ad7, 0x3ed1, 0x075f, 0xcd9c, 0xbbc4, 0xcbe8, 0xeb85, 0xd822, 
+0xfbc3, 0x3e44, 0x459b, 0x10ea, 0x17ee, 0x43df, 0xf7f9, 0xc0a0, 0xc419, 0xcf1f, 
+0xdea4, 0xe05f, 0x0678, 0x330f, 0x42d4, 0x111c, 0x0fba, 0x3f57, 0xf9a8, 0xb669, 
+0xbe1b, 0xe146, 0xdd9a, 0xd4be, 0x11a3, 0x389d, 0x37d6, 0x13b2, 0x1c70, 0x3370, 
+0xf10c, 0xc063, 0xb6e6, 0xd48a, 0xdc66, 0xd809, 0x1789, 0x3f92, 0x3566, 0x0e0f, 
+0x231e, 0x2ea3, 0xde28, 0xbb31, 0xba09, 0xcf05, 0xd866, 0xdfc8, 0x18f1, 0x3ecd, 
+0x369b, 0x0a8f, 0x2386, 0x2af2, 0xda2a, 0xb79e, 0xb7d0, 0xd687, 0xde35, 0xe721, 
+0x22ba, 0x4574, 0x3572, 0x0dd3, 0x2e06, 0x263b, 0xd7ab, 0xbfc7, 0xc2f6, 0xdf1b, 
+0xe1c3, 0xf1d5, 0x2cb4, 0x4e1c, 0x37cd, 0x115d, 0x35cd, 0x1fe6, 0xd779, 0xc301, 
+0xc58e, 0xe72d, 0xe5ce, 0xf960, 0x335a, 0x4fb4, 0x357b, 0x1898, 0x426e, 0x1cc2, 
+0xd473, 0xc727, 0xc831, 0xe1fb, 0xe68f, 0x072e, 0x3da1, 0x58d4, 0x39ac, 0x1d25, 
+0x4338, 0x1401, 0xcf2b, 0xbee6, 0xca41, 0xe875, 0xe64f, 0x1316, 0x4982, 0x5236, 
+0x2f67, 0x2085, 0x38b8, 0xfd01, 0xc7c8, 0xba93, 0xc979, 0xebc7, 0xea26, 0x168d, 
+0x477d, 0x4817, 0x212b, 0x1fdd, 0x335a, 0xef3e, 0xc484, 0xb895, 0xc9b8, 0xec42, 
+0xe805, 0x136b, 0x4a61, 0x4971, 0x17b6, 0x1f6a, 0x2f97, 0xe4b1, 0xc086, 0xb999, 
+0xcac9, 0xe5fd, 0xee0c, 0x1807, 0x412f, 0x460f, 0x166d, 0x1f4c, 0x29b3, 0xdc64, 
+0xb965, 0xb861, 0xd211, 0xe147, 0xeb99, 0x2193, 0x450f, 0x3ce4, 0x113e, 0x1f63, 
+0x1c84, 0xd769, 0xb874, 0xb487, 0xd682, 0xe1c9, 0xed74, 0x24b0, 0x43a4, 0x33ba, 
+0x0e1c, 0x2413, 0x10f7, 0xcdd3, 0xb977, 0xb8d7, 0xdbc4, 0xe37c, 0xf175, 0x272e, 
+0x457d, 0x2d0a, 0x07d0, 0x297e, 0x0f41, 0xca51, 0xb9f7, 0xbc9a, 0xdaa7, 0xddfe, 
+0xf766, 0x2c64, 0x4532, 0x2d7b, 0x0dd9, 0x2cf4, 0x0c17, 0xc90f, 0xb4bc, 0xc07f, 
+0xe270, 0xdce1, 0xfc63, 0x371a, 0x4749, 0x2579, 0x1187, 0x2dc1, 0xff1f, 0xc7eb, 
+0xb7f0, 0xc150, 0xe209, 0xe0bb, 0x0562, 0x39a6, 0x419b, 0x18df, 0x11d0, 0x32b0, 
+0xf640, 0xc162, 0xbaa8, 0xc92a, 0xe355, 0xdf42, 0x07ce, 0x3de6, 0x485f, 0x1a8d, 
+0x15e0, 0x345d, 0xf2a7, 0xc2b4, 0xbc48, 0xcb43, 0xe331, 0xe771, 0x171d, 0x41c7, 
+0x46e8, 0x1e6a, 0x1d99, 0x3169, 0xea47, 0xbb34, 0xb612, 0xcfe5, 0xe372, 0xe4f4, 
+0x1dce, 0x4978, 0x4538, 0x1abb, 0x1ff9, 0x2726, 0xe2ee, 0xbf5a, 0xb642, 0xd6a7, 
+0xeb65, 0xe981, 0x26c2, 0x5246, 0x3d0f, 0x142e, 0x2f6c, 0x28fc, 0xda88, 0xc3aa, 
+0xbdbe, 0xd749, 0xeb54, 0xf1e0, 0x25cd, 0x526c, 0x41ba, 0x10bf, 0x2fe6, 0x2449, 
+0xd374, 0xbfc4, 0xbbe2, 0xd283, 0xe25c, 0xf99f, 0x2cef, 0x4ac7, 0x3ddf, 0x17d9, 
+0x3082, 0x1925, 0xce89, 0xb6a1, 0xbc50, 0xe283, 0xe474, 0xfd8d, 0x3bcc, 0x4e96, 
+0x33c3, 0x167a, 0x2e47, 0x0a43, 0xcef1, 0xbc29, 0xba3d, 0xe1a3, 0xe5f7, 0xfe7c, 
+0x39db, 0x4bea, 0x270e, 0x128b, 0x30de, 0xfb59, 0xc505, 0xbdab, 0xbd60, 0xe0c5, 
+0xe64a, 0x0171, 0x35c3, 0x47fc, 0x21b5, 0x11b5, 0x30fa, 0xf4fc, 0xc06e, 0xbaa3, 
+0xbc7a, 0xd83f, 0xe4e1, 0x0b66, 0x373d, 0x497a, 0x2421, 0x109c, 0x26f1, 0xecb6, 
+0xbadf, 0xb11f, 0xc45d, 0xdf59, 0xe4b2, 0x1641, 0x3f59, 0x42bc, 0x1c1c, 0x129c, 
+0x1bee, 0xe133, 0xbe64, 0xb1ad, 0xcc9f, 0xec32, 0xe986, 0x19ae, 0x44e5, 0x3a19, 
+0x0e88, 0x1ade, 0x1f2c, 0xdec4, 0xc3cc, 0xb2ef, 0xdaab, 0xfd08, 0xe6a7, 0x1123, 
+0x3704, 0x3898, 0x3ad4, 0x346f, 0xfe92, 0xd1d3, 0xcc04, 0x9cbd, 0xc135, 0x02eb, 
+0xf63b, 0x365b, 0x8b58, 0x58ad, 0x0415, 0x0488, 0xcf1c, 0x8e64, 0xb611, 0xc2c4, 
+0xeda1, 0x4ea8, 0x63da, 0x49bb, 0x50ec, 0x3618, 0xc859, 0xb818, 0xe010, 0xbc83, 
+0xd14a, 0x1ad8, 0x32a9, 0x4030, 0x4434, 0x0f51, 0xf80f, 0x1895, 0xeaf8, 0xc48d, 
+0x175a, 0x2702, 0xe895, 0x0fd2, 0x2756, 0xcf30, 0xdfad, 0x3a11, 0xfb80, 0xfa5f, 
+0x565f, 0x121d, 0xf290, 0x2352, 0xddf3, 0xa5f4, 0xfe06, 0x187b, 0xde96, 0x3a13, 
+0x5105, 0xf698, 0x255a, 0x212e, 0xb7a3, 0xc5a7, 0x10d7, 0xdeff, 0xe90b, 0x551a, 
+0x1708, 0xfd81, 0x42e8, 0xf9ae, 0xb328, 0xf8c8, 0x0cd4, 0xc910, 0x1398, 0x3cf8, 
+0xe89b, 0x1c9d, 0x36c1, 0xcb0b, 0xcca6, 0x2759, 0xf1e2, 0xd264, 0x3d80, 0x146d, 
+0xe372, 0x36c2, 0x0ab3, 0xb2ef, 0x0a0e, 0x2e96, 0xc7be, 0x0dcf, 0x4ba5, 0xdcd8, 
+0xff1f, 0x391f, 0xcf51, 0xc4c3, 0x314b, 0xfef3, 0xd680, 0x41c6, 0x156e, 0xdd3b, 
+0x2eeb, 0x0886, 0xa9c9, 0xf3a6, 0x247e, 0xc927, 0x069f, 0x4a37, 0xe895, 0x0061, 
+0x378e, 0xd6a1, 0xb348, 0x1688, 0xf810, 0xc498, 0x323f, 0x1fc5, 0xe066, 0x29b3, 
+0x139d, 0xadbb, 0xe71a, 0x2c44, 0xcae3, 0xe8e1, 0x3f89, 0xe822, 0xf034, 0x367a, 
+0xdf30, 0xb32c, 0x1aba, 0x0281, 0xcc1b, 0x36c4, 0x14ca, 0xc6d5, 0x2590, 0x1c08, 
+0xa351, 0xd7ce, 0x2a74, 0xd59f, 0xf3fa, 0x477e, 0xf4e0, 0xf8ff, 0x3121, 0xdc01, 
+0xb775, 0x150c, 0xfcd8, 0xcc0d, 0x38c8, 0x2ece, 0xe423, 0x2849, 0x29b5, 0xc302, 
+0xda74, 0x1f47, 0xdd2f, 0xf247, 0x3ab2, 0xf2d7, 0x006a, 0x4787, 0xf2b8, 0xbc9f, 
+0x1f1c, 0x0ac7, 0xbde9, 0x23df, 0x2b4d, 0xd869, 0x1cf2, 0x2e59, 0xc8ac, 0xe6ca, 
+0x2cef, 0xd907, 0xf197, 0x4b23, 0xf20c, 0xef15, 0x4469, 0xf156, 0xb2a9, 0x1bfd, 
+0x127b, 0xca28, 0x306d, 0x3438, 0xdf08, 0x20cf, 0x27a1, 0xb9c7, 0xd8d7, 0x2741, 
+0xd309, 0xe588, 0x5056, 0x03d5, 0xef96, 0x4207, 0xfd8d, 0xae5f, 0x03b5, 0x0589, 
+0xbd38, 0x23af, 0x3a76, 0xe095, 0x2023, 0x3839, 0xc165, 0xd4ca, 0x2de1, 0xd781, 
+0xe09b, 0x50bd, 0x0340, 0xea0c, 0x4022, 0xf840, 0xad2c, 0x1331, 0x12e3, 0xc260, 
+0x2f2a, 0x3b6c, 0xd12c, 0x18a4, 0x3197, 0xb77c, 0xd13d, 0x2bd2, 0xd972, 0xe616, 
+0x52eb, 0x041e, 0xeb26, 0x3bdc, 0xf119, 0xa2b2, 0x06d5, 0x1049, 0xbd97, 0x289f, 
+0x44ee, 0xdf14, 0x1d7f, 0x34ac, 0xb7bb, 0xc690, 0x278a, 0xda25, 0xdff9, 0x579a, 
+0x080c, 0xe6ec, 0x4374, 0xfcbd, 0xa5be, 0x078c, 0x146b, 0xbb5b, 0x2164, 0x4262, 
+0xdc47, 0x1e50, 0x39f8, 0xbce7, 0xcbb4, 0x2afe, 0xdc45, 0xdb5e, 0x5409, 0x0b3a, 
+0xe53c, 0x4358, 0x02ae, 0xa896, 0x0857, 0x1af8, 0xc23a, 0x2352, 0x496b, 0xdfb5, 
+0x197e, 0x3ce3, 0xbe54, 0xc506, 0x3012, 0xe677, 0xd704, 0x5217, 0x11ee, 0xe2e7, 
+0x3fe4, 0x06fa, 0xa5a3, 0xfdcd, 0x181f, 0xbb44, 0x1747, 0x4a1f, 0xdca9, 0x10d6, 
+0x4291, 0xc4a6, 0xbd25, 0x2a87, 0xe605, 0xcbf6, 0x4b38, 0x15fb, 0xe0ad, 0x3f35, 
+0x0d36, 0xa652, 0x0068, 0x234a, 0xbde1, 0x11e2, 0x4aeb, 0xdbe0, 0x0a9d, 0x4344, 
+0xcb41, 0xbfb5, 0x3005, 0xef5d, 0xcc1b, 0x497b, 0x1516, 0xd825, 0x3b8a, 0x1677, 
+0xabc7, 0xfeb9, 0x2dcb, 0xc484, 0x08d9, 0x4f69, 0xe275, 0x041d, 0x4846, 0xd81a, 
+0xc055, 0x3307, 0xfcca, 0xce29, 0x4a68, 0x20cb, 0xd8f3, 0x379a, 0x1b24, 0xaf02, 
+0xfaf5, 0x36a2, 0xdc0c, 0xf2c4, 0x1be5, 0xefab, 0x3121, 0x54a4, 0xf198, 0xe7b1, 
+0x2ba4, 0xe144, 0xad6e, 0x0105, 0xf0a8, 0xe331, 0x4379, 0x5911, 0x2529, 0x2cc9, 
+0x279d, 0xcce3, 0xc4aa, 0xd6d0, 0xaebe, 0xee7a, 0x3b83, 0x0e08, 0x0c23, 0x6c6b, 
+0x4249, 0xd2d0, 0xee99, 0xf0dc, 0xb1d9, 0xc315, 0x0097, 0x05b2, 0x198e, 0x3a21, 
+0x0a87, 0x19af, 0x3001, 0xda73, 0xbf3b, 0xf320, 0xf1e8, 0xce48, 0xfde9, 0x1c97, 
+0x092a, 0x1c03, 0x1996, 0x174f, 0x1e06, 0x0784, 0xc7d4, 0xc266, 0xf6c0, 0xcc3e, 
+0xdd41, 0x35c9, 0x3070, 0x0e9b, 0x2df6, 0x46cc, 0xf777, 0xdb3b, 0xd86d, 0xb2ad, 
+0xdad5, 0xea97, 0xeb13, 0x2dfd, 0x5bf5, 0x1d45, 0x0c80, 0x4c6b, 0xf9d2, 0xb332, 
+0xd3b1, 0xcca7, 0xc90a, 0xeeb9, 0x1637, 0x2142, 0x4501, 0x2b65, 0x034c, 0x35ee, 
+0x0df0, 0xbcaf, 0xb962, 0xda48, 0xd509, 0xd169, 0x125a, 0x2f7e, 0x3ce9, 0x31e9, 
+0x1f9f, 0x25c3, 0xf9ce, 0xc7fa, 0xa4bc, 0xc4e4, 0xde14, 0xd114, 0x1820, 0x4ec1, 
+0x3955, 0x1716, 0x2ffb, 0x23e1, 0xd401, 0xc118, 0xaea8, 0xc267, 0xe761, 0xe650, 
+0x166b, 0x5317, 0x4508, 0x02ef, 0x256f, 0x2a58, 0xc9bf, 0xbfb1, 0xc690, 0xc4c0, 
+0xdb5a, 0xfc3e, 0x1d56, 0x406f, 0x4672, 0x07f9, 0x258b, 0x3563, 0xd0af, 0xad4b, 
+0xc62c, 0xd7ec, 0xd118, 0xfacb, 0x32c8, 0x3cf8, 0x3893, 0x1827, 0x2a88, 0x2056, 
+0xd2e0, 0xa9a8, 0xbc95, 0xe82d, 0xd209, 0xed42, 0x4049, 0x4bca, 0x27a4, 0x17b5, 
+0x33c7, 0x048c, 0xc896, 0xbbc4, 0xb5e8, 0xde55, 0xe670, 0xf26e, 0x319d, 0x5284, 
+0x20bb, 0x0a37, 0x3f54, 0x0425, 0xb7b6, 0xbeac, 0xc4a7, 0xd10a, 0xdf90, 0x067a, 
+0x32d8, 0x4def, 0x29e9, 0x0de0, 0x33b8, 0x00f9, 0xbb53, 0xb44c, 0xca99, 0xdcb3, 
+0xdf0d, 0x140a, 0x4211, 0x47c0, 0x2741, 0x1ffe, 0x3026, 0xf2ee, 0xc44d, 0xb8c2, 
+0xcbde, 0xe86b, 0xed77, 0x1b4d, 0x47ee, 0x4766, 0x1ae9, 0x2386, 0x33e9, 0xea57, 
+0xc4ae, 0xc182, 0xd3ec, 0xeae1, 0xf2fa, 0x1c99, 0x46ce, 0x4849, 0x16e5, 0x2357, 
+0x2d0d, 0xe171, 0xc2b4, 0xc619, 0xdb43, 0xe861, 0xf96a, 0x2580, 0x41a1, 0x3fcc, 
+0x14f6, 0x245e, 0x2692, 0xe3d9, 0xc4b2, 0xc084, 0xdcfb, 0xe481, 0xf277, 0x26e8, 
+0x4453, 0x3677, 0x1401, 0x2eb5, 0x1c61, 0xda3a, 0xc536, 0xbbc2, 0xd95f, 0xe409, 
+0xf088, 0x24e3, 0x4a50, 0x36ef, 0x1343, 0x3794, 0x1bd7, 0xd0b1, 0xbf04, 0xc0c0, 
+0xd999, 0xe102, 0xfe57, 0x307b, 0x4c60, 0x3446, 0x110b, 0x34af, 0x1719, 0xd246, 
+0xbe92, 0xc661, 0xdf01, 0xde95, 0x04b9, 0x34ae, 0x44b2, 0x2c3e, 0x140f, 0x311d, 
+0x09e5, 0xcd57, 0xb673, 0xc4ea, 0xe8e6, 0xdfae, 0x02f2, 0x3c51, 0x460d, 0x2037, 
+0x160e, 0x33a4, 0xffd5, 0xd044, 0xbb77, 0xbff6, 0xe547, 0xe2d3, 0x02a5, 0x3927, 
+0x483e, 0x1e84, 0x18a8, 0x35a4, 0xf428, 0xc4b4, 0xb810, 0xbe31, 0xdf3f, 0xe3b9, 
+0x070a, 0x3a6e, 0x4a01, 0x1d3d, 0x19b7, 0x312f, 0xe9ed, 0xb9d2, 0xb185, 0xc27d, 
+0xdf74, 0xeaac, 0x163c, 0x40b2, 0x480f, 0x196b, 0x1a68, 0x2946, 0xe387, 0xbd44, 
+0xb687, 0xcdd3, 0xe1c0, 0xe73f, 0x19c6, 0x454e, 0x4471, 0x1517, 0x1f37, 0x2415, 
+0xde12, 0xbc28, 0xb193, 0xce92, 0xe199, 0xeb2a, 0x208d, 0x45c9, 0x3dfd, 0x140f, 
+0x2554, 0x1b8d, 0xd3e4, 0xb631, 0xaeee, 0xd2a0, 0xe032, 0xeefc, 0x2bad, 0x4d46, 
+0x3a27, 0x0f3b, 0x24c9, 0x111e, 0xcdbf, 0xb6b5, 0xb194, 0xd7c9, 0xe60a, 0xf93b, 
+0x2f30, 0x4968, 0x3246, 0x1306, 0x2d46, 0x06e7, 0xc785, 0xba49, 0xb9ab, 0xde3a, 
+0xe629, 0xff26, 0x3a02, 0x5456, 0x30f0, 0x10ea, 0x3149, 0x0578, 0xc92c, 0xbe07, 
+0xc00c, 0xe26f, 0xec57, 0x0aaf, 0x3ec0, 0x560f, 0x2fbd, 0x16da, 0x3543, 0xfe12, 
+0xc441, 0xbe1e, 0xce80, 0xec2a, 0xeeda, 0x1761, 0x467e, 0x531c, 0x2945, 0x16f3, 
+0x30b3, 0xfa85, 0xc82a, 0xb95b, 0xd0b9, 0xf0bf, 0xecf0, 0x1a23, 0x4acc, 0x48e2, 
+0x1c65, 0x1e4d, 0x2902, 0xe8e0, 0xc9c2, 0xbc2f, 0xd2c0, 0xf22e, 0xed1c, 0x1844, 
+0x4b01, 0x4776, 0x146e, 0x2125, 0x2832, 0xde1c, 0xc52b, 0xbd52, 0xcf76, 0xec76, 
+0xf496, 0x1c9f, 0x4726, 0x432c, 0x116f, 0x25e7, 0x2766, 0xd731, 0xbc99, 0xc162, 
+0xd7c6, 0xe12d, 0xf3c2, 0x27ac, 0x489f, 0x3fb7, 0x11f9, 0x23e3, 0x1dd1, 0xd9f9, 
+0xbc81, 0xbc41, 0xe051, 0xe6f9, 0xf6af, 0x2df2, 0x4613, 0x2fe6, 0x12b9, 0x303c, 
+0x120f, 0xd130, 0xc1da, 0xbc62, 0xdb80, 0xe279, 0xf4be, 0x2c52, 0x4660, 0x275e, 
+0x0d1c, 0x3149, 0x075f, 0xc931, 0xbf24, 0xbaf3, 0xd888, 0xe2cc, 0xfb8b, 0x2cb6, 
+0x4a52, 0x29ea, 0x0caa, 0x3097, 0xff78, 0xbdf9, 0xb45b, 0xc1cb, 0xdd4e, 0xe310, 
+0x068a, 0x24f2, 0x54ac, 0x60d2, 0x1650, 0xf4c6, 0xe059, 0xb014, 0x83b1, 0xbc91, 
+0x02f9, 0x0157, 0x4fca, 0x7cb3, 0x41bb, 0x0df7, 0xea9f, 0xace6, 0x957f, 0xc6c1, 
+0xb25c, 0xf25c, 0x6d4a, 0x3c23, 0x2274, 0x5314, 0x2754, 0xc59a, 0xd13d, 0xdf25, 
+0xc110, 0x097d, 0xfee9, 0xe7e9, 0x4a58, 0x3073, 0xd0cf, 0x0834, 0x3f47, 0xde37, 
+0xefad, 0x3de0, 0xef24, 0xe80f, 0x1519, 0xd4ff, 0xbae7, 0x160b, 0x1ed5, 0xf6f3, 
+0x4a32, 0x391f, 0xed02, 0x1a95, 0x0194, 0xa798, 0xcdb4, 0x1870, 0xed7d, 0x0805, 
+0x5609, 0x1649, 0x0c10, 0x37fb, 0xe698, 0xb602, 0x0ab1, 0x02bc, 0xc982, 0x29a0, 
+0x3592, 0xeb4c, 0x26a0, 0x2b39, 0xc51e, 0xe028, 0x25df, 0xdd3d, 0xeb89, 0x3c7d, 
+0xf25b, 0xf2a8, 0x40cd, 0xf67a, 0xbd91, 0x18e1, 0x1367, 0xcbf7, 0x1e2b, 0x2469, 
+0xd608, 0x16f8, 0x2a0b, 0xc927, 0xe2cc, 0x37b1, 0xf346, 0xe694, 0x382d, 0xf93e, 
+0xe10a, 0x2a89, 0xf6d1, 0xba9a, 0x1681, 0x2591, 0xd24e, 0x187c, 0x2fad, 0xd8f6, 
+0x0b46, 0x2ae5, 0xc8c2, 0xd38a, 0x2a7a, 0xe7b1, 0xdcb3, 0x3e95, 0x03d8, 0xe5e1, 
+0x3718, 0x0451, 0xb6fc, 0x05d7, 0x1636, 0xc589, 0x0c0d, 0x2d31, 0xe2a5, 0x145e, 
+0x2ff3, 0xd16c, 0xd748, 0x2961, 0xeee4, 0xd89a, 0x2f77, 0x0413, 0xe432, 0x2a18, 
+0x07e4, 0xbf90, 0xffac, 0x1a5c, 0xce43, 0x0eae, 0x3e2a, 0xe525, 0xfcdf, 0x3412, 
+0xe19f, 0xc0d0, 0x160c, 0xf679, 0xdaf7, 0x3d0f, 0x184f, 0xe643, 0x3314, 0x0d97, 
+0xa9d1, 0xf210, 0x1e09, 0xc374, 0x0591, 0x4995, 0xef24, 0x05bf, 0x3aa6, 0xdaf6, 
+0xc1a1, 0x198b, 0xe5e1, 0xce1f, 0x40dc, 0x134c, 0xddc5, 0x3b68, 0x1d73, 0xb2c0, 
+0xf385, 0x2228, 0xc6a9, 0xff0d, 0x4056, 0xea16, 0x071a, 0x3ca3, 0xd74b, 0xbcb1, 
+0x210f, 0xf2c1, 0xcb2c, 0x414d, 0x1f07, 0xd958, 0x2f24, 0x195a, 0xa747, 0xe84d, 
+0x2605, 0xc501, 0xff0e, 0x4e0a, 0xea48, 0x02a4, 0x46c5, 0xd723, 0xafda, 0x23af, 
+0xf6a4, 0xbc7c, 0x3c45, 0x26f8, 0xdc74, 0x367d, 0x2543, 0xb0bd, 0xed3e, 0x27e5, 
+0xc333, 0xf8e2, 0x4d51, 0xeb5f, 0xfefc, 0x4865, 0xe34b, 0xb937, 0x2748, 0x0266, 
+0xc562, 0x3a6b, 0x25b1, 0xd774, 0x2daa, 0x2313, 0xb311, 0xef4a, 0x32e8, 0xcf60, 
+0xf8b2, 0x51fb, 0xee07, 0xf368, 0x44ab, 0xe548, 0xb2da, 0x24f2, 0x07b3, 0xc446, 
+0x3bc4, 0x2db3, 0xd779, 0x2ee4, 0x281e, 0xace1, 0xe4c5, 0x335a, 0xceab, 0xf17b, 
+0x55c7, 0xf4d4, 0xf24d, 0x4603, 0xeb3d, 0xaf65, 0x1bbf, 0x08f3, 0xbf31, 0x300f, 
+0x30d1, 0xd9cf, 0x29ba, 0x2ead, 0xb5b6, 0xdd53, 0x2dff, 0xcf0d, 0xe2d2, 0x4b14, 
+0xf7cf, 0xf104, 0x48fe, 0xf5f9, 0xb102, 0x175c, 0x0bd9, 0xbcb2, 0x27b4, 0x336a, 
+0xd7be, 0x2088, 0x3408, 0xbf37, 0xdc20, 0x3264, 0xdb9f, 0xe60e, 0x5013, 0xffb1, 
+0xe856, 0x4281, 0xff01, 0xb10f, 0x1094, 0x176a, 0xc863, 0x243b, 0x390b, 0xdf6d, 
+0x1d95, 0x3900, 0xc65f, 0xd25c, 0x2c3a, 0xe187, 0xdbeb, 0x465f, 0x0986, 0xeb79, 
+0x4044, 0x0711, 0xb0da, 0x0496, 0x1513, 0xc287, 0x187b, 0x3c78, 0xe032, 0x1521, 
+0x3c5f, 0xccc3, 0xcce1, 0x2b96, 0xe4ca, 0xd2ba, 0x430a, 0x0aa2, 0xdffc, 0x3ad9, 
+0x0be5, 0xaea0, 0x03b6, 0x1ba6, 0xbbed, 0x0db5, 0x4113, 0xdc05, 0x05bb, 0x3a65, 
+0xcc55, 0xc14b, 0x25ec, 0xe783, 0xd1d2, 0x4965, 0x1616, 0xdbb4, 0x3263, 0x0a8b, 
+0xa569, 0xf7cf, 0x1f57, 0xc4d2, 0x1559, 0x517f, 0xea47, 0x0848, 0x3a1f, 0xc9f1, 
+0xbb1e, 0x266f, 0xea60, 0xcd1c, 0x4d59, 0x23a6, 0xe328, 0x3b46, 0x19d2, 0xabe2, 
+0xf47d, 0x1e1a, 0xbcd3, 0x09ed, 0x4fb3, 0xe964, 0x0dbc, 0x485b, 0xd3bb, 0xbbbe, 
+0x2722, 0xffc5, 0xce39, 0x0d09, 0xfe2c, 0x112d, 0x596c, 0x16f5, 0xd170, 0x12a7, 
+0x07ab, 0xa521, 0xd945, 0x0290, 0xcf7b, 0x0c60, 0x5af6, 0x3c64, 0x1c78, 0x2c17, 
+0xf082, 0xb62e, 0xcf0c, 0xac7d, 0xba75, 0x27ac, 0x23af, 0xf129, 0x473d, 0x6f3b, 
+0xefd4, 0xd0fc, 0xfcb5, 0xc5fa, 0xa532, 0xe2aa, 0x08ff, 0x0704, 0x304a, 0x21e6, 
+0x0f85, 0x38c1, 0x010f, 0xbcdf, 0xd894, 0xf8ab, 0xd8c7, 0xe36a, 0x1b7a, 0x178e, 
+0x1a72, 0x1741, 0x157f, 0x1dd4, 0x0dfe, 0xe47e, 0xbdd3, 0xf139, 0xe9ae, 0xc861, 
+0x198e, 0x432e, 0x1c93, 0x1246, 0x4ca3, 0x23d4, 0xd5a3, 0xdda1, 0xc097, 0xcd1a, 
+0xeddd, 0xed1a, 0x1738, 0x5658, 0x41b1, 0xfba0, 0x3319, 0x2a1d, 0xc048, 0xc0cf, 
+0xd583, 0xd4c9, 0xdb7a, 0x070a, 0x2588, 0x3798, 0x3aa9, 0x0add, 0x25af, 0x2337, 
+0xd4c2, 0xb504, 0xca8a, 0xe4dd, 0xd039, 0xf1df, 0x2bb9, 0x3c1d, 0x3426, 0x22ac, 
+0x331f, 0x0f10, 0xdc7d, 0xbbe1, 0xb47c, 0xdb63, 0xd984, 0xfcbd, 0x450f, 0x5431, 
+0x271a, 0x210b, 0x3c62, 0xf43d, 0xc565, 0xc201, 0xc114, 0xe4f6, 0xee9b, 0x085b, 
+0x3cf5, 0x5653, 0x1e82, 0x0d52, 0x38a8, 0xf608, 0xc456, 0xce8b, 0xcfd1, 0xda08, 
+0xf0f6, 0x16f4, 0x3014, 0x4610, 0x1a46, 0x0c35, 0x36d1, 0xfb60, 0xbc9c, 0xbcea, 
+0xdb0c, 0xda74, 0xdb6c, 0x17ce, 0x3715, 0x33b3, 0x13c8, 0x1e7d, 0x290c, 0xe55b, 
+0xb756, 0xb135, 0xdad6, 0xde70, 0xd336, 0x1782, 0x43a0, 0x29e5, 0x03f8, 0x2c8f, 
+0x2768, 0xd396, 0xc0e1, 0xbc23, 0xccce, 0xdf32, 0xe829, 0x16bf, 0x4610, 0x3567, 
+0x012e, 0x312c, 0x3059, 0xcf4c, 0xbc48, 0xcf7d, 0xdb0c, 0xd4f7, 0xefe3, 0x2327, 
+0x3f5e, 0x34bf, 0x11d9, 0x3885, 0x2a09, 0xd700, 0xbd59, 0xc753, 0xde26, 0xd765, 
+0xf612, 0x31cc, 0x45d3, 0x2d56, 0x17c3, 0x3e94, 0x16b7, 0xce82, 0xc389, 0xc8ab, 
+0xdd9d, 0xdd82, 0xfe36, 0x3550, 0x4d5b, 0x2a45, 0x1384, 0x3ff2, 0x0ef3, 0xc81d, 
+0xbe61, 0xcce9, 0xe4aa, 0xe0ab, 0x0699, 0x385e, 0x486b, 0x2294, 0x15f0, 0x3d85, 
+0x01db, 0xc686, 0xc116, 0xcff5, 0xe34d, 0xe14b, 0x10c9, 0x3f07, 0x466b, 0x1f0d, 
+0x1d05, 0x3ab5, 0xf8ef, 0xc8ce, 0xc05e, 0xd357, 0xe7d4, 0xe29f, 0x13df, 0x471a, 
+0x4a47, 0x1c4c, 0x297f, 0x3e3f, 0xed74, 0xc6f8, 0xbfdc, 0xccde, 0xe3d5, 0xeaa0, 
+0x19ee, 0x4b1b, 0x4d49, 0x1865, 0x2976, 0x37a0, 0xe1a2, 0xb9e8, 0xba35, 0xd299, 
+0xde2b, 0xecfc, 0x27c6, 0x4ae2, 0x4564, 0x19a4, 0x28b5, 0x2426, 0xd885, 0xbc0a, 
+0xb90e, 0xd777, 0xe284, 0xf34a, 0x2d9a, 0x4813, 0x38b9, 0x14ee, 0x2c67, 0x1894, 
+0xd324, 0xbc7e, 0xb3bc, 0xda55, 0xe3e2, 0xef0a, 0x2fd7, 0x4da0, 0x2e6a, 0x0ee2, 
+0x326e, 0x0fc1, 0xcb23, 0xbee7, 0xb82c, 0xdaac, 0xe70d, 0xf676, 0x2c96, 0x4efe, 
+0x3180, 0x0f59, 0x3430, 0x0900, 0xc464, 0xbdf3, 0xbfd4, 0xdc18, 0xe54f, 0x02ac, 
+0x346a, 0x4ca2, 0x2bdb, 0x0ba0, 0x2ca5, 0x00e4, 0xc0c2, 0xb4ae, 0xbea2, 0xdd3b, 
+0xe1b5, 0x05e5, 0x36cd, 0x455d, 0x228c, 0x0f39, 0x2721, 0xf06a, 0xbe3c, 0xb625, 
+0xc315, 0xe0db, 0xe130, 0x0824, 0x3af9, 0x4450, 0x1a04, 0x1254, 0x2a20, 0xeab7, 
+0xbec0, 0xb857, 0xc3f1, 0xdf5a, 0xe831, 0x122e, 0x3daa, 0x44fa, 0x18f6, 0x1739, 
+0x28bb, 0xe41d, 0xbbf3, 0xb89c, 0xcff6, 0xe5c1, 0xea00, 0x1c60, 0x45d5, 0x43ef, 
+0x1c06, 0x2434, 0x292a, 0xe39e, 0xc2cb, 0xbd71, 0xd5c4, 0xe95c, 0xf5d3, 0x2a36, 
+0x4b75, 0x403d, 0x1c75, 0x32bf, 0x27ef, 0xdda2, 0xcb76, 0xc7c5, 0xdb1a, 0xe84b, 
+0xf612, 0x2b74, 0x5112, 0x4137, 0x18a7, 0x3889, 0x2791, 0xd8ed, 0xc90a, 0xc6c8, 
+0xd83c, 0xe5cf, 0x01d1, 0x32e1, 0x4e08, 0x3e77, 0x1bcc, 0x39cc, 0x1bcb, 0xcf7c, 
+0xbfad, 0xc693, 0xe1af, 0xe44a, 0x0379, 0x3b80, 0x5122, 0x34da, 0x12cd, 0x2ff7, 
+0x0b3f, 0xcb7c, 0xb95e, 0xc0f4, 0xe555, 0xe1ce, 0x01a1, 0x3cc9, 0x475e, 0x2196, 
+0x156a, 0x33d5, 0xf97d, 0xc4c1, 0xb9ed, 0xbd90, 0xe1db, 0xe24b, 0x021d, 0x3cfa, 
+0x4dca, 0x1ea3, 0x12f7, 0x33e9, 0xf159, 0xbf15, 0xb984, 0xbdf4, 0xd9dc, 0xe483, 
+0x0d28, 0x3bb5, 0x4aee, 0x1fcf, 0x1792, 0x2e75, 0xe773, 0xb55d, 0xaeed, 0xc525, 
+0xdc07, 0xe07a, 0x162d, 0x403a, 0x41df, 0x18e6, 0x1816, 0x22ca, 0xe0d7, 0xba3f, 
+0xab7d, 0xc6d9, 0xe296, 0xe464, 0x1a6b, 0x45ec, 0x3cb4, 0x1203, 0x21d7, 0x1e19, 
+0xd553, 0xc042, 0xb44a, 0xca17, 0xe29f, 0xe893, 0x1a35, 0x457e, 0x3ca4, 0x0eee, 
+0x274f, 0x1dc0, 0xd010, 0xbe2a, 0xb43a, 0xca4c, 0xe2e4, 0xf448, 0x246d, 0x4965, 
+0x3fdb, 0x10f7, 0x25b8, 0x162e, 0xcca7, 0xb882, 0xb947, 0xd7a5, 0xe438, 0xfea1, 
+0x33b7, 0x4cfe, 0x3b14, 0x1175, 0x24b7, 0x0bf7, 0xcecd, 0xbc06, 0xbdfc, 0xe81e, 
+0xee24, 0x01b0, 0x3af8, 0x476e, 0x28b0, 0x20d9, 0x3412, 0xf8f1, 0xc8c9, 0xbcf1, 
+0xbe75, 0xed66, 0xf061, 0x0477, 0x2e04, 0x4a13, 0x58d9, 0x3473, 0x0a86, 0xde23, 
+0xc927, 0xa391, 0xa85a, 0xfd01, 0x01c0, 0x26a1, 0x8016, 0x6b60, 0x1f2e, 0x05f0, 
+0xdab1, 0x948b, 0xb8c2, 0xc47d, 0xcb07, 0x3e6c, 0x61b3, 0x38d1, 0x421e, 0x423b, 
+0xe147, 0xbac6, 0xe0e9, 0xbe22, 0xd9dd, 0x0b3a, 0x03de, 0x31f4, 0x40dc, 0xf8e0, 
+0xf398, 0x2cdd, 0xec3a, 0xc582, 0x25ea, 0x1c58, 0xd8cd, 0x0700, 0x13d5, 0xbffb, 
+0xdfbf, 0x2eeb, 0xf5a6, 0x0a90, 0x5506, 0x0dfc, 0xf5d4, 0x194f, 0xd0b1, 0xa469, 
+0xf944, 0x0659, 0xe225, 0x3e8d, 0x4455, 0xf804, 0x285d, 0x16e8, 0xac54, 0xcbe6, 
+0x0dc1, 0xcfa2, 0xef3a, 0x51ba, 0x0cea, 0x02d9, 0x4169, 0xec8e, 0xb42c, 0x04b3, 
+0xfdcb, 0xc5c1, 0x233b, 0x2fa0, 0xe530, 0x27ec, 0x2937, 0xc096, 0xdeaa, 0x2435, 
+0xe010, 0xe6f7, 0x3e0a, 0xfd91, 0xeb2e, 0x333b, 0xf30c, 0xb2be, 0x1250, 0x1fd9, 
+0xc7fa, 0x1877, 0x3b5d, 0xdbdb, 0x0644, 0x23bb, 0xbdc0, 0xcc54, 0x2f0c, 0xf1f3, 
+0xe57b, 0x48e5, 0x082c, 0xe598, 0x360e, 0xf80f, 0xa876, 0x0659, 0x1b42, 0xc57b, 
+0x1fb9, 0x48cb, 0xe657, 0x1591, 0x3682, 0xcb26, 0xccd4, 0x2692, 0xe8fa, 0xda38, 
+0x445f, 0x1220, 0xf0e0, 0x3d8f, 0x09d0, 0xb6bc, 0x00e1, 0x260a, 0xd188, 0x0576, 
+0x3935, 0xef31, 0x1179, 0x33e9, 0xd401, 0xcde0, 0x2d56, 0xfa21, 0xdbb0, 0x4a3c, 
+0x1c17, 0xdc92, 0x334e, 0x1ceb, 0xb17d, 0xebbf, 0x27e0, 0xd919, 0x0f7e, 0x4a4b, 
+0xf20c, 0x107b, 0x3a20, 0xcab0, 0xba0a, 0x24cb, 0xf1fa, 0xcaf2, 0x3f6a, 0x2005, 
+0xe495, 0x30ba, 0x16ef, 0xb7a7, 0xec01, 0x1401, 0xc9b7, 0x05b6, 0x393b, 0xe12d, 
+0x07bf, 0x44cb, 0xdee8, 0xbd85, 0x23f1, 0xfc20, 0xc5f2, 0x2bd6, 0x194b, 0xdfc0, 
+0x26e3, 0x160b, 0xba3e, 0xf25d, 0x2457, 0xcdc4, 0x004b, 0x4634, 0xe4dc, 0xf4a7, 
+0x3d04, 0xdcc3, 0xb397, 0x1fb0, 0x0021, 0xcbc7, 0x37a0, 0x223d, 0xdd2e, 0x2e4a, 
+0x1e22, 0xae9d, 0xea89, 0x28db, 0xc94f, 0xf4c9, 0x4a0c, 0xf565, 0xfefa, 0x4525, 
+0xee89, 0xbfb1, 0x1b8b, 0xfa5c, 0xc436, 0x2f51, 0x24ca, 0xdfcd, 0x2cf4, 0x2a31, 
+0xbd55, 0xe94e, 0x2b96, 0xd147, 0xee2f, 0x4235, 0xf2bf, 0xf601, 0x3b75, 0xe821, 
+0xb876, 0x1f6c, 0x056a, 0xc597, 0x378b, 0x2e60, 0xd377, 0x1e9d, 0x283c, 0xb892, 
+0xdee1, 0x2781, 0xd1f0, 0xf4ba, 0x554c, 0x0123, 0xf9be, 0x420b, 0xea52, 0xaa76, 
+0x121d, 0x04f0, 0xbdca, 0x333f, 0x4315, 0xe753, 0x27d8, 0x325a, 0xb873, 0xd272, 
+0x2388, 0xcf65, 0xe913, 0x57fe, 0x07f4, 0xf542, 0x4773, 0xf6c7, 0xab18, 0x11a2, 
+0x0c42, 0xb926, 0x2816, 0x3c96, 0xde7c, 0x28fb, 0x3ab1, 0xb843, 0xd1f6, 0x2e08, 
+0xd30e, 0xdd67, 0x552d, 0x04b1, 0xe6f1, 0x4408, 0xfac7, 0xa436, 0x0956, 0x1138, 
+0xb9e0, 0x267a, 0x42e3, 0xd676, 0x199d, 0x3443, 0xb086, 0xc200, 0x28e5, 0xda7a, 
+0xd827, 0x53d9, 0x0bab, 0xe3c1, 0x40a6, 0xfc98, 0xa29e, 0x018f, 0x1105, 0xb6e7, 
+0x1b43, 0x498c, 0xdd00, 0x1541, 0x4138, 0xc0de, 0xbf2e, 0x283d, 0xe09c, 0xce50, 
+0x4aa8, 0x1053, 0xdfdb, 0x3f0a, 0x0676, 0xa0c4, 0xfe21, 0x1b86, 0xb753, 0x10a7, 
+0x4958, 0xd934, 0x0821, 0x3f0a, 0xc34f, 0xba57, 0x2b9e, 0xe817, 0xc7b8, 0x46a9, 
+0x0faa, 0xd39d, 0x38e6, 0x0b67, 0x9f2e, 0xfa87, 0x2298, 0xbafd, 0x0a31, 0x466b, 
+0xd41d, 0xfd51, 0x3a2b, 0xc101, 0xb40d, 0x2b20, 0xef1f, 0xc9c0, 0x46b9, 0x10a8, 
+0xce9c, 0x3371, 0x097d, 0x9c55, 0xf5c4, 0x3090, 0xd2df, 0xecd4, 0x147e, 0xe806, 
+0x2e2d, 0x4ebd, 0xe525, 0xe179, 0x26a7, 0xd61d, 0xaa44, 0x0053, 0xe8dc, 0xe136, 
+0x46b6, 0x57fc, 0x24b5, 0x2da9, 0x235d, 0xcd31, 0xca81, 0xd1c7, 0xaf26, 0xfdb0, 
+0x3bad, 0x09ac, 0x1da0, 0x74cf, 0x3a9c, 0xd9e6, 0xf662, 0xf1b3, 0xb74e, 0xc78b, 
+0x079d, 0x1303, 0x25f7, 0x3f88, 0x14f4, 0x2459, 0x2c9b, 0xdd69, 0xc8da, 0xfb0c, 
+0xfc56, 0xd94a, 0x0b6d, 0x29c0, 0x150a, 0x22e5, 0x1d92, 0x18ef, 0x1cfc, 0x0c23, 
+0xcdc3, 0xcd7b, 0x0116, 0xd225, 0xea05, 0x3ecf, 0x321c, 0x114b, 0x3429, 0x4818, 
+0xf80f, 0xe0f6, 0xd86d, 0xb88f, 0xe34c, 0xec85, 0xf335, 0x37f0, 0x5dfb, 0x1c42, 
+0x11db, 0x4f23, 0xfc26, 0xba44, 0xd5aa, 0xd324, 0xd1fd, 0xf17c, 0x1856, 0x276a, 
+0x4692, 0x286a, 0x0ba3, 0x3d7b, 0x1150, 0xc1ac, 0xbdf0, 0xe136, 0xd542, 0xcf26, 
+0x1384, 0x2faf, 0x3870, 0x2e2c, 0x2318, 0x28d4, 0xfdee, 0xcb16, 0xa730, 0xc88d, 
+0xdb00, 0xceb6, 0x1995, 0x4d9d, 0x384a, 0x1a5c, 0x3253, 0x2473, 0xd8f1, 0xc53c, 
+0xafa7, 0xc440, 0xe9ed, 0xe807, 0x176e, 0x51f8, 0x4372, 0x074b, 0x2912, 0x2b6d, 
+0xcf1e, 0xc37a, 0xc518, 0xc3a3, 0xdc9c, 0xfa3e, 0x1a98, 0x40fa, 0x4783, 0x0983, 
+0x2539, 0x3545, 0xd15a, 0xad3e, 0xc7ca, 0xd8f8, 0xd06d, 0xf96a, 0x3340, 0x3d0f, 
+0x375f, 0x19a1, 0x2cbe, 0x2480, 0xd619, 0xaa0f, 0xbfde, 0xe9c8, 0xd157, 0xf05e, 
+0x42af, 0x4a8c, 0x2ada, 0x1e55, 0x372a, 0x09e1, 0xcd35, 0xbbbe, 0xb8fb, 0xe193, 
+0xe480, 0xf329, 0x3476, 0x51aa, 0x233d, 0x1102, 0x44ce, 0x08c4, 0xbbca, 0xc158, 
+0xc692, 0xd1e1, 0xdde2, 0x0656, 0x33cd, 0x4f74, 0x2ddc, 0x0f4d, 0x394e, 0x09e6, 
+0xbe5c, 0xb5ad, 0xcc4d, 0xdc27, 0xdab2, 0x1043, 0x3ea4, 0x479b, 0x2b41, 0x1d61, 
+0x308b, 0xf8bb, 0xc464, 0xb735, 0xcd64, 0xe75e, 0xe437, 0x161f, 0x4870, 0x48ad, 
+0x1c9b, 0x1ea2, 0x33d1, 0xf0d7, 0xc828, 0xc0cf, 0xd2aa, 0xe99c, 0xeb83, 0x1a23, 
+0x47fe, 0x4a7b, 0x1905, 0x1e38, 0x324a, 0xe958, 0xc1e9, 0xc325, 0xd7e4, 0xe635, 
+0xf2dc, 0x2267, 0x3faa, 0x415f, 0x1a59, 0x202f, 0x2852, 0xe889, 0xc4bd, 0xbe6c, 
+0xdab6, 0xe56a, 0xef10, 0x26eb, 0x4556, 0x3a6e, 0x180a, 0x2a09, 0x1fb9, 0xde8b, 
+0xc5cf, 0xb9e8, 0xd7a7, 0xe7b9, 0xedd9, 0x2300, 0x49df, 0x37d1, 0x12a8, 0x2f9a, 
+0x18aa, 0xce1b, 0xbdb0, 0xbc6b, 0xd29e, 0xdeee, 0xf71a, 0x2781, 0x45f4, 0x339d, 
+0x0ccf, 0x2b8f, 0x12d6, 0xc8e8, 0xb6b6, 0xbda1, 0xd3af, 0xd912, 0xfe42, 0x2d6d, 
+0x3ef8, 0x304b, 0x1689, 0x29cf, 0x067c, 0xcba1, 0xb57d, 0xbede, 0xdf90, 0xdc36, 
+0xfffb, 0x3465, 0x3c40, 0x2128, 0x1a44, 0x31e1, 0xfd23, 0xcc9c, 0xbac3, 0xbc48, 
+0xdd17, 0xde23, 0xfd31, 0x3137, 0x4362, 0x1eee, 0x18fc, 0x32b8, 0xf20e, 0xc5cc, 
+0xbb44, 0xbdcc, 0xd9bd, 0xe2e3, 0x076b, 0x353c, 0x4892, 0x1e7b, 0x18f6, 0x30cf, 
+0xea76, 0xbae7, 0xb387, 0xc4fa, 0xdcc0, 0xe7b8, 0x15fe, 0x3d5b, 0x45ed, 0x199f, 
+0x192d, 0x2670, 0xe39c, 0xbd23, 0xb49a, 0xce79, 0xe000, 0xe7b3, 0x1c0b, 0x42fb, 
+0x4231, 0x1500, 0x214f, 0x24b7, 0xddd0, 0xbdaf, 0xb443, 0xd1d6, 0xe488, 0xf035, 
+0x248c, 0x481a, 0x412e, 0x17e3, 0x2a09, 0x1e55, 0xd730, 0xbb6d, 0xb458, 0xd6fe, 
+0xe4f4, 0xf65d, 0x30dd, 0x50e1, 0x3ee0, 0x15ff, 0x2a77, 0x133f, 0xd208, 0xbb41, 
+0xb5d0, 0xdc9b, 0xea0f, 0xfe2e, 0x33e8, 0x4ec6, 0x3729, 0x17b0, 0x327e, 0x0ae7, 
+0xcbb1, 0xbd40, 0xbbb0, 0xe021, 0xe92f, 0x0274, 0x3a54, 0x53fa, 0x3201, 0x1417, 
+0x340a, 0x073d, 0xcaf8, 0xbd21, 0xbddc, 0xdfe9, 0xebda, 0x0cee, 0x3df0, 0x5410, 
+0x3025, 0x16c7, 0x32e0, 0xfb90, 0xc1f6, 0xbac8, 0xcb01, 0xe852, 0xeb00, 0x14bb, 
+0x4362, 0x4e09, 0x267e, 0x175e, 0x2ea6, 0xf673, 0xc679, 0xb7ca, 0xce42, 0xef38, 
+0xea88, 0x19da, 0x4c19, 0x4976, 0x1f9b, 0x2155, 0x2984, 0xe747, 0xc939, 0xbc60, 
+0xced0, 0xf05b, 0xef4a, 0x1a1b, 0x4d06, 0x49db, 0x1707, 0x21a4, 0x261f, 0xdb58, 
+0xc42f, 0xbd07, 0xcd03, 0xeb57, 0xf6f1, 0x1fe4, 0x4885, 0x45cb, 0x1391, 0x2121, 
+0x232c, 0xd7ec, 0xbd29, 0xbf59, 0xd799, 0xe575, 0xf6b7, 0x28c6, 0x4774, 0x3e39, 
+0x1137, 0x1ef7, 0x1744, 0xd610, 0xbc35, 0xb9e4, 0xdd70, 0xe860, 0xf41e, 0x2929, 
+0x4423, 0x2e1c, 0x110a, 0x2d77, 0x0e41, 0xced2, 0xc1cd, 0xbb1d, 0xd9b8, 0xe41e, 
+0xf4ed, 0x2b8f, 0x4959, 0x2b92, 0x0f36, 0x32ac, 0x0962, 0xc983, 0xc063, 0xbadd, 
+0xd65d, 0xe557, 0xfe42, 0x2c4a, 0x49b0, 0x2cc4, 0x11af, 0x335e, 0x0099, 0xbfb6, 
+0xb950, 0xc282, 0xda13, 0xe2c3, 0x0c6b, 0x2301, 0x3d0d, 0x5b32, 0x2bf1, 0xf816, 
+0xd811, 0xc694, 0x94e5, 0xa76b, 0x02b3, 0xf90f, 0x23f0, 0x863b, 0x6a8b, 0x1164, 
+0xf826, 0xd412, 0x8d7c, 0xade7, 0xbb44, 0xce06, 0x446e, 0x60cd, 0x37d3, 0x464b, 
+0x4603, 0xdb1a, 0xadc9, 0xd748, 0xbb79, 0xd2d1, 0x0130, 0x0928, 0x3b0a, 0x4390, 
+0x0002, 0xef18, 0x25c7, 0xf662, 0xbcac, 0x1201, 0x1f14, 0xda32, 0xff28, 0x1fbe, 
+0xd1ed, 0xd6db, 0x389e, 0x0dbf, 0xf3fb, 0x488e, 0x1c7e, 0xe70e, 0x1374, 0xed9e, 
+0xa6a3, 0xedff, 0x24fa, 0xe3d7, 0x2454, 0x55ff, 0xfbf6, 0x19ad, 0x27e2, 0xbe48, 
+0xc206, 0x1296, 0xe45b, 0xdd35, 0x4db6, 0x1c33, 0xef46, 0x4348, 0x0b24, 0xb5eb, 
+0xf732, 0x126a, 0xcd2b, 0x063c, 0x37c5, 0xec01, 0x18d9, 0x3cc8, 0xd616, 0xd2bc, 
+0x273a, 0xf84b, 0xd381, 0x30e7, 0x1385, 0xdff9, 0x30f4, 0x18b0, 0xc10e, 0x0696, 
+0x364d, 0xd762, 0xfbf8, 0x3d8c, 0xe397, 0xf63d, 0x3932, 0xe0e0, 0xc7fb, 0x31c6, 
+0x0e47, 0xd472, 0x33f1, 0x19cb, 0xd9b6, 0x297e, 0x174d, 0xb770, 0xf385, 0x2b80, 
+0xd844, 0x020b, 0x44ae, 0xecdc, 0xffc6, 0x3c84, 0xe59b, 0xc239, 0x1b9c, 0x03d8, 
+0xcdfc, 0x284d, 0x2050, 0xe856, 0x29ba, 0x1da6, 0xc79c, 0xf13e, 0x2a8b, 0xdb89, 
+0xe7cf, 0x315a, 0xf321, 0xf5f9, 0x332c, 0xf230, 0xc508, 0x1566, 0x093d, 0xce9a, 
+0x23e7, 0x1dac, 0xd1bc, 0x1aa1, 0x2c3b, 0xbf9a, 0xd5cb, 0x286f, 0xe374, 0xeccb, 
+0x3bb8, 0xfa4b, 0xf5e8, 0x2f2d, 0xe9fe, 0xbb23, 0x0ce2, 0xff3a, 0xc469, 0x2484, 
+0x2c01, 0xe186, 0x1b3d, 0x26db, 0xc966, 0xd43c, 0x0cf6, 0xd3cc, 0xeaf1, 0x349d, 
+0xf49e, 0xfa1b, 0x3da3, 0xf2ae, 0xb5a2, 0x09f1, 0x0303, 0xbee6, 0x1c15, 0x2f77, 
+0xe137, 0x187e, 0x2a96, 0xc3d0, 0xd414, 0x1e88, 0xd685, 0xe774, 0x4a59, 0xfa19, 
+0xe6e2, 0x3f71, 0xf365, 0xa657, 0x0aac, 0x0b27, 0xbbf9, 0x22a4, 0x3896, 0xdde2, 
+0x1ea6, 0x2ddb, 0xb6a3, 0xcf13, 0x234d, 0xd209, 0xdfcd, 0x4de4, 0x0530, 0xf235, 
+0x458e, 0xfe1c, 0xaf9c, 0x04ff, 0x0ba8, 0xc04a, 0x1dfe, 0x3a8f, 0xe44e, 0x1ebd, 
+0x3786, 0xc838, 0xd340, 0x2d49, 0xe462, 0xdc75, 0x4606, 0x05e5, 0xe8d6, 0x3e07, 
+0x0367, 0xb349, 0x0d09, 0x1be3, 0xc56a, 0x2148, 0x4004, 0xd8d7, 0x1595, 0x3a7d, 
+0xc56d, 0xd126, 0x3261, 0xe7bb, 0xe124, 0x5308, 0x0eb8, 0xeb26, 0x437a, 0x042c, 
+0xaf26, 0x0eb2, 0x218d, 0xc6ad, 0x22c2, 0x4ab9, 0xe2d2, 0x1874, 0x40cd, 0xca8d, 
+0xc838, 0x2e68, 0xedb9, 0xd7fa, 0x4c7a, 0x1526, 0xe7cb, 0x4150, 0x0c9e, 0xae99, 
+0x0430, 0x20bb, 0xc1b5, 0x1187, 0x47d4, 0xe4da, 0x1440, 0x42ec, 0xcdff, 0xc6df, 
+0x2c13, 0xec08, 0xd2d5, 0x46ed, 0x0ef1, 0xdd36, 0x3d9e, 0x0f6f, 0xadf9, 0x0331, 
+0x2434, 0xc516, 0x0f43, 0x4485, 0xde32, 0x0700, 0x3d61, 0xce91, 0xbeff, 0x2926, 
+0xf4fa, 0xd134, 0x41a9, 0x1664, 0xdc49, 0x34e2, 0x1333, 0xace3, 0xf361, 0x1f70, 
+0xc693, 0x0699, 0x47e9, 0xe934, 0x0537, 0x4024, 0xd7ae, 0xba09, 0x1da8, 0xf1cd, 
+0xcbb4, 0x3981, 0x188e, 0xddeb, 0x326b, 0x1892, 0xb095, 0xf130, 0x20bc, 0xc29d, 
+0xf9a7, 0x3f9b, 0xe3d4, 0xfb7a, 0x3e64, 0xdf3d, 0xbe59, 0x2395, 0xf6d6, 0xc4b9, 
+0x3386, 0x1936, 0xd767, 0x2b7a, 0x1dd1, 0xb547, 0xeefe, 0x2814, 0xcaa5, 0xf817, 
+0x487c, 0xeb89, 0xf26b, 0x397c, 0xdf7f, 0xb39b, 0x1c04, 0xfe68, 0xc54d, 0x349f, 
+0x2a68, 0xdbdd, 0x22d6, 0x1ddd, 0xb0a0, 0xe0fa, 0x21cc, 0xc993, 0xf898, 0x52ec, 
+0xf689, 0xf70a, 0x426a, 0xe741, 0xaf61, 0x151d, 0xf921, 0xc0cc, 0x3886, 0x3002, 
+0xdf54, 0x2dc5, 0x25fe, 0xb022, 0xe019, 0x2b01, 0xdc46, 0xdf34, 0x113b, 0xf3ef, 
+0x2b9e, 0x5380, 0xf6a9, 0xdedb, 0x2143, 0xe2d9, 0xa1ed, 0xf09b, 0xf0dc, 0xdb67, 
+0x3407, 0x5e55, 0x32ca, 0x27e1, 0x25c5, 0xd709, 0xc36a, 0xcfc9, 0xa7f8, 0xea51, 
+0x3bd7, 0x0e16, 0x0801, 0x6978, 0x4f5b, 0xdcee, 0xefc1, 0xfe47, 0xbe36, 0xbc03, 
+0xf6fb, 0x0a54, 0x1b49, 0x3bd0, 0x15ec, 0x2382, 0x3cb2, 0xeb19, 0xc5aa, 0xedb7, 
+0xf957, 0xd7a6, 0xf768, 0x22e7, 0x17a3, 0x2061, 0x1ba7, 0x1fd9, 0x23d8, 0x0c01, 
+0xd667, 0xc4b5, 0xfb1e, 0xd994, 0xd7e9, 0x3398, 0x3e92, 0x166b, 0x27af, 0x4ec2, 
+0x0515, 0xd7d3, 0xde1a, 0xb994, 0xdcbe, 0xf079, 0xeced, 0x2d31, 0x5f61, 0x253a, 
+0x040a, 0x4aa6, 0x0dcf, 0xb7f1, 0xcf3e, 0xd1b1, 0xcf61, 0xe63f, 0x105c, 0x26cc, 
+0x431a, 0x31ef, 0x089d, 0x3279, 0x1505, 0xc9c8, 0xbc77, 0xd253, 0xdbe3, 0xd185, 
+0x028c, 0x2ef7, 0x3d5b, 0x2ff3, 0x2436, 0x2ecc, 0xffae, 0xd27d, 0xae72, 0xb7bb, 
+0xda8b, 0xd2ea, 0x0b5f, 0x4d03, 0x43e6, 0x19f3, 0x2a63, 0x2e3d, 0xdc83, 0xc2d3, 
+0xb8a6, 0xbf1e, 0xe681, 0xe9fe, 0x0c02, 0x47ed, 0x4b9b, 0x0b96, 0x1c09, 0x3193, 
+0xdad3, 0xc2e7, 0xcba3, 0xc7a2, 0xd979, 0xf765, 0x1768, 0x34eb, 0x4272, 0x0e6d, 
+0x1cba, 0x35bf, 0xe2f7, 0xb4ec, 0xc2dc, 0xdbc9, 0xd4b0, 0xeaf5, 0x2a04, 0x3d45, 
+0x3135, 0x163c, 0x29bf, 0x1de9, 0xd862, 0xb512, 0xbc25, 0xe60f, 0xdb2d, 0xe4e1, 
+0x2e4c, 0x46ed, 0x2280, 0x0c95, 0x3390, 0x0dba, 0xc912, 0xc227, 0xbe99, 0xd9c1, 
+0xe290, 0xed33, 0x2239, 0x44f4, 0x1ed4, 0x0166, 0x3720, 0x122c, 0xc1e5, 0xbe0b, 
+0xcc00, 0xd5f1, 0xd17f, 0xf3b3, 0x23a2, 0x3db4, 0x2624, 0x0cc4, 0x33e1, 0x1023, 
+0xc9ae, 0xb631, 0xc8cd, 0xdd8a, 0xceea, 0xfaf7, 0x3621, 0x3ded, 0x1ca5, 0x1b0d, 
+0x3ba6, 0x0216, 0xce92, 0xc394, 0xc90e, 0xdd1a, 0xd9c7, 0x0438, 0x3a3b, 0x43f5, 
+0x193b, 0x1b93, 0x427f, 0xfe8c, 0xc66d, 0xc591, 0xd58c, 0xe393, 0xe1bc, 0x0fe2, 
+0x3df6, 0x448e, 0x1c8a, 0x21c0, 0x3e71, 0xf9bd, 0xc96f, 0xc456, 0xd5d9, 0xe4b5, 
+0xe922, 0x1ce5, 0x418b, 0x417b, 0x1d09, 0x2518, 0x341d, 0xf03a, 0xcbea, 0xc1e1, 
+0xd6e8, 0xe7f3, 0xe55f, 0x1d2e, 0x4954, 0x3f9e, 0x1b23, 0x31e7, 0x3163, 0xe580, 
+0xcb7b, 0xbe90, 0xd27b, 0xe98e, 0xede5, 0x22f3, 0x51cc, 0x440f, 0x174a, 0x3744, 
+0x308b, 0xdab4, 0xc2e8, 0xc03f, 0xd50d, 0xe3f9, 0xf766, 0x2e0e, 0x4fbc, 0x4269, 
+0x17f2, 0x2ec2, 0x1f55, 0xd524, 0xbca2, 0xbb93, 0xda21, 0xe34e, 0xfad1, 0x31b6, 
+0x47da, 0x36e7, 0x19ff, 0x2ef6, 0x0ef3, 0xd0a0, 0xb94c, 0xb54a, 0xdd97, 0xe171, 
+0xf86b, 0x35bc, 0x47ba, 0x2983, 0x1694, 0x3324, 0x023b, 0xc961, 0xbc03, 0xb2d4, 
+0xd7d9, 0xe2e7, 0xf9f7, 0x3391, 0x4b1a, 0x23f3, 0x1255, 0x2f9f, 0xf2dd, 0xbf1b, 
+0xb8c8, 0xb595, 0xd67b, 0xe49e, 0x04eb, 0x3553, 0x491e, 0x20bc, 0x101c, 0x2d09, 
+0xefb9, 0xbc9b, 0xb456, 0xbc74, 0xdcb8, 0xe7e3, 0x1085, 0x3e2d, 0x4862, 0x20a4, 
+0x178e, 0x24e7, 0xe5be, 0xbfc5, 0xb5ac, 0xc6ce, 0xe4c1, 0xe9df, 0x156b, 0x41e6, 
+0x4347, 0x169b, 0x1dcf, 0x2537, 0xdbdb, 0xbd60, 0xb4ac, 0xc74f, 0xe58f, 0xf1d1, 
+0x1bdb, 0x438d, 0x41e3, 0x1215, 0x1c5f, 0x197b, 0xd34e, 0xbb05, 0xb7f2, 0xd3b2, 
+0xe362, 0xf0f9, 0x2581, 0x46a8, 0x3c22, 0x115f, 0x2009, 0x122f, 0xd304, 0xbd34, 
+0xb54b, 0xd890, 0xe911, 0xf7d8, 0x2be6, 0x4644, 0x3124, 0x11c4, 0x2d7b, 0x0ee0, 
+0xcfc2, 0xc445, 0xbf59, 0xdf01, 0xe6a3, 0xf6fe, 0x2fa7, 0x4f24, 0x32c6, 0x10fe, 
+0x360f, 0x14d0, 0xd1fe, 0xc5f6, 0xc3cd, 0xdf16, 0xe84d, 0x00f9, 0x3302, 0x4f34, 
+0x330f, 0x190f, 0x3c38, 0x0f70, 0xcd2f, 0xc1c9, 0xccf8, 0xe5e1, 0xe528, 0x0d0a, 
+0x3fdc, 0x4c89, 0x2965, 0x1572, 0x3558, 0x0773, 0xcf30, 0xbe56, 0xcfa1, 0xeeb4, 
+0xe390, 0x0d40, 0x446b, 0x47d6, 0x22c9, 0x1f4d, 0x33f7, 0xf611, 0xcd9c, 0xbd57, 
+0xc66d, 0xec7d, 0xe7bf, 0x0df9, 0x474d, 0x4b43, 0x1b2f, 0x1f2d, 0x35f1, 0xea3c, 
+0xc455, 0xbc6b, 0xc16f, 0xe41e, 0xef9d, 0x16e5, 0x457b, 0x4d9b, 0x1df1, 0x2052, 
+0x310e, 0xe35e, 0xbd3b, 0xbe4a, 0xd17b, 0xe63a, 0xf0dd, 0x2445, 0x4bde, 0x4c1f, 
+0x20d2, 0x25a1, 0x2da1, 0xe9a8, 0xc288, 0xb909, 0xd9c6, 0xee3e, 0xf6a6, 0x2ef9, 
+0x50a3, 0x43ee, 0x1dd3, 0x2eed, 0x2309, 0xe027, 0xcabc, 0xbd16, 0xdbde, 0xee25, 
+0xf339, 0x2c27, 0x5390, 0x40a0, 0x1b96, 0x375c, 0x1d2b, 0xd734, 0xc78b, 0xb807, 
+0xd541, 0xecee, 0xfe54, 0x2fa0, 0x5361, 0x3f28, 0x1522, 0x3393, 0x1266, 0xc88d, 
+0xbc85, 0xb8d2, 0xd4a8, 0xe5ab, 0x0438, 0x3396, 0x4c0c, 0x33cd, 0x0a79, 0x2169, 
+0xfe45, 0xc2f1, 0xb2f9, 0xb954, 0xe0e9, 0xe165, 0x029e, 0x2aa5, 0x318e, 0x465f, 
+0x33d0, 0x0444, 0xd0f3, 0xc734, 0xa46c, 0x9309, 0xec1b, 0xfbdf, 0x010e, 0x6440, 
+0x7e13, 0x1ed8, 0xeedd, 0xe7dd, 0x9c36, 0x94bd, 0xaeea, 0xb4e6, 0x08d9, 0x4ccc, 
+0x44d3, 0x3995, 0x43b3, 0xfbc8, 0xa9f8, 0xbc47, 0xb7e9, 0xb05c, 0xd4b9, 0x0205, 
+0x2fad, 0x38f1, 0x145d, 0xf759, 0x0aec, 0xf6cf, 0xb93a, 0xdb0a, 0x14b9, 0xe52f, 
+0xdb64, 0x2275, 0xfc04, 0xc169, 0x1482, 0x2708, 0xda58, 0x13ad, 0x34f3, 0xe68c, 
+0xf5c6, 0x0b27, 0xbfca, 0xc11f, 0x1a39, 0xf895, 0xf15a, 0x535e, 0x1fbe, 0xfd1c, 
+0x2fab, 0xeb46, 0xb207, 0xf114, 0xfe7d, 0xd0f4, 0x2a5f, 0x4be3, 0xf98f, 0x2db3, 
+0x365b, 0xcbe5, 0xd12f, 0x160e, 0xe93e, 0xe29c, 0x4478, 0x1d6f, 0x0413, 0x49f1, 
+0x0cdb, 0xc582, 0x08ff, 0x1ce3, 0xd295, 0x10d4, 0x44fb, 0xeff9, 0x15bb, 0x4310, 
+0xddfd, 0xd8c9, 0x34f7, 0xfaaf, 0xd716, 0x4457, 0x1cff, 0xe28a, 0x3514, 0x1237, 
+0xb5a9, 0x01cc, 0x3075, 0xd90a, 0x1130, 0x4b8f, 0xf1cd, 0x0fee, 0x37f4, 0xcf77, 
+0xc32c, 0x262d, 0xfb1f, 0xde11, 0x4cfa, 0x220f, 0xe7b6, 0x379f, 0x1630, 0xb473, 
+0xeb2b, 0x1f40, 0xcdde, 0xfb49, 0x44ba, 0xf7a8, 0x0b44, 0x3ad4, 0xdf56, 0xbc11, 
+0x192e, 0xfdae, 0xc1e6, 0x2be2, 0x260a, 0xe13b, 0x285b, 0x1e09, 0xb912, 0xe471, 
+0x2223, 0xd36d, 0xfe2f, 0x46c5, 0xe36b, 0xf7a8, 0x4755, 0xdf55, 0xa7b3, 0x1a23, 
+0x0b84, 0xc893, 0x2faf, 0x2991, 0xe2bb, 0x2481, 0x13cb, 0xb383, 0xe0a3, 0x1702, 
+0xc7e4, 0xf45d, 0x4b67, 0xf6a6, 0xf97a, 0x3e6f, 0xecd9, 0xadf3, 0xfeb4, 0xfd06, 
+0xc788, 0x1f7a, 0x200a, 0xe5ba, 0x31ba, 0x2511, 0xb3da, 0xe100, 0x2776, 0xc990, 
+0xe1ba, 0x44f0, 0xef0a, 0xe6e3, 0x3c2c, 0xf024, 0xb397, 0x1376, 0x054e, 0xc2a5, 
+0x2c7f, 0x2067, 0xc5d1, 0x227f, 0x2507, 0xa6ee, 0xd8b4, 0x2da2, 0xd0d2, 0xe5d2, 
+0x4ae3, 0xf3c8, 0xec01, 0x3d1d, 0xe4c8, 0xa76d, 0x0cd7, 0x02fe, 0xc051, 0x2a3f, 
+0x2ff4, 0xd96d, 0x206e, 0x2cdb, 0xbcc2, 0xcfce, 0x1d9e, 0xd936, 0xe286, 0x3c62, 
+0xf899, 0xf161, 0x4188, 0xfacc, 0xb89c, 0x13b2, 0x0f18, 0xbfc2, 0x1908, 0x2b9b, 
+0xdd40, 0x1c58, 0x31c8, 0xcc18, 0xe1de, 0x3029, 0xe1a2, 0xeab8, 0x4814, 0xf8bb, 
+0xec3b, 0x41cd, 0xfd3d, 0xbb42, 0x1ab1, 0x1bc5, 0xd03f, 0x2b94, 0x39e6, 0xe56b, 
+0x20f6, 0x302f, 0xc7e3, 0xe07e, 0x304b, 0xe35d, 0xef37, 0x556b, 0x0a77, 0xf3f3, 
+0x471e, 0x0715, 0xb6bf, 0x0a15, 0x15a7, 0xc8f0, 0x27ce, 0x49e1, 0xef3f, 0x24d8, 
+0x3fc8, 0xcf85, 0xd3a9, 0x2981, 0xe391, 0xe1e2, 0x5568, 0x1a44, 0xf6f8, 0x47a5, 
+0x0bb1, 0xb4f6, 0x0758, 0x180f, 0xc264, 0x1c7f, 0x4997, 0xe7b6, 0x1790, 0x3eec, 
+0xcc71, 0xc989, 0x25c5, 0xe0ff, 0xd5eb, 0x4cb5, 0x1585, 0xe9fb, 0x3f4e, 0x079f, 
+0xa4e8, 0xf8b6, 0x18b7, 0xbe0e, 0x140f, 0x4dcd, 0xe6f8, 0x106e, 0x3e48, 0xc659, 
+0xb8d1, 0x1fc6, 0xe2f7, 0xcafc, 0x4b21, 0x1aac, 0xddf9, 0x38ef, 0x0d86, 0xa172, 
+0xefb8, 0x1ae3, 0xb8b9, 0x022b, 0x4952, 0xe3b7, 0x0763, 0x3fb6, 0xcaa1, 0xb546, 
+0x2034, 0xe7b3, 0xc26e, 0x4341, 0x1b44, 0xd872, 0x37f9, 0x158c, 0xa302, 0xed16, 
+0x212e, 0xbda6, 0x0112, 0x4eb5, 0xe481, 0x0180, 0x448c, 0xd2be, 0xb34a, 0x2659, 
+0xf969, 0xc3e7, 0x4253, 0x2498, 0xd3ac, 0x2f84, 0x1c93, 0xa86a, 0xeae4, 0x2be9, 
+0xc824, 0xfb1e, 0x5254, 0xeb1f, 0xf85a, 0x40c6, 0xd602, 0xacc6, 0x20d2, 0xfcc1, 
+0xbfa1, 0x3d9b, 0x2b83, 0xd669, 0x2fcc, 0x202d, 0xa65f, 0xe170, 0x2e20, 0xdd4c, 
+0xe4e8, 0x1128, 0xe9c6, 0x2b2e, 0x54f5, 0xec68, 0xd881, 0x25b3, 0xe44f, 0x9e7f, 
+0xf130, 0xeb8e, 0xd492, 0x3413, 0x5451, 0x26e6, 0x289d, 0x2623, 0xcf51, 0xbd9d, 
+0xcfb5, 0xa20d, 0xdfe7, 0x36b7, 0x0cc4, 0x056d, 0x65fe, 0x4dbe, 0xdc03, 0xeb0b, 
+0xf3c5, 0xb95e, 0xbfab, 0xf463, 0x0575, 0x1cd4, 0x3d59, 0x1332, 0x1c9e, 0x36b2, 
+0xe6ff, 0xc1d2, 0xebab, 0xf875, 0xd9ed, 0xf751, 0x1ec8, 0x177a, 0x1fdf, 0x14b0, 
+0x158a, 0x1d8b, 0x09a1, 0xd3cc, 0xc301, 0xfa03, 0xda41, 0xd913, 0x31d2, 0x3bcd, 
+0x1398, 0x2276, 0x47f0, 0x04ad, 0xdb13, 0xde05, 0xbc40, 0xe0b4, 0xf233, 0xedf8, 
+0x2b4d, 0x5c62, 0x258d, 0x04db, 0x4756, 0x0b9d, 0xbaa9, 0xd2dc, 0xd3e6, 0xd2e5, 
+0xeb10, 0x1044, 0x260b, 0x4492, 0x307c, 0x0989, 0x37e3, 0x1952, 0xc9b1, 0xbe5d, 
+0xd980, 0xdd51, 0xcfb1, 0x0665, 0x3440, 0x3f66, 0x32e5, 0x2caa, 0x3828, 0x04a2, 
+0xd6f3, 0xb98c, 0xc152, 0xdc75, 0xd7fc, 0x131d, 0x50a8, 0x4584, 0x218f, 0x39e9, 
+0x3a8c, 0xe3c0, 0xca56, 0xc147, 0xc3c0, 0xe3a0, 0xec33, 0x13df, 0x4aaa, 0x4c83, 
+0x117c, 0x2896, 0x399a, 0xdc86, 0xc6f6, 0xcd47, 0xc6ce, 0xd9cc, 0xf86e, 0x19ad, 
+0x3a91, 0x491f, 0x123e, 0x24d9, 0x3cde, 0xe11b, 0xb37c, 0xc2df, 0xd7a4, 0xd130, 
+0xef29, 0x2c49, 0x3d20, 0x37d9, 0x16ea, 0x291c, 0x26ac, 0xda1f, 0xaaed, 0xb607, 
+0xe686, 0xd568, 0xe17d, 0x337f, 0x4b43, 0x2881, 0x1389, 0x38c7, 0x12c8, 0xcd26, 
+0xbcc3, 0xb56e, 0xdd1b, 0xe483, 0xea42, 0x2a90, 0x51ed, 0x261e, 0x0805, 0x4126, 
+0x1494, 0xbddc, 0xbaf3, 0xc450, 0xd324, 0xd5cd, 0xf712, 0x2ef6, 0x4d20, 0x2af3, 
+0x0e0c, 0x3762, 0x0ac6, 0xbe79, 0xae49, 0xc076, 0xd8d1, 0xd3ec, 0x0029, 0x3a43, 
+0x4756, 0x22ca, 0x1958, 0x35d2, 0xf721, 0xbeb2, 0xb3fe, 0xbef0, 0xda1f, 0xdc92, 
+0x07d3, 0x4050, 0x4bd0, 0x19d3, 0x154a, 0x3522, 0xefeb, 0xbbc4, 0xb715, 0xc994, 
+0xdf48, 0xe0b3, 0x1046, 0x40b6, 0x462c, 0x16f6, 0x1aab, 0x3230, 0xe981, 0xbd2a, 
+0xbab3, 0xd2a2, 0xe5c9, 0xe97f, 0x1c0b, 0x466f, 0x4272, 0x167d, 0x2642, 0x3042, 
+0xe930, 0xc684, 0xbe13, 0xdccc, 0xed63, 0xea9d, 0x2413, 0x5441, 0x43f9, 0x180c, 
+0x36e2, 0x2e3f, 0xdd7b, 0xc957, 0xc358, 0xdaa2, 0xeec1, 0xf6ba, 0x27c0, 0x5560, 
+0x448c, 0x1635, 0x38ef, 0x285a, 0xd524, 0xc336, 0xc6ef, 0xdd82, 0xe86a, 0x024a, 
+0x3514, 0x5243, 0x4024, 0x1679, 0x30ad, 0x19cb, 0xd2e3, 0xbea4, 0xc57f, 0xe4e0, 
+0xe5d6, 0xfff4, 0x3873, 0x4af7, 0x2f8e, 0x188b, 0x3243, 0x0881, 0xcd5e, 0xbb93, 
+0xbf31, 0xe52f, 0xe3f9, 0xfc94, 0x39c7, 0x4714, 0x1d41, 0x169d, 0x38c9, 0xfecd, 
+0xcb1a, 0xc0fc, 0xbdbe, 0xdc75, 0xe1b5, 0xfaa7, 0x3213, 0x48a1, 0x1b68, 0x15dc, 
+0x3a99, 0xf55f, 0xc01b, 0xbf71, 0xc2a6, 0xd4e4, 0xdf4d, 0x066a, 0x3170, 0x40f1, 
+0x1a26, 0x18e0, 0x342c, 0xedf9, 0xba41, 0xb3b4, 0xc38e, 0xd795, 0xe02b, 0x10cf, 
+0x387d, 0x3bf9, 0x151b, 0x1afe, 0x254b, 0xde99, 0xbc43, 0xb3bd, 0xc921, 0xde4a, 
+0xe189, 0x1332, 0x3ec6, 0x3af6, 0x0d82, 0x1fcf, 0x23ba, 0xd6bf, 0xb847, 0xb180, 
+0xcc73, 0xe0cc, 0xeb2b, 0x1cb5, 0x417e, 0x395b, 0x0e37, 0x260e, 0x1c37, 0xceea, 
+0xb693, 0xb466, 0xd44d, 0xde55, 0xeccf, 0x28e9, 0x4c64, 0x3a26, 0x1085, 0x2a16, 
+0x12d5, 0xcc04, 0xb7f6, 0xb4e4, 0xda25, 0xe424, 0xf801, 0x3387, 0x4c82, 0x2ff0, 
+0x133d, 0x33da, 0x0a6a, 0xc653, 0xba9f, 0xb9a4, 0xdb0d, 0xe2d3, 0xfd70, 0x3932, 
+0x535b, 0x2ec6, 0x131d, 0x36f2, 0x041c, 0xc4de, 0xbc13, 0xbb88, 0xdb49, 0xe632, 
+0x0792, 0x3bf9, 0x5215, 0x2df5, 0x197b, 0x38ba, 0xfc1c, 0xc000, 0xb9c1, 0xc559, 
+0xe3b9, 0xea55, 0x13bb, 0x45e0, 0x506f, 0x2598, 0x1a8a, 0x31d4, 0xf25d, 0xc2c1, 
+0xb752, 0xc926, 0xeaa3, 0xebad, 0x18ac, 0x4b3a, 0x4b14, 0x1dc9, 0x246e, 0x2f24, 
+0xe2ff, 0xc4be, 0xbca8, 0xccb7, 0xee7a, 0xf1d7, 0x1fad, 0x5446, 0x4e8c, 0x1a55, 
+0x2bfd, 0x2de3, 0xdbcc, 0xc7c4, 0xc19e, 0xcdf0, 0xeebf, 0x0347, 0x2b46, 0x50aa, 
+0x4efc, 0x1ae7, 0x2bc2, 0x29fc, 0xd661, 0xbcdd, 0xc496, 0xddc3, 0xe917, 0xff6c, 
+0x336f, 0x4f83, 0x433f, 0x1820, 0x2877, 0x176c, 0xd63d, 0xbf37, 0xbd41, 0xe3e4, 
+0xec70, 0xfccc, 0x35e8, 0x4cad, 0x2f68, 0x12a7, 0x2fac, 0x08d7, 0xcd76, 0xc4f5, 
+0xbf59, 0xdfbb, 0xe9f3, 0xfd34, 0x3194, 0x4aa3, 0x2767, 0x0f36, 0x33c2, 0x0048, 
+0xc54f, 0xc2fd, 0xbd10, 0xd605, 0xe41c, 0xff51, 0x2a83, 0x4801, 0x28e6, 0x0aff, 
+0x2f62, 0xfdb7, 0xbd39, 0xb775, 0xc18e, 0xd7dc, 0xe021, 0x0a7d, 0x33af, 0x423a, 
+0x2081, 0x0d26, 0x28f2, 0xf6aa, 0xc604, 0xb20f, 0xca22, 0xf929, 0xe0c9, 0xfe41, 
+0x2c91, 0x285c, 0x3479, 0x40e1, 0x11dd, 0xd23c, 0xd207, 0xa861, 0xa807, 0xfe96, 
+0xf904, 0x0d6b, 0x7934, 0x78f8, 0x0f08, 0xfce1, 0xe859, 0x8e1b, 0xa714, 0xc4a3, 
+0xd05d, 0x3229, 0x6379, 0x4af3, 0x48ea, 0x4a2d, 0xe67d, 0xa875, 0xd782, 0xc120, 
+0xb7cb, 0xfb9f, 0x1f2e, 0x34e8, 0x4bf0, 0x20cd, 0xf0b2, 0x1643, 0x0563, 0xbcd0, 
+0xf27f, 0x2741, 0xe7cd, 0xef58, 0x2d5f, 0xebc6, 0xc657, 0x2de0, 0x1cb6, 0xe47e, 
+0x4360, 0x2d6e, 0xe23e, 0x16ee, 0xf98d, 0xa445, 0xddbb, 0x207f, 0xe2c0, 0x123e, 
+0x5bce, 0x016d, 0x1099, 0x3582, 0xc93d, 0xb242, 0x0573, 0xeaa3, 0xcd42, 0x3ec8, 
+0x2edf, 0xedf6, 0x39f9, 0x19b8, 0xb85b, 0xe3bc, 0x1369, 0xd1a8, 0xf1db, 0x3e71, 
+0xf679, 0x05fa, 0x4211, 0xe5a8, 0xbfbb, 0x17fb, 0x0686, 0xc767, 0x1e4b, 0x24e5, 
+0xdea8, 0x2460, 0x26bf, 0xbfbf, 0xebef, 0x3662, 0xdb5b, 0xe735, 0x478f, 0xf36f, 
+0xe6aa, 0x3a12, 0xedab, 0xb885, 0x2168, 0x1a11, 0xd137, 0x2b7c, 0x29a9, 0xd6be, 
+0x2004, 0x24d0, 0xb744, 0xddad, 0x2f52, 0xe201, 0xeeef, 0x4b3b, 0xfc02, 0xef7b, 
+0x3d92, 0xf6b9, 0xb6be, 0x0b17, 0x0d77, 0xc534, 0x191c, 0x30b3, 0xe945, 0x23b0, 
+0x2f3b, 0xc9bb, 0xd7dc, 0x269c, 0xe46c, 0xd902, 0x3766, 0x0212, 0xeb25, 0x39af, 
+0x03e0, 0xb8e7, 0x077c, 0x169d, 0xcc6f, 0x1b10, 0x2e0e, 0xd19a, 0x0fd8, 0x38f6, 
+0xca91, 0xc8f9, 0x29d6, 0xf078, 0xdd5c, 0x3b96, 0x09ef, 0xf001, 0x3507, 0xfbb1, 
+0xb660, 0x03d5, 0x0e0a, 0xc387, 0x17f0, 0x3e5b, 0xe93c, 0x15a4, 0x38a5, 0xd46a, 
+0xc5fe, 0x1360, 0xe4bc, 0xda9b, 0x39bc, 0x0c8d, 0xef2a, 0x3f9f, 0x0fdb, 0xb193, 
+0xf8d2, 0x1694, 0xb855, 0xffea, 0x4558, 0xed39, 0x083b, 0x3cd1, 0xda45, 0xc36d, 
+0x1e6e, 0xe476, 0xc765, 0x430f, 0x19a5, 0xde45, 0x3c55, 0x16d3, 0xa619, 0xf171, 
+0x1f0a, 0xbe1b, 0x04f9, 0x4d9d, 0xeec4, 0x0d1f, 0x3e78, 0xccbe, 0xb49f, 0x1d9b, 
+0xeb29, 0xc2b6, 0x448d, 0x28e1, 0xe2a4, 0x3aab, 0x21b9, 0xad2c, 0xe5d9, 0x1d14, 
+0xbe21, 0xf5ec, 0x4db1, 0xef99, 0x030b, 0x4e45, 0xe3cc, 0xb105, 0x20c5, 0xfc50, 
+0xb9ac, 0x35e2, 0x2898, 0xd9cf, 0x3397, 0x236d, 0xace6, 0xea90, 0x2c38, 0xc65d, 
+0xf7eb, 0x5313, 0xe39f, 0xf211, 0x477a, 0xdbe9, 0xad7a, 0x1ffa, 0x0017, 0xc201, 
+0x3906, 0x27ff, 0xd56a, 0x2d70, 0x20b7, 0xa843, 0xe22b, 0x2d3a, 0xc8d1, 0xeff9, 
+0x5809, 0xf171, 0xf1ca, 0x4aa1, 0xe752, 0xa7f6, 0x1531, 0x03a8, 0xbd38, 0x3515, 
+0x35e4, 0xd873, 0x2cec, 0x2fa3, 0xaedb, 0xd92e, 0x2cc6, 0xccea, 0xe531, 0x5116, 
+0xf947, 0xf6dd, 0x4ce8, 0xef45, 0xaeac, 0x190f, 0x0bfc, 0xbc68, 0x2afb, 0x3612, 
+0xd723, 0x2687, 0x3899, 0xbdfb, 0xda26, 0x3069, 0xdbaf, 0xe6bf, 0x5016, 0x0057, 
+0xf1d5, 0x480e, 0xf64b, 0xad29, 0x13a0, 0x16f4, 0xc33e, 0x2614, 0x4041, 0xe193, 
+0x201a, 0x3648, 0xc1be, 0xd35e, 0x2aee, 0xe031, 0xe3b6, 0x52de, 0x0b18, 0xedc3, 
+0x4b67, 0x084a, 0xaf95, 0x0ccc, 0x1af7, 0xc089, 0x19da, 0x4369, 0xe6d2, 0x1d97, 
+0x422d, 0xcfe2, 0xd1f7, 0x2e93, 0xe6d4, 0xd904, 0x4acc, 0x0d46, 0xe47d, 0x425b, 
+0x0eb4, 0xb1bb, 0x06af, 0x2009, 0xc469, 0x12a4, 0x3fee, 0xdd98, 0x0e0f, 0x3d40, 
+0xcdb1, 0xc9b2, 0x2f38, 0xedc8, 0xcf7d, 0x42ef, 0x1026, 0xd9af, 0x3710, 0x1033, 
+0xad12, 0xfd62, 0x2285, 0xc358, 0x0c72, 0x48be, 0xe51c, 0x0a9a, 0x2ff8, 0xbdc8, 
+0xc28d, 0x2cc9, 0xfec9, 0xc7ca, 0x13e5, 0x17e1, 0x02ca, 0x35c6, 0x0fac, 0xcd93, 
+0xf8c0, 0xfbac, 0xbba6, 0xe67f, 0x0735, 0xd6a6, 0x1bde, 0x7350, 0x2eb9, 0xfad9, 
+0x2334, 0xeee4, 0xa104, 0xc9e5, 0xcf89, 0xd376, 0x2f8b, 0x2f58, 0x13f9, 0x6199, 
+0x5172, 0xd760, 0xdae6, 0x0109, 0xaaab, 0x9f01, 0x11f6, 0x1c74, 0xff8b, 0x303b, 
+0x3d89, 0x2a49, 0x1900, 0xe5d6, 0xbb94, 0xe00a, 0xeeb6, 0xce23, 0x0253, 0x3291, 
+0x20e8, 0x0d77, 0x2650, 0x2ac1, 0xf46d, 0xf971, 0xdbe5, 0xc599, 0xf13a, 0xdd86, 
+0xebfb, 0x30a4, 0x422d, 0x0726, 0x20e1, 0x53cf, 0xe990, 0xbf8d, 0xd717, 0xc738, 
+0xcc12, 0xed69, 0x1207, 0x2679, 0x4b59, 0x2072, 0x0f6e, 0x3b3c, 0xef93, 0xaf82, 
+0xc07e, 0xdcf5, 0xccea, 0xe17b, 0x31b5, 0x3ad1, 0x3673, 0x24ae, 0x1fad, 0x2260, 
+0xf0dd, 0xc29e, 0xb494, 0xe43c, 0xe377, 0xdb2b, 0x2318, 0x45fc, 0x34e0, 0x20c4, 
+0x3ea5, 0x232d, 0xdb31, 0xcc1d, 0xb320, 0xc65a, 0xdf18, 0xea47, 0x25f0, 0x5cd4, 
+0x4386, 0x10e7, 0x3d78, 0x214b, 0xc538, 0xbca9, 0xbe8b, 0xcd16, 0xe049, 0x05f5, 
+0x2fe8, 0x5197, 0x45f2, 0x0fc2, 0x2f2f, 0x1971, 0xc5a7, 0xb7fc, 0xca80, 0xd975, 
+0xd7df, 0x0c99, 0x3a4e, 0x3fc6, 0x30e6, 0x13a0, 0x2b87, 0x0f79, 0xcd82, 0xaf27, 
+0xc107, 0xe381, 0xd5f3, 0x035c, 0x44e6, 0x44fc, 0x1db9, 0x1e95, 0x3a4e, 0xf713, 
+0xc17f, 0xb545, 0xc44b, 0xea43, 0xe0b2, 0x034f, 0x458e, 0x4e96, 0x1557, 0x1819, 
+0x3caa, 0xeb53, 0xb81f, 0xc29d, 0xcb34, 0xd827, 0xea2e, 0x153f, 0x3683, 0x4599, 
+0x17a8, 0x1025, 0x3238, 0xefae, 0xb3df, 0xb7d0, 0xd811, 0xd6f7, 0xd85a, 0x1792, 
+0x3a94, 0x35ea, 0x1657, 0x21c8, 0x243d, 0xdfb1, 0xbb30, 0xb0e9, 0xceed, 0xddbf, 
+0xdff2, 0x1be1, 0x44e0, 0x3265, 0x0879, 0x260d, 0x1f6a, 0xcd4c, 0xba1b, 0xbafd, 
+0xcb3d, 0xd899, 0xeb07, 0x19d6, 0x3c13, 0x3544, 0x08ed, 0x2407, 0x1daa, 0xcd68, 
+0xb792, 0xbf01, 0xd1c2, 0xd611, 0xf34b, 0x259b, 0x3b2f, 0x2f39, 0x1053, 0x2d78, 
+0x1a05, 0xd265, 0xba97, 0xc02a, 0xdab7, 0xd903, 0xf86d, 0x2ff9, 0x403d, 0x28d3, 
+0x14a1, 0x34af, 0x0a0e, 0xcda4, 0xc3ac, 0xc13a, 0xdd8d, 0xe2ea, 0xfd27, 0x2eb2, 
+0x45ac, 0x26be, 0x14ec, 0x3dd9, 0x06bc, 0xc81d, 0xc6e2, 0xc719, 0xd8c3, 0xe5c7, 
+0x0b66, 0x32c9, 0x4b92, 0x2cb4, 0x19ce, 0x3c10, 0x0272, 0xc5eb, 0xbb96, 0xccd7, 
+0xe07a, 0xdfbb, 0x160a, 0x4341, 0x4749, 0x2676, 0x21c7, 0x2fd3, 0xf0d0, 0xc6ee, 
+0xb624, 0xcad8, 0xe85f, 0xe7c5, 0x1d81, 0x4b84, 0x45af, 0x1eba, 0x2c0d, 0x30c1, 
+0xe4ba, 0xca8d, 0xbdbe, 0xcc89, 0xed50, 0xf3dd, 0x2203, 0x5159, 0x4cd1, 0x1b22, 
+0x2e08, 0x3255, 0xe28f, 0xc7e6, 0xc2e3, 0xd510, 0xe8de, 0xfa14, 0x2846, 0x4a33, 
+0x4c04, 0x1fed, 0x2f64, 0x2cdb, 0xe195, 0xc51d, 0xc13f, 0xdb62, 0xe696, 0xfa3e, 
+0x31bd, 0x4d3c, 0x4355, 0x2150, 0x33b3, 0x204a, 0xe0d7, 0xc877, 0xbdd9, 0xdeff, 
+0xeb46, 0x0024, 0x3a0c, 0x5485, 0x3c57, 0x1fe4, 0x3a57, 0x110e, 0xd1f0, 0xc4f8, 
+0xbfae, 0xe303, 0xf0e8, 0x0757, 0x3795, 0x525c, 0x364d, 0x163e, 0x3411, 0x078d, 
+0xc95e, 0xbed3, 0xc146, 0xdd79, 0xe8cb, 0x0fb0, 0x3b8b, 0x4b40, 0x2f52, 0x1708, 
+0x2c9b, 0xf6f7, 0xc33e, 0xb8f8, 0xc0a0, 0xe27b, 0xe6d8, 0x0c22, 0x3d9b, 0x4878, 
+0x24a6, 0x186c, 0x2467, 0xe600, 0xc014, 0xb323, 0xbc0b, 0xe0eb, 0xe8da, 0x0f11, 
+0x3cef, 0x40c5, 0x12df, 0x1430, 0x227a, 0xdb2e, 0xb8c4, 0xb5de, 0xc528, 0xdd7a, 
+0xe824, 0x13d4, 0x3e15, 0x4384, 0x124e, 0x1469, 0x1e10, 0xd6df, 0xb7fb, 0xb8e3, 
+0xcdaf, 0xdd42, 0xecbb, 0x1e7d, 0x3c6f, 0x378a, 0x1149, 0x1e8a, 0x1b08, 0xd447, 
+0xb3c7, 0xb0b3, 0xd341, 0xe16d, 0xebda, 0x22db, 0x4450, 0x345d, 0x0fcd, 0x27aa, 
+0x137c, 0xcfd2, 0xc241, 0xbb1b, 0xd538, 0xe771, 0xf62c, 0x297f, 0x4c37, 0x3271, 
+0x103e, 0x360c, 0x143c, 0xc8cb, 0xc2e2, 0xc46f, 0xd919, 0xe83f, 0x0316, 0x2e44, 
+0x49f7, 0x320d, 0x1102, 0x34eb, 0x0f20, 0xc998, 0xc1e5, 0xc68b, 0xd8b7, 0xe3aa, 
+0x0e51, 0x3839, 0x473d, 0x306d, 0x1936, 0x313b, 0x023a, 0xca3b, 0xb9cb, 0xc4e8, 
+0xe9a8, 0xe8e8, 0x0e4f, 0x4390, 0x4a72, 0x23d2, 0x1d52, 0x31ca, 0xf0b0, 0xc813, 
+0xbd25, 0xc202, 0xe6ea, 0xee18, 0x12c8, 0x4476, 0x4b2e, 0x198b, 0x19a1, 0x2fcc, 
+0xe518, 0xbf8d, 0xbe9e, 0xcb6d, 0xe622, 0xee0e, 0x167e, 0x3fbf, 0x46fb, 0x1a7d, 
+0x1f4e, 0x2d08, 0xe17f, 0xbedd, 0xbaa3, 0xcc16, 0xe196, 0xeedc, 0x21cc, 0x44ed, 
+0x4348, 0x1a18, 0x2363, 0x242e, 0xdc65, 0xbd61, 0xb300, 0xcfa0, 0xe712, 0xe5c7, 
+0x169f, 0x5f17, 0x7299, 0x2bb1, 0x0b65, 0xe2fd, 0x9b1c, 0xa3b5, 0xaeb5, 0xe147, 
+0x3787, 0x593a, 0x5290, 0x4a3c, 0x2e69, 0xcbb4, 0xa91f, 0xc5a3, 0xbd85, 0xd07b, 
+0x1055, 0x3d01, 0x2411, 0x222c, 0x2b1a, 0x0b05, 0xffdc, 0xe3f2, 0xcf8c, 0xf390, 
+0x15ad, 0xd9f5, 0xc944, 0x2d37, 0x09de, 0xc93f, 0x0d00, 0x229d, 0x0eb5, 0x31fb, 
+0x193d, 0xdefd, 0x0b6e, 0xe2b8, 0x80c1, 0xd2cb, 0x1719, 0xe9c2, 0x3008, 0x6a8a, 
+0xfee8, 0x01bc, 0x299a, 0xb39d, 0xa48f, 0x0798, 0xe5e9, 0xddfa, 0x41e1, 0x17dc, 
+0xf43b, 0x3829, 0x05c3, 0xbd89, 0xf1bc, 0x0dab, 0xcd37, 0xfad8, 0x2e14, 0xf080, 
+0x107b, 0x24ea, 0xd852, 0xd4a0, 0x17fd, 0xfd24, 0xd818, 0x2b57, 0x168d, 0xdb81, 
+0x1759, 0x0cdb, 0xc867, 0xf2e6, 0x257d, 0xe349, 0xfff1, 0x39a1, 0xe33d, 0xee45, 
+0x2b9d, 0xe388, 0xc702, 0x21a8, 0x103e, 0xda0f, 0x2f4b, 0x1b70, 0xd6c1, 0x1b55, 
+0x104d, 0xb577, 0xe811, 0x28c6, 0xe0aa, 0xfee3, 0x4403, 0xf56f, 0xf711, 0x2c32, 
+0xe60a, 0xbd96, 0x0d61, 0x048f, 0xce3d, 0x272f, 0x325d, 0xf1c7, 0x2094, 0x1ff0, 
+0xc860, 0xe30a, 0x2515, 0xdac5, 0xe92d, 0x441f, 0x0548, 0xfb76, 0x3d79, 0xfd5c, 
+0xbecb, 0x1149, 0x13f9, 0xd214, 0x2a6f, 0x3388, 0xe6f8, 0x2190, 0x2948, 0xc4a5, 
+0xdd42, 0x2f43, 0xe6af, 0xf03f, 0x54db, 0x13d9, 0xfca6, 0x3215, 0xf506, 0xc57a, 
+0x12c0, 0x0f9f, 0xd3cc, 0x322e, 0x4301, 0xf273, 0x23ab, 0x356e, 0xd3b2, 0xd051, 
+0x21b7, 0xf281, 0xecda, 0x4489, 0x12f0, 0x0242, 0x4407, 0x06d1, 0xbafe, 0x0b6c, 
+0x1d26, 0xc6ee, 0x19bc, 0x44e9, 0xe86d, 0x13b7, 0x39ca, 0xd446, 0xd119, 0x2941, 
+0xee93, 0xe7c5, 0x4bc2, 0x0643, 0xe908, 0x4535, 0x0444, 0xaaed, 0x0a10, 0x21a1, 
+0xc807, 0x1964, 0x41d6, 0xe77b, 0x16b3, 0x34e4, 0xc869, 0xc8dc, 0x2196, 0xe4ba, 
+0xdb97, 0x4973, 0x106a, 0xe7d9, 0x3cc5, 0x0a39, 0xa769, 0xf083, 0x1925, 0xc4c2, 
+0x075d, 0x3c4a, 0xe3ca, 0x0d28, 0x38d3, 0xc8d1, 0xbd34, 0x29a4, 0xea91, 0xbfc6, 
+0x3ad0, 0x0fbe, 0xd348, 0x3125, 0x0f03, 0xa6a3, 0xf4e3, 0x222b, 0xbe73, 0x00e2, 
+0x3cfa, 0xd671, 0xff6d, 0x3893, 0xc753, 0xb6c9, 0x236e, 0xec95, 0xc571, 0x3925, 
+0x1324, 0xdbd6, 0x2c09, 0x07a8, 0xaa2d, 0xf242, 0x1fa6, 0xc716, 0x042c, 0x441c, 
+0xe490, 0xffd3, 0x3dc4, 0xdc2a, 0xb9f6, 0x1f30, 0xfbb0, 0xca2e, 0x371c, 0x2003, 
+0xddf1, 0x31fa, 0x2307, 0xb4d8, 0xf004, 0x2cbc, 0xc878, 0xf7c6, 0x4caf, 0xed6b, 
+0xfe78, 0x48e2, 0xe5f3, 0xb861, 0x209c, 0xffdd, 0xc990, 0x3a8f, 0x2235, 0xd8df, 
+0x3307, 0x26fb, 0xb85c, 0xf04e, 0x2cb8, 0xd049, 0xfa7c, 0x49ae, 0xedac, 0xfa25, 
+0x3f7d, 0xe587, 0xbae6, 0x1de2, 0x03f4, 0xc964, 0x35b0, 0x2bf3, 0xdcc1, 0x287a, 
+0x2509, 0xb53e, 0xdd34, 0x21f5, 0xd014, 0xf4e6, 0x5327, 0xfbed, 0xf63d, 0x422a, 
+0xebde, 0xadff, 0x109b, 0x03c0, 0xc66e, 0x34a1, 0x371f, 0xe1e5, 0x266b, 0x298a, 
+0xb6ec, 0xdb6e, 0x2815, 0xd421, 0xf019, 0x5352, 0xff26, 0xf3f2, 0x43a2, 0xf389, 
+0xb155, 0x11bc, 0x093e, 0xc3cf, 0x2cd7, 0x37d3, 0xe04d, 0x22e3, 0x2ecd, 0xb8a8, 
+0xd4f6, 0x2b5c, 0xd879, 0xe9c1, 0x5345, 0x0074, 0xeb1b, 0x3d0d, 0xf0a8, 0xa78e, 
+0x0f83, 0x1369, 0xc523, 0x2e80, 0x3d4c, 0xdb13, 0x1e41, 0x2ecc, 0xb34d, 0xd013, 
+0x2f65, 0xd81e, 0xe458, 0x57d2, 0x0406, 0xebe0, 0x457a, 0xf7e1, 0xa66e, 0x0b6f, 
+0x0e7a, 0xb8d1, 0x251b, 0x3fe1, 0xdd7d, 0x20b9, 0x3687, 0xbb17, 0xd0b9, 0x2e06, 
+0xd6de, 0xd8c9, 0x50ce, 0x0665, 0xe605, 0x3fce, 0xfc63, 0xac6f, 0x0f4a, 0x249e, 
+0xcfcc, 0xfc68, 0x0488, 0xeb03, 0x4794, 0x43ec, 0xda83, 0xf3bd, 0x2644, 0xc019, 
+0xac19, 0xfdb7, 0xdae0, 0xebc8, 0x4a7e, 0x4842, 0x204b, 0x2f4a, 0x0bd7, 0xb466, 
+0xc7b6, 0xc25a, 0x9ff5, 0xfeaa, 0x3147, 0xf5d6, 0x1606, 0x7098, 0x2536, 0xcb1f, 
+0xef7c, 0xd8bb, 0xa610, 0xc6a6, 0xf94d, 0x01cf, 0x2326, 0x2e92, 0xfa36, 0x1b23, 
+0x1fee, 0xc9e0, 0xbf64, 0xf0f7, 0xebf9, 0xcd60, 0xfed7, 0x1727, 0x0a34, 0x1723, 
+0x0a36, 0x0e7b, 0x18aa, 0xfc64, 0xb854, 0xc985, 0xfdd8, 0xc68b, 0xea58, 0x3e80, 
+0x2a34, 0x0ba2, 0x2d28, 0x367f, 0xec1b, 0xe1de, 0xce20, 0xb654, 0xf084, 0xed7d, 
+0xf556, 0x44c2, 0x5de8, 0x118c, 0x103a, 0x43c2, 0xea97, 0xbbb3, 0xd781, 0xd5a7, 
+0xe105, 0xfd04, 0x1bc6, 0x2dbd, 0x4a4e, 0x2262, 0x090c, 0x37f3, 0x0697, 0xc337, 
+0xc445, 0xe70d, 0xe217, 0xdb53, 0x1953, 0x38c9, 0x40c1, 0x2ede, 0x22c3, 0x260c, 
+0xfc8c, 0xcfd4, 0xb0e1, 0xd39e, 0xe34c, 0xdae1, 0x253f, 0x508f, 0x342f, 0x1aa5, 
+0x3628, 0x1e6e, 0xd753, 0xc9cd, 0xb7c4, 0xd23c, 0xef41, 0xeb30, 0x1cc2, 0x523c, 
+0x3c38, 0x02b5, 0x29f9, 0x28a2, 0xd759, 0xd1f8, 0xd1bf, 0xd245, 0xe508, 0xfe91, 
+0x19fc, 0x3b30, 0x3d9b, 0x0a4c, 0x2fd0, 0x37f4, 0xdc8c, 0xbe49, 0xd7b4, 0xe591, 
+0xd3af, 0xfd0f, 0x3070, 0x36f1, 0x325e, 0x18a4, 0x3386, 0x27ca, 0xdc73, 0xb513, 
+0xcdc8, 0xf809, 0xd5d9, 0xf013, 0x4334, 0x4964, 0x2395, 0x1b7b, 0x3c5a, 0x0fe4, 
+0xd7a3, 0xc6c6, 0xc6b6, 0xf0cf, 0xeb7d, 0xf80b, 0x3914, 0x525a, 0x2445, 0x1417, 
+0x4928, 0x0ff5, 0xc35d, 0xc78a, 0xd244, 0xdff9, 0xe35e, 0x07df, 0x35ae, 0x4ba7, 
+0x2974, 0x1106, 0x3cf3, 0x0fec, 0xc4b4, 0xb9c7, 0xd562, 0xe489, 0xd970, 0x0e52, 
+0x3f61, 0x43d6, 0x27aa, 0x2131, 0x364b, 0xfd16, 0xc955, 0xb961, 0xcde0, 0xe8ce, 
+0xe024, 0x0e4f, 0x4544, 0x4582, 0x18cd, 0x22be, 0x3a77, 0xf22e, 0xc4f3, 0xbabf, 
+0xcce0, 0xe32e, 0xe352, 0x12f7, 0x43a1, 0x4666, 0x1401, 0x1c0c, 0x30e6, 0xe619, 
+0xbb56, 0xbb95, 0xd491, 0xe00b, 0xe61a, 0x17a4, 0x3b47, 0x3b00, 0x10e7, 0x1c7e, 
+0x2707, 0xe361, 0xb750, 0xb2d2, 0xd7be, 0xdb41, 0xe145, 0x2096, 0x40ed, 0x319a, 
+0x118b, 0x2924, 0x1a2e, 0xd6af, 0xba5f, 0xad6c, 0xd2c9, 0xe064, 0xe67c, 0x25df, 
+0x4ea4, 0x3357, 0x0fc7, 0x312c, 0x1020, 0xc418, 0xb5ff, 0xb68a, 0xd4f7, 0xe2ef, 
+0xfb14, 0x2e11, 0x4c3e, 0x3280, 0x08fc, 0x2966, 0x0e36, 0xc69d, 0xb3ba, 0xbf26, 
+0xde72, 0xe461, 0x0918, 0x3887, 0x4967, 0x313c, 0x1236, 0x2763, 0x0526, 0xcb44, 
+0xb35a, 0xc8b5, 0xed8f, 0xdf83, 0x05bf, 0x41b2, 0x4548, 0x20ab, 0x1a30, 0x2bd9, 
+0xf884, 0xce0f, 0xb377, 0xc10c, 0xede8, 0xe5b7, 0x0520, 0x42f2, 0x4b64, 0x19c0, 
+0x1a50, 0x2fd7, 0xee52, 0xc8d4, 0xbcea, 0xc661, 0xe5d5, 0xe9b8, 0x0e4b, 0x42da, 
+0x4c23, 0x187a, 0x1ba9, 0x2fdd, 0xe89e, 0xbcad, 0xb84a, 0xd201, 0xe619, 0xeba8, 
+0x1a61, 0x40ef, 0x41b7, 0x151a, 0x1cbf, 0x2b05, 0xea44, 0xc1f8, 0xbc6c, 0xdb3c, 
+0xe422, 0xe69f, 0x208e, 0x4881, 0x3cc7, 0x1503, 0x2aa9, 0x27ed, 0xe431, 0xc5cc, 
+0xbdfa, 0xdd9a, 0xe8e9, 0xf074, 0x2496, 0x4a59, 0x3e74, 0x1374, 0x2e8f, 0x252c, 
+0xd82c, 0xba66, 0xbeda, 0xe1cc, 0xe3a5, 0xf456, 0x3043, 0x4df4, 0x382a, 0x0d8b, 
+0x25d9, 0x1516, 0xd249, 0xb805, 0xbbdd, 0xe317, 0xe31f, 0xf717, 0x307f, 0x4438, 
+0x2ce7, 0x1089, 0x29b8, 0x060d, 0xc757, 0xb6c7, 0xb848, 0xdd4c, 0xde36, 0xf60e, 
+0x341a, 0x45f6, 0x1fc8, 0x0b03, 0x2ed5, 0xff75, 0xc14a, 0xb3bb, 0xb4dc, 0xd6d2, 
+0xdc36, 0xfbb0, 0x356c, 0x49c3, 0x2300, 0x0fe9, 0x2f18, 0xf499, 0xb802, 0xb1b2, 
+0xc06f, 0xdc85, 0xde22, 0x0805, 0x3cc1, 0x488e, 0x1f2e, 0x11d7, 0x2c64, 0xf3b1, 
+0xbd78, 0xadbb, 0xc5eb, 0xe451, 0xde57, 0x0e82, 0x4140, 0x4137, 0x1916, 0x1b84, 
+0x28d4, 0xe639, 0xc1a0, 0xb2e7, 0xc697, 0xe4be, 0xdf87, 0x10dc, 0x49b4, 0x457d, 
+0x1479, 0x2405, 0x2b0f, 0xdcbe, 0xbefc, 0xb3a9, 0xc6dd, 0xe60b, 0xed45, 0x1b13, 
+0x497b, 0x4531, 0x1324, 0x24b0, 0x243c, 0xd210, 0xb83d, 0xb984, 0xd0bc, 0xe2a6, 
+0xf3b7, 0x2766, 0x4a82, 0x4204, 0x133f, 0x22b4, 0x1b4e, 0xd4a3, 0xba37, 0xbaaf, 
+0xdf26, 0xea12, 0xf84b, 0x3177, 0x4e17, 0x39af, 0x193b, 0x308a, 0x13c1, 0xd6b0, 
+0xc5d3, 0xbffc, 0xe599, 0xeec6, 0xff4d, 0x38ac, 0x5167, 0x346a, 0x1b9d, 0x376a, 
+0x0ce4, 0xd4a8, 0xc78f, 0xc195, 0xe4f4, 0xf0f5, 0x07bb, 0x3cdc, 0x5981, 0x3510, 
+0x1b26, 0x3a31, 0x03fb, 0xca72, 0xc53e, 0xcd25, 0xecab, 0xf768, 0x193e, 0x437d, 
+0x53af, 0x2c6f, 0x15b8, 0x31bf, 0xff10, 0xcc99, 0xc147, 0xd348, 0xee05, 0xee95, 
+0x1782, 0x2f2b, 0x4b20, 0x5a80, 0x2b14, 0xfd25, 0xdd6a, 0xccb5, 0x9c77, 0xbb91, 
+0x0abb, 0xfa6d, 0x308d, 0x8b3b, 0x6386, 0x0f1b, 0x0366, 0xd9a6, 0x969a, 0xbb36, 
+0xbe42, 0xd650, 0x4a43, 0x5e11, 0x39f6, 0x4e5f, 0x3f3f, 0xd1f7, 0xbac7, 0xda01, 
+0xb75e, 0xdb85, 0x0689, 0x0f50, 0x402d, 0x3a48, 0xf492, 0xf3ba, 0x232e, 0xe3c2, 
+0xc221, 0x1c7e, 0x103b, 0xda32, 0x0d99, 0x12a9, 0xc374, 0xe4a9, 0x2fee, 0xef59, 
+0xf571, 0x4551, 0x09ce, 0xee4d, 0x190c, 0xdd87, 0xa5eb, 0xf5c9, 0x0d02, 0xd8dd, 
+0x32e0, 0x4556, 0xf27b, 0x272d, 0x1a0f, 0xac2d, 0xc929, 0x0d48, 0xd065, 0xe73f, 
+0x4fb6, 0x0a4b, 0xfcc1, 0x4512, 0xed54, 0xb2b9, 0x0350, 0xfc0b, 0xbed7, 0x1926, 
+0x2f0c, 0xe1a6, 0x2871, 0x338a, 0xc365, 0xd8fc, 0x2261, 0xe12a, 0xda5e, 0x3836, 
+0x02a6, 0xeb2d, 0x3c29, 0xfc95, 0xb47f, 0x126c, 0x2240, 0xc4df, 0x1301, 0x42d9, 
+0xddbd, 0x05c8, 0x2ff4, 0xc609, 0xc9ef, 0x2ebd, 0xf193, 0xda07, 0x46da, 0x0cd3, 
+0xe052, 0x39eb, 0x0085, 0xa3df, 0xfdbd, 0x1d67, 0xc36d, 0x1321, 0x461a, 0xe3db, 
+0x121d, 0x3bc5, 0xce7e, 0xc611, 0x1e92, 0xe869, 0xd146, 0x3d6e, 0x12f6, 0xe781, 
+0x3a2e, 0x100e, 0xb4c0, 0xf87f, 0x2451, 0xce12, 0xfd54, 0x3b61, 0xe9af, 0x0485, 
+0x363a, 0xd7a5, 0xc531, 0x26b6, 0xfb26, 0xd3af, 0x4024, 0x13d3, 0xcf38, 0x31ca, 
+0x1fe6, 0xacba, 0xe830, 0x28d0, 0xd67b, 0x03f4, 0x4390, 0xeff5, 0x0d9b, 0x3cdc, 
+0xd2ef, 0xbce5, 0x1df5, 0xf194, 0xcc0a, 0x3c7b, 0x22be, 0xe9d0, 0x37e4, 0x1f21, 
+0xbf6a, 0xed14, 0x13f9, 0xccad, 0xfeed, 0x36f2, 0xe931, 0x0bd9, 0x4870, 0xe9a7, 
+0xc649, 0x2406, 0x009e, 0xc7de, 0x28c6, 0x1d14, 0xe19d, 0x2d2e, 0x24eb, 0xc1ae, 
+0xf293, 0x2948, 0xd034, 0xfc36, 0x4c80, 0xed33, 0xf76a, 0x4574, 0xe546, 0xb51f, 
+0x205e, 0x01e4, 0xc8f6, 0x3c9b, 0x2dfd, 0xe000, 0x3231, 0x23e4, 0xac3f, 0xe1e2, 
+0x2470, 0xc806, 0xf279, 0x51f9, 0xfc93, 0xfd3d, 0x471f, 0xf14b, 0xb564, 0x0d8d, 
+0xf7a1, 0xbaf7, 0x2ae2, 0x3330, 0xe3cf, 0x2876, 0x2f9d, 0xbe99, 0xd8ed, 0x2066, 
+0xcc5b, 0xe037, 0x444b, 0xfc55, 0xf1ae, 0x3dee, 0xedb1, 0xa9f3, 0x0f58, 0x052a, 
+0xb88b, 0x286b, 0x32e9, 0xd191, 0x1a2d, 0x2b19, 0xb1ba, 0xd055, 0x2574, 0xcd9d, 
+0xe17a, 0x4f5d, 0xf991, 0xe9c8, 0x4424, 0xee22, 0xa03f, 0x0b3e, 0x0833, 0xb2f6, 
+0x25d7, 0x3fb5, 0xd971, 0x1eca, 0x3552, 0xb55f, 0xc5ed, 0x2341, 0xd2b5, 0xd7c1, 
+0x523e, 0x069d, 0xe63d, 0x453d, 0xfaec, 0xa137, 0x0414, 0x12c4, 0xb981, 0x1bb8, 
+0x4054, 0xdb21, 0x1feb, 0x3f6a, 0xbc6b, 0xcb19, 0x2eaa, 0xdddc, 0xd782, 0x53f0, 
+0x0db9, 0xe5f5, 0x4ae5, 0x09f1, 0xaaaa, 0x08ea, 0x1b96, 0xc280, 0x22c4, 0x4ce0, 
+0xe24f, 0x1cfe, 0x4491, 0xc23a, 0xc424, 0x2faf, 0xe9a8, 0xd606, 0x50b8, 0x16c3, 
+0xe5a3, 0x41e4, 0x0b1a, 0xa940, 0xfef6, 0x1bdf, 0xbfb1, 0x1607, 0x4e4e, 0xe252, 
+0x116e, 0x44af, 0xc71f, 0xbeed, 0x2c56, 0xed57, 0xd13f, 0x46da, 0x1220, 0xdf44, 
+0x3fcf, 0x0e72, 0xa687, 0xfe99, 0x22c2, 0xc0f4, 0x10f5, 0x4ab0, 0xdcc9, 0x0862, 
+0x42d3, 0xcce8, 0xbf2b, 0x2c4a, 0xf130, 0xcf23, 0x47a0, 0x1557, 0xd894, 0x3b17, 
+0x15eb, 0xac91, 0xfc3e, 0x2839, 0xc889, 0x0a6b, 0x4a0a, 0xe524, 0x0571, 0x40a3, 
+0xd642, 0xc2d3, 0x2b1c, 0xfa19, 0xd4f9, 0x465b, 0x1ef6, 0xe106, 0x371e, 0x15ec, 
+0xb185, 0xfc2f, 0x2898, 0xcc97, 0x0b55, 0x4c1f, 0xebc4, 0x08bc, 0x3f08, 0xd705, 
+0xc599, 0x2bb5, 0x081d, 0xcd96, 0x0d3b, 0x0ffa, 0x0823, 0x3f09, 0x1a45, 0xdad9, 
+0x0662, 0x07b7, 0xbb6a, 0xde9a, 0x0740, 0xda46, 0x0e1e, 0x6549, 0x38b1, 0x04bd, 
+0x2510, 0xf943, 0xad98, 0xc9a0, 0xca5c, 0xcaba, 0x22c9, 0x2b10, 0x01f0, 0x511a, 
+0x637c, 0xe409, 0xcfea, 0xff1b, 0xbae4, 0x9b34, 0xfafc, 0x154f, 0xfdb5, 0x2da1, 
+0x2e82, 0x1b20, 0x2472, 0xf46c, 0xbc6b, 0xd8c3, 0xf895, 0xcd65, 0xe4ee, 0x20c1, 
+0x1821, 0x08d6, 0x178c, 0x2a03, 0x07e8, 0xfe05, 0xe136, 0xbccf, 0xeb99, 0xdae7, 
+0xd3aa, 0x1d70, 0x3e94, 0x094b, 0x0900, 0x5434, 0x0901, 0xc4b1, 0xdc6e, 0xc832, 
+0xca7f, 0xe370, 0xfc55, 0x19fb, 0x5037, 0x3174, 0xfe1c, 0x3bdc, 0x1079, 0xb5a5, 
+0xbd97, 0xde91, 0xd7dc, 0xd8e9, 0x1ed3, 0x2fd7, 0x3373, 0x2e1c, 0x130d, 0x2861, 
+0x0ada, 0xcec0, 0xaf81, 0xd3f1, 0xe991, 0xcbf7, 0x0636, 0x408c, 0x3d14, 0x22da, 
+0x2e7f, 0x334f, 0xf091, 0xd23f, 0xb6f6, 0xbe39, 0xe0ea, 0xdac6, 0x0ab7, 0x52de, 
+0x5241, 0x1a28, 0x36a7, 0x3ee4, 0xdc10, 0xbfb1, 0xc06c, 0xc69f, 0xdf82, 0xf62e, 
+0x1f54, 0x4e25, 0x578d, 0x17a6, 0x26c4, 0x37fc, 0xe05d, 0xc099, 0xcd8c, 0xd886, 
+0xd8c3, 0xfcba, 0x2d83, 0x3fa6, 0x48bb, 0x1e77, 0x2a31, 0x31eb, 0xe98e, 0xbcf5, 
+0xc196, 0xe4e4, 0xdb34, 0xf4b5, 0x398d, 0x47e8, 0x3526, 0x2168, 0x3d9a, 0x20eb, 
+0xddcb, 0xbe09, 0xb85c, 0xe775, 0xe3f6, 0xedd1, 0x3731, 0x576a, 0x2d99, 0x1229, 
+0x4011, 0x0fb4, 0xc58a, 0xc2e0, 0xc163, 0xd8b3, 0xe485, 0xfbc4, 0x28a2, 0x4aba, 
+0x2b57, 0x06a4, 0x385f, 0x150e, 0xc2cd, 0xb65c, 0xcd33, 0xde60, 0xd4fe, 0x0096, 
+0x3507, 0x45bc, 0x2781, 0x142c, 0x33ba, 0x049c, 0xc775, 0xb39c, 0xc6ec, 0xe39b, 
+0xd75b, 0x0203, 0x3c34, 0x4589, 0x1c2f, 0x171d, 0x336b, 0xeff6, 0xbf31, 0xb8c6, 
+0xc21c, 0xde19, 0xe412, 0x0b3a, 0x399a, 0x4631, 0x1799, 0x116c, 0x3085, 0xeefe, 
+0xbcec, 0xb922, 0xcdc6, 0xe051, 0xe2d7, 0x10d0, 0x38e1, 0x3dfb, 0x1356, 0x1516, 
+0x2876, 0xe6f8, 0xbb6a, 0xb636, 0xd128, 0xdda0, 0xdf16, 0x11df, 0x387e, 0x338c, 
+0x0c5c, 0x211c, 0x2422, 0xdca8, 0xbf10, 0xb435, 0xcd32, 0xde18, 0xe25f, 0x144e, 
+0x3fe0, 0x3472, 0x0753, 0x2b41, 0x27e8, 0xd555, 0xc117, 0xbddb, 0xcb8c, 0xdaa8, 
+0xee16, 0x185e, 0x406a, 0x394d, 0x0e4c, 0x3224, 0x2283, 0xcee6, 0xb78f, 0xbe46, 
+0xd600, 0xd73a, 0xf882, 0x2db5, 0x4253, 0x3500, 0x1558, 0x2eee, 0x13ba, 0xd1b3, 
+0xb80a, 0xbd32, 0xe28d, 0xdf23, 0xfd44, 0x3980, 0x4ace, 0x2d3f, 0x18f4, 0x34ae, 
+0x039f, 0xcc97, 0xbb5e, 0xbe2a, 0xe6fa, 0xe555, 0x023b, 0x3de8, 0x4db4, 0x2192, 
+0x1578, 0x3a68, 0xfe29, 0xc84a, 0xbd0b, 0xc1ef, 0xe3a9, 0xe936, 0x0a3b, 0x3ab4, 
+0x505a, 0x260d, 0x1903, 0x39c0, 0xf9ac, 0xc53b, 0xbc41, 0xcc45, 0xe5fc, 0xe843, 
+0x15b8, 0x436d, 0x4dae, 0x24c5, 0x212b, 0x33f2, 0xf1b2, 0xc3a3, 0xb509, 0xcd57, 
+0xe8db, 0xeb7c, 0x1d1e, 0x4aef, 0x4a01, 0x1af5, 0x24c7, 0x2df1, 0xe4a5, 0xc1ae, 
+0xb8ad, 0xd2c8, 0xe887, 0xee7b, 0x21d0, 0x4d5f, 0x4806, 0x171f, 0x2854, 0x27e5, 
+0xdd26, 0xc075, 0xb9c1, 0xd6dc, 0xe94e, 0xf760, 0x2a99, 0x4d0c, 0x4405, 0x1751, 
+0x2a63, 0x1e7d, 0xd670, 0xba60, 0xb674, 0xde00, 0xe8fc, 0xf57e, 0x3121, 0x51b2, 
+0x3a66, 0x11d4, 0x29d9, 0x107f, 0xd01f, 0xbbd1, 0xb864, 0xe08f, 0xea2a, 0xfafd, 
+0x34de, 0x5038, 0x3061, 0x1294, 0x3316, 0x07d3, 0xc6ab, 0xbd82, 0xc0f2, 0xe421, 
+0xebe4, 0x0398, 0x39c6, 0x54a2, 0x2e8b, 0x0e55, 0x3308, 0x0648, 0xc5ad, 0xbd8e, 
+0xc53c, 0xdfb2, 0xe8b4, 0x0f4a, 0x3d14, 0x4caa, 0x2bf1, 0x15bf, 0x2e89, 0xf945, 
+0xc136, 0xb890, 0xcaeb, 0xe950, 0xe7bf, 0x115d, 0x451b, 0x4aa1, 0x20cd, 0x1684, 
+0x2a91, 0xf0a3, 0xc5b7, 0xb815, 0xc9bf, 0xee16, 0xea12, 0x117d, 0x470b, 0x42c7, 
+0x113f, 0x1b7c, 0x2b91, 0xe191, 0xc212, 0xbd24, 0xc84b, 0xe419, 0xe8c1, 0x104f, 
+0x440c, 0x4662, 0x1122, 0x20a6, 0x2d8e, 0xda8b, 0xbcf3, 0xc089, 0xcbf5, 0xde1c, 
+0xf3c0, 0x2135, 0x414e, 0x3fd9, 0x15e1, 0x26f5, 0x292e, 0xdc7e, 0xb937, 0xb924, 
+0xd769, 0xe06d, 0xee92, 0x2aa0, 0x48ae, 0x379d, 0x15e3, 0x2afa, 0x167d, 0xd370, 
+0xbfeb, 0xb8aa, 0xd8da, 0xe695, 0xf331, 0x2abe, 0x4918, 0x2e1c, 0x0f19, 0x32cf, 
+0x0f46, 0xc822, 0xbf6b, 0xbca2, 0xdadc, 0xe628, 0xf835, 0x2cf1, 0x4b03, 0x2c10, 
+0x0df9, 0x358e, 0x0a2c, 0xc678, 0xc06b, 0xc05f, 0xd849, 0xe170, 0x02e1, 0x3324, 
+0x4bd0, 0x2fc8, 0x13c8, 0x3314, 0x0029, 0xbf2e, 0xb455, 0xc1d3, 0xe027, 0xe480, 
+0x0a7f, 0x2c7a, 0x5506, 0x634d, 0x2129, 0xfadf, 0xe1b5, 0xb620, 0x8bd2, 0xbfae, 
+0x0a2a, 0x0d5d, 0x5240, 0x8109, 0x4e83, 0x15cf, 0xf367, 0xba2c, 0x9d5f, 0xcd2e, 
+0xbdc8, 0xf85d, 0x6f35, 0x4484, 0x29e8, 0x54f0, 0x2a04, 0xcc06, 0xd6d5, 0xe253, 
+0xc387, 0x09da, 0xff4a, 0xebc6, 0x4eb3, 0x2edb, 0xcfcc, 0x0b9a, 0x3d1b, 0xdc1f, 
+0xf4a1, 0x3fae, 0xeb9b, 0xe915, 0x13be, 0xcb86, 0xb940, 0x1643, 0x18ee, 0xf7d9, 
+0x4acf, 0x30df, 0xe6dc, 0x16fe, 0xf4d5, 0x9c55, 0xcc79, 0x10aa, 0xe384, 0x0496, 
+0x4c2c, 0x0504, 0xff4c, 0x2d7e, 0xd93d, 0xacb4, 0x00e4, 0xf5af, 0xc18e, 0x2289, 
+0x2a64, 0xe0a9, 0x2089, 0x21b8, 0xbaf3, 0xdd89, 0x1ea4, 0xd2e4, 0xe648, 0x37ea, 
+0xec35, 0xe993, 0x35d6, 0xed2e, 0xbadd, 0x15b4, 0x0a9d, 0xc841, 0x1a7c, 0x191c, 
+0xcaef, 0x0f4e, 0x1fff, 0xbfae, 0xe155, 0x3460, 0xeb55, 0xe0b6, 0x3048, 0xf2f2, 
+0xddca, 0x235a, 0xee7f, 0xb7cc, 0x15dd, 0x2097, 0xce52, 0x180f, 0x2dcf, 0xd499, 
+0x0857, 0x29b8, 0xc4c2, 0xd000, 0x28ff, 0xe652, 0xde94, 0x43c5, 0x05e6, 0xe425, 
+0x356a, 0xfee7, 0xb2c1, 0x0914, 0x1584, 0xbe7b, 0x0e5a, 0x368a, 0xe276, 0x1274, 
+0x3391, 0xd008, 0xd357, 0x26c2, 0xec06, 0xdd61, 0x39e2, 0x0868, 0xe6f9, 0x3207, 
+0x091c, 0xbc0e, 0x0582, 0x1f6d, 0xd133, 0x1cab, 0x4d57, 0xeb81, 0x02e3, 0x3712, 
+0xde41, 0xc71f, 0x212b, 0xfb67, 0xe7a1, 0x504a, 0x23ac, 0xedd8, 0x3eb6, 0x157e, 
+0xad36, 0xfc30, 0x2995, 0xcb86, 0x10c5, 0x529b, 0xf7a7, 0x15fe, 0x4546, 0xdc21, 
+0xcaba, 0x26eb, 0xe984, 0xd493, 0x4c8e, 0x16e6, 0xe56c, 0x463b, 0x1cf9, 0xb4a9, 
+0xfd71, 0x24ab, 0xc8a4, 0x09c8, 0x41c1, 0xe4ff, 0x0a9c, 0x3d28, 0xd226, 0xc16f, 
+0x2d0a, 0xf732, 0xcb2f, 0x42b2, 0x1d8f, 0xd5f3, 0x2c26, 0x1649, 0xa7c7, 0xed21, 
+0x286f, 0xc688, 0x04e2, 0x51dd, 0xe73b, 0x0013, 0x46f0, 0xd1e8, 0xab29, 0x260f, 
+0xf7aa, 0xbdee, 0x402d, 0x25c0, 0xda8b, 0x3989, 0x21df, 0xa95c, 0xf0ed, 0x290b, 
+0xbd3d, 0xfb44, 0x4eba, 0xe63a, 0xfecd, 0x4a1d, 0xe177, 0xbc6f, 0x2af3, 0xfdf2, 
+0xc4cf, 0x3b3d, 0x1ebb, 0xd4a0, 0x319d, 0x221e, 0xaf94, 0xf1b0, 0x3313, 0xcaf9, 
+0xf7f2, 0x4fd1, 0xeb5b, 0xf54e, 0x3faa, 0xd925, 0xb016, 0x2624, 0x012e, 0xc2f3, 
+0x3e16, 0x255d, 0xce61, 0x2b67, 0x1e8d, 0xa020, 0xe075, 0x2e2f, 0xc930, 0xf3f3, 
+0x4f96, 0xe6da, 0xef8a, 0x43fb, 0xdd85, 0xab7b, 0x2022, 0xfe5f, 0xba39, 0x346d, 
+0x27b4, 0xd20a, 0x2bfd, 0x2882, 0xae6f, 0xe3d3, 0x2b38, 0xc9c6, 0xef8e, 0x49d8, 
+0xeade, 0xf2c2, 0x46de, 0xe8ca, 0xb2fe, 0x208e, 0x0855, 0xc5c4, 0x338e, 0x29eb, 
+0xd645, 0x257e, 0x260c, 0xb7e2, 0xebef, 0x3365, 0xd6d8, 0xf811, 0x518d, 0xf457, 
+0xf134, 0x4558, 0xf41a, 0xb66e, 0x1a28, 0x0bd1, 0xcaa3, 0x31f9, 0x3045, 0xe17a, 
+0x2ad4, 0x2f2d, 0xbd2b, 0xe13e, 0x2cfe, 0xd3bd, 0xea52, 0x4fb4, 0x020e, 0xf40a, 
+0x4278, 0xf8f7, 0xb45e, 0x127c, 0x0af1, 0xc2d1, 0x2b03, 0x36f1, 0xdd10, 0x20d2, 
+0x35ec, 0xc074, 0xd7bd, 0x2eef, 0xd9db, 0xe543, 0x52c9, 0x05cf, 0xec53, 0x41bb, 
+0xfa65, 0xaf2a, 0x15c6, 0x1274, 0xbe0e, 0x2c97, 0x448e, 0xdd59, 0x1c74, 0x3817, 
+0xbb2b, 0xcf5b, 0x2f9a, 0xdc0c, 0xe4f0, 0x586d, 0x096c, 0xe913, 0x42c2, 0xf921, 
+0xa4d2, 0x0f94, 0x157d, 0xbee7, 0x2a97, 0x46c2, 0xe0bf, 0x1d38, 0x3786, 0xb9af, 
+0xcb2a, 0x2dd9, 0xd952, 0xdcbe, 0x5596, 0x0bab, 0xea4b, 0x4531, 0xffe2, 0xa78b, 
+0x0c61, 0x136f, 0xb532, 0x2148, 0x44ae, 0xd96e, 0x195c, 0x392c, 0xb898, 0xc8e9, 
+0x3388, 0xef92, 0xcd85, 0x0ef6, 0xf796, 0x13e1, 0x506a, 0x028d, 0xcd42, 0x14f5, 
+0xf58e, 0x9d81, 0xe29f, 0xfb3c, 0xcd66, 0x1bbf, 0x6302, 0x30d7, 0x14e4, 0x29bc, 
+0xdf14, 0xae5e, 0xce80, 0xabdc, 0xca7e, 0x3503, 0x1ee4, 0xf688, 0x5aac, 0x62a7, 
+0xd87d, 0xd4d5, 0xfc76, 0xb6dd, 0xa5b5, 0xf6e7, 0x0b99, 0x0665, 0x381b, 0x1f19, 
+0x1206, 0x2ed5, 0xebdd, 0xb56d, 0xde2e, 0xf87e, 0xce4d, 0xed47, 0x2439, 0x121c, 
+0x1266, 0x1483, 0x16c8, 0x10fd, 0x0650, 0xd754, 0xbaff, 0xf7e2, 0xda39, 0xcd45, 
+0x2986, 0x40dc, 0x0e53, 0x182a, 0x50a1, 0x01de, 0xcb6e, 0xdc62, 0xb781, 0xcfc4, 
+0xee54, 0xf542, 0x2240, 0x5981, 0x2c5e, 0xf8e5, 0x3e3b, 0x0d29, 0xaf98, 0xc3b7, 
+0xd787, 0xd3b1, 0xe2e2, 0x19c0, 0x28df, 0x3943, 0x2fe3, 0x081e, 0x2922, 0x0f78, 
+0xc962, 0xb6cc, 0xd979, 0xe6a6, 0xd121, 0x07cf, 0x3500, 0x3ad0, 0x2c2a, 0x2624, 
+0x2c95, 0xfb6f, 0xd7be, 0xb61f, 0xc05e, 0xe300, 0xd931, 0x0c0c, 0x4eae, 0x4878, 
+0x15a7, 0x2a43, 0x31b1, 0xdd24, 0xc4ea, 0xbda7, 0xc680, 0xe6be, 0xf0c6, 0x13f8, 
+0x45f0, 0x4cdc, 0x09ee, 0x185b, 0x3039, 0xdd40, 0xc562, 0xd19d, 0xd51e, 0xdcc7, 
+0xfbf1, 0x1f9a, 0x3311, 0x4108, 0x10a0, 0x1d6d, 0x368a, 0xebc0, 0xbacd, 0xc61c, 
+0xe6be, 0xd8c6, 0xecc7, 0x2b4f, 0x3ad6, 0x3234, 0x16aa, 0x312b, 0x2c20, 0xe5cf, 
+0xbf0c, 0xc2d3, 0xef02, 0xde96, 0xe42b, 0x3264, 0x4f6e, 0x2b87, 0x1502, 0x434e, 
+0x2169, 0xd824, 0xcd4a, 0xcbe5, 0xe67d, 0xe8bc, 0xf5fe, 0x2bd2, 0x4fbf, 0x2b2a, 
+0x05aa, 0x4482, 0x2857, 0xcb20, 0xc28b, 0xdaa2, 0xe5a8, 0xd616, 0xfaa0, 0x2fc3, 
+0x4640, 0x2ce5, 0x0f5a, 0x3ab7, 0x1944, 0xcda3, 0xbbcb, 0xcda1, 0xe22a, 0xd491, 
+0x0143, 0x3873, 0x3fbe, 0x22bb, 0x1736, 0x3ae6, 0x0407, 0xc3a8, 0xb9c4, 0xc437, 
+0xdc67, 0xd7ba, 0x00f1, 0x3801, 0x41a0, 0x1951, 0x11c6, 0x35de, 0xf7fb, 0xbeac, 
+0xb811, 0xc658, 0xdc21, 0xd8e4, 0x060e, 0x39e5, 0x4146, 0x14d2, 0x16dd, 0x36f4, 
+0xed6d, 0xba86, 0xb9b4, 0xcb20, 0xdd7e, 0xdfe1, 0x0f15, 0x3b82, 0x3e9b, 0x1158, 
+0x1b8a, 0x323f, 0xe8e2, 0xbdfb, 0xb835, 0xd09f, 0xddf2, 0xdd36, 0x148a, 0x40d3, 
+0x3e5f, 0x13a7, 0x2794, 0x2f4a, 0xde17, 0xbd25, 0xb6e3, 0xcb99, 0xdc56, 0xe6b9, 
+0x1ce9, 0x4836, 0x40a4, 0x1189, 0x2c70, 0x2966, 0xd436, 0xb74c, 0xb722, 0xd074, 
+0xdc0f, 0xf37b, 0x2f67, 0x4c6c, 0x3aa1, 0x13df, 0x2e82, 0x1863, 0xcd4e, 0xbc3f, 
+0xbce0, 0xd9c4, 0xe1be, 0xfb8d, 0x359d, 0x4c01, 0x3625, 0x17b8, 0x32ce, 0x1032, 
+0xcc89, 0xbc30, 0xbdba, 0xe2ec, 0xe81c, 0x005e, 0x3db9, 0x512c, 0x2c97, 0x17fc, 
+0x380c, 0x06f5, 0xcdb1, 0xc0d4, 0xbe6b, 0xe241, 0xead9, 0x05a4, 0x3a27, 0x518a, 
+0x2c10, 0x187d, 0x3809, 0xfd0c, 0xc4ac, 0xbff0, 0xc939, 0xe3de, 0xe907, 0x0ded, 
+0x3e36, 0x4e75, 0x2456, 0x1759, 0x31b3, 0xf547, 0xc449, 0xba76, 0xcb7c, 0xe629, 
+0xeb17, 0x17cc, 0x43ae, 0x4970, 0x1dfb, 0x1c5c, 0x2c1b, 0xe97c, 0xc40d, 0xbedd, 
+0xd492, 0xe90c, 0xea14, 0x18aa, 0x44ec, 0x43bf, 0x15aa, 0x2421, 0x2f68, 0xe453, 
+0xc2c4, 0xbef4, 0xd4c2, 0xe5c8, 0xf22d, 0x2430, 0x475e, 0x4461, 0x187f, 0x2916, 
+0x2d8a, 0xe382, 0xc1ee, 0xc2fa, 0xe144, 0xe6ea, 0xf400, 0x30a7, 0x50eb, 0x4265, 
+0x1b39, 0x2f67, 0x2260, 0xde78, 0xc61b, 0xc3e2, 0xe4c5, 0xea6e, 0xf9b7, 0x32e4, 
+0x4b24, 0x330a, 0x1529, 0x377b, 0x1ad4, 0xd298, 0xc471, 0xc39e, 0xdfcf, 0xe493, 
+0xf83e, 0x339f, 0x5169, 0x3178, 0x0fe4, 0x3634, 0x10e7, 0xcad8, 0xc188, 0xc0cb, 
+0xd97a, 0xe36b, 0x01cf, 0x3255, 0x49ca, 0x2dc9, 0x1019, 0x33a3, 0x059a, 0xbd42, 
+0xb33f, 0xbe30, 0xd9b3, 0xdc31, 0x0338, 0x37ee, 0x44ae, 0x224f, 0x0cf2, 0x27ab, 
+0xf5dc, 0xbd67, 0xaf02, 0xbe02, 0xde1c, 0xd738, 0x02b2, 0x3eba, 0x4074, 0x174f, 
+0x1829, 0x2c82, 0xe72a, 0xbf61, 0xb6b3, 0xbe85, 0xe2b1, 0xe25f, 0x05c1, 0x4181, 
+0x4a2b, 0x1512, 0x1a96, 0x326a, 0xe3c7, 0xbc8c, 0xb7af, 0xbd6f, 0xd849, 0xe90a, 
+0x150e, 0x3ed0, 0x469e, 0x176f, 0x1b23, 0x2908, 0xdb26, 0xb2f3, 0xb1f8, 0xca6a, 
+0xdb06, 0xe6a5, 0x1fb9, 0x4383, 0x3e5d, 0x1596, 0x1e94, 0x1cb0, 0xd8cf, 0xba95, 
+0xaec4, 0xcef4, 0xe43f, 0xeaf7, 0x2443, 0x4766, 0x336a, 0x0e32, 0x27a3, 0x1356, 
+0xcd5d, 0xc150, 0xb6ba, 0xd1d8, 0xe528, 0xee84, 0x2426, 0x4adf, 0x3667, 0x10cd, 
+0x310e, 0x1388, 0xcbbb, 0xc47e, 0xbd1f, 0xd491, 0xe98e, 0x0244, 0x3289, 0x53b3, 
+0x3eb9, 0x1566, 0x3290, 0x11e3, 0xcc07, 0xc004, 0xc4fd, 0xe223, 0xed0a, 0x10ae, 
+0x3ff0, 0x5037, 0x36e6, 0x164f, 0x29a1, 0x0284, 0xcdb8, 0xbdcd, 0xc637, 0xed96, 
+0xeeb1, 0x0cd0, 0x4050, 0x49bb, 0x239a, 0x1780, 0x2eab, 0xf6b6, 0xce3d, 0xbc38, 
+0xc8a0, 0x00e6, 0xefad, 0x0021, 0x33f9, 0x3ae3, 0x3cd3, 0x3fb1, 0x1838, 0xd924, 
+0xd541, 0xaecf, 0xa5de, 0xf7be, 0xfc4c, 0x140b, 0x790a, 0x7937, 0x1616, 0xfecc, 
+0xe9f4, 0x93de, 0xa330, 0xc0f0, 0xcf7e, 0x2cbc, 0x6286, 0x4ccf, 0x462d, 0x450f, 
+0xe74f, 0xa99c, 0xd6b1, 0xc669, 0xba55, 0xfefe, 0x25a9, 0x3149, 0x43ec, 0x1f26, 
+0xede2, 0x0adf, 0xff6f, 0xbdad, 0xf121, 0x2c23, 0xf18d, 0xf0cc, 0x2718, 0xe6c1, 
+0xbbba, 0x1d92, 0x14c7, 0xde85, 0x3e57, 0x31f4, 0xe295, 0x0f8d, 0xf992, 0xa267, 
+0xd117, 0x1bec, 0xe179, 0x07c9, 0x5af9, 0x03a7, 0x02e9, 0x3014, 0xd04d, 0xa794, 
+0xfb7e, 0xf282, 0xc715, 0x36b9, 0x3764, 0xea25, 0x307a, 0x1cb0, 0xb2ec, 0xd406, 
+0x117c, 0xd2a9, 0xea54, 0x43e9, 0xfc21, 0xfaa3, 0x3fc1, 0xeafd, 0xb060, 0x0b4c, 
+0x0ff9, 0xc461, 0x1954, 0x3040, 0xd984, 0x1601, 0x2825, 0xbc3f, 0xdbce, 0x3875, 
+0xe248, 0xdd2e, 0x4e02, 0xfd2c, 0xd91c, 0x3749, 0xf658, 0xaa69, 0x13e1, 0x2498, 
+0xcc14, 0x21ba, 0x3a26, 0xdb15, 0x1623, 0x2c3d, 0xba40, 0xcd2e, 0x2cf5, 0xe4ae, 
+0xe186, 0x52e0, 0x0d31, 0xe5cf, 0x3778, 0xffc1, 0xac3d, 0xfddf, 0x1bac, 0xc8ec, 
+0x14d4, 0x4029, 0xe79d, 0x15d6, 0x3792, 0xcc34, 0xca86, 0x3225, 0xf50a, 0xcf32, 
+0x3e28, 0x12b9, 0xe181, 0x364b, 0x1002, 0xb4c9, 0x031c, 0x26d6, 0xd0a9, 0x1e6a, 
+0x443a, 0xd350, 0x08d3, 0x41ed, 0xc7a2, 0xb99c, 0x2fe3, 0xff21, 0xdc75, 0x4839, 
+0x19bb, 0xe84c, 0x32f7, 0x01b7, 0xaddf, 0xfef1, 0x1e1c, 0xcae8, 0x16e4, 0x4bda, 
+0xecbb, 0x0caf, 0x3f24, 0xe0dc, 0xc4bc, 0x18da, 0xf67e, 0xdd77, 0x3908, 0x10f4, 
+0xed5b, 0x4369, 0x1b8d, 0xb980, 0x0190, 0x297a, 0xc6e3, 0x009e, 0x4462, 0xea33, 
+0x0155, 0x3cba, 0xe27f, 0xcbef, 0x2bda, 0xf9a0, 0xd4bc, 0x439f, 0x150b, 0xd559, 
+0x344d, 0x1a5b, 0xaf57, 0xf935, 0x2de0, 0xcf9a, 0x0979, 0x49a9, 0xea95, 0x051a, 
+0x3cdb, 0xd6df, 0xbc25, 0x2174, 0xf28b, 0xc89b, 0x4222, 0x2645, 0xdfc1, 0x315e, 
+0x201e, 0xb2fc, 0xe3d4, 0x181b, 0xc442, 0xfd80, 0x4a43, 0xed31, 0xff1f, 0x4381, 
+0xdf06, 0xb4dc, 0x1fd7, 0xf6dc, 0xbffe, 0x3a30, 0x24f3, 0xd6d6, 0x297b, 0x1c5d, 
+0xaf37, 0xedb8, 0x286b, 0xc61d, 0xfe95, 0x515b, 0xe559, 0xf3c9, 0x4090, 0xd830, 
+0xae85, 0x1db8, 0xf7ec, 0xc607, 0x3f9f, 0x264d, 0xd94a, 0x2a8a, 0x1485, 0xa002, 
+0xdeaf, 0x235b, 0xc381, 0xfa49, 0x5796, 0xefa6, 0xf6b9, 0x4056, 0xd904, 0xa813, 
+0x17bf, 0xf931, 0xbf26, 0x3e31, 0x2c1d, 0xd50a, 0x2d55, 0x22b9, 0xa846, 0xdf9f, 
+0x28c5, 0xc598, 0xef6b, 0x51e5, 0xf17d, 0xfa6e, 0x46ce, 0xddcb, 0xac63, 0x1bcf, 
+0xff42, 0xc08e, 0x3b8a, 0x30ab, 0xd540, 0x2b2a, 0x2b14, 0xb01e, 0xe003, 0x2eb4, 
+0xd207, 0xf705, 0x5a04, 0xf5f1, 0xf4f2, 0x49c1, 0xe735, 0xac7d, 0x1ff2, 0x0bc1, 
+0xc150, 0x3a15, 0x3cd0, 0xdc44, 0x29ee, 0x3079, 0xb504, 0xdcbb, 0x2cd7, 0xcfca, 
+0xeed8, 0x5c84, 0xfe19, 0xf346, 0x4ec0, 0xf24e, 0xa9a2, 0x1b01, 0x120e, 0xbf61, 
+0x31bd, 0x3ed0, 0xdca8, 0x27d7, 0x3553, 0xb79f, 0xddc0, 0x376a, 0xd743, 0xea45, 
+0x592a, 0xf9f4, 0xe94c, 0x4a1d, 0xf552, 0xa9a1, 0x19d2, 0x14c6, 0xbc9b, 0x2b11, 
+0x3913, 0xd2dc, 0x1f02, 0x340a, 0xb6b6, 0xd426, 0x33f8, 0xd9a8, 0xdc7f, 0x5123, 
+0xfd3a, 0xde46, 0x40ce, 0xfa10, 0xa997, 0x14a8, 0x1bb4, 0xc08d, 0x2376, 0x3d24, 
+0xd503, 0x166b, 0x35f1, 0xbc86, 0xd0fa, 0x36e8, 0xf1a1, 0xd628, 0x16ed, 0xf145, 
+0x0d1a, 0x55e9, 0x09b3, 0xd0ea, 0x189e, 0xfae5, 0xa1d9, 0xe581, 0xfd1f, 0xd241, 
+0x1ffa, 0x5b9f, 0x2d05, 0x1f94, 0x316b, 0xe330, 0xba22, 0xd9ab, 0xb354, 0xcfaa, 
+0x3059, 0x1e34, 0xfcfc, 0x565e, 0x623a, 0xe738, 0xe027, 0xfe57, 0xc099, 0xb327, 
+0xf470, 0x0c3c, 0x0e38, 0x38fd, 0x1a11, 0x0892, 0x3339, 0xf5c3, 0xbab1, 0xe297, 
+0xf843, 0xce95, 0xe620, 0x1c2a, 0x09ee, 0x1283, 0x1b02, 0x1187, 0x188b, 0x0e86, 
+0xd87e, 0xb652, 0xeca9, 0xdb2d, 0xc7dd, 0x1fe5, 0x379e, 0x0fd2, 0x1c45, 0x4c2e, 
+0x1316, 0xd85d, 0xdfc8, 0xb6df, 0xc87f, 0xeb35, 0xe54a, 0x1628, 0x57e4, 0x3419, 
+0xff6c, 0x4156, 0x1c74, 0xb5b4, 0xca06, 0xd49b, 0xc6db, 0xdff3, 0x0f42, 0x1c9b, 
+0x38c2, 0x3cc3, 0x059b, 0x2a27, 0x2699, 0xce85, 0xb4f9, 0xd393, 0xdea9, 0xcdb3, 
+0x03e7, 0x3281, 0x3d54, 0x3c61, 0x2583, 0x2ce2, 0x0c86, 0xdb4d, 0xb3bf, 0xbb9c, 
+0xe353, 0xd3fa, 0x034f, 0x4cdb, 0x4ab4, 0x21fa, 0x2b59, 0x391f, 0xeb27, 0xc6cb, 
+0xb8e4, 0xba9a, 0xe811, 0xec0e, 0x0c31, 0x4bdb, 0x5772, 0x163d, 0x1a19, 0x3f4d, 
+0xe9e8, 0xc3a2, 0xce2a, 0xc788, 0xd9f4, 0xf83e, 0x1bc6, 0x3ce8, 0x5548, 0x1db0, 
+0x1a55, 0x4521, 0xf1e2, 0xb3ab, 0xc2fd, 0xdbe1, 0xd800, 0xed52, 0x2c30, 0x402d, 
+0x430b, 0x23ff, 0x260b, 0x2f76, 0xea68, 0xb3d7, 0xb28e, 0xe14a, 0xdd06, 0xe066, 
+0x33b3, 0x51ec, 0x33b4, 0x1667, 0x3052, 0x1b77, 0xd41e, 0xc1bd, 0xb6c4, 0xd7a4, 
+0xeae0, 0xe9c9, 0x2119, 0x50ee, 0x3348, 0x0504, 0x35a7, 0x2224, 0xc555, 0xbad4, 
+0xc362, 0xd0c4, 0xdade, 0xf6c3, 0x247a, 0x463c, 0x3726, 0x098e, 0x2ae9, 0x1a2f, 
+0xc9d7, 0xb0fe, 0xc012, 0xdaac, 0xd5e1, 0xf9b0, 0x351f, 0x47da, 0x2cc6, 0x10fb, 
+0x2d9f, 0x068e, 0xc5e3, 0xb7fe, 0xc297, 0xe2b0, 0xe422, 0x01db, 0x36ef, 0x48cb, 
+0x23b7, 0x10de, 0x3507, 0x0307, 0xc7bf, 0xbff3, 0xc77c, 0xe128, 0xe56e, 0x0857, 
+0x3924, 0x4aaf, 0x2249, 0x103e, 0x31eb, 0xfa7b, 0xc42a, 0xbff2, 0xca69, 0xdf50, 
+0xe715, 0x1070, 0x37d6, 0x4303, 0x1eac, 0x16ba, 0x3184, 0xf739, 0xc4f5, 0xba46, 
+0xcd7e, 0xe4d0, 0xe592, 0x10ee, 0x3d09, 0x4044, 0x17ce, 0x2016, 0x2f3f, 0xe9e5, 
+0xc633, 0xbad5, 0xc6f9, 0xdeac, 0xe624, 0x121c, 0x413b, 0x4301, 0x1783, 0x29fd, 
+0x2ba5, 0xdaa4, 0xbe2e, 0xbb8e, 0xcbc8, 0xdde4, 0xf1e9, 0x21db, 0x439b, 0x4190, 
+0x172e, 0x27a0, 0x21f8, 0xd636, 0xbad8, 0xb8bf, 0xd096, 0xdf64, 0xf8a8, 0x2b93, 
+0x443b, 0x3b96, 0x185e, 0x26da, 0x10a6, 0xd167, 0xbdb5, 0xb977, 0xdb3a, 0xe708, 
+0xfa86, 0x2f52, 0x4806, 0x3265, 0x17a3, 0x31bc, 0x0e05, 0xd510, 0xc461, 0xbd66, 
+0xe192, 0xed77, 0x0119, 0x32ba, 0x50ed, 0x31ea, 0x16d3, 0x36ec, 0x0732, 0xcfc7, 
+0xc460, 0xc184, 0xdf83, 0xea58, 0x0626, 0x3550, 0x5246, 0x2def, 0x16cd, 0x3427, 
+0xfd3a, 0xc953, 0xbd3c, 0xc544, 0xe4ec, 0xf153, 0x166b, 0x3e10, 0x4e6d, 0x26d4, 
+0x1968, 0x2f16, 0xf428, 0xcae0, 0xbedd, 0xccf8, 0xe956, 0xefa2, 0x1950, 0x4297, 
+0x4a75, 0x1de5, 0x1955, 0x29ba, 0xeb91, 0xc61c, 0xbb12, 0xce33, 0xe7ce, 0xefe6, 
+0x18c6, 0x3e32, 0x43c5, 0x1922, 0x1cc3, 0x20fd, 0xde2b, 0xbf55, 0xb70b, 0xd16f, 
+0xe788, 0xef8e, 0x20c4, 0x4654, 0x3d93, 0x11d7, 0x1d2e, 0x15c5, 0xd810, 0xc122, 
+0xb7df, 0xd5bd, 0xe934, 0xf5a0, 0x24cd, 0x4321, 0x356b, 0x10be, 0x2522, 0x0e25, 
+0xcdbf, 0xc120, 0xbd1c, 0xd9ef, 0xe950, 0xf8ec, 0x2940, 0x4a04, 0x31e9, 0x09bb, 
+0x2935, 0x0de2, 0xcd32, 0xc3e0, 0xc0ad, 0xd96f, 0xebee, 0x0617, 0x2f65, 0x4a9d, 
+0x32b8, 0x104d, 0x2b20, 0x042c, 0xc6fe, 0xc0fc, 0xccb1, 0xe4c6, 0xe7e5, 0x0a2f, 
+0x3646, 0x44a9, 0x27ed, 0x0f84, 0x2482, 0xf9ba, 0xc9c9, 0xbc46, 0xc6f1, 0xe7c9, 
+0xe7b4, 0x0935, 0x38ab, 0x3dfb, 0x17f4, 0x1202, 0x2366, 0xe8cf, 0xc894, 0xc02b, 
+0xc4e7, 0xe682, 0xe9b4, 0x07dc, 0x39bc, 0x4323, 0x1255, 0x11a3, 0x2383, 0xde38, 
+0xc201, 0xc28c, 0xc797, 0xe30e, 0xf319, 0x11aa, 0x3329, 0x3e07, 0x11d9, 0x1242, 
+0x2173, 0xdd6c, 0xbc12, 0xbfc4, 0xd3cc, 0xe301, 0xf14f, 0x1ed7, 0x3c0b, 0x3bbe, 
+0x150a, 0x16d9, 0x1504, 0xded6, 0xc844, 0xc0c3, 0xdedd, 0xf0d7, 0xf666, 0x25d8, 
+0x4424, 0x33d0, 0x130e, 0x2876, 0x1370, 0xd7a6, 0xcf17, 0xc604, 0xdfb9, 0xf3d2, 
+0xfde9, 0x29bc, 0x4a3a, 0x328f, 0x0b59, 0x293f, 0x0f84, 0xd398, 0xd04b, 0xc938, 
+0xdc96, 0xf077, 0x05ff, 0x2a1d, 0x46e9, 0x33e3, 0x0e06, 0x27af, 0x084b, 0xcbee, 
+0xc5ed, 0xce50, 0xe4ec, 0xee95, 0x0fc4, 0x3481, 0x4291, 0x2ab8, 0x0ee7, 0x217a, 
+0xfbca, 0xd072, 0xc584, 0xcdc2, 0xeeae, 0xf284, 0x0beb, 0x2a91, 0x499c, 0x4ab9, 
+0x1751, 0xfb4e, 0xdff4, 0xc548, 0xaa11, 0xcb25, 0x079b, 0x0c5f, 0x3e98, 0x6247, 
+0x3e07, 0x0f43, 0xf0e4, 0xca5f, 0xb34f, 0xd401, 0xc893, 0xf3d1, 0x4c26, 0x308b, 
+0x22b3, 0x41c0, 0x2279, 0xdc8b, 0xdff8, 0xe310, 0xcceb, 0x027f, 0xf615, 0xee06, 
+0x3db0, 0x2392, 0xe01d, 0x1366, 0x3415, 0xe34c, 0xf6fc, 0x29c3, 0xe8c4, 0xee7a, 
+0x0fa2, 0xddee, 0xd84b, 0x1d1b, 0x1722, 0xff58, 0x3ac2, 0x1f74, 0xf03f, 0x1870, 
+0xfcd6, 0xbff1, 0xe68f, 0x1180, 0xed1f, 0x0a12, 0x3895, 0x07ec, 0x0a31, 0x24b3, 
+0xe648, 0xc9fc, 0x0734, 0xf757, 0xd412, 0x1f4f, 0x1e8b, 0xee37, 0x1f0e, 0x1be3, 
+0xd43a, 0xefa3, 0x194b, 0xddce, 0xf237, 0x287d, 0xeedf, 0xf88e, 0x2f7f, 0xf704, 
+0xd874, 0x1c88, 0x0972, 0xd8d5, 0x1702, 0x0f28, 0xe05e, 0x15f4, 0x1a7c, 0xd9ff, 
+0xf6eb, 0x29b0, 0xf002, 0xf068, 0x23d5, 0xf4b8, 0xf046, 0x1d23, 0xf157, 0xd110, 
+0x1519, 0x14cc, 0xdede, 0x142d, 0x1a12, 0xe515, 0x0b1c, 0x1636, 0xd4d5, 0xe629, 
+0x1cf8, 0xe7c6, 0xea58, 0x2b1f, 0xfc3e, 0xeeea, 0x236a, 0xfb53, 0xcfca, 0x089d, 
+0x0488, 0xd160, 0x0a55, 0x141d, 0xe5cd, 0x107d, 0x186d, 0xd8c8, 0xeaf7, 0x1870, 
+0xe826, 0xe955, 0x18d7, 0xf4b0, 0xf2f4, 0x198f, 0xf637, 0xd898, 0x0a60, 0x099d, 
+0xe121, 0x112c, 0x19f0, 0xe9f0, 0x0257, 0x16f3, 0xea68, 0xe825, 0x11db, 0xf73d, 
+0xf784, 0x22c2, 0x01a7, 0xfa94, 0x2329, 0xff98, 0xd3ac, 0x066b, 0x0f20, 0xe092, 
+0x0cc3, 0x1ddc, 0xf6f5, 0x1320, 0x1de5, 0xe877, 0xf111, 0x167b, 0xeabe, 0xf59b, 
+0x2682, 0xf99e, 0xf763, 0x2689, 0x0359, 0xdfbd, 0x0e98, 0x0da2, 0xe78d, 0x0e20, 
+0x0ddb, 0xeff0, 0x11e2, 0x1312, 0xe459, 0xf4b0, 0x1704, 0xee92, 0xf4ab, 0x1ec2, 
+0xfc20, 0xf450, 0x169f, 0xfcad, 0xdbac, 0x0468, 0x089e, 0xe794, 0x0e53, 0x118e, 
+0xefe9, 0x0e4a, 0x169a, 0xe1da, 0xebc0, 0x15eb, 0xefcb, 0xf2ee, 0x1beb, 0xfce8, 
+0xfa9c, 0x1c17, 0xffdb, 0xe6b1, 0x0fc5, 0x065c, 0xe6be, 0x10a6, 0x0c31, 0xefee, 
+0x1306, 0x13f9, 0xe94c, 0xfe45, 0x19f0, 0xf32a, 0xfe85, 0x1905, 0xf62a, 0xfd6b, 
+0x1747, 0xf729, 0xeaea, 0x11d1, 0x0593, 0xf301, 0x1786, 0x0b5f, 0xf124, 0x0940, 
+0x0668, 0xe6ec, 0xfe96, 0x1506, 0xf474, 0x04f3, 0x1923, 0xf708, 0xfe00, 0x1197, 
+0xf0a5, 0xe784, 0x0dcb, 0xff73, 0xf084, 0x1476, 0x091e, 0xf640, 0x0af0, 0x0286, 
+0xe773, 0xfd6b, 0x0efa, 0xf175, 0xf89a, 0x07af, 0xf9a6, 0x0516, 0x128d, 0x00ff, 
+0xfb4e, 0x0ed0, 0xfc70, 0xe60e, 0xf53d, 0xf46c, 0xf494, 0x0bff, 0x1551, 0x06e1, 
+0x0c9f, 0x0f55, 0xefab, 0xed70, 0xf731, 0xf0fe, 0xfd13, 0x0d56, 0x068f, 0x0174, 
+0x0fee, 0xffe4, 0xea15, 0xfb9a, 0xffd4, 0xf166, 0xfe33, 0x0e6f, 0xfeb8, 0x0068, 
+0x0cad, 0xf543, 0xef47, 0x0118, 0xf5be, 0xeb4f, 0x04dc, 0x09b3, 0xf586, 0x0081, 
+0x05bb, 0xf123, 0xf60d, 0x03d9, 0xf8d9, 0xfe28, 0x0dac, 0xfb79, 0xf27c, 0xfe7f, 
+0xf2c5, 0xeeb0, 0x04d2, 0x030d, 0xfb07, 0x0e9e, 0x0d11, 0xf686, 0xfc94, 0xffbf, 
+0xed59, 0xf589, 0x05ab, 0xfa48, 0xffa7, 0x10c1, 0x014b, 0xfa25, 0x09af, 0xfdfc, 
+0xf0ef, 0x03b9, 0x0400, 0xf635, 0x063f, 0x0b0b, 0xf9ca, 0x03dd, 0x0d8d, 0xfce6, 
+0x00df, 0x0f4b, 0x024e, 0xff59, 0x0dc5, 0x0159, 0xf654, 0x067a, 0x0580, 0xfe5c, 
+0x0e74, 0x0f97, 0x0220, 0x099e, 0x09f1, 0xf6cc, 0xfa19, 0x04a0, 0xfb69, 0x0199, 
+0x10a2, 0x0726, 0x02f2, 0x0c0d, 0x00c5, 0xf7e4, 0x056d, 0x020c, 0xf921, 0x0880, 
+0x0a05, 0xfc9b, 0x05b1, 0x0ba8, 0xfd73, 0x0126, 0x0afa, 0xfedb, 0xfe8e, 0x0754, 
+0xff08, 0x010e, 0x0a12, 0xff2a, 0xfc7a, 0x0965, 0x0306, 0xfbf9, 0x0735, 0x05c2, 
+0xfdbe, 0x020b, 0x01d4, 0xfd23, 0x035d, 0x0690, 0x0006, 0x0536, 0x0b42, 0x02fd, 
+0x0048, 0x04d9, 0xffac, 0xfb96, 0x0522, 0x06ea, 0x01a3, 0x0640, 0x0721, 0x02e7, 
+0x04ad, 0x0494, 0xfe70, 0x009e, 0x0380, 0xfafb, 0xfecf, 0x0890, 0x0224, 0xffd6, 
+0x0613, 0x005f, 0xfada, 0x0129, 0xfdf3, 0xf949, 0x014d, 0x006d, 0xfa91, 0x0029, 
+0x002c, 0xf7d8, 0xff02, 0x0615, 0xfbc4, 0xfc2b, 0x035b, 0xfb89, 0xf601, 0xfa4f, 
+0xfabf, 0xfbd9, 0x00a3, 0xfe0a, 0xfbd4, 0x0009, 0xfe8b, 0xf866, 0xf96c, 0xfcbd, 
+0xf750, 0xf6d5, 0xfee5, 0xfea6, 0xfc47, 0x00a5, 0x013f, 0xfaa4, 0xf910, 0xf98a, 
+0xf6f0, 0xfa55, 0xfc01, 0xfac1, 0xff53, 0x001d, 0xfac1, 0xfb9d, 0xfef2, 0xf9c9, 
+0xf9ce, 0xff10, 0xfabf, 0xfab8, 0xfe59, 0xfa05, 0xfa90, 0x00a1, 0xff54, 0xfdbe, 
+0x0243, 0xff6b, 0xfac6, 0xfde2, 0xfc78, 0xf927, 0xfc12, 0xfe2f, 0xfc8a, 0xfe15, 
+0x00a9, 0xff55, 0x0011, 0x0049, 0xfbfb, 0xfa18, 0xfd23, 0xfbc7, 0xf7ac, 0xfd25, 
+0x019e, 0x0030, 0x02a9, 0x0344, 0x0053, 0x0036, 0x003f, 0xfc42, 0xfd77, 0x047f, 
+0x022f, 0xffd5, 0x0747, 0x065b, 0xffcd, 0x058c, 0x0801, 0x00b8, 0x029f, 0x057c, 
+0x0228, 0x02a9, 0x03ae, 0x0336, 0x052e, 0x06d3, 0x0355, 0x0367, 0x097b, 0x0767, 
+0x040b, 0x0708, 0x062b, 0x00f3, 0x010e, 0x0624, 0x0661, 0x0641, 0x0870, 0x08cf, 
+0x095c, 0x0672, 0x0114, 0x0064, 0x0450, 0x0372, 0x00f0, 0x074e, 0x0927, 0x0375, 
+0x04d0, 0x06fa, 0x0278, 0x00e0, 0x023e, 0x0105, 0x0392, 0x0478, 0x01dc, 0x0633, 
+0x06ad, 0x0137, 0x035b, 0x071e, 0x039a, 0x00b9, 0x0238, 0x0257, 0x03b3, 0x032c, 
+0x00b5, 0x062b, 0x0920, 0x0425, 0x05d7, 0x09b0, 0x0457, 0x011e, 0x02cb, 0x0112, 
+0x01e7, 0x03e0, 0x04a0, 0x09f0, 0x0993, 0x025d, 0x03ab, 0x06f0, 0x01ce, 0xffa9, 
+0x0343, 0x03bf, 0x02bc, 0x0192, 0x0175, 0x03f8, 0x025f, 0xfe13, 0xffaf, 0x037b, 
+0x017f, 0xff0d, 0x010c, 0x01cc, 0xff47, 0xfda7, 0xff79, 0xffc8, 0xfd08, 0xfdcd, 
+0x01e5, 0x03c0, 0x00fa, 0xfdf8, 0xfdb9, 0xff87, 0xff9b, 0xfbe2, 0xfeae, 0x0380, 
+0x0014, 0xfe6f, 0x0115, 0x0048, 0xfe1d, 0xff3b, 0xff7b, 0xff0a, 0x0012, 0xfed0, 
+0xfed6, 0xffe0, 0xfcbf, 0xfbdb, 0x005d, 0xffb1, 0xf9ae, 0xfb2b, 0x0004, 0xff44, 
+0xfc6c, 0xfb62, 0xfdf8, 0xff0d, 0xfbbb, 0xfae7, 0xfd8a, 0xfd70, 0xfaee, 0xfbe3, 
+0xfdf3, 0xfc89, 0xfa9a, 0xfb6e, 0xfd82, 0xfcb8, 0xfaa3, 0xfc2a, 0xfeb9, 0xfc5c, 
+0xf8a1, 0xfb85, 0x000c, 0xfee7, 0xfbc5, 0xfc1f, 0xfee8, 0xfdac, 0xfae0, 0xfc8b, 
+0xfef5, 0xfebd, 0xfdf5, 0xfec1, 0x0023, 0xff0f, 0xfc4a, 0xfdd7, 0x00f5, 0xfea6, 
+0xfd0c, 0x002f, 0x0087, 0xfc77, 0xfc93, 0x0024, 0x013b, 0x00dc, 0xfdb0, 0xfcbd, 
+0x0060, 0xfed8, 0xfc65, 0xfff5, 0x0160, 0xfef8, 0x0045, 0x0243, 0x0065, 0xfff6, 
+0x0124, 0x00f9, 0x00f5, 0x00ae, 0xff8e, 0x00df, 0x02e1, 0xffa3, 0xfea2, 0x0390, 
+0x035d, 0xff35, 0xff1f, 0x009b, 0x0048, 0xffed, 0x0005, 0xfff7, 0x0019, 0xff23, 
+0xfe36, 0xff91, 0x0112, 0x0088, 0xfff6, 0x00fa, 0x00a3, 0xfe18, 0xfe82, 0x01b6, 
+0x00ae, 0xfead, 0x018f, 0x02ef, 0x0126, 0x002b, 0xffb6, 0x01e3, 0x0382, 0x00b0, 
+0x00bd, 0x0402, 0x024e, 0x0002, 0x02e3, 0x0327, 0x00b6, 0x01cf, 0x02ca, 0x0250, 
+0x0280, 0x01bd, 0x021d, 0x04f6, 0x0340, 0xfee9, 0x0095, 0x0305, 0x00bc, 0x012c, 
+0x04fc, 0x0469, 0x0257, 0x027e, 0x0242, 0x01ad, 0x014b, 0x00c3, 0x0147, 0x037a, 
+0x036a, 0x00b5, 0x0068, 0x0121, 0xff9a, 0xfec8, 0x0143, 0x0151, 0xfd18, 0xfced, 
+0xffbd, 0x0066, 0x007d, 0xff3b, 0xfdd4, 0xfe9a, 0xff0d, 0xfdc1, 0xfe33, 0xffd7, 
+0xfd45, 0xfbe9, 0xffc6, 0xff2d, 0xfb3e, 0xfd69, 0x0057, 0xff59, 0xffc4, 0x00ad, 
+0x0017, 0xffc4, 0xfde4, 0xfc22, 0xfe08, 0x004b, 0xffd4, 0x0028, 0x0265, 0x00fa, 
+0xfdc5, 0xfe0b, 0xff0e, 0xfe78, 0xfdca, 0xfe74, 0xff9b, 0x005c, 0x0106, 0x00eb, 
+0x015c, 0x01a8, 0xff52, 0xfee2, 0x00ee, 0xffbe, 0xfec8, 0x010d, 0x01ab, 0x00d9, 
+0x0106, 0x010d, 0x00e8, 0x0118, 0x00e8, 0x012b, 0x02b4, 0x0211, 0xff7a, 0xff8e, 
+0x0115, 0x0100, 0x00de, 0x02dd, 0x0379, 0x00f9, 0xffd1, 0x0018, 0xfff6, 0xfffa, 
+0x000c, 0xfff1, 0x0004, 0x0012, 0xffc4, 0x009c, 0x010c, 0xfffb, 0xffe4, 0x001a, 
+0xfff2, 0xfffc, 0x0012, 0xffe2, 0x0015, 0x015a, 0x0257, 0x01c9, 0x004d, 0xfff9, 
+0xffdd, 0x0059, 0x019b, 0x004f, 0x0095, 0x030f, 0x0191, 0xff96, 0x015d, 0x0296, 
+0x01ee, 0x0205, 0x01f5, 0x0220, 0x0303, 0x0276, 0x01b6, 0x02a2, 0x02f4, 0x01f9, 
+0x0209, 0x01e3, 0x0073, 0x00ad, 0x0219, 0x0205, 0x00f2, 0x000a, 0xffc0, 0x00c9, 
+0x0105, 0xffac, 0x007c, 0x0198, 0x0051, 0xffcf, 0x001b, 0xfff4, 0x0001, 0x0002, 
+0xfffe, 0xfffb, 0x0005, 0xfffd, 0xfff3, 0x0025, 0xff14, 0xfe3b, 0xffa5, 0xfffc, 
+0xfee0, 0xff17, 0xffe8, 0x0010, 0xffec, 0x0017, 0xffe5, 0xff21, 0xfef3, 0xfef8, 
+0xff4b, 0x002c, 0xffc0, 0xfee9, 0xffc3, 0x001f, 0xff65, 0xffbc, 0x001d, 0xfff2, 
+000000, 0x0003, 0xfffc, 0xfffc, 0x000a, 0xffec, 0x0015, 0x0095, 0x002c, 0xffc9, 
+0x006a, 0x0078, 0xfff2, 0xfffb, 0x0006, 0xfffa, 0x0002, 0xfffd, 0x0004, 0xfff4, 
+0x0010, 0xfff2, 0xfff7, 0x003a, 0xfeb1, 0xfe3a, 0xfff4, 0x0020, 0xffde, 0x0015, 
+0xfff6, 000000, 0x0002, 0xfffc, 0x0001, 0xfffe, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 
+000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000000 };
diff --git a/utils/iaxclient/lib/libiax2/src/ringtone.h b/utils/iaxclient/lib/libiax2/src/ringtone.h
new file mode 100644 (file)
index 0000000..637021d
--- /dev/null
@@ -0,0 +1,30 @@
+/* ringtone.h: Generated from frequencies 440 and 480 
+   by gensound.  200 samples  */
+static short ringtone[200] = {
+           0, 11581, 21659, 28927, 32445, 31764, 26981, 18727, 
+        8084, -3559, -14693, -23875, -29927, -32083, -30088, -24228, 
+       -15290, -4453,  6864, 17195, 25212, 29902, 30693, 27526, 
+       20856, 11585,   944, -9673, -18899, -25560, -28837, -28357, 
+       -24244, -17089, -7868,  2192, 11780, 19667, 24872, 26779, 
+       25212, 20450, 13179,  4396, -4731, -13019, -19421, -23164, 
+       -23839, -21446, -16384, -9384, -1408,  6484, 13281, 18145, 
+       20517, 20182, 17286, 12301,  5951,  -887, -7314, -12519, 
+       -15886, -17068, -16017, -12983, -8458, -3109,  2327,  7142, 
+       10750, 12757, 13007, 11585,  8793,  5095,  1044, -2800, 
+       -5951, -8053, -8921, -8560, -7141, -4967, -2421,   104, 
+        2260,  3791,  4567,  4589,  3977,  2941,  1733,   600, 
+        -257,  -722,  -772,  -481,     0,   481,   772,   722, 
+         257,  -600, -1733, -2941, -3977, -4589, -4567, -3791, 
+       -2260,  -104,  2421,  4967,  7141,  8560,  8921,  8053, 
+        5951,  2800, -1044, -5095, -8793, -11585, -13007, -12757, 
+       -10750, -7142, -2327,  3109,  8458, 12983, 16017, 17068, 
+       15886, 12519,  7314,   887, -5951, -12301, -17286, -20182, 
+       -20517, -18145, -13281, -6484,  1408,  9384, 16384, 21446, 
+       23839, 23164, 19421, 13019,  4731, -4396, -13179, -20450, 
+       -25212, -26779, -24872, -19667, -11780, -2192,  7868, 17089, 
+       24244, 28357, 28837, 25560, 18899,  9673,  -944, -11585, 
+       -20856, -27526, -30693, -29902, -25212, -17195, -6864,  4453, 
+       15290, 24228, 30088, 32083, 29927, 23875, 14693,  3559, 
+       -8084, -18727, -26981, -31764, -32445, -28927, -21659, -11581, 
+       
+};
diff --git a/utils/iaxclient/lib/libiax2/src/winiphone.c b/utils/iaxclient/lib/libiax2/src/winiphone.c
new file mode 100644 (file)
index 0000000..0bc3147
--- /dev/null
@@ -0,0 +1,761 @@
+/*
+ * Miniphone: A simple, command line telephone
+ *
+ * IAX Support for talking to Asterisk and other Gnophone clients
+ *
+ * Copyright (C) 1999, Linux Support Services, Inc.
+ *
+ * Mark Spencer <markster@linux-support.net>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License
+ */
+
+/* #define     PRINTCHUCK /* enable this to indicate chucked incomming packets */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <io.h>
+#include <conio.h>
+#include <stdio.h>
+#include <errno.h>
+#include <time.h>
+#include <process.h>
+#include <windows.h>
+#include <winsock.h>
+#include <mmsystem.h>
+#include <malloc.h>
+#include "gsm.h"
+#include "iax-client.h"
+#include "frame.h"
+#include "miniphone.h"
+
+
+struct peer {
+       int time;
+       gsm gsmin;
+       gsm gsmout;
+
+       struct iax_session *session;
+       struct peer *next;
+};
+
+static struct peer *peers;
+static int answered_call = 0;
+
+/* stuff for wave audio device */
+HWAVEOUT wout;
+HWAVEIN win;
+
+typedef struct whout {
+       WAVEHDR w;
+       short   data[160];
+       struct whout *next;
+} WHOUT;
+
+WHOUT *outqueue = NULL;
+
+/* parameters for audio in */
+#define        NWHIN 8                         /* number of input buffer entries */
+/* NOTE the OUT_INTERVAL parameter *SHOULD* be more around 18 to 20 or so, since the packets should
+be spaced by 20 milliseconds. However, in practice, especially in Windoze-95, setting it that high
+caused underruns. 10 is just ever so slightly agressive, and the receiver has to chuck a packet
+every now and then. Thats about the way it should be to be happy. */
+#define        OUT_INTERVAL 10         /* number of ms to wait before sending more data to peer */
+/* parameters for audio out */
+#define        OUT_DEPTH 12            /* number of outbut buffer entries */
+#define        OUT_PAUSE_THRESHOLD 2 /* number of active entries needed to start output (for smoothing) */
+
+/* audio input buffer headers */
+WAVEHDR whin[NWHIN];
+/* audio input buffers */
+char bufin[NWHIN][320];
+
+/* initialize the sequence variables for the audio in stuff */
+unsigned int whinserial = 1,nextwhin = 1;
+
+static struct peer *find_peer(struct iax_session *);
+static void parse_args(FILE *, unsigned char *);
+void do_iax_event(FILE *);
+void call(FILE *, char *);
+void answer_call(void);
+void reject_call(void);
+static void handle_event(FILE *, struct iax_event *e, struct peer *p);
+void parse_cmd(FILE *, int, char **);
+void issue_prompt(FILE *);
+void dump_array(FILE *, char **);
+
+static char *help[] = {
+"Welcome to the miniphone telephony client, the commands are as follows:\n",
+"Help\t\t-\tDisplays this screen.",
+"Call <Number>\t-\tDials the number supplied.",
+"Answer\t\t-\tAnswers an Inbound call.",
+"Reject\t\t-\tRejects an Inbound call.",
+"Dump\t\t-\tDumps (disconnects) the current call.",
+"Dtmf <Digit>\t-\tSends specified DTMF digit.",
+"Status\t\t-\tLists the current sessions and their current status.",
+"Quit\t\t-\tShuts down the client.",
+"",
+0
+};
+
+static struct peer *most_recent_answer;
+static struct iax_session *newcall = 0;
+
+/* holder of the time, relative to startup in system ticks. See our
+gettimeofday() implementation */
+time_t startuptime;
+
+/* routine called at exit to shutdown audio I/O and close nicely.
+NOTE: If all this isnt done, the system doesnt not handle this
+cleanly and has to be rebooted. What a pile of doo doo!! */
+void killem(void)
+{
+       waveInStop(win);
+       waveInReset(win);
+       waveInClose(win); 
+       waveOutReset(wout);
+       waveOutClose(wout);
+       WSACleanup(); /* dont forget socket stuff too */
+       return;
+}
+
+/* Win-doze doenst have gettimeofday(). This sux. So, what we did is
+provide some gettimeofday-like functionality that works for our purposes.
+In the main(), we take a sample of the system tick counter (into startuptime).
+This function returns the relative time since program startup, more or less,
+which is certainly good enough for our purposes. */
+void gettimeofday(struct timeval *tv, struct timezone *tz)
+{
+       long l = startuptime + GetTickCount();
+
+       tv->tv_sec = l / 1000;
+       tv->tv_usec = (l % 1000) * 1000;
+       return;
+}
+
+
+static struct peer *find_peer(struct iax_session *session)
+{
+       struct peer *cur = peers;
+       while(cur) {
+               if (cur->session == session)
+                       return cur;
+               cur = cur->next;
+       }
+       return NULL;
+}
+
+void
+parse_args(FILE *f, unsigned char *cmd)
+{
+       static char *argv[MAXARGS];
+       unsigned char *parse = cmd;
+       int argc = 0, t = 0;
+
+       // Don't mess with anything that doesn't exist...
+       if(!*parse)
+               return;
+
+       memset(argv, 0, sizeof(argv));
+       while(*parse) {
+               if(*parse < 33 || *parse > 128) {
+                       *parse = 0, t++;
+                       if(t > MAXARG) {
+                               fprintf(f, "Warning: Argument exceeds maximum argument size, command ignored!\n");
+                               return;
+                       }
+               } else if(t || !argc) {
+                       if(argc == MAXARGS) {
+                               fprintf(f, "Warning: Command ignored, too many arguments\n");
+                               return;
+                       }
+                       argv[argc++] = parse;
+                       t = 0;
+               }
+
+               parse++;
+       }
+
+       if(argc)
+               parse_cmd(f, argc, argv);
+}
+
+/* handle all network requests, and a pending scheduled event, if any */
+void service_network(int netfd, FILE *f)
+{
+       fd_set readfd;
+       struct timeval dumbtimer;
+
+       /* set up a timer that falls-through */
+       dumbtimer.tv_sec = 0;
+       dumbtimer.tv_usec = 0;
+
+
+               for(;;) /* suck everything outa network stuff */
+               {
+                       FD_ZERO(&readfd);
+                       FD_SET(netfd, &readfd);
+                       if (select(netfd + 1, &readfd, 0, 0, &dumbtimer) > 0)
+                       {
+                               if (FD_ISSET(netfd,&readfd))
+                               {
+                                       do_iax_event(f);
+                                       (void) iax_time_to_next_event();
+                               } else break;
+                       } else break;
+               }
+               do_iax_event(f); /* do pending event if any */
+}
+
+
+int
+main(int argc, char *argv[])
+{
+       int port;
+       int netfd;
+       int c, i;
+       FILE *f;
+       char rcmd[RBUFSIZE];
+       gsm_frame fo;
+       WSADATA foop;
+       time_t  t;
+       WAVEFORMATEX wf;
+       WHOUT *wh,*wh1,*wh2;
+       unsigned long lastouttick = 0;
+
+
+
+       /* get time of day in milliseconds, offset by tick count (see our
+          gettimeofday() implementation) */
+       time(&t);
+       startuptime = ((t % 86400) * 1000) - GetTickCount();
+
+       f = stdout;
+       _dup2(fileno(stdout),fileno(stderr));
+
+       /* start up the windoze-socket layer stuff */
+       if (WSAStartup(0x0101,&foop)) {
+               fprintf(stderr,"Fatal error: Falied to startup windows sockets\n");
+               return -1;
+       }
+
+
+       /* setup the format for opening audio channels */
+       wf.wFormatTag = WAVE_FORMAT_PCM;
+       wf.nChannels = 1;
+       wf.nSamplesPerSec = 8000;
+       wf.nAvgBytesPerSec = 16000;
+       wf.nBlockAlign = 2;
+       wf.wBitsPerSample = 16;
+       wf.cbSize = 0;
+       /* open the audio out channel */
+       if (waveOutOpen(&wout,0,&wf,0,0,CALLBACK_NULL) != MMSYSERR_NOERROR)
+               {
+                       fprintf(stderr,"Fatal Error: Failed to open wave output device\n");
+                       return -1;
+               }
+       /* open the audio in channel */
+       if (waveInOpen(&win,0,&wf,0,0,CALLBACK_NULL) != MMSYSERR_NOERROR)
+               {
+                       fprintf(stderr,"Fatal Error: Failed to open wave input device\n");
+                       waveOutReset(wout);
+                       waveOutClose(wout);
+                       return -1;
+               }
+       /* activate the exit handler */
+       atexit(killem);
+       /* initialize the audio in buffer structures */
+       memset(&whin,0,sizeof(whin));
+
+       if ( (port = iax_init(0) < 0)) {
+               fprintf(stderr, "Fatal error: failed to initialize iax with port %d\n", port);
+               return -1;
+       }
+
+
+       iax_set_formats(AST_FORMAT_GSM);
+       netfd = iax_get_fd();
+
+       fprintf(f, "Text Based Telephony Client.\n\n");
+       issue_prompt(f);
+
+       /* main tight loop */
+       while(1) {
+               /* service the network stuff */
+               service_network(netfd,f);
+               if (outqueue) /* if stuff in audio output queue, free it up if its available */
+               {
+                       /* go through audio output queue */
+                       for(wh = outqueue,wh1 = wh2 = NULL,i = 0; wh != NULL; wh = wh->next)
+                       {
+                               service_network(netfd,f); /* service network here for better performance */
+                               /* if last one was removed from queue, zot it here */
+                               if (i && wh1)
+                               { 
+                                       free(wh1);
+                                       wh1 = wh2;
+                               }
+                               i = 0; /* reset "last one removed" flag */
+                               if (wh->w.dwFlags & WHDR_DONE) /* if this one is done */
+                               {
+                                       /* prepare audio header */
+                                       if ((c = waveOutUnprepareHeader(wout,&wh->w,sizeof(WAVEHDR))) != MMSYSERR_NOERROR)
+                                       { 
+                                               fprintf(stderr,"Cannot unprepare audio out header, error %d\n",c);
+                                               exit(255);
+                                       }
+                                       if (wh1 != NULL) /* if there was a last one */
+                                       {
+                                               wh1->next = wh->next;
+                                       } 
+                                       if (outqueue == wh) /* is first one, so set outqueue to next one */
+                                       {
+                                               outqueue = wh->next;
+                                       }
+                                       i = 1; /* set 'to free' flag */
+                               }
+                               wh2 = wh1;      /* save old,old wh pointer */
+                               wh1 = wh; /* save the old wh pointer */
+                       }
+               }
+               /* go through all audio in buffers, and prepare and queue ones that are currently idle */
+               for(i = 0; i < NWHIN; i++)
+               {
+                       service_network(netfd,f); /* service network stuff here for better performance */
+                       if (!(whin[i].dwFlags & WHDR_PREPARED)) /* if not prepared, do so */
+                       {
+                               /* setup this input buffer header */
+                               memset(&whin[i],0,sizeof(WAVEHDR));
+                               whin[i].lpData = bufin[i];
+                               whin[i].dwBufferLength = 320;
+                               whin[i].dwUser = whinserial++; /* set 'user data' to current serial number */
+                               /* prepare the buffer */
+                               if (waveInPrepareHeader(win,&whin[i],sizeof(WAVEHDR)))
+                               {
+                                       fprintf(stderr,"Unable to prepare header for input\n");
+                                       return -1;
+                               }
+                               /* add it to device (queue) */
+                               if (waveInAddBuffer(win,&whin[i],sizeof(WAVEHDR)))
+                               {
+                                       fprintf(stderr,"Unable to prepare header for input\n");
+                                       return -1;
+                               }
+                       }
+                       waveInStart(win); /* start it (if not already started) */
+               }
+               
+               /* if key pressed, do command stuff */
+               if(_kbhit())
+               {
+                               if ( ( fgets(&*rcmd, 256, stdin))) {
+                                       rcmd[strlen(rcmd)-1] = 0;
+                                       parse_args(f, &*rcmd);
+                               } else fprintf(f, "Fatal error: failed to read data!\n");
+
+                               issue_prompt(f);
+               }
+               /* do audio input stuff for buffers that have received data from audio in device already. Must
+                       do them in serial number order (the order in which they were originally queued). */
+               if(answered_call) /* send audio only if call answered */
+               {
+                       for(;;) /* loop until all are found */
+                       {
+                               for(i = 0; i < NWHIN; i++) /* find an available one that's the one we are looking for */
+                               {
+                                       service_network(netfd,f); /* service network here for better performance */
+                                       /* if not time to send any more, dont */
+                                       if (GetTickCount() < (lastouttick + OUT_INTERVAL))
+                                       {
+                                               i = NWHIN; /* set to value that WILL exit loop */
+                                               break;
+                                       }
+                                       if ((whin[i].dwUser == nextwhin) && (whin[i].dwFlags & WHDR_DONE)) { /* if audio is ready */
+
+                                               /* must have read exactly 320 bytes */
+                                               if (whin[i].dwBytesRecorded != whin[i].dwBufferLength)
+                                               {
+                                                       fprintf(stderr,"Short audio read, got %d bytes, expected %d bytes\n", whin[i].dwBytesRecorded,
+                                                               whin[i].dwBufferLength);
+                                                       return -1;
+                                               }
+                                               if(!most_recent_answer->gsmout)
+                                                               most_recent_answer->gsmout = gsm_create();
+
+                                               service_network(netfd,f); /* service network here for better performance */
+                                               /* encode the audio from the buffer into GSM format */
+                                               gsm_encode(most_recent_answer->gsmout, (short *) ((char *) whin[i].lpData), fo);
+                                               if(iax_send_voice(most_recent_answer->session,
+                                                       AST_FORMAT_GSM, (char *)fo, sizeof(gsm_frame)) == -1)
+                                                                       puts("Failed to send voice!"); 
+                                               lastouttick = GetTickCount(); /* save time of last output */
+
+                                               /* unprepare (free) the header */
+                                               waveInUnprepareHeader(win,&whin[i],sizeof(WAVEHDR));
+                                               /* initialize the buffer */
+                                               memset(&whin[i],0,sizeof(WAVEHDR));
+                                               /* bump the serial number to look for the next time */
+                                               nextwhin++;
+                                               /* exit the loop so that we can start at lowest buffer again */
+                                               break;
+                                       }
+                               } 
+                               if (i >= NWHIN) break; /* if all found, get out of loop */
+                       }
+               }
+
+       }
+       return 0;
+}
+
+void
+do_iax_event(FILE *f) {
+       int sessions = 0;
+       struct iax_event *e = 0;
+       struct peer *peer;
+
+       while ( (e = iax_get_event(0))) {
+               peer = find_peer(e->session);
+               if(peer) {
+                       handle_event(f, e, peer);
+               } else {
+                       if(e->etype != IAX_EVENT_CONNECT) {
+                               fprintf(stderr, "Huh? This is an event for a non-existant session?\n");
+                       }
+                       sessions++;
+
+                       if(sessions >= MAX_SESSIONS) {
+                               fprintf(f, "Missed a call... too many sessions open.\n");
+                       }
+
+
+                       if(e->event.connect.callerid && e->event.connect.dnid)
+                               fprintf(f, "Call from '%s' for '%s'", e->event.connect.callerid, 
+                               e->event.connect.dnid);
+                       else if(e->event.connect.dnid) {
+                               fprintf(f, "Call from '%s'", e->event.connect.dnid);
+                       } else if(e->event.connect.callerid) {
+                               fprintf(f, "Call from '%s'", e->event.connect.callerid);
+                       } else printf("Call from");
+                       fprintf(f, " (%s)\n", inet_ntoa(iax_get_peer_addr(e->session).sin_addr));
+
+                       if(most_recent_answer) {
+                               fprintf(f, "Incoming call ignored, there's already a call waiting for answer... \
+please accept or reject first\n");
+                               iax_reject(e->session, "Too many calls, we're busy!");
+                       } else {
+                               if ( !(peer = malloc(sizeof(struct peer)))) {
+                                       fprintf(f, "Warning: Unable to allocate memory!\n");
+                                       return;
+                               }
+
+                               peer->time = time(0);
+                               peer->session = e->session;
+                               peer->gsmin = 0;
+                               peer->gsmout = 0;
+
+                               peer->next = peers;
+                               peers = peer;
+
+                               iax_accept(peer->session);
+                               iax_ring_announce(peer->session);
+                               most_recent_answer = peer;
+                               fprintf(f, "Incoming call!\n");
+                       }
+                       iax_event_free(e);
+                       issue_prompt(f);
+               }
+       }
+}
+
+void
+call(FILE *f, char *num)
+{
+       struct peer *peer;
+
+       if(!newcall)
+               newcall = iax_session_new();
+       else {
+               fprintf(f, "Already attempting to call somewhere, please cancel first!\n");
+               return;
+       }
+
+       if ( !(peer = malloc(sizeof(struct peer)))) {
+               fprintf(f, "Warning: Unable to allocate memory!\n");
+               return;
+       }
+
+       peer->time = time(0);
+       peer->session = newcall;
+       peer->gsmin = 0;
+       peer->gsmout = 0;
+
+       peer->next = peers;
+       peers = peer;
+
+       most_recent_answer = peer;
+
+       iax_call(peer->session, num, 10);
+}
+
+void
+answer_call(void)
+{
+       if(most_recent_answer)
+               iax_answer(most_recent_answer->session);
+       printf("Answering call!\n");
+       answered_call = 1;
+}
+
+void
+dump_call(void)
+{
+       if(most_recent_answer)
+       {
+               iax_hangup(most_recent_answer->session,"");
+               free(most_recent_answer);
+       }
+       printf("Dumping call!\n");
+       answered_call = 0;
+       most_recent_answer = 0;
+       answered_call = 0;
+       peers = 0;
+       newcall = 0;
+}
+
+void
+reject_call(void)
+{
+       iax_reject(most_recent_answer->session, "Call rejected manually.");
+       most_recent_answer = 0;
+}
+
+void
+handle_event(FILE *f, struct iax_event *e, struct peer *p)
+{
+       int len,n;
+       WHOUT *wh,*wh1;
+       short fr[160];
+       static paused_xmit = 0;
+
+
+       switch(e->etype) {
+               case IAX_EVENT_HANGUP:
+                       iax_hangup(most_recent_answer->session, "Byeee!");
+                       fprintf(f, "Call disconnected by peer\n");
+                       free(most_recent_answer);
+                       most_recent_answer = 0;
+                       answered_call = 0;
+                       peers = 0;
+                       newcall = 0;
+                       
+                       break;
+
+               case IAX_EVENT_REJECT:
+                       fprintf(f, "Authentication was rejected\n");
+                       break;
+               case IAX_EVENT_ACCEPT:
+                       fprintf(f, "Waiting for answer... RING RING\n");
+                       issue_prompt(f);
+                       break;
+               case IAX_EVENT_ANSWER:
+                       answer_call();
+                       break;
+               case IAX_EVENT_VOICE:
+                       switch(e->event.voice.format) {
+                               case AST_FORMAT_GSM:
+                                       if(e->event.voice.datalen % 33) {
+                                               fprintf(stderr, "Weird gsm frame, not a multiple of 33.\n");
+                                               break;
+                                       }
+
+                                       if (!p->gsmin)
+                                               p->gsmin = gsm_create();
+
+                                       len = 0;
+                                       while(len < e->event.voice.datalen) {
+                                               if(gsm_decode(p->gsmin, (char *) e->event.voice.data + len, fr)) {
+                                                       fprintf(stderr, "Bad GSM data\n");
+                                                       break;
+                                               } else {  /* its an audio packet to be output to user */
+
+                                                       /* get count of pending items in audio output queue */
+                                                       n = 0; 
+                                                       if (outqueue) 
+                                                       {       /* determine number of pending out queue items */
+                                                               for(wh = outqueue; wh != NULL; wh = wh->next)
+                                                               {
+                                                                       if (!(wh->w.dwFlags & WHDR_DONE)) n++;
+                                                               }
+                                                       }
+                                                       /* if not too many, send to user, otherwise chuck packet */
+                                                       if (n <= OUT_DEPTH) /* if not to chuck packet */
+                                                       {
+                                                               /* malloc the memory for the queue item */
+                                                               wh = (WHOUT *) malloc(sizeof(WHOUT));
+                                                               if (wh == (WHOUT *) NULL) /* if error, bail */
+                                                               {
+                                                                       fprintf(stderr,"Outa memory!!!!\n");
+                                                                       exit(255);
+                                                               }
+                                                               /* initialize the queue entry */
+                                                               memset(wh,0,sizeof(WHOUT));
+                                                               /* copy the PCM data from the gsm conversion buffer */
+                                                               memcpy((char *)wh->data,(char *)fr,sizeof(fr));
+                                                               /* set parameters for data */
+                                                               wh->w.lpData = (char *) wh->data;
+                                                               wh->w.dwBufferLength = 320;
+                                                               
+                                                               /* prepare buffer for output */
+                                                               if (waveOutPrepareHeader(wout,&wh->w,sizeof(WAVEHDR)))
+                                                               {
+                                                                       fprintf(stderr,"Cannot prepare header for audio out\n");
+                                                                       exit(255);
+                                                               }
+                                                               /* if not currently transmitting, hold off a couple of packets for 
+                                                                       smooth sounding output */
+                                                               if ((!n) && (!paused_xmit))
+                                                               {
+                                                                       /* pause output (before starting) */
+                                                                       waveOutPause(wout);
+                                                                       /* indicate as such */
+                                                                       paused_xmit = 1;
+                                                               }
+                                                               /* queue packet for output on audio device */
+                                                               if (waveOutWrite(wout,&wh->w,sizeof(WAVEHDR)))
+                                                               {
+                                                                       fprintf(stderr,"Cannot output to wave output device\n");
+                                                                       exit(255);
+                                                               }
+                                                               /* if we are paused, and we have enough packets, start audio */
+                                                               if ((n > OUT_PAUSE_THRESHOLD) && paused_xmit)
+                                                               {
+                                                                       /* start the output */
+                                                                       waveOutRestart(wout);
+                                                                       /* indicate as such */
+                                                                       paused_xmit = 0;
+                                                               }
+                                                               /* insert it onto tail of outqueue */
+                                                               if (outqueue == NULL) /* if empty queue */
+                                                                       outqueue = wh; /* point queue to new entry */
+                                                               else /* otherwise is non-empty queue */
+                                                               {
+                                                                       wh1 = outqueue;
+                                                                       while(wh1->next) wh1 = wh1->next; /* find last entry in queue */
+                                                                       wh1->next = wh; /* point it to new entry */
+                                                               }
+                                                       } 
+#ifdef PRINTCHUCK
+                                                       else printf("Chucking packet!!\n");
+#endif
+                                               }
+                                               len += 33;
+                                       }
+                                       break;
+                               default :
+                                       fprintf(f, "Don't know how to handle that format %d\n", e->event.voice.format);
+                       }
+                       break;
+               case IAX_EVENT_RINGA:
+                       break;
+               default:
+                       fprintf(f, "Unknown event: %d\n", e->etype);
+                       break;
+       }
+}
+
+void
+parse_cmd(FILE *f, int argc, char **argv)
+{
+       _strupr(argv[0]);
+       if(!strcmp(argv[0], "HELP")) {
+               if(argc == 1)
+                       dump_array(f, help);
+               else if(argc == 2) {
+                       if(!strcmp(argv[1], "HELP"))
+                               fprintf(f, "Help <Command>\t-\tDisplays general help or specific help on command if supplied an arguement\n");
+                       else if(!strcmp(argv[1], "QUIT"))
+                               fprintf(f, "Quit\t\t-\tShuts down the miniphone\n");
+                       else fprintf(f, "No help available on %s\n", argv[1]);
+               } else {
+                       fprintf(f, "Too many arguements for command help.\n");
+               }
+       } else if(!strcmp(argv[0], "STATUS")) {
+               if(argc == 1) {
+                       int c = 0;
+                       struct peer *peerptr = peers;
+
+                       if(!peerptr)
+                               fprintf(f, "No session matches found.\n");
+                       else while(peerptr) {
+                               fprintf(f, "Listing sessions:\n\n");
+                               fprintf(f, "Session %d\n", ++c);
+                               fprintf(f, "Session existed for %d seconds\n", (int)time(0)-peerptr->time);
+                               if(answered_call)
+                                       fprintf(f, "Call answered.\n");
+                               else fprintf(f, "Call ringing.\n");
+
+                               peerptr = peerptr->next;
+                       }
+               } else fprintf(f, "Too many arguments for command status.\n");
+       } else if(!strcmp(argv[0], "ANSWER")) {
+               if(argc > 1)
+                       fprintf(f, "Too many arguements for command answer\n");
+               else answer_call();
+       } else if(!strcmp(argv[0], "REJECT")) {
+               if(argc > 1)
+                       fprintf(f, "Too many arguements for command reject\n");
+               else {
+                       fprintf(f, "Rejecting current phone call.\n");
+                       reject_call();
+               }
+       } else if(!strcmp(argv[0], "CALL")) {
+               if(argc > 2)
+                       fprintf(f, "Too many arguements for command call\n");
+               else {
+                       call(f, argv[1]);
+               }
+       } else if(!strcmp(argv[0], "DUMP")) {
+               if(argc > 1)
+                       fprintf(f, "Too many arguements for command dump\n");
+               else {
+                       dump_call();
+               }
+       } else if(!strcmp(argv[0], "DTMF")) {
+               if(argc > 2)
+               {
+                       fprintf(f, "Too many arguements for command dtmf\n");
+                       return;
+               }
+               if (argc < 1)
+               {
+                       fprintf(f, "Too many arguements for command dtmf\n");
+                       return;
+               }
+               if(most_recent_answer)
+                               iax_send_dtmf(most_recent_answer->session,*argv[1]);
+       } else if(!strcmp(argv[0], "QUIT")) {
+               if(argc > 1)
+                       fprintf(f, "Too many arguements for command quit\n");
+               else {
+                       fprintf(f, "Good bye!\n");
+                       exit(1);
+               }
+       } else fprintf(f, "Unknown command of %s\n", argv[0]);
+}
+
+void
+issue_prompt(FILE *f)
+{
+       fprintf(f, "TeleClient> ");
+       fflush(f);
+}
+
+void
+dump_array(FILE *f, char **array) {
+       while(*array)
+               fprintf(f, "%s\n", *array++);
+}
diff --git a/utils/iaxclient/lib/libiax2/src/winpoop.h b/utils/iaxclient/lib/libiax2/src/winpoop.h
new file mode 100644 (file)
index 0000000..4e9d112
--- /dev/null
@@ -0,0 +1,52 @@
+/* 
+ * Functions Windows doesn't have... but should
+ * Copyright(C) 2001, Linux Support Services, Inc.
+ *
+ * Distributed under GNU LGPL.
+ *
+ * These are NOT fully compliant with BSD 4.3 and are not
+ * threadsafe.
+ *
+ */
+
+#ifndef _winpoop_h
+#define _winpoop_h
+
+#if defined(_MSC_VER)
+#define INLINE __inline
+#define inline __inline
+#define snprintf _snprintf
+// should try without these
+#pragma warning(disable: 4996 4244 4305 4018 4804)
+#if defined(_WIN64)
+   typedef __int64      ssize_t;
+#elif defined(_WIN32)
+   typedef __int32      ssize_t;
+#endif
+#else
+#define INLINE inline
+#endif
+
+#include <winsock2.h>   // this include <windows.h>
+#include <io.h> // for open, close, write, read
+#include <stdio.h>
+
+void gettimeofday(struct timeval *tv, void /*struct timezone*/ *tz);
+
+static INLINE int inet_aton(char *cp, struct in_addr *inp)
+{
+       int a1, a2, a3, a4;
+       unsigned int saddr;
+
+       if (sscanf(cp, "%d.%d.%d.%d", &a1, &a2, &a3, &a4) != 4)
+               return 0;
+       a1 &= 0xff;
+       a2 &= 0xff;
+       a3 &= 0xff;
+       a4 &= 0xff; 
+       saddr = (a1 << 24) | (a2 << 16) | (a3 << 8) | a4;
+       inp->s_addr = htonl(saddr);
+       return 1;
+}
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/ChangeLog b/utils/iaxclient/lib/libspeex/ChangeLog
new file mode 100644 (file)
index 0000000..c5f957f
--- /dev/null
@@ -0,0 +1,4350 @@
+2005-05-09 21:27  jm
+
+       * trunk/speex/include/speex/speex_echo.h,
+         trunk/speex/libspeex/mdf.c: Smoothed correlation/energy
+
+2005-05-09 21:03  jm
+
+       * trunk/speex/include/speex/speex_echo.h,
+         trunk/speex/libspeex/mdf.c: Some more regularization work for mdf
+
+2005-05-09 18:15  jm
+
+       * trunk/speex/libspeex/mdf.c: System in underdetermined, trying to
+         work around that.
+
+2005-05-08 04:49  jm
+
+       * trunk/speex/include/speex/speex_echo.h,
+         trunk/speex/libspeex/mdf.c: Some more AEC cleanup. Played a bit
+         with echo energy estimation.
+
+2005-05-08 00:08  jm
+
+       * trunk/speex/include/speex/speex_echo.h,
+         trunk/speex/include/speex/speex_preprocess.h,
+         trunk/speex/libspeex/mdf.c, trunk/speex/libspeex/preprocess.c:
+         Simplified the code a lot. Put back the denoiser hooks for further
+         cancellation (changed spectral param to float* at least for now).
+
+2005-05-07 08:07  jm
+
+       * trunk/speex/libspeex/mdf.c: trying some ideas for soft-decision
+         DTD based on residual-to-signal ratio
+
+2005-05-04 05:38  jm
+
+       * trunk/speex/libspeex/misc.h: changed version number for those not
+         using autoconf
+
+2005-05-02 07:05  jm
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/src/Makefile.am,
+         trunk/speex/src/speexdec.c, trunk/speex/src/speexenc.c,
+         trunk/speex/src/wav_io.h: support for top_builddir != top_srcdir
+
+2005-05-02 00:49  jm
+
+       * trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/ltp.h,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h: Added some control on the
+         aggressiveness of the pitch predictor in the form of a
+         SPEEX_SET_PLC_TUNING call.
+
+2005-04-29 05:33  jm
+
+       * trunk/speex/Speex.spec.in, trunk/speex/libspeex/arch.h,
+         trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/sb_celp.c: Think I fixed the PLC slowdown due
+         to denorm/underflow. Also don't re- synthesize on encode (i.e.
+         don't overwrite input buffer).
+
+2005-04-25 18:21  jm
+
+       * trunk/speex/libspeex/sb_celp.c: pseudo-stack optional for wideband
+         too
+
+2005-04-25 08:12  jm
+
+       * trunk/speex/configure.ac, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/stack_alloc.h: Autodetection of C99 variable
+         arrays and alloca. The pseudo-stack is only used if nothing else
+         is available.
+
+2005-04-25 07:16  jm
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/ltp.c:
+         convert codebook data (signed char) to spx_word16_t in a cleaner
+         manner
+
+2005-04-25 06:16  jm
+
+       * trunk/speex/configure.ac, trunk/speex/include/speex/speex.h,
+         trunk/speex/include/speex/speex_header.h,
+         trunk/speex/include/speex/speex_preprocess.h,
+         trunk/speex/include/speex/speex_stereo.h,
+         trunk/speex/include/speex/speex_types.h.in,
+         trunk/speex/libspeex/arch.h, trunk/speex/libspeex/fixed_debug.h,
+         trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/misc.c,
+         trunk/speex/libspeex/misc.h, trunk/speex/libspeex/preprocess.c,
+         trunk/speex/libspeex/speex.c, trunk/speex/libspeex/stereo.c,
+         trunk/speex/src/wav_io.c, trunk/speex/src/wav_io.h: Now
+         autodetects (and handles) size of integer types.
+
+2005-04-24 04:45  jm
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/fixed_debug.h, trunk/speex/libspeex/lsp.c,
+         trunk/speex/libspeex/ltp.c: some cleaning up
+
+2005-04-24 03:23  jm
+
+       * trunk/speex/libspeex/filters.c: fixed-point stuff
+
+2005-04-22 08:57  jm
+
+       * trunk/speex/libspeex/filters_arm4.h: oops
+
+2005-04-22 07:39  jm
+
+       * trunk/speex/libspeex/arch.h, trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/filters.c, trunk/speex/libspeex/fixed_arm4.h,
+         trunk/speex/libspeex/fixed_arm5e.h,
+         trunk/speex/libspeex/fixed_debug.h,
+         trunk/speex/libspeex/fixed_generic.h, trunk/speex/libspeex/lpc.c,
+         trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/math_approx.c,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/quant_lsp.c,
+         trunk/speex/libspeex/vq.c: More work on fixed-point operators
+
+2005-04-22 06:23  jm
+
+       * trunk/speex/libspeex/arch.h, trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/filters.c, trunk/speex/libspeex/fixed_arm4.h,
+         trunk/speex/libspeex/fixed_arm5e.h,
+         trunk/speex/libspeex/fixed_debug.h,
+         trunk/speex/libspeex/fixed_generic.h, trunk/speex/libspeex/lpc.c,
+         trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/sb_celp.c: Added some more fixed-point
+         operators
+
+2005-04-22 04:40  jm
+
+       * trunk/speex/TODO, trunk/speex/configure.ac,
+         trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c:
+         Fixed-point improvements (moved some stuff to 16-bit arithmetic)
+
+2005-04-02 04:10  jm
+
+       * trunk/speex/libspeex/arch.h: Oops, forgot to add MAC16_16_Q13 for
+         float too.
+
+2005-03-30 03:31  jm
+
+       * trunk/speex/include/speex/speex.h,
+         trunk/speex/include/speex/speex_jitter.h,
+         trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/speex.c: Removed another bunch of warnings
+         (when using some of the -W options)
+
+2005-03-30 01:13  jm
+
+       * trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/misc.c,
+         trunk/speex/libspeex/misc.h, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/quant_lsp.c,
+         trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/speex_header.c: fixed-point cleanup, removed
+         some warnings
+
+2005-03-25 02:58  jm
+
+       * trunk/speex/libspeex/medfilter.c,
+         trunk/speex/libspeex/medfilter.h: Median filter. May need that in
+         the future.
+
+2005-03-15 05:18  jm
+
+       * trunk/speex/configure.ac, trunk/speex/include/speex/speex_bits.h,
+         trunk/speex/include/speex/speex_header.h,
+         trunk/speex/libspeex/arch.h, trunk/speex/libspeex/bits.c,
+         trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/fixed_arm4.h,
+         trunk/speex/libspeex/fixed_arm5e.h,
+         trunk/speex/libspeex/fixed_debug.h,
+         trunk/speex/libspeex/fixed_generic.h,
+         trunk/speex/libspeex/jitter.c, trunk/speex/libspeex/lpc.c,
+         trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/misc.c, trunk/speex/libspeex/misc.h,
+         trunk/speex/libspeex/modes.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/quant_lsp.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex_callbacks.c,
+         trunk/speex/libspeex/speex_header.c,
+         trunk/speex/libspeex/testenc.c: Merged a modified version of Jamey
+         Hicks' C55 patch, fixed a long-standing fixed-point wideband
+         overflow. Replaced some "+" and "-" with ADD() and SUB().
+
+2005-03-11 20:08  jm
+
+       * trunk/speex/libspeex/stack_alloc.h: Support for alloca (untested)
+
+2005-03-03 18:30  jm
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search_sse.h,
+         trunk/speex/libspeex/filters.c, trunk/speex/libspeex/lsp.c,
+         trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/ltp_sse.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/stack_alloc.h, trunk/speex/libspeex/vq.c: Now
+         possible to put temporary arrays directly on the (real) stack
+
+2005-03-03 06:08  jm
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c:
+         First cleanup step for stack allocation
+
+2005-03-02 08:23  jm
+
+       * trunk/speex/libspeex/cb_search.c: Comment
+
+2005-03-01 23:47  jm
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c: cleanup
+
+2005-03-01 09:22  jm
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h:
+         Reduced unnecessary buffers (reduced memory usage)
+
+2005-02-17 05:42  jm
+
+       * trunk/speex/libspeex/ltp.c: oops, that should fix the float
+         version
+
+2005-02-09 09:13  jm
+
+       * trunk/speex/libspeex/filters_arm4.h: Unrolled version of
+         filter_mem2 and iir_mem2
+
+2005-02-09 09:13  jm
+
+       * trunk/speex/libspeex/nb_celp.c: Added a shortcut for ringing
+         computation
+
+2005-02-09 08:32  jm
+
+       * trunk/speex/libspeex/ltp_arm4.h: oops...
+
+2005-02-09 08:19  jm
+
+       * trunk/speex/libspeex/ltp_arm4.h: added a shortcut to skip every
+         second sample in open-loop pitch
+
+2005-02-09 08:14  jm
+
+       * trunk/speex/libspeex/ltp_arm4.h: reordering asm
+
+2005-02-09 08:02  jm
+
+       * trunk/speex/libspeex/ltp_arm4.h: no "memory" clobbered in inline
+         asm
+
+2005-02-09 07:47  jm
+
+       * trunk/speex/libspeex/vq_arm4.h: oops
+
+2005-02-09 07:34  jm
+
+       * trunk/speex/libspeex/Makefile.am: ...
+
+2005-02-09 07:31  jm
+
+       * trunk/speex/libspeex/fixed_arm4.h, trunk/speex/libspeex/lsp.c,
+         trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/vq.c: misc
+         optimizations
+
+2005-02-09 04:10  jm
+
+       * trunk/speex/libspeex/filters.c: Cleared the last float ops from
+         the comb filter
+
+2005-02-09 03:56  jm
+
+       * trunk/speex/libspeex/cb_search.c: Removed warning, unnecessary
+         variables
+
+2005-02-09 03:47  jm
+
+       * trunk/speex/libspeex/ltp.c: oops... ANSI C fix
+
+2005-02-09 03:35  jm
+
+       * trunk/speex/libspeex/cb_search.c: Special case for complexity=1
+
+2005-02-09 02:56  jm
+
+       * trunk/speex/libspeex/filters.c: Fixed-point-ized a critical divide
+         in the comb filter
+
+2005-02-08 23:54  jm
+
+       * trunk/speex/libspeex/vq_arm4.h: ARM version of VQ quantizer, but
+         only for N=1
+
+2005-02-08 22:29  jm
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/cb_search.c: Make use of cb_search_arm4.h
+
+2005-02-08 22:28  jm
+
+       * trunk/speex/libspeex/nb_celp.c: A bit less agressive on ringing
+         computation (complexity 0), but simplified memory update at end of
+         subframe
+
+2005-02-08 21:40  jm
+
+       * trunk/speex/libspeex/fixed_arm4.h,
+         trunk/speex/libspeex/fixed_arm5e.h: ARM arch fixes, assembly
+         version of MULT16_32_Q15 and MULT16_32_Q14
+
+2005-02-08 18:29  jm
+
+       * trunk/speex/libspeex/nb_celp.c: removed some useless memory access
+
+2005-02-08 10:18  jm
+
+       * trunk/speex/libspeex/cb_search_arm4.h: ARM assembly version of
+         compute_weighted_codebook()
+
+2005-02-08 06:23  jm
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/lsp.c,
+         trunk/speex/libspeex/ltp.c: Some general (minor) optimizations
+
+2005-02-07 22:21  jm
+
+       * trunk/speex/libspeex/lsp.c: changed 0.0 to 0 for fixed-point
+         version
+
+2005-02-07 22:06  jm
+
+       * trunk/speex/libspeex/cb_search.c: Brought back a version
+         split_cb_search_shape_sign optimized for complexity 1
+
+2005-02-07 21:14  jm
+
+       * trunk/speex/libspeex/ltp.c: Removed unnecessary initialization
+
+2005-02-07 10:01  jm
+
+       * trunk/speex/libspeex/filters_arm4.h,
+         trunk/speex/libspeex/ltp_arm4.h: added some %= signs for labels
+
+2005-02-07 09:03  jm
+
+       * trunk/speex/libspeex/fixed_arm4.h,
+         trunk/speex/libspeex/fixed_arm5e.h,
+         trunk/speex/libspeex/ltp_arm4.h: oops. Fixed some bad copy/paste
+
+2005-02-07 08:46  jm
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/arch.h,
+         trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters_arm4.h,
+         trunk/speex/libspeex/fixed_arm4.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp_arm4.h: ARM assembly version of
+         pitch_xcorr, moved all ARM assembly to separate files
+
+2005-02-07 04:00  jm
+
+       * trunk/speex/libspeex/ltp.c: an alternative implementation of
+         pitch_xcorr for machines with enough registers (more than x86,
+         that is).
+
+2005-02-07 00:35  jm
+
+       * trunk/speex/libspeex/fixed_arm5e.h: ARM assembly version of
+         DIV32_16
+
+2005-02-05 23:23  jm
+
+       * trunk/speex/libspeex/ltp.c: ARM assembly version of inner_prod
+         with 8x unrolling
+
+2005-02-05 08:16  jm
+
+       * trunk/speex/libspeex/bits.c: removed unnecessary
+         (re)initialization of the bit packer bytes
+
+2005-02-05 07:43  jm
+
+       * trunk/speex/libspeex/fixed_arm.h: That was renamed to
+         fixed_arm5e.h
+
+2005-02-05 07:42  jm
+
+       * trunk/speex/configure.ac, trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/arch.h, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/fixed_arm5e.h: Renamed --enable-arm-asm to
+         --enable-arm5e-asm to reflect the fact that these instructions
+         aren't supported everywhere. Also added --enable-arm4-asm.
+
+2005-02-05 06:37  jm
+
+       * trunk/speex/libspeex/filters.c: ARM instruction scheduling for
+         iir_mem2
+
+2005-02-05 06:00  jm
+
+       * trunk/speex/libspeex/filters.c: More ARM stuff
+
+2005-02-05 05:38  jm
+
+       * trunk/speex/libspeex/filters.c: Better instruction scheduling for
+         ARM
+
+2005-02-05 05:36  jm
+
+       * trunk/speex/libspeex/filters.c: An ARM assembly implementation of
+         filters_mem2 -- work in progress
+
+2005-02-03 22:18  jm
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/sb_celp.c: Removed redundent filtering calls,
+         added complexity 0 (even more shortcuts)
+
+2005-02-02 19:20  jm
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/sb_celp.c: Misc fixed-point fixes
+
+2005-01-06 01:52  conrad
+
+       * trunk/speex/libspeex/arch.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/symbian/config.h: applied symbian related config and
+         casting diffs from Colin Ward
+
+2004-10-29 12:22  jm
+
+       * trunk/speex/libspeex/mdf.c, trunk/speex/libspeex/preprocess.c,
+         trunk/speex/libspeex/smallft.c, trunk/speex/libspeex/smallft.h:
+         Renamed the FFT in order to remove the symbol clash with Vorbis.
+
+2004-10-24 03:37  jm
+
+       * trunk/speex/libspeex/cb_search.c: Shouldn't warn with fixed-point
+         anymore
+
+2004-10-10 02:38  conrad
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/src/Makefile.am,
+         trunk/speex/src/wave_out.h: Applied build system patch from Erik
+         de Castro Lopo; now builds on MinGW: * guard src/wave_out.h
+         against multiple includes * add @OGG_CFLAGS@ to INCLUDES in
+         subdirs
+
+2004-09-22 07:09  jm
+
+       * trunk/speex/libspeex/nb_celp.c: Fixed scaling problem for
+         fixed-point
+
+2004-08-13 07:29  conrad
+
+       * trunk/speex/configure.ac, trunk/speex/include/speex/Makefile.am,
+         trunk/speex/libspeex/Makefile.am: remove references to noglobals
+         stuff from build
+
+2004-08-11 00:56  conrad
+
+       * trunk/speex/libspeex/modes.c: remove spurious #if 0 around
+         speex_lib_get_mode() definition. in other news, kfish is crazy.
+
+2004-08-10 06:40  conrad
+
+       * trunk/speex/include/speex/speex.h, trunk/speex/libspeex/modes.c:
+         added speex_get_mode() function
+
+2004-08-10 06:22  conrad
+
+       * trunk/speex/include/speex/speex.h, trunk/speex/libspeex/modes.c:
+         add explicit consts in front of speex_mode_list[] declarations
+
+2004-07-21 07:18  conrad
+
+       * trunk/speex/include/speex/speex_noglobals.h,
+         trunk/speex/libspeex/modes_noglobals.c: remove unneeded public
+         constructors/destructors for _noglobals modes; replaced with
+         cleaner speex_mode_{new,destroy}() functions.
+
+2004-07-21 06:03  conrad
+
+       * trunk/speex/include/speex/speex_noglobals.h,
+         trunk/speex/libspeex/modes_noglobals.c: add speex_mode_new() and
+         speex_mode_destroy() API calls to _noglobals API
+
+2004-07-16 06:32  conrad
+
+       * trunk/speex/libspeex/modes_noglobals.c: add some (void *) casts in
+         calls to speex_free to stop random errors on random compilers ...
+         it must be almost time for beer
+
+2004-07-16 06:20  conrad
+
+       * trunk/speex/include/speex/speex_noglobals.h,
+         trunk/speex/libspeex/modes_noglobals.c: add some attribution lines
+         to *_noglobals
+
+2004-07-16 06:11  conrad
+
+       * trunk/speex/libspeex/modes_noglobals.c: add const to params_free()
+         functions
+
+2004-07-16 06:07  conrad
+
+       * trunk/speex/libspeex/modes_noglobals.c: free alloc'd params in
+         malloc'd submodes
+
+2004-07-16 05:22  conrad
+
+       * trunk/speex/libspeex/modes_noglobals.c: add include of <string.h>
+         to modes_noglobals.c to remove *link* error on vc++
+
+2004-07-15 07:52  jm
+
+       * trunk/speex/Makefile.am, trunk/speex/include/speex/speex_echo.h,
+         trunk/speex/include/speex/speex_jitter.h,
+         trunk/speex/libspeex/jitter.c, trunk/speex/libspeex/mdf.c: cleanup
+         in EC and hitter buffer. removed some automake options
+
+2004-07-15 04:31  conrad
+
+       * trunk/speex/libspeex/bits.c, trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/filters.c, trunk/speex/libspeex/jitter.c,
+         trunk/speex/libspeex/lbr_48k_tables.c, trunk/speex/libspeex/lpc.c,
+         trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/math_approx.c, trunk/speex/libspeex/mdf.c,
+         trunk/speex/libspeex/misc.c, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes_noglobals.c,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/preprocess.c,
+         trunk/speex/libspeex/quant_lsp.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/smallft.c, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex_callbacks.c,
+         trunk/speex/libspeex/speex_header.c,
+         trunk/speex/libspeex/stereo.c, trunk/speex/libspeex/testdenoise.c,
+         trunk/speex/libspeex/testecho.c, trunk/speex/libspeex/testenc.c,
+         trunk/speex/libspeex/testenc_uwb.c,
+         trunk/speex/libspeex/testenc_wb.c, trunk/speex/libspeex/vbr.c,
+         trunk/speex/libspeex/vq.c, trunk/speex/src/speexdec.c,
+         trunk/speex/src/speexenc.c, trunk/speex/src/wav_io.c,
+         trunk/speex/src/wave_out.c: added guarded #include "config.h"
+         throughout libspeex/ and src/
+
+2004-07-15 01:55  conrad
+
+       * trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/modes_noglobals.c,
+         trunk/speex/libspeex/vbr.c, trunk/speex/libspeex/vbr.h: added
+         const in front of vbr_*_thresh tables (internal change, affects
+         libspeex memory layout only; no impact on modes.c code). Patch
+         from Colin Ward.
+
+2004-07-15 01:38  conrad
+
+       * trunk/speex/libspeex/modes_noglobals.c: remove empty statements
+         which codewarrior complains about. patch from Colin Ward.
+
+2004-07-14 04:34  conrad
+
+       * trunk/speex/libspeex/modes_noglobals.c: minor fixes to
+         modes_noglobals.c
+
+2004-07-14 03:50  jm
+
+       * trunk/speex/Makefile.am, trunk/speex/configure.in,
+         trunk/speex/include, trunk/speex/include/Makefile.am,
+         trunk/speex/include/speex, trunk/speex/include/speex/Makefile.am,
+         trunk/speex/include/speex/speex.h,
+         trunk/speex/include/speex/speex_bits.h,
+         trunk/speex/include/speex/speex_callbacks.h,
+         trunk/speex/include/speex/speex_echo.h,
+         trunk/speex/include/speex/speex_header.h,
+         trunk/speex/include/speex/speex_jitter.h,
+         trunk/speex/include/speex/speex_noglobals.h,
+         trunk/speex/include/speex/speex_preprocess.h,
+         trunk/speex/include/speex/speex_stereo.h,
+         trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/bits.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/jitter.c,
+         trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/ltp.h,
+         trunk/speex/libspeex/mdf.c, trunk/speex/libspeex/misc.h,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h, trunk/speex/libspeex/preprocess.c,
+         trunk/speex/libspeex/quant_lsp.h, trunk/speex/libspeex/sb_celp.h,
+         trunk/speex/libspeex/speex.h, trunk/speex/libspeex/speex_bits.h,
+         trunk/speex/libspeex/speex_callbacks.c,
+         trunk/speex/libspeex/speex_callbacks.h,
+         trunk/speex/libspeex/speex_echo.h,
+         trunk/speex/libspeex/speex_header.c,
+         trunk/speex/libspeex/speex_header.h,
+         trunk/speex/libspeex/speex_jitter.h,
+         trunk/speex/libspeex/speex_noglobals.h,
+         trunk/speex/libspeex/speex_preprocess.h,
+         trunk/speex/libspeex/speex_stereo.h,
+         trunk/speex/libspeex/stereo.c, trunk/speex/libspeex/testdenoise.c,
+         trunk/speex/libspeex/testecho.c, trunk/speex/libspeex/testenc.c,
+         trunk/speex/libspeex/testenc_uwb.c,
+         trunk/speex/libspeex/testenc_wb.c, trunk/speex/speex.m4,
+         trunk/speex/speex.pc.in, trunk/speex/src/Makefile.am,
+         trunk/speex/src/speexdec.c, trunk/speex/src/speexenc.c: Moved all
+         the includes from /usr/include to /usr/include/speex
+
+2004-07-10 00:12  jm
+
+       * trunk/speex/configure.in, trunk/speex/libspeex/mdf.c,
+         trunk/speex/libspeex/misc.h: minor stuff for 1.1.6
+
+2004-07-09 18:56  jm
+
+       * trunk/speex/libspeex/mdf.c: Echo canceller sucks less (cross-talk
+         detection works a bit better).
+
+2004-07-09 18:56  jm
+
+       * trunk/speex/libspeex/jitter.c, trunk/speex/libspeex/lsp.c,
+         trunk/speex/libspeex/speex_jitter.h: Removed some warnings
+
+2004-07-09 07:06  jm
+
+       * trunk/speex/configure.in, trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes_noglobals.c,
+         trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex_noglobals.h,
+         trunk/speex/libspeex/testecho.c: Symbian support by Conrad Parker
+
+2004-07-09 05:18  jm
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/speex.c: moved
+         the mode list back to modes.c
+
+2004-07-09 04:31  jm
+
+       * trunk/speex/Makefile.am, trunk/speex/autogen.sh,
+         trunk/speex/configure.in, trunk/speex/libspeex/mdf.c: Separated
+         the version macros
+
+2004-07-09 04:28  jm
+
+       * trunk/speex/libspeex/misc.h, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex.h, trunk/speex/libspeex/speex_header.c:
+         run-time calls for identifying the Speex version
+
+2004-07-08 05:26  jm
+
+       * trunk/speex/libspeex/preprocess.c: Removed the frame probability
+         of speech presence and increased noise estimate by a constant
+         factor.
+
+2004-07-08 05:25  jm
+
+       * trunk/speex/libspeex/jitter.c, trunk/speex/libspeex/misc.h: ...
+
+2004-07-08 05:24  jm
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/modes.h:
+         Rest of the modes.c split
+
+2004-07-08 05:23  jm
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/speex.c: Split
+         modes.c in two. Now modes.c only contains the mode struct
+         definitions
+
+2004-07-03 04:37  jm
+
+       * trunk/speex/libspeex/jitter.c,
+         trunk/speex/libspeex/speex_jitter.h: Removed all the drift_average
+         crap and just kept the timing histogram. Simple and works good
+         now.
+
+2004-06-20 04:52  jm
+
+       * trunk/speex/libspeex/jitter.c,
+         trunk/speex/libspeex/speex_jitter.h: Jitter buffer is now adaptive
+         and should resume properly when link is lost.
+
+2004-06-06 03:02  giles
+
+       * trunk/speex/libspeex/bits.c, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/speex.h, trunk/speex/src/speexdec.c,
+         trunk/speex/src/speexenc.c: Recommit changes lost in server
+         migration. Original commit (r6809) 2004-06-04 00:54:26 -0400 (Fri,
+         04 Jun 2004) by jm. Think I've got gapless working properly now.
+         Also, started implementing the speex_lib_ctl() interface and
+         simplified speex_bits_advance (patch by Alfr?\195?\169do Moreira)
+
+2004-05-26 15:26  jm
+
+       * trunk/speex/libspeex/preprocess.c: oops... that wasn't ansi C
+
+2004-04-20 21:52  jm
+
+       * trunk/speex/Speex.kdevelop, trunk/speex/doc/manual.lyx,
+         trunk/speex/libspeex/filters.c, trunk/speex/libspeex/filters.h,
+         trunk/speex/libspeex/jitter.c, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/sb_celp.h, trunk/speex/libspeex/speex.h,
+         trunk/speex/libspeex/speex_stereo.h,
+         trunk/speex/libspeex/stereo.c, trunk/speex/libspeex/testenc.c,
+         trunk/speex/libspeex/testenc_uwb.c,
+         trunk/speex/libspeex/testenc_wb.c, trunk/speex/libspeex/vbr.c,
+         trunk/speex/libspeex/vbr.h, trunk/speex/src/speexdec.c,
+         trunk/speex/src/speexenc.c: speex_encode/speex_decode are back to
+         using floats, new speex_encode_int and speex_decode_int for the
+         short version
+
+2004-04-10 07:56  jm
+
+       * trunk/speex/libspeex/preprocess.c,
+         trunk/speex/libspeex/testdenoise.c: At least the dereverb now has
+         a chance of working...
+
+2004-04-02 21:16  jm
+
+       * trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/vq.c: Changed
+         some constants to single-precision
+
+2004-04-02 21:09  jm
+
+       * trunk/speex/libspeex/mdf.c, trunk/speex/libspeex/speex_echo.h:
+         Echo cancellor interface changed to short (instead of float)
+
+2004-04-02 21:08  jm
+
+       * trunk/speex/libspeex/preprocess.c: changed constants to single
+         precision
+
+2004-03-31 04:17  jm
+
+       * trunk/speex/libspeex/preprocess.c,
+         trunk/speex/libspeex/speex_preprocess.h: Fixed a minor memory
+         leak, added de-reverberation, fixed denoiser hook for residual
+         echo cancellation.
+
+2004-03-30 08:52  jm
+
+       * trunk/speex/libspeex/sb_celp.c: oops, encoder calls
+         speex_encoder_ctl
+
+2004-02-18 07:20  jm
+
+       * trunk/speex/.cvsignore, trunk/speex/ChangeLog,
+         trunk/speex/doc/.cvsignore, trunk/speex/libspeex/.cvsignore,
+         trunk/speex/src/.cvsignore: .cvsignore files
+
+2004-02-12 08:41  jm
+
+       * trunk/speex/libspeex/sb_celp.c: Valgrind support for sb_celp.c too
+
+2004-02-12 08:30  jm
+
+       * trunk/speex/configure.in, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/stack_alloc.h: added extra valgrind checks
+         for the Speex stack
+
+2004-02-06 14:20  oddsock
+
+       * trunk/speex/libspeex/quant_lsp.c: M_PI not defined on win32 (and
+         possibly other platforms)
+
+2004-01-21 19:50  jm
+
+       * trunk/speex/libspeex/speex_echo.h,
+         trunk/speex/libspeex/speex_jitter.h,
+         trunk/speex/libspeex/speex_preprocess.h,
+         trunk/speex/libspeex/speex_stereo.h: include gards and c++
+         compatibility (extern "C")
+
+2004-01-19 09:10  jm
+
+       * trunk/speex/libspeex/ltp_sse.h: Now works on multiples of 8
+         (instead of 40), so it's a bit more general
+
+2004-01-19 08:58  jm
+
+       * trunk/speex/configure.in, trunk/speex/libspeex/ltp.c: Fixed
+         FIXED_POINT bug caused during SSE-ification.
+
+2004-01-19 08:09  jm
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search_sse.h, trunk/speex/libspeex/vq.c,
+         trunk/speex/libspeex/vq.h: VQ search has been SSE-ized. Not really
+         clean yet, though.
+
+2004-01-18 23:37  jm
+
+       * trunk/speex/libspeex/lsp.c: Saves some useless "cos" calculations
+
+2004-01-18 08:20  jm
+
+       * trunk/speex/libspeex/Makefile.am: The CVS tag was annoying
+
+2004-01-18 08:13  jm
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search_sse.h: SSE speedup for the codebook
+         response part of split_cb_search_shape_sign
+
+2004-01-18 06:47  jm
+
+       * trunk/speex/libspeex/ltp_sse.h: converted the inner product
+         function to SSE intrinsics too
+
+2004-01-17 20:52  jm
+
+       * trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/ltp_sse.h: faster
+         SSE implementation (reduced unaligned loads)
+
+2004-01-17 16:06  jm
+
+       * trunk/speex/libspeex/lsp.c: replaced cos by an approximation for
+         the float version
+
+2004-01-16 08:07  jm
+
+       * trunk/speex/libspeex/filters_sse.h: A couple 'const's to make that
+         compile cleanly
+
+2004-01-16 07:50  jm
+
+       * trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters_sse.h: New SSE implementation based
+         on intrinsics instead of assembly
+
+2003-12-24 06:14  jm
+
+       * trunk/speex/libspeex/fixed_arm.h: removed unnecessary 'volatile'
+         keyword
+
+2003-12-23 08:20  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/filters.h,
+         trunk/speex/libspeex/modes.c, trunk/speex/libspeex/modes.h:
+         fixed-point: converted comb_gain
+
+2003-12-23 08:11  jm
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c: fixed-point: some perceptual
+         enhancement coef converted.
+
+2003-12-05 14:59  jm
+
+       * trunk/speex/libspeex/quant_lsp.c,
+         trunk/speex/libspeex/quant_lsp.h, trunk/speex/libspeex/sb_celp.c:
+         more const stuff, fixed a stupid bug in sb_decoder_ctl
+
+2003-12-04 21:29  jm
+
+       * trunk/speex/configure.in, trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h,
+         trunk/speex/libspeex/exc_10_16_table.c,
+         trunk/speex/libspeex/exc_10_32_table.c,
+         trunk/speex/libspeex/exc_20_32_table.c,
+         trunk/speex/libspeex/exc_5_256_table.c,
+         trunk/speex/libspeex/exc_5_64_table.c,
+         trunk/speex/libspeex/exc_8_128_table.c,
+         trunk/speex/libspeex/filters.c, trunk/speex/libspeex/filters.h,
+         trunk/speex/libspeex/fixed_debug.h,
+         trunk/speex/libspeex/gain_table.c,
+         trunk/speex/libspeex/gain_table_lbr.c,
+         trunk/speex/libspeex/hexc_10_32_table.c,
+         trunk/speex/libspeex/hexc_table.c,
+         trunk/speex/libspeex/high_lsp_tables.c,
+         trunk/speex/libspeex/lbr_48k_tables.c,
+         trunk/speex/libspeex/lsp_tables_nb.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h, trunk/speex/libspeex/preprocess.c,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h,
+         trunk/speex/libspeex/speex.h, trunk/speex/libspeex/speex_header.c,
+         trunk/speex/libspeex/speex_header.h,
+         trunk/speex/libspeex/stereo.c, trunk/speex/libspeex/vq.c,
+         trunk/speex/libspeex/vq.h, trunk/speex/src/speexdec.c,
+         trunk/speex/src/speexenc.c: Added const's all over the place
+
+2003-12-01 01:00  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/filters.h:
+         fixed-point: comb filter, part 4.12
+
+2003-11-30 22:22  jm
+
+       * trunk/speex/libspeex/filters.c: fixed-point: comb filter, part III
+
+2003-11-30 20:23  jm
+
+       * trunk/speex/libspeex/filters.c: fixed-point: comb filter, part II
+
+2003-11-30 19:38  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/filters.h:
+         fixed-point: started work on comb filter
+
+2003-11-30 17:56  jm
+
+       * trunk/speex/libspeex/filters.c: fixed-point: oops, fixed another
+         overflow for 4 kbps mode.
+
+2003-11-30 16:43  jm
+
+       * trunk/speex/libspeex/ltp.c: oops. Got pitch_unquant_3tap to
+         compile again with floating point.
+
+2003-11-30 16:35  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/quant_lsp.c: ...
+
+2003-11-30 07:11  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/sb_celp.c:
+         fixed-point: Think I got rid of all overflows I could find
+
+2003-11-30 05:46  jm
+
+       * trunk/speex/libspeex/arch.h, trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/filters.c, trunk/speex/libspeex/fixed_arm.h,
+         trunk/speex/libspeex/fixed_debug.h,
+         trunk/speex/libspeex/fixed_generic.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/nb_celp.c: fixed-point: Fixed several
+         overflows. Added an explicit saturation function
+
+2003-11-29 19:25  jm
+
+       * trunk/speex/libspeex/fixed_debug.h, trunk/speex/libspeex/lsp.c,
+         trunk/speex/libspeex/ltp.c: fixed-point: fixed another overflow
+         problem
+
+2003-11-29 08:12  jm
+
+       * trunk/speex/configure.in, trunk/speex/libspeex/fixed_debug.h,
+         trunk/speex/libspeex/nb_celp.c: fixed-point: fixed some overflows
+
+2003-11-29 07:38  jm
+
+       * trunk/speex/libspeex/fixed_debug.h, trunk/speex/libspeex/lsp.c,
+         trunk/speex/libspeex/testenc.c,
+         trunk/speex/libspeex/testenc_uwb.c,
+         trunk/speex/libspeex/testenc_wb.c: debug code for fixed-point
+         operators. Already fixed an overflow in lsp code
+
+2003-11-29 07:03  jm
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/arch.h,
+         trunk/speex/libspeex/fixed_arm.h,
+         trunk/speex/libspeex/fixed_debug.h,
+         trunk/speex/libspeex/fixed_generic.h, trunk/speex/libspeex/misc.c,
+         trunk/speex/libspeex/nb_celp.h, trunk/speex/libspeex/testenc.c,
+         trunk/speex/libspeex/testenc_uwb.c,
+         trunk/speex/libspeex/testenc_wb.c: separated fixed-point operators
+         in: generic, ARM, debug
+
+2003-11-29 05:17  jm
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h:
+         fixed-point: pitch gain again
+
+2003-11-29 02:45  jm
+
+       * trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/ltp.h,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/nb_celp.c:
+         fixed-point: pitch gain stuff
+
+2003-11-28 05:39  jm
+
+       * trunk/speex/libspeex/arch.h, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/nb_celp.c: fixed-point: some work on pitch
+         gain, fixed a packet-loss bug
+
+2003-11-27 08:42  jm
+
+       * trunk/speex/libspeex/arch.h, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/lsp.c,
+         trunk/speex/libspeex/lsp.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/sb_celp.h: fixed-point: bw_lpc and lpc_to_lsp
+         are now done.
+
+2003-11-27 05:00  jm
+
+       * trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/lsp.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c:
+         fixed-point: lsp_enforce_margin argument no longer a float
+
+2003-11-25 16:40  jm
+
+       * trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/testenc.c: ...
+
+2003-11-25 06:58  jm
+
+       * trunk/speex/libspeex/arch.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/testenc.c: fixed-point: done quantizing
+         open-loop pitch
+
+2003-11-21 06:59  jm
+
+       * trunk/speex/libspeex/quant_lsp.c, trunk/speex/libspeex/sb_celp.c:
+         fixed-point: wideband work (LSP and excitation gain decoding)
+
+2003-11-21 03:06  jm
+
+       * trunk/speex/libspeex/arch.h,
+         trunk/speex/libspeex/lbr_48k_tables.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/math_approx.c,
+         trunk/speex/libspeex/sb_celp.c: fixed-point: converted pitch gain
+         computation in open-loop search
+
+2003-11-14 19:16  jm
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h:
+         fixed-point: integerized pi_gain's
+
+2003-11-14 18:46  jm
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c:
+         fixed-point: sb_celp gain quantization, fixed missing entry in
+         nb_celp gain
+
+2003-11-14 18:28  jm
+
+       * trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/testenc_wb.c:
+         fixed-point: before I screw everything up...
+
+2003-11-14 18:04  jm
+
+       * trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/sb_celp.c:
+         fixed-point: fixed float regression
+
+2003-11-14 17:48  jm
+
+       * trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/sb_celp.h: cleanup
+
+2003-11-13 20:39  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/filters.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/src/speexdec.c: spelling, cleanup
+
+2003-11-13 08:47  jm
+
+       * trunk/speex/libspeex/sb_celp.c: ...
+
+2003-11-13 08:45  jm
+
+       * trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/testenc_wb.c:
+         fixed-point: converting wideband excitation gain to int (halfway
+         done)
+
+2003-11-12 17:16  jm
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/arch.h,
+         trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/lsp.c,
+         trunk/speex/libspeex/misc.h, trunk/speex/libspeex/sb_celp.c: put
+         all fixed-point macros in a separate file (arch.h), some cleanup
+         with wideband excitation gain
+
+2003-11-12 07:30  jm
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/vq.c, trunk/speex/libspeex/vq.h: fixed-point:
+         excitation gain completely converted to fixed-point
+
+2003-11-12 06:00  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/filters.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/vq.c,
+         trunk/speex/libspeex/vq.h: fixed-point: converting excitation gain
+         quantization (halfway done)
+
+2003-11-12 05:09  jm
+
+       * trunk/speex/libspeex/misc.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/testenc_uwb.c: think I've fixed the
+         performance problem caused by underflows.
+
+2003-11-11 15:51  jm
+
+       * trunk/speex/libspeex/filters.c: oops... fixed an #ifdef that
+         wasn't including compute_rms when compiling with SSE support.
+
+2003-11-11 07:33  jm
+
+       * trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/sb_celp.c: fixed-point: increased precision
+         of the cos approximation, fixed some floating-point/fixed-point
+         mismatch
+
+2003-11-11 04:33  jm
+
+       * trunk/speex/libspeex/sb_celp.c: fixed-point: some wideband work
+
+2003-11-11 00:19  jm
+
+       * trunk/speex/configure.in, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/misc.h,
+         trunk/speex/libspeex/vq.c: fixed-point: Defined fused multiply-add
+         operators and some ARM assembly to use it.
+
+2003-11-10 19:38  jm
+
+       * trunk/speex/libspeex/filters.c: oops...
+
+2003-11-10 19:28  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/misc.h, trunk/speex/libspeex/nb_celp.c:
+         fixed-point: integerized pi_gain, pitch prediction error
+         accumulation in 64 bits (should make that 32 if possible).
+
+2003-11-10 17:17  jm
+
+       * trunk/speex/libspeex/filters.c: fixed-point: integerized bandwidth
+         expansion
+
+2003-11-10 08:57  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/lsp.c,
+         trunk/speex/libspeex/misc.h, trunk/speex/libspeex/nb_celp.c:
+         fixed-point: converted lsp_enforce_margin, some assembly ARM
+         optimizations
+
+2003-11-10 06:56  jm
+
+       * trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/lsp.h,
+         trunk/speex/libspeex/nb_celp.c: fixed-point: integerized lsp
+         interpolation
+
+2003-11-10 06:27  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/nb_celp.c:
+         fixed-point: scaling functions are a bit less ugly, fine exc gain
+         quantization now done in the linear domain and it didn't change
+         anything
+
+2003-11-09 06:20  jm
+
+       * trunk/speex/libspeex/ltp.c: removed sqrt's that ended up not being
+         used in some cases in the open-loop pitch function
+
+2003-11-08 06:52  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/filters.h,
+         trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/testenc.c: fixed-point: removed some float
+         ops in lpc_to_lsp and wrote signal scaling functions (which need
+         to be improved).
+
+2003-11-07 08:34  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/lsp.c,
+         trunk/speex/libspeex/math_approx.c,
+         trunk/speex/libspeex/math_approx.h,
+         trunk/speex/libspeex/nb_celp.c: fixed-point: acos function
+         approximated with fixed-point arithmetic
+
+2003-11-06 21:35  jm
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/misc.h,
+         trunk/speex/libspeex/quant_lsp.c,
+         trunk/speex/libspeex/testenc_uwb.c: fixed-point: some ARM work
+
+2003-11-06 09:14  jm
+
+       * trunk/speex/libspeex/math_approx.c: ...
+
+2003-11-06 08:41  jm
+
+       * trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/math_approx.c,
+         trunk/speex/libspeex/math_approx.h: fixed-point: interger version
+         of sqrt function
+
+2003-11-03 08:59  jm
+
+       * trunk/speex/libspeex/quant_lsp.c: fixed-point: integerized lsp
+         weight computation
+
+2003-11-02 07:44  jm
+
+       * trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/misc.c,
+         trunk/speex/libspeex/misc.h, trunk/speex/libspeex/testenc.c:
+         fixed-point: added code to count MIPS
+
+2003-11-02 06:59  jm
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/misc.h,
+         trunk/speex/libspeex/vq.c: fixed-point: cleanup
+
+2003-11-02 06:38  jm
+
+       * trunk/speex/libspeex/lsp.c: fixed-point: removed some float ops in
+         the LSP root search.
+
+2003-11-02 05:55  jm
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/misc.h: ...
+
+2003-11-02 05:08  jm
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/lpc.c,
+         trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/misc.h, trunk/speex/libspeex/quant_lsp.c:
+         fixed-point: cleaned up operators, removed a couple float ops,
+         fixed a MULT16_16 that had a 32-bit operand in ltp.c
+
+2003-11-01 17:42  jm
+
+       * trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/quant_lsp.c:
+         fixed-point: cos approximation for lsp_to_lpc, removed some float
+         ops in LSP quantization (more to do).
+
+2003-10-28 01:02  jm
+
+       * trunk/speex/libspeex/ltp.c: fixed-point: oops...
+
+2003-10-28 00:57  jm
+
+       * trunk/speex/libspeex/ltp.c: fixed-point: pitch decoder (mostly)
+         converted
+
+2003-10-27 23:05  jm
+
+       * trunk/speex/libspeex/misc.h: fixed-point: don't cast MUL* operands
+         to int. Compiler should generate better code now.
+
+2003-10-27 22:53  jm
+
+       * trunk/speex/libspeex/ltp.c: fixed-point: excitation and error
+         computation for closed-loop search mostly converted
+
+2003-10-27 21:43  jm
+
+       * trunk/speex/libspeex/ltp.c: fixed-point: integerized open-loop
+         pitch score computation
+
+2003-10-24 15:01  jm
+
+       * trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/misc.h:
+         fixed-point: open-loop score calculation converted
+
+2003-10-24 06:00  jm
+
+       * trunk/speex/libspeex/ltp.c: ...
+
+2003-10-09 21:33  jm
+
+       * trunk/speex/libspeex/sb_celp.c: output saturation for wideband
+
+2003-10-09 20:53  jm
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/testenc.c:
+         output saturation for narrowband (need to do the same for
+         wideband)
+
+2003-10-09 06:51  jm
+
+       * trunk/speex/configure.in, trunk/speex/libspeex/quant_lsp.c:
+         fixed-point: LSP quantization cleanup
+
+2003-10-09 03:54  jm
+
+       * trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/lsp.h,
+         trunk/speex/libspeex/misc.h, trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/quant_lsp.c,
+         trunk/speex/libspeex/quant_lsp.h, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/sb_celp.h: fixed-point: LSPs are now stored
+         quantized
+
+2003-10-08 22:31  jm
+
+       * trunk/speex/AUTHORS, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/lsp.c,
+         trunk/speex/libspeex/lsp.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h:
+         fixed-point: QMF entirely in fixed-point now
+
+2003-10-08 05:12  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/filters.h,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/smallft.c:
+         fixed-point: converted QMF functions
+
+2003-10-08 05:11  jm
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/misc.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/quant_lsp.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/smallft.c: fixed-point: rounding for shifts
+
+2003-10-08 05:09  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/filters.h,
+         trunk/speex/libspeex/lpc.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/smallft.c: fixed-point: merged floating-point
+         and fixed-point functions (LPC and open-loop pitch), converted the
+         gain search of the closed-loop pitch
+
+2003-10-08 05:06  jm
+
+       * trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/quant_lsp.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/smallft.c: fixed-point: LSP quantization
+         work, also LSP's are now in the angle domain
+
+2003-10-08 05:03  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/jitter.c,
+         trunk/speex/libspeex/misc.c, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/preprocess.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/sb_celp.h, trunk/speex/libspeex/smallft.c,
+         trunk/speex/libspeex/speex.h, trunk/speex/libspeex/speex_jitter.h,
+         trunk/speex/libspeex/speex_preprocess.h,
+         trunk/speex/libspeex/speex_stereo.h,
+         trunk/speex/libspeex/stereo.c, trunk/speex/libspeex/testdenoise.c,
+         trunk/speex/libspeex/testenc.c,
+         trunk/speex/libspeex/testenc_uwb.c,
+         trunk/speex/libspeex/testenc_wb.c, trunk/speex/libspeex/vbr.c,
+         trunk/speex/libspeex/vbr.h, trunk/speex/src/speexdec.c,
+         trunk/speex/src/speexenc.c: fixed-point: converted user-visible
+         functions to use "short" signals, fixed (fixed-point) bug in
+         comb-filter.
+
+2003-10-08 05:01  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/misc.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/smallft.c: fixed-point: replace divisions by
+         shifts...
+
+2003-10-08 04:57  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/smallft.c: fixed-point: normalization
+         function, some work on pitch closed-loop search
+
+2003-10-08 04:56  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/misc.h, trunk/speex/libspeex/smallft.c:
+         fixed-point: pitch stuff
+
+2003-10-08 04:53  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/smallft.c: fixed-point: conversion of the
+         open-loop pitch analysis
+
+2003-10-08 04:52  jm
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/smallft.c:
+         fixed-point: computation of rms values in fp
+
+2003-10-08 04:50  jm
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/smallft.c:
+         fixed-point: removed some float's in innovation search
+
+2003-10-08 04:49  jm
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/smallft.c:
+         fixed-point: some innovation search details
+
+2003-10-08 04:47  jm
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/smallft.c,
+         trunk/speex/libspeex/vq.c, trunk/speex/libspeex/vq.h: fixed-point:
+         most of the innovation search converted
+
+2003-10-08 04:45  jm
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/misc.h,
+         trunk/speex/libspeex/smallft.c, trunk/speex/libspeex/vq.c,
+         trunk/speex/libspeex/vq.h: fixed-point: some work on innovation
+         quantization
+
+2003-10-08 04:44  jm
+
+       * trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/smallft.c: fixed-point: saturation for
+         lsp_to_lpc, probably not the best solution
+
+2003-10-08 04:42  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/mdf.c, trunk/speex/libspeex/misc.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/preprocess.c,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/smallft.c:
+         fixed-point: more conversion to spx_sig_t
+
+2003-10-08 04:40  jm
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/misc.c,
+         trunk/speex/libspeex/misc.h, trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h,
+         trunk/speex/libspeex/vq.c, trunk/speex/libspeex/vq.h: fixed-point:
+         converted all signals to spx_sig_t
+
+2003-10-08 04:38  jm
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/lpc.c,
+         trunk/speex/libspeex/lpc.h, trunk/speex/libspeex/misc.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h,
+         trunk/speex/libspeex/testenc.c: fixed-point: more signal scaling
+         again, some auto-correlation work
+
+2003-10-08 04:37  jm
+
+       * trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/testenc.c:
+         fixed-point: signal scaling... again
+
+2003-10-08 04:36  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/nb_celp.c: more signal scaling
+
+2003-10-08 04:35  jm
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/misc.h, trunk/speex/libspeex/nb_celp.c:
+         fixed-point: signals scaling
+
+2003-10-08 04:35  jm
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/misc.h,
+         trunk/speex/libspeex/modes.c, trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/preprocess.c, trunk/speex/libspeex/stereo.c,
+         trunk/speex/src/speexdec.c: fixed-point: removed pre-emphasis,
+         more cleanup
+
+2003-10-08 04:33  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/lpc.c,
+         trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/sb_celp.c: fixed-point: more LPC/LSP cleanup
+
+2003-10-08 04:32  jm
+
+       * trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/misc.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/testenc_wb.c: fixed-point: LPC/LSP cleanup
+
+2003-10-08 04:31  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/lpc.c,
+         trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/misc.h,
+         trunk/speex/libspeex/nb_celp.c: fixed-point: LPC and LSP types
+         changed to word16
+
+2003-10-08 04:30  jm
+
+       * trunk/speex/libspeex/lpc.c, trunk/speex/libspeex/lpc.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h:
+         fixed-point: more lpc stuff
+
+2003-10-08 04:29  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/lpc.c,
+         trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/misc.h,
+         trunk/speex/libspeex/modes.c, trunk/speex/libspeex/nb_celp.c:
+         fixed-point: lpc stuff
+
+2003-10-08 04:29  jm
+
+       * trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/misc.h:
+         fixed-point work on LSP's
+
+2003-10-08 04:27  jm
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/lpc.c,
+         trunk/speex/libspeex/lpc.h, trunk/speex/libspeex/lsp.c,
+         trunk/speex/libspeex/lsp.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/misc.h,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h, trunk/speex/libspeex/preprocess.c,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h,
+         trunk/speex/libspeex/testenc.c, trunk/speex/src/speexdec.c: first
+         step in fixed-point port, converted the LPC filters
+
+2003-10-01 22:17  jm
+
+       * trunk/speex/libspeex/lpc.c: improved LPC analysis (mostly for very
+         tonal signals)
+
+2003-09-30 00:44  jm
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/preprocess.c, trunk/speex/src/speexdec.c:
+         denoiser tuning, Solaris support, small optimization in codebook
+         computations.
+
+2003-09-18 03:58  jm
+
+       * trunk/speex/libspeex/jitter.c, trunk/speex/libspeex/mdf.c,
+         trunk/speex/libspeex/preprocess.c, trunk/speex/libspeex/smallft.c:
+         cleaning up for 1.1
+
+2003-09-18 03:46  jm
+
+       * trunk/speex/libspeex/testenc.c: oops...
+
+2003-09-18 03:34  jm
+
+       * trunk/speex/libspeex/preprocess.c,
+         trunk/speex/libspeex/speex_preprocess.h,
+         trunk/speex/libspeex/testdenoise.c: Added probability of speech
+         presence to denoiser.
+
+2003-09-18 01:08  jm
+
+       * trunk/speex/libspeex/preprocess.c,
+         trunk/speex/libspeex/speex_preprocess.h: cleanup
+
+2003-09-17 21:31  jm
+
+       * trunk/speex/libspeex/preprocess.c: made a table-lookup version
+         instead of approximating using pow's
+
+2003-09-17 17:30  jm
+
+       * trunk/speex/libspeex/preprocess.c: some AGC tuning
+
+2003-09-17 04:12  jm
+
+       * trunk/speex/libspeex/preprocess.c,
+         trunk/speex/libspeex/speex_preprocess.h: based the AGC adaptation
+         decision on the MCRA stuff.
+
+2003-09-17 00:15  jm
+
+       * trunk/speex/libspeex/preprocess.c,
+         trunk/speex/libspeex/speex_preprocess.h: added function to update
+         the estimates without applying denoising
+
+2003-09-16 23:44  jm
+
+       * trunk/speex/libspeex/preprocess.c,
+         trunk/speex/libspeex/speex_preprocess.h,
+         trunk/speex/libspeex/testdenoise.c: cleaned up stuff that was no
+         longer necessary.
+
+2003-09-16 20:41  jm
+
+       * trunk/speex/libspeex/speex_preprocess.h: implemented MCRA noise
+         adaptation
+
+2003-09-16 20:39  jm
+
+       * trunk/speex/libspeex/preprocess.c: added MCRA noise estimation,
+         fixed stupid bug in a priori SNR adaptation
+
+2003-09-16 19:36  jm
+
+       * trunk/speex/libspeex/preprocess.c,
+         trunk/speex/libspeex/speex_preprocess.h,
+         trunk/speex/libspeex/testdenoise.c: added sampling rate option to
+         preprocessor
+
+2003-09-16 18:35  jm
+
+       * trunk/speex/libspeex/mdf.c, trunk/speex/libspeex/preprocess.c,
+         trunk/speex/libspeex/smallft.c, trunk/speex/libspeex/smallft.h,
+         trunk/speex/libspeex/speex_echo.h,
+         trunk/speex/libspeex/speex_preprocess.h: smallft.h doesn't need to
+         be included from the .h files anymore
+
+2003-09-16 17:50  jm
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/denoise.c,
+         trunk/speex/libspeex/preprocess.c,
+         trunk/speex/libspeex/speex_denoise.h,
+         trunk/speex/libspeex/speex_preprocess.h,
+         trunk/speex/libspeex/testdenoise.c: Renamed the 'denoiser' to
+         'preprocessor', added options to enable/disable the denoiser, the
+         agc and the vad.
+
+2003-09-16 01:51  jm
+
+       * trunk/speex/libspeex/denoise.c: prevented the AGC from causing
+         clipping
+
+2003-09-02 06:26  jm
+
+       * trunk/speex/libspeex/testenc.c: segmental SNR estimate works
+
+2003-08-26 05:42  jm
+
+       * trunk/speex/libspeex/bits.c, trunk/speex/libspeex/speex_bits.h:
+         fixed an "off by one". Moved definition of MAX_BYTES_PER_FRAME to
+         the .c file.
+
+2003-08-24 04:28  jm
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c:
+         Allow setting the decode submode in case it's not embedded in the
+         stream (which you shouldn't think about unless you know what
+         you're doing and want to be incompatible with everyone else)
+
+2003-08-23 03:10  jm
+
+       * trunk/speex/libspeex/bits.c: oops...
+
+2003-08-22 22:01  jm
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h:
+         added a call telling the codec not to encode the submode in the
+         frame.
+
+2003-08-22 21:44  jm
+
+       * trunk/speex/libspeex/bits.c: speex_bits_write now properly inserts
+         a terminator before copying the data
+
+2003-08-22 21:30  jm
+
+       * trunk/speex/libspeex/denoise.c: cleanup: separated VAD and AGC
+         from the denoising (put them in different functions) and added
+         some comments
+
+2003-08-22 20:17  jm
+
+       * trunk/speex/libspeex/mdf.c: Added some comments
+
+2003-08-22 05:10  jm
+
+       * trunk/speex/libspeex/denoise.c, trunk/speex/libspeex/mdf.c,
+         trunk/speex/libspeex/speex_denoise.h,
+         trunk/speex/libspeex/testdenoise.c: Coupling between the echo
+         canceller and the denoiser so that residual echo can be removed.
+
+2003-08-21 23:25  jm
+
+       * trunk/speex/libspeex/mdf.c, trunk/speex/libspeex/speex_echo.h:
+         first shot at dealing with cross-talk
+
+2003-08-21 22:39  jm
+
+       * trunk/speex/libspeex/mdf.c: Well, it seems like implementing the
+         algorithm correctly helps getting good results.
+
+2003-08-21 04:25  jm
+
+       * trunk/speex/libspeex/mdf.c, trunk/speex/libspeex/speex_echo.h: did
+         some cleanup. Still some work to do with adaptation rate
+         adjustment and cross-talk detection.
+
+2003-08-19 06:07  jm
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/denoise.c,
+         trunk/speex/libspeex/speex.h: minor stuff
+
+2003-08-19 05:47  jm
+
+       * trunk/speex/libspeex/mdf.c: implemented destructor
+
+2003-08-19 03:59  jm
+
+       * trunk/speex/libspeex/mdf.c, trunk/speex/libspeex/speex_echo.h:
+         added normalization. Should be roughly equivalent to NLMS.
+
+2003-08-18 21:52  jm
+
+       * trunk/speex/libspeex/mdf.c, trunk/speex/libspeex/speex_echo.h:
+         Initial checkin of MDF-based echo canceller (still incomplete)
+
+2003-08-12 17:17  jm
+
+       * trunk/speex/libspeex/denoise.c: some tuning...
+
+2003-08-12 05:21  jm
+
+       * trunk/speex/libspeex/denoise.c: Fixed a couple bugs, changed the
+         estimator to log-amplitude (second Ephraim-Malah paper).
+
+2003-08-10 06:35  jm
+
+       * trunk/speex/libspeex/sb_celp.c: oops.
+
+2003-08-04 17:28  jm
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/jitter.c:
+         removed debug stuff
+
+2003-08-04 17:17  jm
+
+       * trunk/speex/libspeex/jitter.c,
+         trunk/speex/libspeex/speex_jitter.h: Adaptive (though not yet)
+         jitter buffer.
+
+2003-06-13 03:59  jm
+
+       * trunk/speex/libspeex/hexc_table.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/stack_alloc.h: minor stuff...
+
+2003-06-03 21:21  jm
+
+       * trunk/speex/libspeex/hexc_10_32_table.c,
+         trunk/speex/libspeex/hexc_table.c: codebook update for lsp bug
+
+2003-06-03 05:29  jm
+
+       * trunk/speex/libspeex/modes.c: oops. Fixed a bug in frame size mode
+         query
+
+2003-05-30 21:36  jm
+
+       * trunk/speex/libspeex/sb_celp.c: new high-band lsp margins
+
+2003-05-30 19:44  jm
+
+       * trunk/speex/libspeex/bits.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/speex_bits.h, trunk/speex/src/speexdec.c,
+         trunk/speex/src/speexenc.c: implemented new
+         speex_bits_insert_terminator call so that the number of frames in
+         a packet can be automatically determined.
+
+2003-05-25 04:13  jm
+
+       * trunk/speex/libspeex/denoise.c: made the VAD a bit more sensitive
+
+2003-05-25 03:01  jm
+
+       * trunk/speex/libspeex/denoise.c: VAD seems to work better, though
+         the code is now a complete mess :(
+
+2003-05-22 21:57  jm
+
+       * trunk/speex/libspeex/denoise.c: fixed some variance estimation
+         problems. still some work to do.
+
+2003-05-22 16:25  jm
+
+       * trunk/speex/libspeex/denoise.c,
+         trunk/speex/libspeex/speex_denoise.h: experimental sub-bands VAD
+
+2003-05-21 22:16  jm
+
+       * trunk/speex/libspeex/denoise.c: oops...
+
+2003-05-21 22:05  jm
+
+       * trunk/speex/libspeex/denoise.c: made the VAD less sensitive
+
+2003-05-21 21:20  jm
+
+       * trunk/speex/libspeex/denoise.c,
+         trunk/speex/libspeex/speex_denoise.h,
+         trunk/speex/libspeex/testdenoise.c: improved the VAD with a simple
+         Markov chain.
+
+2003-05-21 19:53  jm
+
+       * trunk/speex/libspeex/denoise.c,
+         trunk/speex/libspeex/speex_denoise.h,
+         trunk/speex/libspeex/testdenoise.c: added the "speex" prefix to
+         the denoising stuff
+
+2003-05-21 18:24  jm
+
+       * trunk/speex/libspeex/denoise.c: returning VAD results in the
+         denoiser
+
+2003-05-21 06:03  jm
+
+       * trunk/speex/libspeex/denoise.c, trunk/speex/libspeex/modes.c,
+         trunk/speex/win32/libspeex/libspeex.dsp: minor compilation fixes
+
+2003-05-20 02:46  jm
+
+       * trunk/speex/libspeex/denoise.c,
+         trunk/speex/libspeex/testdenoise.c: denoiser now behaves correctly
+         with 240-sample frames
+
+2003-05-17 05:46  jm
+
+       * trunk/speex/libspeex/lpc.c: oops. Shouldn't have removed that in
+         the previous update
+
+2003-05-16 20:41  jm
+
+       * trunk/speex/libspeex/lpc.c, trunk/speex/libspeex/lpc.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h:
+         Minor cleanup (who needs reflection coefficients anyway) in LPC
+         code.
+
+2003-05-14 04:37  jm
+
+       * trunk/speex/libspeex/denoise.c,
+         trunk/speex/libspeex/speex_denoise.h: Basic adaptive gain control
+         working
+
+2003-05-13 20:57  jm
+
+       * trunk/speex/configure.in, trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/denoise.c,
+         trunk/speex/libspeex/lbr_48k_tables.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h, trunk/speex/libspeex/quant_lsp.c,
+         trunk/speex/libspeex/quant_lsp.h, trunk/speex/libspeex/speex.h:
+         Merged an experimental (and non-standard) 4.8 kbps mode. Note that
+         this mode is completely independent from the other modes and
+         cannot be used in multi-rate operation.
+
+2003-05-12 01:23  jm
+
+       * trunk/speex/libspeex/denoise.c, trunk/speex/libspeex/smallft.h,
+         trunk/speex/libspeex/speex_denoise.h: made the code OK for
+         inclusion with C++ files. Merge some early AGC work.
+
+2003-05-12 01:02  jm
+
+       * trunk/speex/libspeex/denoise.c, trunk/speex/libspeex/denoise.h,
+         trunk/speex/libspeex/speex_denoise.h,
+         trunk/speex/libspeex/testdenoise.c: renamed denoise.h to
+         speex_denoise.h, removed some C++-style stuff
+
+2003-05-09 05:28  jm
+
+       * trunk/speex/libspeex/nb_celp.c: oops... another stupid bug
+
+2003-05-08 04:27  jm
+
+       * trunk/speex/libspeex/sb_celp.c: fixed bug (found by segher) where
+         lsp_enforce_margin would be called on x-domain (instead of angle
+         domain) LSP's.
+
+2003-05-08 04:04  jm
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/smallft.c,
+         trunk/speex/libspeex/smallft.h,
+         trunk/speex/libspeex/testdenoise.c: the rest of the files for the
+         Ephraim-Malah denoiser
+
+2003-05-08 03:58  jm
+
+       * trunk/speex/libspeex/denoise.c, trunk/speex/libspeex/denoise.h:
+         modif to only adapt noise when 3 consecutive noise frames are
+         detected.
+
+2003-05-08 03:56  jm
+
+       * trunk/speex/libspeex/denoise.c, trunk/speex/libspeex/denoise.h:
+         First version of denoiser (Epic contract) using Ephraim-Malah
+         algorithm
+
+2003-05-06 01:19  jm
+
+       * trunk/speex/libspeex/ltp.c: oops...
+
+2003-05-05 23:34  jm
+
+       * trunk/speex/libspeex/sb_celp.c, trunk/speex/src/speexenc.c: merged
+         some fixes in the main branch
+
+2003-05-02 02:08  jm
+
+       * trunk/speex/libspeex/filters_sse.h,
+         trunk/speex/libspeex/ltp_sse.h: removed multi-line strings
+
+2003-03-22 19:19  jm
+
+       * trunk/speex/configure.in, trunk/speex/doc/manual.lyx,
+         trunk/speex/doc/manual.pdf, trunk/speex/libspeex/misc.h,
+         trunk/speex/src/speexdec.1, trunk/speex/src/speexdec.c,
+         trunk/speex/src/speexenc.1, trunk/speex/src/speexenc.c: cosmetic
+         fixes
+
+2003-03-19 01:07  jm
+
+       * trunk/speex/libspeex/filters_sse.h: gets rid of some warnings
+
+2003-03-18 06:13  jm
+
+       * trunk/speex/configure.in, trunk/speex/doc/Makefile.am,
+         trunk/speex/doc/manual.lyx, trunk/speex/libspeex/bits.c,
+         trunk/speex/libspeex/sb_celp.c: minor tweaks, removed some
+         warnings
+
+2003-03-17 22:40  jm
+
+       * trunk/speex/Speex.spec.in, trunk/speex/configure.in,
+         trunk/speex/doc/manual.lyx, trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/math_approx.c: manual update. Made libtool
+         use -version-info. removed math_approx tables when not needed.
+
+2003-03-10 17:16  jm
+
+       * trunk/speex/libspeex/bits.c, trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/math_approx.c,
+         trunk/speex/libspeex/misc.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/speex_callbacks.h: Removed some gcc warnings
+
+2003-03-05 17:47  jm
+
+       * trunk/speex/configure.in, trunk/speex/doc/manual.lyx,
+         trunk/speex/libspeex/misc.h, trunk/speex/src/speexdec.1,
+         trunk/speex/src/speexenc.1: version number bump
+
+2003-03-05 17:46  jm
+
+       * trunk/speex/libspeex/math_approx.c: oops...
+
+2003-03-03 06:52  jm
+
+       * trunk/speex/configure.in, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/speex_bits.h,
+         trunk/speex/libspeex/speex_callbacks.h,
+         trunk/speex/libspeex/speex_stereo.h, trunk/speex/src/speexenc.c:
+         build fix for FreeBSD (gnugetopt), allow VBR without DTX
+
+2003-03-03 03:36  jm
+
+       * trunk/speex/configure.in, trunk/speex/doc/manual.lyx,
+         trunk/speex/libspeex/modes.c: some tuning
+
+2003-02-05 06:03  jm
+
+       * trunk/speex/configure.in, trunk/speex/libspeex/misc.h,
+         trunk/speex/src/speexenc.c: version change
+
+2003-02-05 06:01  jm
+
+       * trunk/speex/libspeex/exc_10_16_table.c,
+         trunk/speex/libspeex/exc_10_32_table.c,
+         trunk/speex/libspeex/exc_20_32_table.c,
+         trunk/speex/libspeex/exc_8_128_table.c: Added an entry with real
+         zeros to remove some artifacts in some transients when the energy
+         is quickly rising in the middle of a frame.
+
+2003-01-31 01:42  jm
+
+       * trunk/speex/doc/manual.lyx,
+         trunk/speex/libspeex/exc_10_16_table.c,
+         trunk/speex/libspeex/exc_10_32_table.c,
+         trunk/speex/libspeex/exc_20_32_table.c,
+         trunk/speex/libspeex/exc_5_256_table.c,
+         trunk/speex/libspeex/exc_5_64_table.c,
+         trunk/speex/libspeex/exc_8_128_table.c,
+         trunk/speex/libspeex/gain_table.c,
+         trunk/speex/libspeex/gain_table_lbr.c,
+         trunk/speex/libspeex/hexc_10_32_table.c,
+         trunk/speex/libspeex/hexc_table.c,
+         trunk/speex/libspeex/high_lsp_tables.c,
+         trunk/speex/libspeex/lsp_tables_nb.c, trunk/speex/libspeex/misc.h:
+         Some cleaning up that might help with MS compilers.
+
+2003-01-28 08:48  jm
+
+       * trunk/speex/libspeex/filters_sse.h, trunk/speex/src/speexenc.c:
+         some rc2 fixes
+
+2003-01-28 08:15  jm
+
+       * trunk/speex/configure.in, trunk/speex/doc/manual.lyx,
+         trunk/speex/libspeex/gain_table.c,
+         trunk/speex/libspeex/gain_table_lbr.c,
+         trunk/speex/libspeex/misc.h, trunk/speex/src/speexdec.1,
+         trunk/speex/src/speexenc.1: Preparing for rc2
+
+2003-01-28 06:52  jm
+
+       * trunk/speex/libspeex/gain_table.c,
+         trunk/speex/libspeex/gain_table_lbr.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/modes.c: Gain
+         codebook also converted to signed char.
+
+2003-01-28 05:22  jm
+
+       * trunk/speex/libspeex/quant_lsp.c: oops...
+
+2003-01-28 00:50  jm
+
+       * trunk/speex/libspeex/high_lsp_tables.c,
+         trunk/speex/libspeex/lsp_tables_nb.c,
+         trunk/speex/libspeex/quant_lsp.c,
+         trunk/speex/libspeex/quant_lsp.h: LSP codebooks are now signed
+         short instead of float, reducing size in binary by a factor of 4.
+
+2003-01-28 00:02  jm
+
+       * trunk/speex/libspeex/high_lsp_tables.c,
+         trunk/speex/libspeex/quant_lsp.c: Quantization for high-band LSP
+         codebook.
+
+2003-01-27 22:09  jm
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/lsp_tables_nb.c,
+         trunk/speex/libspeex/quant_lsp.c: Some work for shrinking the LSP
+         codebook size
+
+2003-01-27 08:31  jm
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h,
+         trunk/speex/libspeex/exc_10_16_table.c,
+         trunk/speex/libspeex/exc_10_32_table.c,
+         trunk/speex/libspeex/exc_20_32_table.c,
+         trunk/speex/libspeex/exc_5_256_table.c,
+         trunk/speex/libspeex/exc_5_64_table.c,
+         trunk/speex/libspeex/exc_8_128_table.c,
+         trunk/speex/libspeex/exc_8_256_table.c,
+         trunk/speex/libspeex/hexc_10_32_table.c,
+         trunk/speex/libspeex/hexc_table.c, trunk/speex/libspeex/modes.c:
+         Transformed all excitation codebooks into sighed short arrays,
+         reducing their size (in the final binary) by a factor of 4.
+
+2003-01-25 05:45  jm
+
+       * trunk/speex/libspeex/gain_table.c,
+         trunk/speex/libspeex/gain_table_lbr.c, trunk/speex/libspeex/ltp.c:
+         Shrunk the pitch gain codebook by removing redundent data.
+
+2003-01-23 07:29  jm
+
+       * trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/speex.h, trunk/speex/libspeex/speex_bits.h,
+         trunk/speex/libspeex/speex_callbacks.c,
+         trunk/speex/libspeex/speex_header.h: Fixed a bunch of typos
+         pointed to by: larry@doolittle.boa.org
+
+2003-01-17 05:15  jm
+
+       * trunk/speex/libspeex/vbr.c, trunk/speex/libspeex/vbr.h,
+         trunk/speex/src/speexdec.c: oops... last minute fixes
+
+2003-01-15 07:51  jm
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/vbr.c: oops...
+         I broke the 6 kbps mode. it's fixed now.
+
+2003-01-15 07:20  jm
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/vbr.c: adjusted VBR for the new 4 kbps mode
+         (still early stage)
+
+2003-01-15 06:47  jm
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/exc_20_32_table.c,
+         trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/nb_celp.c: Added a new 3.95 kbps mode
+
+2003-01-13 22:29  jm
+
+       * trunk/speex/libspeex/speex_header.c,
+         trunk/speex/libspeex/speex_header.h, trunk/speex/src/speexdec.c:
+         slightly changed the header format (still compatible)
+
+2003-01-11 01:32  jm
+
+       * trunk/speex/libspeex/speex_header.c: oops...
+
+2003-01-11 01:24  jm
+
+       * trunk/speex/doc/manual.lyx, trunk/speex/libspeex/speex_header.h,
+         trunk/speex/src/speexdec.1, trunk/speex/src/speexenc.1: misc.
+
+2003-01-10 07:27  jm
+
+       * trunk/speex/doc/manual.lyx, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/vbr.c, trunk/speex/src/speexdec.c: mostly
+         wideband tuning...
+
+2003-01-09 16:30  jm
+
+       * trunk/speex/libspeex/bits.c: Fixed (I think) potential overflow in
+         Speex Bits
+
+2003-01-08 21:59  jm
+
+       * trunk/speex/libspeex/bits.c, trunk/speex/libspeex/misc.c,
+         trunk/speex/libspeex/misc.h, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h,
+         trunk/speex/libspeex/speex.h, trunk/speex/libspeex/speex_bits.h,
+         trunk/speex/src/speexdec.c: Added a return value (error) to the
+         *ctl functions, added re-allocation to SpeexBits when buffer is
+         too small.
+
+2003-01-08 06:57  jm
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/speex.h: Fixed some bad
+         DTX/packet-loss/wideband interactions.
+
+2003-01-07 04:30  jm
+
+       * trunk/speex/libspeex/misc.c, trunk/speex/libspeex/misc.h: oops!
+         stupid bug
+
+2003-01-07 04:11  jm
+
+       * trunk/speex/libspeex/bits.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/speex_bits.h,
+         trunk/speex/src/speexdec.c: Added some bounds checking when
+         reading bits, including a bug when forcing higher bit-rates
+         (force-wb on a narrowband stream). Some cleaning up too.
+
+2003-01-06 22:06  jm
+
+       * trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/speex_stereo.h,
+         trunk/speex/libspeex/stereo.c, trunk/speex/src/speexdec.c,
+         trunk/speex/src/speexenc.c: Some stereo enhancements
+
+2003-01-06 20:43  jm
+
+       * trunk/speex/doc/manual.lyx, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/src/speexdec.c: Used
+         the last 4 bits of mode1 for a CNG flag, plus some cleanup, bugfix
+
+2003-01-06 08:35  jm
+
+       * trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h:
+         Cleaned up mem allocation in sb_celp.c like in nb_celp.c
+
+2003-01-06 06:53  jm
+
+       * trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/stack_alloc.h: Replaced all the alloc's by
+         one big memory allocation for a whole state
+
+2003-01-06 05:56  jm
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/lsp.c,
+         trunk/speex/libspeex/lsp.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/stack_alloc.h: Think I made the stack
+         operations more portable in case sizeof(int) != sizeof(void*)
+
+2003-01-06 04:18  jm
+
+       * trunk/speex/doc/manual.lyx, trunk/speex/libspeex/bits.c,
+         trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/lsp.c,
+         trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/misc.c,
+         trunk/speex/libspeex/misc.h, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/quant_lsp.c,
+         trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/speex_callbacks.c,
+         trunk/speex/libspeex/speex_header.c: cleanup: all use of libc has
+         been moved to misc.c to make porting easier.
+
+2003-01-05 08:46  jm
+
+       * trunk/speex/doc/manual.lyx, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/src/speexdec.c, trunk/speex/src/speexenc.c,
+         trunk/speex/src/wav_io.c: fixed some bugs in wave input: should
+         now handle extra chunks as well as extended "fmt " chunks. Also,
+         fixed a bug in invalid comment handling.
+
+2002-12-31 06:07  jm
+
+       * trunk/speex/configure.in, trunk/speex/doc/manual.lyx,
+         trunk/speex/libspeex/misc.h, trunk/speex/libspeex/speex.h,
+         trunk/speex/libspeex/speex_callbacks.h,
+         trunk/speex/libspeex/speex_stereo.h: documentation update
+
+2002-12-31 03:25  jm
+
+       * trunk/speex/libspeex/sb_celp.c: Fixed a segfault in
+         wideband/ultra-wideband decoding when a packet is lost while in
+         NULL mode.
+
+2002-12-20 19:51  jm
+
+       * trunk/speex/libspeex/nb_celp.c: removed debug printf...
+
+2002-12-20 17:45  jm
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/vbr.c:
+         Allowed CNG in VBR mode
+
+2002-12-20 08:24  jm
+
+       * trunk/speex/configure.in, trunk/speex/doc/manual.lyx,
+         trunk/speex/doc/manual.pdf, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h,
+         trunk/speex/libspeex/speex.h, trunk/speex/src/speexdec.1,
+         trunk/speex/src/speexdec.c, trunk/speex/src/speexenc.1,
+         trunk/speex/src/speexenc.c: misc stuff for beta4
+
+2002-12-20 07:16  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/filters.h,
+         trunk/speex/libspeex/modes.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h: Improvements to the perceptual
+         enhancement code: smoother pitch comb filter, better tuning, and a
+         stupid bugfix (gain hard-coded to .5).
+
+2002-12-20 05:20  jm
+
+       * trunk/speex/TODO, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/vbr.c, trunk/speex/src/speexdec.c: Think DTX
+         now works for wideband too
+
+2002-12-19 08:21  jm
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/speex.h:
+         Started work on discontinuous transmission (DTX)
+
+2002-12-19 04:07  jm
+
+       * trunk/speex/libspeex/lsp.c: Oops... this bug was found by Ming Wu
+         <mingwu@cyberon.com.tw>
+
+2002-12-15 06:45  jm
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h:
+         ABR seems to work for wideband too...
+
+2002-12-15 06:01  jm
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/src/speexenc.c: Average bit-rate (ABR) now seems to
+         work good for narrowband (no wideband yet, but shouldn't be hard)
+
+2002-12-15 04:45  jm
+
+       * trunk/speex/libspeex/vq.c: Patch by Bernard Blackham
+         <b-speex@blackham.com.au> that speeds up the VQ N-best search. Can
+         reach up to 10-15% speed improvement on higher complexity
+         settings.
+
+2002-12-14 06:29  jm
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/speex.h: More
+         ABR work...
+
+2002-12-13 22:59  jm
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c: Starting (still incomplete)
+         average bit-rate (ABR) implementation
+
+2002-12-13 01:47  jm
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/sb_celp.h: VAD should now work on wideband
+         too.
+
+2002-12-12 07:51  jm
+
+       * trunk/speex/TODO, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h, trunk/speex/libspeex/speex.h,
+         trunk/speex/libspeex/vbr.c, trunk/speex/src/speexenc.c:
+         Implemented VAD-only mode with comfort noise generation, did some
+         tuning to the VAD too. Next thing: adapt VAD-only to work with
+         wideband too.
+
+2002-12-12 03:28  jm
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/sb_celp.h: First shot at high-band perceptual
+         enhancement
+
+2002-12-11 22:03  jm
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/vbr.c:
+         Improvements to the way silence is handled in VBR.
+
+2002-12-11 08:24  jm
+
+       * trunk/speex/libspeex/nb_celp.c: More 2.15 kbps tuning, improved
+         open-loop pitch estimation (less pitch doubling)
+
+2002-12-11 06:49  jm
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h:
+         Big (hopefully) improvement in quality for the 2.15 kbps mode
+         (better excitation).
+
+2002-12-02 00:12  jm
+
+       * trunk/speex/TODO, trunk/speex/doc/manual.lyx,
+         trunk/speex/libspeex/misc.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/speex.h:
+         Implemented SPEEX_RESET_STATE and reduced memory allocation size.
+
+2002-11-30 05:24  jm
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h,
+         trunk/speex/libspeex/vbr.c, trunk/speex/libspeex/vbr.h:
+         Ultra-wideband VBR seems to work. Also, fixed a bug for wideband
+         VBR.
+
+2002-11-28 06:32  jm
+
+       * trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/ltp.h,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h: Many improvements (hopefully) to
+         packet loss concealing, part of it from a patch sent by Guilhem
+         Tardy.
+
+2002-11-27 20:36  jm
+
+       * trunk/speex/TODO, trunk/speex/libspeex/sb_celp.c: ...
+
+2002-11-27 05:22  jm
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c:
+         wideband VBR seems to (almost) work. Need to adapt it to work on
+         ultra- wideband too.
+
+2002-11-27 02:54  jm
+
+       * trunk/speex/configure.in, trunk/speex/doc/manual.lyx,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/vbr.c, trunk/speex/libspeex/vbr.h: ...
+
+2002-11-15 06:26  jm
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h,
+         trunk/speex/libspeex/speex.h, trunk/speex/libspeex/speex_bits.h,
+         trunk/speex/libspeex/vbr.c: Fixed a bug in the VBR analyzer,
+         trying to re-tune it... also, started implementing VBR for
+         wideband (still a big kludge for now).
+
+2002-11-14 04:49  jm
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/stereo.c, trunk/speex/libspeex/vbr.c: Fixed
+         bugs in stereo and zero-mode and did some VBR tuning... it's
+         looking good.
+
+2002-11-14 00:51  jm
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/vbr.c,
+         trunk/speex/libspeex/vbr.h: Trying a new VBR implementation...
+         still experimental
+
+2002-11-11 06:05  jm
+
+       * trunk/speex/doc/manual.lyx, trunk/speex/doc/manual.pdf,
+         trunk/speex/libspeex/speex_header.h,
+         trunk/speex/libspeex/speex_stereo.h, trunk/speex/src/speexdec.1,
+         trunk/speex/src/speexdec.c: Last updates (hopefully) for beta 3.
+
+2002-11-11 01:08  jm
+
+       * trunk/speex/configure.in, trunk/speex/doc/manual.lyx,
+         trunk/speex/libspeex/modes.c, trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/src/speexdec.1, trunk/speex/src/speexdec.c,
+         trunk/speex/src/speexenc.1, trunk/speex/src/speexenc.c: Misc stuff
+         for beta 3
+
+2002-11-10 05:17  jm
+
+       * trunk/speex/Speex.spec.in, trunk/speex/configure.in,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h,
+         trunk/speex/libspeex/speex.h, trunk/speex/src/speexdec.c,
+         trunk/speex/src/speexenc.c: Update for non-standard (not 8,16,32
+         kHz) sampling rates, changed package name from "Speex" to "speex"
+         (removed capital S) and moved doc to the devel package.
+
+2002-11-09 06:00  jm
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/src/speexdec.1, trunk/speex/src/speexdec.c,
+         trunk/speex/src/speexenc.1, trunk/speex/src/speexenc.c,
+         trunk/speex/win32/libspeex/libspeex.dsp: Preparing for beta 3,
+         cleaned up the mode/bit-rate code in speexdec, updated the help
+         and man pages, updated MSVC project.
+
+2002-11-08 05:58  jm
+
+       * trunk/speex/libspeex/sb_celp.c, trunk/speex/src/speexenc.c: Some
+         temporary kludging to make ultra-wideband work...
+
+2002-11-08 05:00  jm
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/sb_celp.c:
+         Fixed a couple stupid bugs
+
+2002-11-07 22:13  jm
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/speex_stereo.h,
+         trunk/speex/libspeex/stereo.c, trunk/speex/src/speexdec.c,
+         trunk/speex/src/speexenc.c: Implemented stereo at the decoder side
+
+2002-11-07 06:10  jm
+
+       * trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/speex_callbacks.h,
+         trunk/speex/libspeex/stereo.c, trunk/speex/src/speexenc.c,
+         trunk/speex/src/wav_io.c: First stereo support in encoder (might
+         be buggy), not in decoder yet.
+
+2002-11-06 21:27  jm
+
+       * trunk/speex/TODO, trunk/speex/libspeex/lsp.c,
+         trunk/speex/src/speexdec.c, trunk/speex/src/speexenc.c: Misc.
+         cosmetic stuff
+
+2002-11-06 01:47  jm
+
+       * trunk/speex/libspeex/lpc.c, trunk/speex/libspeex/lpc.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c:
+         Prevents a symbol name clash with the G729 version used by
+         OpenH323
+
+2002-11-05 15:57  jm
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/speex_stereo.h,
+         trunk/speex/libspeex/stereo.c: before my laptop drops dead... :(
+
+2002-11-04 03:00  jm
+
+       * trunk/speex/doc/manual.lyx, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/speex.h,
+         trunk/speex/libspeex/testenc_uwb.c, trunk/speex/src/speexenc.c,
+         trunk/speex/src/wav_io.c: Integrated "ultra-wideband" with
+         encoder/decoder.
+
+2002-11-02 15:27  jm
+
+       * trunk/speex/libspeex/nb_celp.c: To make the OpenH323 people happy
+         (warning on Win32)
+
+2002-11-02 06:25  jm
+
+       * trunk/speex/libspeex/sb_celp.c: Think I fixed the "ultra-wideband"
+         gain problem
+
+2002-11-02 06:08  jm
+
+       * trunk/speex/libspeex/cb_search.c: Stupid bug :-<
+
+2002-11-01 03:50  jm
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/src/speexenc.c: VBR
+         quality is now a float parameter
+
+2002-10-30 22:12  jm
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/math_approx.h, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/sb_celp.h, trunk/speex/libspeex/speex.h,
+         trunk/speex/libspeex/testenc_uwb.c: Wideband code cleanup, first
+         shot at an "ultra-wideband" mode at 32 kHz, but still buggy.
+
+2002-10-30 20:27  jm
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/math_approx.c,
+         trunk/speex/libspeex/math_approx.h,
+         trunk/speex/libspeex/nb_celp.c: New cos approximation for slow
+         CPU's (don't use it on x86)
+
+2002-10-27 06:01  jm
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/bits.c,
+         trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/lsp.c,
+         trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/ltp_sse.h,
+         trunk/speex/libspeex/misc.c, trunk/speex/libspeex/misc.h,
+         trunk/speex/libspeex/modes.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/speex_callbacks.c,
+         trunk/speex/libspeex/speex_header.c,
+         trunk/speex/libspeex/testenc.c, trunk/speex/libspeex/testenc_wb.c,
+         trunk/speex/src/speexdec.c, trunk/speex/src/speexenc.c: Made the
+         code valid for a C++ compiler (void* stuff), plus some cleanup
+
+2002-10-27 02:59  jm
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/lsp.c,
+         trunk/speex/libspeex/lsp.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h,
+         trunk/speex/libspeex/stack_alloc.h,
+         trunk/speex/libspeex/testenc_wb.c: The temp stack is now void*
+         instead of float*
+
+2002-10-27 02:36  jm
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/stack_alloc.h: ...
+
+2002-10-26 19:16  jm
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/lsp.c,
+         trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/stack_alloc.h: Stack allocation cleanup...
+
+2002-10-26 04:51  jm
+
+       * trunk/speex/configure.in, trunk/speex/doc/manual.lyx,
+         trunk/speex/libspeex/misc.h, trunk/speex/src/speexdec.c: Getting
+         ready for beta2
+
+2002-10-26 04:37  jm
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters_sse.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp_sse.h: Added SSE support (gcc only) by
+         defining _USE_SSE
+
+2002-10-26 02:58  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/sb_celp.h: QMF optimizations by segher
+
+2002-10-25 04:11  jm
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/nb_celp.c: Code cleanup
+
+2002-10-24 06:29  jm
+
+       * trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/nb_celp.c: Decoder optimizations, mostly when
+         perceptual enhancement is off.
+
+2002-10-24 03:59  jm
+
+       * trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/nb_celp.c: More
+         cleanups, do something more intelligent with LPC->LSP
+
+2002-10-23 19:06  jm
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c: fixed a double_codebook bug and
+         prevented pitch from doing weird things in VBR mode when the last
+         frame was vocoded.
+
+2002-10-23 16:35  jm
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c:
+         Compute impulse response of "perceptual synthesis filter" globally
+         and use it in pitch prediction to reduce some calculations.
+
+2002-10-23 06:24  jm
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/nb_celp.c:
+         Continuing cleanup, removed unused functions, ...
+
+2002-10-23 06:10  jm
+
+       * trunk/speex/libspeex/filters.c: ...
+
+2002-10-23 06:03  jm
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/sb_celp.c: Merged split_cb_search_nogain and
+         split_cb_search_shape_sign so there's now only one search function
+         with an option to search for a sign or not.
+
+2002-10-23 05:18  jm
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/vq.c,
+         trunk/speex/libspeex/vq.h: Re-wrote the signed search to be like
+         the unsigned one (should make them use the same code now)
+
+2002-10-23 02:56  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/filters.h,
+         trunk/speex/libspeex/sb_celp.c: Modified QMF filters so we don't
+         calculate useless (zeros) values.
+
+2002-10-23 00:53  jm
+
+       * trunk/speex/libspeex/cb_search.c: Removed un-necessary copies and
+         re-ordered some calculations to make them faster.
+
+2002-10-22 19:29  jm
+
+       * trunk/speex/libspeex/nb_celp.c: Prevents useless calculation of
+         perceptually-weighted frame
+
+2002-10-22 19:14  jm
+
+       * trunk/speex/libspeex/nb_celp.c: Don't compute open-loop pitch when
+         mode has a per-subframe pitch and VBR is not used. This gains a
+         bit of CPU.
+
+2002-10-22 03:22  jm
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/stack_alloc.h: Slight optimization to the way
+         the target is updated in the search. Also fixed the stack PUSH.
+
+2002-10-22 01:50  jm
+
+       * trunk/speex/libspeex/stack_alloc.h: oops... there was a bug in
+         PUSH (don't know what yet)
+
+2002-10-21 20:39  jm
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/lsp.c,
+         trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/stack_alloc.h,
+         trunk/speex/libspeex/testenc.c: Filter optimizations, cleanup,
+         removed the stack POP to simplify things and prevent errors
+
+2002-10-20 23:56  jm
+
+       * trunk/speex/libspeex/nb_celp.c: Separated the enhanced LPC filter
+         in 2
+
+2002-10-20 21:11  jm
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/filters.h:
+         Big cleanup, removed Direct-Form I filters
+
+2002-10-11 03:44  jm
+
+       * trunk/speex/libspeex/ltp.c, trunk/speex/src/wave_out.c,
+         trunk/speex/src/wave_out.h: ...
+
+2002-10-11 03:39  jm
+
+       * trunk/speex/COPYING, trunk/speex/Speex.spec.in, trunk/speex/TODO,
+         trunk/speex/libspeex/bits.c, trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/lpc.c,
+         trunk/speex/libspeex/lpc.h, trunk/speex/libspeex/lsp.c,
+         trunk/speex/libspeex/lsp.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/misc.c,
+         trunk/speex/libspeex/misc.h, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h, trunk/speex/libspeex/quant_lsp.c,
+         trunk/speex/libspeex/quant_lsp.h, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/sb_celp.h, trunk/speex/libspeex/speex.h,
+         trunk/speex/libspeex/speex_bits.h,
+         trunk/speex/libspeex/speex_callbacks.c,
+         trunk/speex/libspeex/speex_callbacks.h,
+         trunk/speex/libspeex/speex_header.c,
+         trunk/speex/libspeex/speex_header.h,
+         trunk/speex/libspeex/stack_alloc.h, trunk/speex/libspeex/vbr.c,
+         trunk/speex/libspeex/vbr.h, trunk/speex/libspeex/vq.c,
+         trunk/speex/libspeex/vq.h, trunk/speex/src/speexdec.c,
+         trunk/speex/src/speexenc.c, trunk/speex/src/wav_io.c,
+         trunk/speex/src/wav_io.h: Changed license to BSD
+
+2002-10-10 04:49  jm
+
+       * trunk/speex/Speex.spec.in, trunk/speex/libspeex/speex_callbacks.h:
+         Put manual in the right place
+
+2002-10-03 04:00  jmvalin
+
+       * trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/speex_callbacks.c,
+         trunk/speex/libspeex/speex_callbacks.h,
+         trunk/speex/libspeex/testenc.c: Most of the request/callback
+         mechanism is implemented, not completely tested yet.
+
+2002-10-02 22:49  jmvalin
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/speex_callbacks.c,
+         trunk/speex/libspeex/speex_callbacks.h: First version of in-band
+         signalling and user callbacks
+
+2002-10-02 19:52  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/speex_callbacks.c,
+         trunk/speex/libspeex/speex_callbacks.h: adding in-band signalling
+         and callback handling
+
+2002-10-02 04:24  jmvalin
+
+       * trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/speex.h:
+         Fixed (hopefully) once and for all the LSP root-finding problem.
+         We now try twice and if it still fails, we "create" a flat filter.
+
+2002-09-20 17:14  jmvalin
+
+       * trunk/speex/TODO, trunk/speex/doc/manual.lyx,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h:
+         ...
+
+2002-09-20 03:37  jmvalin
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/filters.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c: Converted filters with memory to
+         direct form II transposed, this creates a "minor
+         incompatibility"...
+
+2002-09-18 22:01  jmvalin
+
+       * trunk/speex/TODO, trunk/speex/doc/manual.lyx,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/src/speexdec.c: packet
+         loss handling...
+
+2002-09-18 07:35  jmvalin
+
+       * trunk/speex/libspeex/ltp.c: Fixed a bug in the pitch_gain return
+         value (make all _unquant functions return a 3-tap gain)
+
+2002-09-13 20:08  jmvalin
+
+       * trunk/speex/libspeex/speex.h, trunk/speex/libspeex/speex_bits.h,
+         trunk/speex/libspeex/speex_header.h: Doxygen...
+
+2002-09-12 15:11  jmvalin
+
+       * trunk/speex/libspeex/speex_bits.h: Doxygen...
+
+2002-09-12 14:55  jmvalin
+
+       * trunk/speex/libspeex/misc.h, trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/nb_celp.h, trunk/speex/libspeex/speex.h:
+         Doxygen...
+
+2002-09-12 03:31  jmvalin
+
+       * trunk/speex/libspeex/misc.h, trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/nb_celp.h, trunk/speex/libspeex/sb_celp.h,
+         trunk/speex/libspeex/speex.h, trunk/speex/libspeex/speex_bits.h,
+         trunk/speex/libspeex/speex_header.h: More Doxygen doc
+
+2002-09-12 02:48  jmvalin
+
+       * trunk/speex/Doxyfile, trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/nb_celp.h, trunk/speex/libspeex/sb_celp.h,
+         trunk/speex/libspeex/speex.h, trunk/speex/libspeex/speex_bits.h,
+         trunk/speex/libspeex/speex_header.h: Comments for Doxygen
+
+2002-08-30 14:31  jmvalin
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/testenc.c: ...
+
+2002-08-30 04:04  jmvalin
+
+       * trunk/speex/libspeex/misc.h: Just in case someone forgets to
+         define VERSION
+
+2002-08-27 20:57  jmvalin
+
+       * trunk/speex/doc/manual.lyx, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h,
+         trunk/speex/libspeex/speex.h, trunk/speex/src/speexdec.c: Moved
+         modeID check in nb_celp/sb_celp
+
+2002-08-27 07:29  jmvalin
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/filters.h,
+         trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/modes.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/sb_celp.c: speeded up lpc_to_lsp and
+         open-loop pitch estimation
+
+2002-08-22 21:17  jmvalin
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h,
+         trunk/speex/libspeex/speex.h, trunk/speex/libspeex/speex_header.c,
+         trunk/speex/libspeex/testenc.c, trunk/speex/libspeex/testenc_wb.c,
+         trunk/speex/src/getopt.c, trunk/speex/src/getopt1.c,
+         trunk/speex/src/speexdec.c: API change: a couple fields were
+         removed from SpeexMode because they can now be accessed through
+         the speex_mode_query call. Also, the "lost" argument has been
+         removed from speex_decode since a lost packet is now specified as
+         a NULL "bits" argument.
+
+2002-08-22 20:47  jmvalin
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/speex.h: Added
+         query function for modes Support for modes > 7 at decoder
+
+2002-08-22 17:58  jmvalin
+
+       * trunk/speex/configure.in, trunk/speex/doc/manual.lyx,
+         trunk/speex/libspeex/cb_search.c, trunk/speex/src/getopt.c,
+         trunk/speex/src/getopt.h, trunk/speex/src/getopt1.c,
+         trunk/speex/src/speexdec.c, trunk/speex/src/speexenc.c,
+         trunk/speex/src/wave_out.c, trunk/speex/src/wave_out.h,
+         trunk/speex/win32, trunk/speex/win32/libspeex,
+         trunk/speex/win32/libspeex/libspeex.dsp,
+         trunk/speex/win32/libspeex/libspeex.dsw,
+         trunk/speex/win32/speexdec,
+         trunk/speex/win32/speexdec/speexdec.dsp,
+         trunk/speex/win32/speexdec/speexdec.dsw,
+         trunk/speex/win32/speexenc,
+         trunk/speex/win32/speexenc/speexenc.dsp,
+         trunk/speex/win32/speexenc/speexenc.dsw: Win32 support, thanks to
+         john33 (Hydrogen Audio)
+
+2002-08-22 06:33  jmvalin
+
+       * trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/testenc.c,
+         trunk/speex/libspeex/testenc_wb.c: Implemented packet loss
+         interpolation for wideband... not optimal yet...
+
+2002-08-22 05:49  jmvalin
+
+       * trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/testenc.c: The decode function can now do the
+         packet loss interpolation without the last bit-stream received...
+         for narrowband. Next: wideband.
+
+2002-08-22 05:07  jmvalin
+
+       * trunk/speex/libspeex/bits.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/modes.c, trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/speex_bits.h: New very high quality modes for
+         narrowband and wideband by using a double codebook
+
+2002-08-16 18:24  jmvalin
+
+       * trunk/speex/libspeex/sb_celp.c: Changed wideband quality mode to
+         adapt to better high-band spectral folding
+
+2002-08-16 07:08  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/nb_celp.c: stupid VBR bug corrected +
+         improvements
+
+2002-08-16 06:02  jmvalin
+
+       * trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/testenc_wb.c: Improved spectral folding
+         wideband mode
+
+2002-08-15 20:08  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c: oops...
+
+2002-08-14 20:19  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/nb_celp.c:
+         Cleaned up vocoder mode...
+
+2002-08-14 17:58  jmvalin
+
+       * trunk/speex/libspeex/bits.c, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/speex_bits.h:
+         Now the narrowband and wideband bit-streams are compatible and can
+         be decoded in either mode
+
+2002-08-13 21:11  jmvalin
+
+       * trunk/speex/libspeex/bits.c, trunk/speex/libspeex/speex_bits.h:
+         Make sure we don't destroy user buffer when SpeexBits is
+         destructed
+
+2002-08-13 20:58  jmvalin
+
+       * trunk/speex/libspeex/bits.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/speex_bits.h,
+         trunk/speex/libspeex/testenc_wb.c: ...
+
+2002-08-08 20:53  jmvalin
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/nb_celp.c:
+         Reduced number of bits to code subframe excitation gain on low
+         modes
+
+2002-08-02 14:39  jmvalin
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c:
+         removed debugging code
+
+2002-08-02 05:46  jmvalin
+
+       * trunk/speex/libspeex/modes.c: Enhancer tuning...
+
+2002-08-02 04:00  jmvalin
+
+       * trunk/speex/Speex.spec, trunk/speex/configure.in,
+         trunk/speex/doc/manual.lyx, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/modes.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/testenc.c,
+         trunk/speex/libspeex/testenc_wb.c, trunk/speex/libspeex/vq.c,
+         trunk/speex/libspeex/vq.h, trunk/speex/src/speexdec.c,
+         trunk/speex/src/speexenc.c: Bug fixes, many leaks/errors fixed
+         thanks to valgrind. Some filter roundoff improvement kludge for
+         enhancer...
+
+2002-08-01 19:58  jmvalin
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c:
+         Implemented "null mode", i.e. silence. Only submodeID is
+         transmitted
+
+2002-08-01 15:14  jmvalin
+
+       * trunk/speex/libspeex/nb_celp.c: oops:-(
+
+2002-08-01 14:48  jmvalin
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h, trunk/speex/libspeex/testenc.c:
+         oops... forgot to remove some useless stuff
+
+2002-08-01 14:45  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/post_filter.c,
+         trunk/speex/libspeex/post_filter.h, trunk/speex/libspeex/roots.c,
+         trunk/speex/libspeex/roots.h, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/sb_celp.h, trunk/speex/libspeex/speex.h,
+         trunk/speex/libspeex/testenc.c, trunk/speex/libspeex/testenc_wb.c:
+         Replaced the post-filter by a simple pitch comb filter plus an LPC
+         synthesis filter enhancer.
+
+2002-07-31 22:30  jmvalin
+
+       * trunk/speex/configure.in, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/speex.h,
+         trunk/speex/src/speexdec.c, trunk/speex/src/speexenc.c: Added
+         bit-rate information via speex_*_ctl calls, fixed stupid bug in
+         speexenc
+
+2002-07-30 06:03  jmvalin
+
+       * trunk/speex/libspeex/filters.c: Think I got rid of all the
+         problems when the roots are wrong...
+
+2002-07-30 04:43  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/post_filter.c,
+         trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/speex_header.c, trunk/speex/libspeex/vbr.c,
+         trunk/speex/libspeex/vq.c, trunk/speex/libspeex/vq.h: Fixed
+         post-filter producing NaN's, started writing some SSE code
+
+2002-07-29 04:38  jmvalin
+
+       * trunk/speex/configure.in, trunk/speex/doc/manual.lyx,
+         trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h, trunk/speex/libspeex/roots.c,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h,
+         trunk/speex/libspeex/speex.h, trunk/speex/libspeex/testenc.c,
+         trunk/speex/src/speexenc.c: added encoder complexity option
+
+2002-07-28 04:09  jmvalin
+
+       * trunk/speex/doc/manual.lyx, trunk/speex/libspeex/bits.c,
+         trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/speex_bits.h,
+         trunk/speex/libspeex/speex_header.c,
+         trunk/speex/libspeex/speex_header.h, trunk/speex/src/speexdec.c,
+         trunk/speex/src/speexenc.c: Allow more than one frame per packet
+
+2002-07-22 05:44  jmvalin
+
+       * trunk/speex/libspeex/misc.c, trunk/speex/libspeex/misc.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c:
+         Replaced memmove by speex_move
+
+2002-07-22 04:46  jmvalin
+
+       * trunk/speex/libspeex/misc.c, trunk/speex/libspeex/misc.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/speex_header.c: Replaced all
+         malloc/calloc/free calls by speex_alloc/speex_free to ease
+         portability
+
+2002-07-20 04:58  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h: Implemented new "global" search
+         for the whole sub-frame, slight improvement over the regular
+         search, but it comes with increased CPU requirement.
+
+2002-07-20 02:27  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c: Removed redundent searches
+
+2002-07-20 02:08  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/vq.c,
+         trunk/speex/libspeex/vq.h: Added an n-best VQ search function in
+         order to simplify the code
+
+2002-07-19 19:21  jmvalin
+
+       * trunk/speex/libspeex/filters.c: work around a convergence problem
+         in ploy_roots
+
+2002-07-19 18:48  jmvalin
+
+       * trunk/speex/libspeex/filters.c, trunk/speex/libspeex/ltp.c: Fixed
+         a root stability bug...
+
+2002-07-19 18:15  jmvalin
+
+       * trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/nb_celp.c: Fixed a pitch prediction bug when
+         pitch is forced (end=start)
+
+2002-07-18 22:55  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/exc_10_16_table.c,
+         trunk/speex/libspeex/modes.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/roots.c: Improved very low bit-rate (~5.9
+         kbps) mode
+
+2002-07-17 06:35  jmvalin
+
+       * trunk/speex/Speex.spec, trunk/speex/configure.in,
+         trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/post_filter.c, trunk/speex/libspeex/roots.c,
+         trunk/speex/libspeex/roots.h: New post-filter based on a new way
+         of moving poles in the LPC polynomial
+
+2002-07-16 14:44  jmvalin
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/testenc_wb.c:
+         cleanup
+
+2002-07-11 06:10  jmvalin
+
+       * trunk/speex/Speex.spec, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/speex.h,
+         trunk/speex/libspeex/testenc.c, trunk/speex/libspeex/testenc_wb.c,
+         trunk/speex/libspeex/vbr.c, trunk/speex/src/speexenc.c: Completed
+         VBR for 0.5.0 release
+
+2002-07-10 20:45  jmvalin
+
+       * trunk/speex/configure.in, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/testenc_wb.c, trunk/speex/libspeex/vbr.c:
+         More VBR work. Also added a 5.5 kbps mode and added frame-wide
+         pitch to comfort noise mode (now at 2.3 kbps).
+
+2002-07-08 18:06  jmvalin
+
+       * trunk/speex/libspeex/vbr.c, trunk/speex/libspeex/vbr.h: Added
+         noise energy estimation and beginning of a VAD.
+
+2002-07-07 07:30  jmvalin
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/vbr.c, trunk/speex/libspeex/vbr.h: Improved
+         VBR by adding pitch and some constraints...
+
+2002-07-07 03:27  jmvalin
+
+       * trunk/speex/libspeex/lpc.c, trunk/speex/libspeex/lpc.h,
+         trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/lsp.h:
+         license/header stuff
+
+2002-07-06 05:30  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h: Cleanup Put mode decision before
+         open-loops analysis Open-loop pitch analysis returns pitch "pseudo
+         gain" (bound to [0,1])
+
+2002-07-05 16:01  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/lpc.c,
+         trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/lsp.h,
+         trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/vq.c, trunk/speex/libspeex/vq.h: code cleanup
+
+2002-07-05 06:51  jmvalin
+
+       * trunk/speex/libspeex/modes.c: Played slightly with bit-rates...
+
+2002-07-04 21:55  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/exc_8_128_table.c,
+         trunk/speex/libspeex/gain_table.c,
+         trunk/speex/libspeex/gain_table_lbr.c: Trained some codebooks...
+
+2002-07-02 05:14  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/exc_10_32_table.c,
+         trunk/speex/libspeex/exc_5_256_table.c,
+         trunk/speex/libspeex/exc_5_64_table.c,
+         trunk/speex/libspeex/exc_8_128_table.c,
+         trunk/speex/libspeex/gain_table.c,
+         trunk/speex/libspeex/gain_table_lbr.c,
+         trunk/speex/libspeex/hexc_10_32_table.c,
+         trunk/speex/libspeex/hexc_table.c,
+         trunk/speex/libspeex/high_lsp_tables.c,
+         trunk/speex/libspeex/lsp_tables_nb.c,
+         trunk/speex/libspeex/lsp_tables_wb.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/quant_lsp.c,
+         trunk/speex/libspeex/quant_lsp.h: Cleaned up unused stuff and
+         licensed all codebooks under the BSD license
+
+2002-07-01 08:18  jmvalin
+
+       * trunk/speex/libspeex/post_filter.c: Comments...
+
+2002-07-01 08:10  jmvalin
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/testenc.c, trunk/speex/libspeex/vbr.c,
+         trunk/speex/libspeex/vbr.h: First try at VBR... off by default
+
+2002-06-28 19:01  jmvalin
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/speex.h: Just
+         some cleanup and comments.
+
+2002-06-27 16:33  jmvalin
+
+       * trunk/speex/libspeex/sb_celp.c, trunk/speex/src/speexdec.c:
+         Oops...
+
+2002-06-27 07:23  jmvalin
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/src/speexdec.c,
+         trunk/speex/src/speexenc.c: Created quality modes for wideband,
+         updated encoder. Getting close to 0.4.0
+
+2002-06-26 20:59  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/sb_celp.c: Added a comfort noise mode...
+
+2002-06-26 06:23  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/exc_8_128_table.c,
+         trunk/speex/libspeex/modes.c, trunk/speex/libspeex/sb_celp.c:
+         Added narrowband mode at 11.75 kbps
+
+2002-06-25 18:46  jmvalin
+
+       * trunk/speex/configure.in, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/sb_celp.h, trunk/speex/libspeex/speex.h,
+         trunk/speex/libspeex/testenc.c, trunk/speex/libspeex/testenc_wb.c,
+         trunk/speex/src/speexdec.c, trunk/speex/src/speexenc.c: First step
+         to variable bit-rate (VBR): it is now possible to change the modes
+         (bit-rate) of the encoder dynamically (decoder adjusts itself).
+
+2002-06-21 19:38  jmvalin
+
+       * trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/speex_header.h, trunk/speex/src/speexdec.c:
+         Improved (I think) quality in presence of packet loss...
+
+2002-06-18 21:22  jmvalin
+
+       * trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c:
+         s/hanning/hamming/ for analysis window provides a slight
+         improvement
+
+2002-06-18 18:28  jmvalin
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/sb_celp.c:
+         Changed the LPC analysis window to an asymetric (pseudo-)Hanning
+         window so the lookahead necesary is now only 10 ms, making the
+         total algorithmic delay 30 ms (down from 40 ms).
+
+2002-06-17 07:14  jmvalin
+
+       * trunk/speex/configure.in, trunk/speex/libspeex/sb_celp.c: ...
+
+2002-06-17 06:47  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/hexc_10_32_table.c,
+         trunk/speex/libspeex/modes.c, trunk/speex/libspeex/speex.h,
+         trunk/speex/src/speexenc.c: New "low bit-rate" wideband mode
+         (20150 kbps)
+
+2002-06-13 05:12  jmvalin
+
+       * trunk/speex/libspeex/sb_celp.c: folding mode is a bit better...
+
+2002-06-12 21:33  jmvalin
+
+       * trunk/speex/Makefile.am, trunk/speex/configure.in,
+         trunk/speex/libspeex/modes.c, trunk/speex/libspeex/post_filter.c,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/speex.h,
+         trunk/speex/src/speexdec.c, trunk/speex/src/speexenc.c,
+         trunk/speex/src/wav_io.c: Speex *should* now work on big-endian
+         architectures.
+
+2002-06-12 08:33  jmvalin
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/speex.h,
+         trunk/speex/libspeex/speex_header.c,
+         trunk/speex/libspeex/speex_header.h,
+         trunk/speex/libspeex/testenc.c: Introduced bit-stream version
+         number (for compatibility)
+
+2002-06-12 06:39  jmvalin
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/speex.h, trunk/speex/libspeex/speex_header.c,
+         trunk/speex/libspeex/speex_header.h: More header work
+
+2002-06-12 05:15  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/misc.c,
+         trunk/speex/libspeex/misc.h, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/speex.h, trunk/speex/libspeex/speex_header.c,
+         trunk/speex/libspeex/speex_header.h: Header work...
+
+2002-06-11 08:34  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/modes.c:
+         oops...
+
+2002-06-11 08:27  jmvalin
+
+       * trunk/speex/libspeex/exc_10_32_table.c,
+         trunk/speex/libspeex/gain_table_lbr.c,
+         trunk/speex/libspeex/modes.c: low bit-rate codebooks optimized
+
+2002-06-11 06:08  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/exc_10_32_table.c,
+         trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/ltp.h,
+         trunk/speex/libspeex/modes.c, trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/quant_lsp.c,
+         trunk/speex/libspeex/quant_lsp.h, trunk/speex/libspeex/speex.h,
+         trunk/speex/libspeex/speex_header.h: Added low bit-rate (8 kbps)
+         narrowband mode. It is still sub-optimal but at least it seems to
+         work...
+
+2002-06-10 08:25  jmvalin
+
+       * trunk/speex/libspeex/gain_table.c, trunk/speex/libspeex/ltp.c:
+         codebook retrained (again)
+
+2002-06-10 07:50  jmvalin
+
+       * trunk/speex/libspeex/exc_5_64_table.c,
+         trunk/speex/libspeex/gain_table.c: Codebooks retrained about 0.3
+         dB in SNR
+
+2002-06-07 21:57  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/lsp.c,
+         trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/ltp.h,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/testenc.c: Implemented an n-best open-loop
+         pitch search to speed up the closed-loop search. Also fixed a bug
+         in open-loop pitch estimation. Some cleanup too as well as
+         PUSH/POP matching.
+
+2002-06-07 05:30  jmvalin
+
+       * trunk/speex/Speex.spec, trunk/speex/configure.in,
+         trunk/speex/libspeex/testenc_wb.c: Getting ready for 0.2.0
+
+2002-06-07 05:11  jmvalin
+
+       * trunk/speex/libspeex/sb_celp.c: Oops... screwed up in the order
+
+2002-06-07 04:55  jmvalin
+
+       * trunk/speex/libspeex/sb_celp.c: Make sure the filters are always
+         stable in the LSP domain
+
+2002-06-07 04:30  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/hexc_table.c, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/sb_celp.c: Removed some warnings, fixed
+         posfilter mode for wideband
+
+2002-06-07 03:20  jmvalin
+
+       * trunk/speex/doc/programming.html,
+         trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h,
+         trunk/speex/libspeex/hexc_table.c, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/testenc_wb.c: High-band (for wideband) is now
+         a shape-sign codebook, reducing search by a factor two
+
+2002-06-06 22:18  jmvalin
+
+       * trunk/speex/libspeex/exc_5_256_table.c: Retrained (optimized)
+         codebook
+
+2002-06-06 22:08  jmvalin
+
+       * trunk/speex/libspeex/exc_5_64_table.c: ...
+
+2002-06-06 19:12  jmvalin
+
+       * trunk/speex/libspeex/exc_5_64_table.c: retrained the codebook
+
+2002-06-06 06:32  jmvalin
+
+       * trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/post_filter.c,
+         trunk/speex/libspeex/post_filter.h,
+         trunk/speex/libspeex/testenc.c, trunk/speex/libspeex/testenc_wb.c:
+         New post-filter A(z/g1)/A(z/g2)
+
+2002-06-06 04:04  jmvalin
+
+       * trunk/speex/libspeex/ltp.c: Fixed a bug allowing the pitch to be
+         larger than the maximum allowed (hence screwing up at the decoder)
+
+2002-06-05 06:07  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/quant_lsp.c,
+         trunk/speex/libspeex/speex_header.h, trunk/speex/src/Makefile.am,
+         trunk/speex/src/speexenc.c, trunk/speex/src/wav_io.c: Encoder now
+         understands wav files, slight modif to LSP quantization weighting
+
+2002-06-05 02:56  jmvalin
+
+       * trunk/speex/Speex.spec, trunk/speex/configure.in,
+         trunk/speex/html/index.html, trunk/speex/libspeex/lsp.c,
+         trunk/speex/libspeex/lsp.h, trunk/speex/libspeex/nb_celp.c:
+         Constrain LSP's to produce a stable filter
+
+2002-06-04 04:10  jmvalin
+
+       * trunk/speex/Speex.spec, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/src/speexdec.c: Last modifs for 0.1.2
+
+2002-06-03 14:48  jmvalin
+
+       * trunk/speex/libspeex/post_filter.h: ...
+
+2002-06-03 02:54  jmvalin
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/sb_celp.h, trunk/speex/libspeex/speex.h,
+         trunk/speex/libspeex/testenc.c, trunk/speex/libspeex/testenc_wb.c,
+         trunk/speex/src/speexdec.c, trunk/speex/src/speexenc.c: Added
+         SPEEX_GET_FRAME_SIZE to speex_*_ctl calls
+
+2002-06-03 02:14  jmvalin
+
+       * trunk/speex/OPTIMIZE, trunk/speex/Speex.spec,
+         trunk/speex/Speex.spec.in, trunk/speex/configure.in,
+         trunk/speex/libspeex/modes.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/sb_celp.h, trunk/speex/libspeex/speex.h,
+         trunk/speex/libspeex/testenc.c, trunk/speex/libspeex/testenc_wb.c,
+         trunk/speex/src/speexdec.c: Added speex_ctl call to set codec
+         parameters (e.g. enable/disable post-filter)
+
+2002-06-03 00:51  jmvalin
+
+       * trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/post_filter.c,
+         trunk/speex/libspeex/post_filter.h: "unified" narrowband and
+         wideband post-filters
+
+2002-05-29 03:41  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/post_filter.c,
+         trunk/speex/libspeex/post_filter.h: Added a post-filter for
+         narrowband (and thus 0-4 kHz in wideband)
+
+2002-05-21 21:49  jmvalin
+
+       * trunk/speex/html/index.html, trunk/speex/html/speex.png,
+         trunk/speex/html/speex.xcf, trunk/speex/libspeex/bits.c,
+         trunk/speex/libspeex/speex.h, trunk/speex/libspeex/speex_bits.h,
+         trunk/speex/src/speexdec.c: Documentation, cleanup, comments
+
+2002-05-21 02:12  jmvalin
+
+       * trunk/speex/configure.in, trunk/speex/libspeex/speex.h,
+         trunk/speex/libspeex/speex_bits.h: API documentation
+
+2002-05-20 18:53  jmvalin
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/speex.h,
+         trunk/speex/libspeex/testenc.c, trunk/speex/libspeex/testenc_wb.c,
+         trunk/speex/src/speexdec.c, trunk/speex/src/speexenc.c: Every
+         symbol in <speex.h> now has a speex_ prefix.
+
+2002-05-18 20:00  jmvalin
+
+       * trunk/speex/libspeex/bits.c, trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/nb_celp.h, trunk/speex/libspeex/quant_lsp.c,
+         trunk/speex/libspeex/quant_lsp.h, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/sb_celp.h, trunk/speex/libspeex/speex.h,
+         trunk/speex/libspeex/speex_bits.h, trunk/speex/libspeex/testenc.c,
+         trunk/speex/libspeex/testenc_wb.c, trunk/speex/src/speexdec.c,
+         trunk/speex/src/speexenc.c: FrameBits renamed to SpeexBits and a
+         "lost" argument was added to the decode function to handle lost
+         packets
+
+2002-05-16 19:16  jmvalin
+
+       * trunk/speex/README, trunk/speex/libspeex/hexc_table.c,
+         trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/sb_celp.c: Wideband quantization improved by
+         adding a sub-frame gain, codebook re-trained.
+
+2002-05-15 21:47  jmvalin
+
+       * trunk/speex/configure.in, trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/modes.c, trunk/speex/src/Makefile.am,
+         trunk/speex/src/speexenc.c: Removed narrowband 256x8 codebook from
+         build.
+
+2002-05-14 21:58  jmvalin
+
+       * trunk/speex/configure.in, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/src/speexdec.c, trunk/speex/src/speexenc.c: speexenc
+         and speexdec now use the Ogg bitstream. This is very preliminary
+         there are probably a couple dozens of bugs...
+
+2002-05-14 14:21  jmvalin
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/testenc_wb.c: ...
+
+2002-05-14 04:08  jmvalin
+
+       * trunk/speex/libspeex/hexc_table.c: shouldn't have been deleted...
+
+2002-05-14 03:25  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h,
+         trunk/speex/libspeex/exc_5_256_table.c,
+         trunk/speex/libspeex/exc_5_64_table.c,
+         trunk/speex/libspeex/exc_8_256_table.c,
+         trunk/speex/libspeex/exc_gains_table.c,
+         trunk/speex/libspeex/exc_gains_wb2_table.c,
+         trunk/speex/libspeex/exc_gains_wb_table.c,
+         trunk/speex/libspeex/exc_sb_table.c,
+         trunk/speex/libspeex/exc_table.c,
+         trunk/speex/libspeex/exc_wb_table.c,
+         trunk/speex/libspeex/hexc_table.c,
+         trunk/speex/libspeex/lsp_tables_nb.c,
+         trunk/speex/libspeex/matrix.c, trunk/speex/libspeex/matrix.h,
+         trunk/speex/libspeex/modes.c, trunk/speex/libspeex/mpulse.c,
+         trunk/speex/libspeex/mpulse.h, trunk/speex/libspeex/nb_celp.c,
+         trunk/speex/libspeex/quant_lsp.c, trunk/speex/libspeex/speex.h,
+         trunk/speex/libspeex/stoc.c, trunk/speex/libspeex/testenc.c,
+         trunk/speex/libspeex/testenc_wb.c, trunk/speex/src/speexdec.c,
+         trunk/speex/src/speexenc.c: Big changes in both narrowband and
+         wideband. Retrained LSP codebook, replaced pseudo-multi-pulse by
+         split codebook (no gain) for narrowband. Changed gain-shape
+         approach to gain-only split-VQ for wideband. Wideband bit-rate
+         goes down (31.3 kbps to 26.9 kbps). Narrowband is about the same
+         (now 15.1 kbps).
+
+2002-05-09 03:55  jmvalin
+
+       * trunk/speex/configure.in, trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/speex_modes.h: Last cleanup for 0.0.3
+
+2002-05-07 19:51  jmvalin
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h,
+         trunk/speex/libspeex/speex.h: More comments
+
+2002-05-06 21:12  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h:
+         Finished cleaning up the sub-band mode
+
+2002-05-06 18:53  jmvalin
+
+       * trunk/speex/libspeex/speex.h: Oops... forgot to add that
+
+2002-05-03 19:27  jmvalin
+
+       * trunk/speex/configure.in, trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/testenc.c,
+         trunk/speex/libspeex/testenc_wb.c, trunk/speex/src/speexdec.c,
+         trunk/speex/src/speexenc.c: Now, all the includes we need to use
+         Speex are speex.h and speex_bits.h
+
+2002-05-03 19:22  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/bits.c,
+         trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/modes.c, trunk/speex/libspeex/mpulse.c,
+         trunk/speex/libspeex/nb_celp.c, trunk/speex/libspeex/nb_celp.h,
+         trunk/speex/libspeex/quant_lsp.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/sb_celp.h, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex.h, trunk/speex/libspeex/speex_bits.h,
+         trunk/speex/libspeex/testenc.c, trunk/speex/libspeex/testenc_wb.c,
+         trunk/speex/src/speexdec.c, trunk/speex/src/speexenc.c: speex.[ch]
+         renamed to nb_celp.[ch] for consistency
+
+2002-05-03 19:13  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/bits.c,
+         trunk/speex/libspeex/bits.h, trunk/speex/libspeex/cb_search.h,
+         trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/ltp.h,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/mpulse.h,
+         trunk/speex/libspeex/quant_lsp.h, trunk/speex/libspeex/sb_celp.h,
+         trunk/speex/libspeex/speex.h, trunk/speex/libspeex/speex_bits.h,
+         trunk/speex/libspeex/speex_modes.h: bits.h was renamed to
+         speex_bits to prevent name clashes
+
+2002-05-03 19:05  jmvalin
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/speex_modes.h: First part of VBR: High-band
+         excitation is coded or folded from low-band
+
+2002-05-02 22:36  jmvalin
+
+       * trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/sb_celp.c: fixed
+         two FIXME's
+
+2002-05-02 22:28  jmvalin
+
+       * trunk/speex/TODO, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/testenc.c, trunk/speex/libspeex/testenc_wb.c:
+         implemented high-band spectral folding at the decoder
+
+2002-05-02 20:55  jmvalin
+
+       * trunk/speex/libspeex/testdec.c: *** empty log message ***
+
+2002-05-02 20:55  jmvalin
+
+       * trunk/speex/TODO, trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/sb_celp.h, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex.h, trunk/speex/libspeex/speex_modes.h,
+         trunk/speex/libspeex/testenc.c, trunk/speex/libspeex/testenc_sb.c,
+         trunk/speex/libspeex/testenc_wb.c, trunk/speex/libspeex/vbr.h,
+         trunk/speex/src/speexdec.c, trunk/speex/src/speexenc.c:
+         Unification of narrowband and wideband modes to simplify the API
+
+2002-04-29 22:45  jmvalin
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/sb_celp.h: Added simple (optional)
+         post-filter
+
+2002-04-29 11:12  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c: removed unused variable
+
+2002-04-29 09:59  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/testenc_sb.c: Decoder back in sync with the
+         encoder
+
+2002-04-24 21:53  jmvalin
+
+       * trunk/speex/libspeex/ltp.c: pitch search now considers two ranges:
+         start < T < subframe and subframe < T < end
+
+2002-04-24 07:26  jmvalin
+
+       * trunk/speex/libspeex/hexc_table.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/speex.c, trunk/speex/libspeex/speex.h:
+         Updated high-band codebook...
+
+2002-04-24 06:50  jmvalin
+
+       * trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/ltp.h,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/mpulse.c,
+         trunk/speex/libspeex/speex.c: Made the initial pitch search
+         open-loop. Removed some modulo and devide operations.
+
+2002-04-23 21:18  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/sb_celp.c:
+         Fixed warnings
+
+2002-04-23 08:12  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/hexc_table.c,
+         trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/ltp.h,
+         trunk/speex/libspeex/modes.c, trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/mpulse.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/sb_celp.h, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex.h, trunk/speex/libspeex/testenc_sb.c:
+         Many, many updates. Better split-VQ search, better handling of
+         pitch for periods shorter than subframe length. Slightly improved
+         multi-pulse search.
+
+2002-04-15 05:04  jmvalin
+
+       * trunk/speex/configure.in, trunk/speex/libspeex/mpulse.c,
+         trunk/speex/libspeex/speex.c, trunk/speex/libspeex/testenc_sb.c,
+         trunk/speex/src/speexdec.c, trunk/speex/src/speexenc.c: Moving on
+         for 0.0.2, updated the "real" encoder and decoder (speexenc,
+         speexdec). Fixed a memory leak.
+
+2002-04-14 04:05  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/modes.c, trunk/speex/libspeex/sb_celp.c: Got
+         rid of a couple mallocs...
+
+2002-04-12 22:58  jmvalin
+
+       * trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/testenc_sb.c: Removed warnings, debug code
+         and un-necessary synthesis in coder
+
+2002-04-12 22:15  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/sb_celp.c:
+         Speed improvements (got rid of a couple divide ops), cleanup...
+
+2002-04-12 05:58  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/filters.c:
+         Speed improvements: faster FIR filter and better algorithm for
+         updating target in split-codebook search.
+
+2002-04-10 20:57  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/sb_celp.h, trunk/speex/libspeex/testenc_sb.c:
+         Big code cleanup, some minor bug fixed too
+
+2002-04-10 07:42  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/sb_celp.h, trunk/speex/libspeex/vbr.c,
+         trunk/speex/libspeex/vbr.h: ...
+
+2002-04-10 05:46  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/speex.c: Think both encoder and decoder for
+         SB-CELP work...
+
+2002-04-09 23:33  jmvalin
+
+       * trunk/speex/libspeex/quant_lsp.c,
+         trunk/speex/libspeex/quant_lsp.h, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/speex.c, trunk/speex/libspeex/speex.h,
+         trunk/speex/libspeex/testenc_sb.c: decoder stuff
+
+2002-04-09 08:08  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/testenc_sb.c: SB-CELP decoder (continued)
+
+2002-04-09 07:48  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/testenc_sb.c: SB-CELP work... more to go
+
+2002-04-09 07:23  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/sb_celp.h: More decoder work
+
+2002-04-09 06:44  jmvalin
+
+       * trunk/speex/libspeex/sb_celp.c: Fixed a bug in the gain
+         quantization (it's now done in the log domain)
+
+2002-04-09 05:15  jmvalin
+
+       * trunk/speex/libspeex/sb_celp.c: Fully quantized test encoder for
+         SB-CELP at (currently) 31.3 kbps.
+
+2002-04-09 02:20  jmvalin
+
+       * trunk/speex/libspeex/testenc_sb.c: Test encoder for SB-CELP
+
+2002-04-08 23:01  jmvalin
+
+       * trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex.h: Quantizing high-band excitation
+         gains (SB-CELP).
+
+2002-04-08 19:08  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/high_lsp_tables.c,
+         trunk/speex/libspeex/quant_lsp.c,
+         trunk/speex/libspeex/quant_lsp.h, trunk/speex/libspeex/sb_celp.c:
+         Added LSP quantization for SB-CELP
+
+2002-04-08 06:26  jmvalin
+
+       * trunk/speex/html/index.html, trunk/speex/libspeex/cb_search.c:
+         Removed useless stuff
+
+2002-04-08 06:23  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h,
+         trunk/speex/libspeex/exc_sb_table.c, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/mpulse.c, trunk/speex/libspeex/mpulse.h,
+         trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h,
+         trunk/speex/libspeex/speex.c: Re-wrote the gain quantization for
+         split-VQ excitation. Added more bits and quantize one at a time.
+
+2002-04-05 19:51  jmvalin
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/speex.c: Cleaned up SB-CELP and added more
+         pulses and tracks for low-band.
+
+2002-04-04 23:36  jmvalin
+
+       * trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h:
+         Fixed interpolation bugs, ...
+
+2002-04-04 21:22  jmvalin
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/sb_celp.h: Using spectral folding (ie
+         aliasing) for high-band excitation
+
+2002-04-03 05:02  jmvalin
+
+       * trunk/speex/libspeex/sb_celp.c: ...
+
+2002-04-03 00:01  jmvalin
+
+       * trunk/speex/libspeex/sb_celp.c, trunk/speex/libspeex/sb_celp.h:
+         more sub-band stuff...
+
+2002-04-02 22:58  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/sb_celp.c,
+         trunk/speex/libspeex/sb_celp.h, trunk/speex/libspeex/testenc.c,
+         trunk/speex/libspeex/testenc_wb.c: Adding sub-band CELP (SB-CELP)
+         -like encoding. Still incomplete.
+
+2002-03-27 22:36  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/mpulse.c:
+         code cleanup, some optimizations
+
+2002-03-27 21:16  jmvalin
+
+       * trunk/speex/ChangeLog, trunk/speex/INSTALL, trunk/speex/README,
+         trunk/speex/TODO, trunk/speex/libspeex/bits.c,
+         trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/mpulse.c,
+         trunk/speex/libspeex/quant_lsp.c, trunk/speex/libspeex/speex.c,
+         trunk/speex/src/speexdec.c: All debug printf's are now within
+         #ifdef DEBUG
+
+2002-03-27 06:53  jmvalin
+
+       * trunk/speex/libspeex/bits.c, trunk/speex/libspeex/bits.h,
+         trunk/speex/src/speexdec.c, trunk/speex/src/speexenc.c: Added a
+         header to speex files. Should eventually choose a "real" magic
+         number for the format.
+
+2002-03-27 06:30  jmvalin
+
+       * trunk/speex/libspeex/bits.c, trunk/speex/libspeex/bits.h,
+         trunk/speex/src/Makefile.am, trunk/speex/src/speexdec.c,
+         trunk/speex/src/speexenc.c: Think the encoder and decoder work!
+         Still a couple fixes left...
+
+2002-03-27 03:40  jmvalin
+
+       * trunk/speex/libspeex/bits.c, trunk/speex/libspeex/bits.h,
+         trunk/speex/src/speexenc.c: Don't fill the last byte in the frame
+         before saving (saves a couple bits per frame).
+
+2002-03-26 23:56  jmvalin
+
+       * trunk/speex/Makefile.am, trunk/speex/configure.in,
+         trunk/speex/libspeex/modes.c, trunk/speex/libspeex/testdec.c,
+         trunk/speex/src/speexenc.c: ...
+
+2002-03-26 20:48  jmvalin
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/mpulse.c,
+         trunk/speex/libspeex/speex.c, trunk/speex/libspeex/speex.h,
+         trunk/speex/libspeex/testenc_wb.c: Fixed pre-emphasis/de-emphasis
+         in the decoder for wideband (and narrowband). Now both should work
+         (really!)
+
+2002-03-25 20:06  jmvalin
+
+       * trunk/speex/libspeex/mpulse.c: oops...
+
+2002-03-25 19:45  jmvalin
+
+       * trunk/speex/libspeex/testenc.c, trunk/speex/libspeex/testenc_wb.c:
+         Wideband encoding seems to work
+
+2002-03-25 19:38  jmvalin
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/mpulse.c,
+         trunk/speex/libspeex/mpulse.h: Multi-pulse narrowband seem to work
+         (encode+decode). Didn't test the wideband yet.
+
+2002-03-25 15:59  jmvalin
+
+       * trunk/speex/libspeex/modes.c, trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/mpulse.c, trunk/speex/libspeex/mpulse.h,
+         trunk/speex/libspeex/testenc.c, trunk/speex/libspeex/testenc_wb.c:
+         Multi-pulse quantization (not complete yet)
+
+2002-03-22 09:42  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/mpulse.c: Multi-pulse seems to work not too
+         bad (but disabled by default)
+
+2002-03-22 05:03  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/mpulse.c, trunk/speex/libspeex/mpulse.h,
+         trunk/speex/libspeex/speex.c, trunk/speex/libspeex/testenc.c:
+         Modified WB perceptual filter, starting a multi-pulse "branch"
+
+2002-03-20 06:59  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/matrix.c,
+         trunk/speex/libspeex/matrix.h, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/speex.c: Added joint optimization of
+         excitation gains
+
+2002-03-19 07:37  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/exc_gains_wb2_table.c,
+         trunk/speex/libspeex/modes.c, trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/speex.c, trunk/speex/libspeex/speex.h: crappy
+         wideband codec at 28.5 kbps...
+
+2002-03-18 05:25  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/exc_gains_wb_table.c,
+         trunk/speex/libspeex/exc_wb_table.c, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/speex.c: Wideband almost done but buggy...
+
+2002-03-15 23:16  jmvalin
+
+       * trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex.h, trunk/speex/libspeex/testenc_wb.c:
+         Adjustable LPC analysis (lag windowing, noise floor), changed
+         wideband frame size
+
+2002-03-15 19:28  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/quant_lsp.c,
+         trunk/speex/libspeex/quant_lsp.h: wideband coexists with
+         narrowband now
+
+2002-03-15 08:06  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/modes.c:
+         OK, back to normal (narrowband codec works)
+
+2002-03-15 07:30  jmvalin
+
+       * trunk/speex/libspeex/testenc_wb.c: Wideband encorer
+
+2002-03-15 07:30  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/exc_wb_table.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/speex.c: More wideband stuff...
+
+2002-03-15 03:29  jmvalin
+
+       * trunk/speex/libspeex/speex.c, trunk/speex/libspeex/testenc.c:
+         Oops... let's leave a working narrowband codec...
+
+2002-03-15 03:24  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/lsp_tables_wb.c,
+         trunk/speex/libspeex/modes.c, trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/quant_lsp.c,
+         trunk/speex/libspeex/quant_lsp.h, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/testenc.c: We're going wideband...
+
+2002-03-14 19:31  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex.h: Think the modularity stuff is mostly
+         done...
+
+2002-03-14 07:32  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex.h: Cleanup mostly done for the encoder.
+         All functions are now in the mode struct.
+
+2002-03-14 07:08  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/vq.c, trunk/speex/libspeex/vq.h: More cleanup
+         in codebook search...
+
+2002-03-14 03:58  jmvalin
+
+       * trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/ltp.h,
+         trunk/speex/libspeex/modes.c, trunk/speex/libspeex/modes.h,
+         trunk/speex/libspeex/speex.c, trunk/speex/libspeex/speex.h,
+         trunk/speex/libspeex/testenc.c: Cleaning up the code and making it
+         easier to switch algorithms...
+
+2002-03-13 18:28  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/testdec.c:
+         Decoder seems to be working...
+
+2002-03-13 18:06  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/testenc.c: Decoder seems to work
+
+2002-03-13 07:29  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/speex.c: More decoder stuff
+
+2002-03-13 05:08  jmvalin
+
+       * trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/ltp.h,
+         trunk/speex/libspeex/speex.c: Decoding of pitch (still untested)
+
+2002-03-13 02:45  jmvalin
+
+       * trunk/speex/libspeex/bits.c, trunk/speex/libspeex/bits.h,
+         trunk/speex/libspeex/quant_lsp.c, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex.h, trunk/speex/libspeex/testenc.c: More
+         decoder work
+
+2002-03-13 00:31  jmvalin
+
+       * trunk/speex/libspeex/bits.c, trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/quant_lsp.c,
+         trunk/speex/libspeex/quant_lsp.h, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/testenc.c: Code cleanup, removed warnings
+
+2002-03-12 18:47  jmvalin
+
+       * trunk/speex/html/index.html, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex.h: Some decoder stuff, web page update
+
+2002-03-11 19:32  jmvalin
+
+       * trunk/speex/libspeex/bits.c, trunk/speex/libspeex/bits.h,
+         trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/testenc.c: The encoder (testenc) now produces
+         a bitstream
+
+2002-03-11 18:34  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/exc_gains_table.c,
+         trunk/speex/libspeex/exc_table.c, trunk/speex/libspeex/testenc.c:
+         Working demo at 14.5 kbps (fully quantized)
+
+2002-03-08 13:09  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/exc_table.c, trunk/speex/libspeex/speex.c:
+         Working demo...
+
+2002-03-07 21:55  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex.h: The code is getting horribly messy,
+         but there's too much stuff that needs to be added: - Fractional
+         pitch - SNR measurements - Split-codebook search for excitation -
+         ...
+
+2002-03-05 17:02  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/lsp.c,
+         trunk/speex/libspeex/lsp.h, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/quant_lsp.c,
+         trunk/speex/libspeex/quant_lsp.h, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex.h, trunk/speex/libspeex/stack_alloc.h,
+         trunk/speex/libspeex/stoc.c: Big cleanup... filter memories, stack
+         allocation, ...
+
+2002-03-01 20:54  jmvalin
+
+       * trunk/speex/libspeex/speex.c, trunk/speex/libspeex/speex.h: Some
+         early decoder stuff
+
+2002-03-01 15:40  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/bits.c,
+         trunk/speex/libspeex/bits.h, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes.h, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex.h, trunk/speex/libspeex/testenc.c:
+         Integrating the modes and bitstream.
+
+2002-02-28 21:12  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/speex.c: Pitch
+         prediction stuff...
+
+2002-02-28 05:18  jmvalin
+
+       * trunk/speex/libspeex/bits.c, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes.h: Bit manipulations seem to work...
+
+2002-02-28 01:32  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/bits.c,
+         trunk/speex/libspeex/bits.h, trunk/speex/libspeex/modes.c,
+         trunk/speex/libspeex/modes.h: Bit manipulation stuff
+
+2002-02-27 21:50  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex.h: Started the decoder part, I think we
+         now update filters in a better way to take into account the
+         encoding error.
+
+2002-02-27 19:32  jmvalin
+
+       * trunk/speex/configure.in, trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/stack_alloc.h: Added 3-tap pitch predictor by
+         analysis by synthesis
+
+2002-02-27 07:34  jmvalin
+
+       * trunk/speex/libspeex/speex.c: First working demo of the encoder
+         (not fully quantized yet, no fancy pitch prediction, ...)
+
+2002-02-27 07:10  jmvalin
+
+       * trunk/speex/libspeex/speex.c: Looks like W(z)=A(z/.9)/A(z/.5)
+         works now...
+
+2002-02-27 06:44  jmvalin
+
+       * trunk/speex/libspeex/speex.c: For the 1000th time, I think I've
+         figured out the filter memory details for W(z)=A(z/.9)... now
+         let's try W(z)=A(z/.9)/A(z/.5)
+
+2002-02-26 22:19  jmvalin
+
+       * trunk/speex/libspeex/speex.c: oops... buggy again...
+
+2002-02-26 21:35  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/filters.h,
+         trunk/speex/libspeex/speex.c, trunk/speex/libspeex/speex.h: Think
+         the filter stuff works with W(z)=A(z/.9)/A(z/.5)
+
+2002-02-26 21:08  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c, trunk/speex/libspeex/speex.c:
+         This time the filters really work with W(z)=A(z/.9)
+
+2002-02-26 17:29  jmvalin
+
+       * trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex.h: Think I figuring out the filter
+         stuff
+
+2002-02-25 08:46  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am, trunk/speex/libspeex/filters.c,
+         trunk/speex/libspeex/filters.h, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex.h: Fixed algorithmic errors, rewiting
+         the main subframe loop from scratch...
+
+2002-02-19 22:44  jmvalin
+
+       * trunk/speex/libspeex/Makefile.am,
+         trunk/speex/libspeex/cb_search.c,
+         trunk/speex/libspeex/cb_search.h, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/stoc.c: Excitation codebook stuff, but it
+         doesn't work;-(
+
+2002-02-19 17:08  jmvalin
+
+       * trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex.h: Think I figured out the filter
+         memory (ringing) stuff, not too sure though. Added notion of
+         target signal and excitation.
+
+2002-02-19 03:14  jmvalin
+
+       * trunk/speex/configure.in, trunk/speex/libspeex/Makefile.am: Forgot
+         the includes...
+
+2002-02-19 03:07  jmvalin
+
+       * trunk/speex/Makefile.am, trunk/speex/configure.in,
+         trunk/speex/libspeex/Makefile.am: Makefile system seems to work
+
+2002-02-19 02:43  jmvalin
+
+       * trunk/speex/AUTHORS, trunk/speex/COPYING, trunk/speex/ChangeLog,
+         trunk/speex/INSTALL, trunk/speex/NEWS, trunk/speex/README,
+         trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/ltp.h,
+         trunk/speex/libspeex/quant_lsp.c,
+         trunk/speex/libspeex/quant_lsp.h, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex.h: Checking in license stuff
+
+2002-02-19 00:27  jmvalin
+
+       * trunk/speex/libspeex/quant_lsp.h, trunk/speex/libspeex/speex.c:
+         Some more comments
+
+2002-02-18 20:47  jmvalin
+
+       * trunk/speex/libspeex/gain_table.c,
+         trunk/speex/libspeex/lsp_tables_nb.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/quant_lsp.c,
+         trunk/speex/libspeex/quant_lsp.h, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex.h: Added both LSP and prediction gain
+         quantization... the code is a bit ugly but it seems to work. For
+         now we assume a fixed narrowband codebook... Next step: Analysis
+         by synthesis and excitation quantization
+
+2002-02-17 22:54  jmvalin
+
+       * trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/testenc.c: Save synthesized speech in second
+         file
+
+2002-02-17 00:05  jmvalin
+
+       * trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/ltp.h,
+         trunk/speex/libspeex/speex.c: fixed a bug in in-place predictor.
+         Think most of the framework is now in place...
+
+2002-02-16 06:02  jmvalin
+
+       * trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/ltp.h,
+         trunk/speex/libspeex/speex.c: 3-tap pitch predictor seems to work
+
+2002-02-15 20:48  jmvalin
+
+       * trunk/speex/libspeex/ltp.c, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/testenc.c: Implementing a 3-tap long-term
+         predictor. Also changed frame size to 160
+
+2002-02-15 08:14  jmvalin
+
+       * trunk/speex/libspeex/ltp.c: Comments
+
+2002-02-15 07:39  jmvalin
+
+       * trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/ltp.c,
+         trunk/speex/libspeex/ltp.h, trunk/speex/libspeex/speex.c: Added
+         long-term prediction, fixed subframe bugs, maybe not fully
+         debugged
+
+2002-02-15 07:15  jmvalin
+
+       * trunk/speex/libspeex/lsp.c, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex.h, trunk/speex/libspeex/testenc.c:
+         added perceptual weighting filter, bug fixes, fixed warnings
+
+2002-02-15 06:10  jmvalin
+
+       * trunk/speex/libspeex/speex.c, trunk/speex/libspeex/speex.h: Fixed
+         a couple bugs (notably in buffer) and added LSP interpolation
+
+2002-02-15 00:31  jmvalin
+
+       * trunk/speex/libspeex/speex.c, trunk/speex/libspeex/speex.h: Some
+         comments
+
+2002-02-14 23:46  jmvalin
+
+       * trunk/speex/libspeex/speex.c, trunk/speex/libspeex/speex.h: Think
+         I have the LPC->LSP->LPC right this time
+
+2002-02-14 01:57  jmvalin
+
+       * trunk/speex/libspeex/lpc.c, trunk/speex/libspeex/lsp.c,
+         trunk/speex/libspeex/lsp.h, trunk/speex/libspeex/speex.c: Oops...
+         now the LSPs are there. Also, lpcSize now represents the order
+         instead of the filter length (including a[0]=1). Cleaner that way
+         and more like what everybody else is doing.
+
+2002-02-14 01:31  jmvalin
+
+       * trunk/speex/libspeex/lpc.c, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex.h: integrated LSPs
+
+2002-02-14 00:19  jmvalin
+
+       * trunk/speex, trunk/speex/libspeex, trunk/speex/libspeex/lpc.c,
+         trunk/speex/libspeex/lpc.h, trunk/speex/libspeex/speex.c,
+         trunk/speex/libspeex/speex.h, trunk/speex/libspeex/testenc.c:
+         Initial commit, some LPC stuff is already there...
+
diff --git a/utils/iaxclient/lib/libspeex/arch.h b/utils/iaxclient/lib/libspeex/arch.h
new file mode 100644 (file)
index 0000000..d54a40c
--- /dev/null
@@ -0,0 +1,168 @@
+/* Copyright (C) 2003 Jean-Marc Valin */
+/**
+   @file arch.h
+   @brief Various architecture definitions Speex
+*/
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifndef ARCH_H
+#define ARCH_H
+
+#include "speex/speex_types.h"
+
+#define ABS(x) ((x) < 0 ? (-(x)) : (x))
+
+#ifdef FIXED_POINT
+
+typedef spx_int16_t spx_word16_t;
+typedef spx_int32_t   spx_word32_t;
+#ifdef _MSC_VER
+typedef __int64      spx_word64_t;
+#else
+typedef long long    spx_word64_t;
+#endif
+typedef spx_word32_t spx_mem_t;
+typedef spx_word16_t spx_coef_t;
+typedef spx_word16_t spx_lsp_t;
+typedef spx_word32_t spx_sig_t;
+
+#define LPC_SCALING  8192
+#define SIG_SCALING  16384
+#define LSP_SCALING  8192.
+#define GAMMA_SCALING 32768.
+#define GAIN_SCALING 64
+#define GAIN_SCALING_1 0.015625
+
+#define LPC_SHIFT    13
+#define SIG_SHIFT    14
+
+#define VERY_SMALL 0
+
+
+#ifdef ARM5E_ASM
+#include "fixed_arm5e.h"
+#elif defined (ARM4_ASM)
+#include "fixed_arm4.h"
+#elif defined (FIXED_DEBUG)
+#include "fixed_debug.h"
+#else
+#include "fixed_generic.h"
+#endif
+
+
+
+#else
+
+typedef float spx_mem_t;
+typedef float spx_coef_t;
+typedef float spx_lsp_t;
+typedef float spx_sig_t;
+typedef float spx_word16_t;
+typedef float spx_word32_t;
+typedef float spx_word64_t;
+
+#define LPC_SCALING  1.
+#define SIG_SCALING  1.
+#define LSP_SCALING  1.
+#define GAMMA_SCALING 1.
+#define GAIN_SCALING 1.
+#define GAIN_SCALING_1 1.
+
+#define LPC_SHIFT    0
+#define SIG_SHIFT    0
+
+#define VERY_SMALL 1e-15
+
+#define NEG16(x) (-(x))
+#define NEG32(x) (-(x))
+#define EXTRACT16(x) (x)
+#define EXTEND32(x) (x)
+#define SHR16(a,shift) (a)
+#define SHL16(a,shift) (a)
+#define SHR32(a,shift) (a)
+#define SHL32(a,shift) (a)
+#define PSHR16(a,shift) (a)
+#define PSHR32(a,shift) (a)
+#define SATURATE16(x,a) (x)
+#define SATURATE32(x,a) (x)
+
+#define PSHR(a,shift)       (a)
+#define SHR(a,shift)       (a)
+#define SHL(a,shift)       (a)
+#define SATURATE(x,a) (x)
+
+#define ADD16(a,b) ((a)+(b))
+#define SUB16(a,b) ((a)-(b))
+#define ADD32(a,b) ((a)+(b))
+#define SUB32(a,b) ((a)-(b))
+#define ADD64(a,b) ((a)+(b))
+#define MULT16_16_16(a,b)     ((a)*(b))
+#define MULT16_16(a,b)     ((spx_word32_t)(a)*(spx_word32_t)(b))
+#define MAC16_16(c,a,b)     ((c)+(spx_word32_t)(a)*(spx_word32_t)(b))
+
+#define MULT16_32_Q11(a,b)     ((a)*(b))
+#define MULT16_32_Q13(a,b)     ((a)*(b))
+#define MULT16_32_Q14(a,b)     ((a)*(b))
+#define MULT16_32_Q15(a,b)     ((a)*(b))
+
+#define MAC16_32_Q11(c,a,b)     ((c)+(a)*(b))
+#define MAC16_32_Q15(c,a,b)     ((c)+(a)*(b))
+
+#define MAC16_16_Q11(c,a,b)     ((c)+(a)*(b))
+#define MAC16_16_Q13(c,a,b)     ((c)+(a)*(b))
+#define MULT16_16_Q11_32(a,b)     ((a)*(b))
+#define MULT16_16_Q13(a,b)     ((a)*(b))
+#define MULT16_16_Q14(a,b)     ((a)*(b))
+#define MULT16_16_Q15(a,b)     ((a)*(b))
+#define MULT16_16_P15(a,b)     ((a)*(b))
+
+#define DIV32_16(a,b)     ((a)/(b))
+#define DIV32(a,b)     ((a)/(b))
+
+
+#endif
+
+
+#ifdef CONFIG_TI_C55X
+
+/* 2 on TI C5x DSP */
+#define BYTES_PER_CHAR 2 
+#define BITS_PER_CHAR 16
+#define LOG2_BITS_PER_CHAR 4
+
+#else 
+
+#define BYTES_PER_CHAR 1
+#define BITS_PER_CHAR 8
+#define LOG2_BITS_PER_CHAR 3
+
+#endif
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/bits.c b/utils/iaxclient/lib/libspeex/bits.c
new file mode 100644 (file)
index 0000000..4569f14
--- /dev/null
@@ -0,0 +1,360 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: speex_bits.c
+
+   Handles bit packing/unpacking
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <speex/speex_bits.h>
+#include "misc.h"
+
+/** Maximum size of the bit-stream (for fixed-size allocation) */
+#define MAX_BYTES_PER_FRAME (2000/BYTES_PER_CHAR)
+
+void speex_bits_init(SpeexBits *bits)
+{
+   bits->chars = (char*)speex_alloc(MAX_BYTES_PER_FRAME);
+   bits->buf_size = MAX_BYTES_PER_FRAME;
+
+   bits->chars[0]=0;
+   bits->nbBits=0;
+   bits->charPtr=0;
+   bits->bitPtr=0;
+   bits->owner=1;
+   bits->overflow=0;
+}
+
+void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size)
+{
+   bits->chars = (char*)buff;
+   bits->buf_size = buf_size;
+
+   bits->chars[0]=0;
+   bits->nbBits=0;
+   bits->charPtr=0;
+   bits->bitPtr=0;
+   bits->owner=0;
+   bits->overflow=0;
+}
+
+void speex_bits_destroy(SpeexBits *bits)
+{
+   if (bits->owner)
+      speex_free(bits->chars);
+   /* Will do something once the allocation is dynamic */
+}
+
+void speex_bits_reset(SpeexBits *bits)
+{
+   bits->chars[0]=0;
+   bits->nbBits=0;
+   bits->charPtr=0;
+   bits->bitPtr=0;
+   bits->overflow=0;
+}
+
+void speex_bits_rewind(SpeexBits *bits)
+{
+   bits->charPtr=0;
+   bits->bitPtr=0;
+   bits->overflow=0;
+}
+
+void speex_bits_read_from(SpeexBits *bits, char *chars, int len)
+{
+   int i;
+   if (len > bits->buf_size)
+   {
+      speex_warning_int("Packet if larger than allocated buffer: ", len);
+      if (bits->owner)
+      {
+         char *tmp = (char*)speex_realloc(bits->chars, len);
+         if (tmp)
+         {
+            bits->buf_size=len;
+            bits->chars=tmp;
+         } else {
+            len=bits->buf_size;
+            speex_warning("Could not resize input buffer: truncating input");
+         }
+      } else {
+         speex_warning("Do not own input buffer: truncating input");
+         len=bits->buf_size;
+      }
+   }
+   for (i=0;i<len;i++)
+      bits->chars[i]=chars[i];
+   bits->nbBits=len<<3;
+   bits->charPtr=0;
+   bits->bitPtr=0;
+   bits->overflow=0;
+}
+
+static void speex_bits_flush(SpeexBits *bits)
+{
+   int i;
+   int nchars = ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
+   if (bits->charPtr>0)
+   {
+     for (i=bits->charPtr;i<nchars; i++) 
+       bits->chars[i-bits->charPtr]=bits->chars[i];
+   }
+   bits->nbBits -= bits->charPtr<<LOG2_BITS_PER_CHAR;
+   bits->charPtr=0;
+}
+
+void speex_bits_read_whole_bytes(SpeexBits *bits, char *chars, int nbytes)
+{
+   int i,pos;
+   int nchars = nbytes/BYTES_PER_CHAR;
+
+   if (((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR)+nchars > bits->buf_size)
+   {
+      /* Packet is larger than allocated buffer */
+      if (bits->owner)
+      {
+         char *tmp = (char*)speex_realloc(bits->chars, (bits->nbBits>>LOG2_BITS_PER_CHAR)+nchars+1);
+         if (tmp)
+         {
+            bits->buf_size=(bits->nbBits>>LOG2_BITS_PER_CHAR)+nchars+1;
+            bits->chars=tmp;
+         } else {
+            nchars=bits->buf_size-(bits->nbBits>>LOG2_BITS_PER_CHAR)-1;
+            speex_warning("Could not resize input buffer: truncating input");
+         }
+      } else {
+         speex_warning("Do not own input buffer: truncating input");
+         nchars=bits->buf_size;
+      }
+   }
+
+   speex_bits_flush(bits);
+   pos=bits->nbBits>>LOG2_BITS_PER_CHAR;
+   for (i=0;i<nchars;i++)
+      bits->chars[pos+i]=chars[i];
+   bits->nbBits+=nchars<<LOG2_BITS_PER_CHAR;
+}
+
+int speex_bits_write(SpeexBits *bits, char *chars, int max_nbytes)
+{
+   int i;
+   int max_nchars = max_nbytes/BYTES_PER_CHAR;
+   int charPtr, bitPtr, nbBits;
+   
+   /* Insert terminator, but save the data so we can put it back after */
+   bitPtr=bits->bitPtr;
+   charPtr=bits->charPtr;
+   nbBits=bits->nbBits;
+   speex_bits_insert_terminator(bits);
+   bits->bitPtr=bitPtr;
+   bits->charPtr=charPtr;
+   bits->nbBits=nbBits;
+
+   if (max_nchars > ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR))
+      max_nchars = ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
+#if BYTES_PER_CHAR==1
+#define HTOLS(A) (A)
+#else
+#define HTOLS(A) ((((A) >> 8)&0xff)|(((A) & 0xff)<<8))
+#endif
+   for (i=0;i<max_nchars;i++)
+      chars[i]=HTOLS(bits->chars[i]);
+   return max_nchars*BYTES_PER_CHAR;
+}
+
+int speex_bits_write_whole_bytes(SpeexBits *bits, char *chars, int max_nbytes)
+{
+   int max_nchars = max_nbytes/BYTES_PER_CHAR;
+   int i;
+   if (max_nchars > ((bits->nbBits)>>LOG2_BITS_PER_CHAR))
+      max_nchars = ((bits->nbBits)>>LOG2_BITS_PER_CHAR);
+   for (i=0;i<max_nchars;i++)
+      chars[i]=bits->chars[i];
+   
+   if (bits->bitPtr>0)
+      bits->chars[0]=bits->chars[max_nchars];
+   else
+      bits->chars[0]=0;
+   for (i=1;i<((bits->nbBits)>>LOG2_BITS_PER_CHAR)+1;i++)
+      bits->chars[i]=0;
+   bits->charPtr=0;
+   bits->nbBits &= (BITS_PER_CHAR-1);
+   return max_nchars*BYTES_PER_CHAR;
+}
+
+void speex_bits_pack(SpeexBits *bits, int data, int nbBits)
+{
+   unsigned int d=data;
+
+   if (bits->charPtr+((nbBits+bits->bitPtr)>>LOG2_BITS_PER_CHAR) >= bits->buf_size)
+   {
+      speex_warning("Buffer too small to pack bits");
+      if (bits->owner)
+      {
+       int new_nchars = ((bits->buf_size+5)*3)>>1;
+         char *tmp = (char*)speex_realloc(bits->chars, new_nchars);
+         if (tmp)
+         {
+           speex_memset_bytes(tmp, 0, new_nchars);
+            bits->buf_size=new_nchars;
+            bits->chars=tmp;
+         } else {
+            speex_warning("Could not resize input buffer: not packing");
+            return;
+         }
+      } else {
+         speex_warning("Do not own input buffer: not packing");
+         return;
+      }
+   }
+
+   while(nbBits)
+   {
+      int bit;
+      bit = (d>>(nbBits-1))&1;
+      bits->chars[bits->charPtr] |= bit<<(7-bits->bitPtr);
+      bits->bitPtr++;
+
+      if (bits->bitPtr==8)
+      {
+         bits->bitPtr=0;
+         bits->charPtr++;
+         bits->chars[bits->charPtr] = 0;
+      }
+      bits->nbBits++;
+      nbBits--;
+   }
+}
+
+int speex_bits_unpack_signed(SpeexBits *bits, int nbBits)
+{
+   unsigned int d=speex_bits_unpack_unsigned(bits,nbBits);
+   /* If number is negative */
+   if (d>>(nbBits-1))
+   {
+      d |= (-1)<<nbBits;
+   }
+   return d;
+}
+
+unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits)
+{
+   unsigned int d=0;
+   if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+nbBits>bits->nbBits)
+      bits->overflow=1;
+   if (bits->overflow)
+      return 0;
+   while(nbBits)
+   {
+      d<<=1;
+      d |= (bits->chars[bits->charPtr]>>(BITS_PER_CHAR-1 - bits->bitPtr))&1;
+      bits->bitPtr++;
+      if (bits->bitPtr==BITS_PER_CHAR)
+      {
+         bits->bitPtr=0;
+         bits->charPtr++;
+      }
+      nbBits--;
+   }
+   return d;
+}
+
+unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits)
+{
+   unsigned int d=0;
+   int bitPtr, charPtr;
+   char *chars;
+
+   if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+nbBits>bits->nbBits)
+     bits->overflow=1;
+   if (bits->overflow)
+      return 0;
+
+   bitPtr=bits->bitPtr;
+   charPtr=bits->charPtr;
+   chars = bits->chars;
+   while(nbBits)
+   {
+      d<<=1;
+      d |= (chars[charPtr]>>(BITS_PER_CHAR-1 - bitPtr))&1;
+      bitPtr++;
+      if (bitPtr==BITS_PER_CHAR)
+      {
+         bitPtr=0;
+         charPtr++;
+      }
+      nbBits--;
+   }
+   return d;
+}
+
+int speex_bits_peek(SpeexBits *bits)
+{
+   if ((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+1>bits->nbBits)
+      bits->overflow=1;
+   if (bits->overflow)
+      return 0;
+   return (bits->chars[bits->charPtr]>>(BITS_PER_CHAR-1 - bits->bitPtr))&1;
+}
+
+void speex_bits_advance(SpeexBits *bits, int n)
+{
+    if (((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr+n>bits->nbBits) || bits->overflow){
+      bits->overflow=1;
+      return;
+    }
+   bits->charPtr += (bits->bitPtr+n) >> LOG2_BITS_PER_CHAR; /* divide by BITS_PER_CHAR */
+   bits->bitPtr = (bits->bitPtr+n) & (BITS_PER_CHAR-1);       /* modulo by BITS_PER_CHAR */
+}
+
+int speex_bits_remaining(SpeexBits *bits)
+{
+   if (bits->overflow)
+      return -1;
+   else
+      return bits->nbBits-((bits->charPtr<<LOG2_BITS_PER_CHAR)+bits->bitPtr);
+}
+
+int speex_bits_nbytes(SpeexBits *bits)
+{
+   return ((bits->nbBits+BITS_PER_CHAR-1)>>LOG2_BITS_PER_CHAR);
+}
+
+void speex_bits_insert_terminator(SpeexBits *bits)
+{
+   if (bits->bitPtr<BITS_PER_CHAR-1)
+      speex_bits_pack(bits, 0, 1);
+   while (bits->bitPtr<BITS_PER_CHAR-1)
+      speex_bits_pack(bits, 1, 1);
+}
diff --git a/utils/iaxclient/lib/libspeex/cb_search.c b/utils/iaxclient/lib/libspeex/cb_search.c
new file mode 100644 (file)
index 0000000..de05f1d
--- /dev/null
@@ -0,0 +1,626 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: cb_search.c
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "cb_search.h"
+#include "filters.h"
+#include "stack_alloc.h"
+#include "vq.h"
+#include "misc.h"
+
+#ifdef _USE_SSE
+#include "cb_search_sse.h"
+#elif defined(ARM4_ASM) || defined(ARM5E_ASM)
+#include "cb_search_arm4.h"
+#else
+
+static void compute_weighted_codebook(const signed char *shape_cb, const spx_word16_t *r, spx_word16_t *resp, spx_word16_t *resp2, spx_word32_t *E, int shape_cb_size, int subvect_size, char *stack)
+{
+   int i, j, k;
+   VARDECL(spx_word16_t *shape);
+   ALLOC(shape, subvect_size, spx_word16_t);
+   for (i=0;i<shape_cb_size;i++)
+   {
+      spx_word16_t *res;
+      
+      res = resp+i*subvect_size;
+      for (k=0;k<subvect_size;k++)
+         shape[k] = (spx_word16_t)shape_cb[i*subvect_size+k];
+      E[i]=0;
+
+      /* Compute codeword response using convolution with impulse response */
+      for(j=0;j<subvect_size;j++)
+      {
+         spx_word32_t resj=0;
+         spx_word16_t res16;
+         for (k=0;k<=j;k++)
+            resj = MAC16_16(resj,shape[k],r[j-k]);
+#ifdef FIXED_POINT
+         res16 = EXTRACT16(SHR32(resj, 11));
+#else
+         res16 = 0.03125f*resj;
+#endif
+         /* Compute codeword energy */
+         E[i]=MAC16_16(E[i],res16,res16);
+         res[j] = res16;
+         /*printf ("%d\n", (int)res[j]);*/
+      }
+   }
+
+}
+
+#endif
+
+
+
+static void split_cb_search_shape_sign_N1(
+spx_sig_t target[],                    /* target vector */
+spx_coef_t ak[],                       /* LPCs for this subframe */
+spx_coef_t awk1[],                     /* Weighted LPCs for this subframe */
+spx_coef_t awk2[],                     /* Weighted LPCs for this subframe */
+const void *par,                      /* Codebook/search parameters*/
+int   p,                        /* number of LPC coeffs */
+int   nsf,                      /* number of samples in subframe */
+spx_sig_t *exc,
+spx_word16_t *r,
+SpeexBits *bits,
+char *stack,
+int   complexity,
+int   update_target
+)
+{
+   int i,j,m,n,q;
+   VARDECL(spx_word16_t *resp);
+#ifdef _USE_SSE
+   VARDECL(__m128 *resp2);
+   VARDECL(__m128 *E);
+#else
+   spx_word16_t *resp2;
+   VARDECL(spx_word32_t *E);
+#endif
+   VARDECL(spx_word16_t *t);
+   VARDECL(spx_sig_t *e);
+   const signed char *shape_cb;
+   int shape_cb_size, subvect_size, nb_subvect;
+   const split_cb_params *params;
+   int N=2;
+   int best_index;
+   spx_word32_t best_dist;
+   int have_sign;
+   N=complexity;
+   if (N>10)
+      N=10;
+   if (N<1)
+      N=1;
+   
+   params = (const split_cb_params *) par;
+   subvect_size = params->subvect_size;
+   nb_subvect = params->nb_subvect;
+   shape_cb_size = 1<<params->shape_bits;
+   shape_cb = params->shape_cb;
+   have_sign = params->have_sign;
+   ALLOC(resp, shape_cb_size*subvect_size, spx_word16_t);
+#ifdef _USE_SSE
+   ALLOC(resp2, (shape_cb_size*subvect_size)>>2, __m128);
+   ALLOC(E, shape_cb_size>>2, __m128);
+#else
+   resp2 = resp;
+   ALLOC(E, shape_cb_size, spx_word32_t);
+#endif
+   ALLOC(t, nsf, spx_word16_t);
+   ALLOC(e, nsf, spx_sig_t);
+   
+   /* FIXME: make that adaptive? */
+   for (i=0;i<nsf;i++)
+      t[i]=EXTRACT16(PSHR32(target[i],6));
+
+   compute_weighted_codebook(shape_cb, r, resp, resp2, E, shape_cb_size, subvect_size, stack);
+
+   for (i=0;i<nb_subvect;i++)
+   {
+      spx_word16_t *x=t+subvect_size*i;
+      /*Find new n-best based on previous n-best j*/
+      if (have_sign)
+         vq_nbest_sign(x, resp2, subvect_size, shape_cb_size, E, 1, &best_index, &best_dist, stack);
+      else
+         vq_nbest(x, resp2, subvect_size, shape_cb_size, E, 1, &best_index, &best_dist, stack);
+      
+      speex_bits_pack(bits,best_index,params->shape_bits+have_sign);
+      
+      {
+         int rind;
+         spx_word16_t *res;
+         spx_word16_t sign=1;
+         rind = best_index;
+         if (rind>=shape_cb_size)
+         {
+            sign=-1;
+            rind-=shape_cb_size;
+         }
+         res = resp+rind*subvect_size;
+         if (sign>0)
+            for (m=0;m<subvect_size;m++)
+               t[subvect_size*i+m] = SUB16(t[subvect_size*i+m], res[m]);
+         else
+            for (m=0;m<subvect_size;m++)
+               t[subvect_size*i+m] = ADD16(t[subvect_size*i+m], res[m]);
+
+#ifdef FIXED_POINT
+         if (sign)
+         {
+            for (j=0;j<subvect_size;j++)
+               e[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5);
+         } else {
+            for (j=0;j<subvect_size;j++)
+               e[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5));
+         }
+#else
+         for (j=0;j<subvect_size;j++)
+            e[subvect_size*i+j]=sign*0.03125*shape_cb[rind*subvect_size+j];
+#endif
+      
+      }
+            
+      for (m=0;m<subvect_size;m++)
+      {
+         spx_word16_t g;
+         int rind;
+         spx_word16_t sign=1;
+         rind = best_index;
+         if (rind>=shape_cb_size)
+         {
+            sign=-1;
+            rind-=shape_cb_size;
+         }
+         
+         q=subvect_size-m;
+#ifdef FIXED_POINT
+         g=sign*shape_cb[rind*subvect_size+m];
+         for (n=subvect_size*(i+1);n<nsf;n++,q++)
+            t[n] = SUB32(t[n],MULT16_16_Q11_32(g,r[q]));
+#else
+         g=sign*0.03125*shape_cb[rind*subvect_size+m];
+         for (n=subvect_size*(i+1);n<nsf;n++,q++)
+            t[n] = SUB32(t[n],g*r[q]);
+#endif
+      }
+   }
+
+   /* Update excitation */
+   /* FIXME: We could update the excitation directly above */
+   for (j=0;j<nsf;j++)
+      exc[j]=ADD32(exc[j],e[j]);
+   
+   /* Update target: only update target if necessary */
+   if (update_target)
+   {
+      VARDECL(spx_sig_t *r2);
+      ALLOC(r2, nsf, spx_sig_t);
+      syn_percep_zero(e, ak, awk1, awk2, r2, nsf,p, stack);
+      for (j=0;j<nsf;j++)
+         target[j]=SUB32(target[j],r2[j]);
+   }
+}
+
+
+
+void split_cb_search_shape_sign(
+spx_sig_t target[],                    /* target vector */
+spx_coef_t ak[],                       /* LPCs for this subframe */
+spx_coef_t awk1[],                     /* Weighted LPCs for this subframe */
+spx_coef_t awk2[],                     /* Weighted LPCs for this subframe */
+const void *par,                      /* Codebook/search parameters*/
+int   p,                        /* number of LPC coeffs */
+int   nsf,                      /* number of samples in subframe */
+spx_sig_t *exc,
+spx_word16_t *r,
+SpeexBits *bits,
+char *stack,
+int   complexity,
+int   update_target
+)
+{
+   int i,j,k,m,n,q;
+   VARDECL(spx_word16_t *resp);
+#ifdef _USE_SSE
+   VARDECL(__m128 *resp2);
+   VARDECL(__m128 *E);
+#else
+   spx_word16_t *resp2;
+   VARDECL(spx_word32_t *E);
+#endif
+   VARDECL(spx_word16_t *t);
+   VARDECL(spx_sig_t *e);
+   VARDECL(spx_sig_t *r2);
+   VARDECL(spx_word16_t *tmp);
+   VARDECL(spx_word32_t *ndist);
+   VARDECL(spx_word32_t *odist);
+   VARDECL(int *itmp);
+   VARDECL(spx_word16_t **ot2);
+   VARDECL(spx_word16_t **nt2);
+   spx_word16_t **ot, **nt;
+   VARDECL(int **nind);
+   VARDECL(int **oind);
+   VARDECL(int *ind);
+   const signed char *shape_cb;
+   int shape_cb_size, subvect_size, nb_subvect;
+   const split_cb_params *params;
+   int N=2;
+   VARDECL(int *best_index);
+   VARDECL(spx_word32_t *best_dist);
+   int have_sign;
+   N=complexity;
+   if (N>10)
+      N=10;
+   if (N<1)
+      N=1;
+   
+   if (N==1)
+   {
+      split_cb_search_shape_sign_N1(target,ak,awk1,awk2,par,p,nsf,exc,r,bits,stack,complexity,update_target);
+      return;
+   }
+   ALLOC(ot2, N, spx_word16_t*);
+   ALLOC(nt2, N, spx_word16_t*);
+   ALLOC(oind, N, int*);
+   ALLOC(nind, N, int*);
+
+   params = (const split_cb_params *) par;
+   subvect_size = params->subvect_size;
+   nb_subvect = params->nb_subvect;
+   shape_cb_size = 1<<params->shape_bits;
+   shape_cb = params->shape_cb;
+   have_sign = params->have_sign;
+   ALLOC(resp, shape_cb_size*subvect_size, spx_word16_t);
+#ifdef _USE_SSE
+   ALLOC(resp2, (shape_cb_size*subvect_size)>>2, __m128);
+   ALLOC(E, shape_cb_size>>2, __m128);
+#else
+   resp2 = resp;
+   ALLOC(E, shape_cb_size, spx_word32_t);
+#endif
+   ALLOC(t, nsf, spx_word16_t);
+   ALLOC(e, nsf, spx_sig_t);
+   ALLOC(r2, nsf, spx_sig_t);
+   ALLOC(ind, nb_subvect, int);
+
+   ALLOC(tmp, 2*N*nsf, spx_word16_t);
+   for (i=0;i<N;i++)
+   {
+      ot2[i]=tmp+2*i*nsf;
+      nt2[i]=tmp+(2*i+1)*nsf;
+   }
+   ot=ot2;
+   nt=nt2;
+   ALLOC(best_index, N, int);
+   ALLOC(best_dist, N, spx_word32_t);
+   ALLOC(ndist, N, spx_word32_t);
+   ALLOC(odist, N, spx_word32_t);
+   
+   ALLOC(itmp, 2*N*nb_subvect, int);
+   for (i=0;i<N;i++)
+   {
+      nind[i]=itmp+2*i*nb_subvect;
+      oind[i]=itmp+(2*i+1)*nb_subvect;
+      for (j=0;j<nb_subvect;j++)
+         nind[i][j]=oind[i][j]=-1;
+   }
+   
+   /* FIXME: make that adaptive? */
+   for (i=0;i<nsf;i++)
+      t[i]=EXTRACT16(PSHR32(target[i],6));
+
+   for (j=0;j<N;j++)
+      for (i=0;i<nsf;i++)
+         ot[j][i]=t[i];
+
+   /*for (i=0;i<nsf;i++)
+     printf ("%d\n", (int)t[i]);*/
+
+   /* Pre-compute codewords response and energy */
+   compute_weighted_codebook(shape_cb, r, resp, resp2, E, shape_cb_size, subvect_size, stack);
+
+   for (j=0;j<N;j++)
+      odist[j]=0;
+   /*For all subvectors*/
+   for (i=0;i<nb_subvect;i++)
+   {
+      /*"erase" nbest list*/
+      for (j=0;j<N;j++)
+         ndist[j]=-2;
+
+      /*For all n-bests of previous subvector*/
+      for (j=0;j<N;j++)
+      {
+         spx_word16_t *x=ot[j]+subvect_size*i;
+         /*Find new n-best based on previous n-best j*/
+         if (have_sign)
+            vq_nbest_sign(x, resp2, subvect_size, shape_cb_size, E, N, best_index, best_dist, stack);
+         else
+            vq_nbest(x, resp2, subvect_size, shape_cb_size, E, N, best_index, best_dist, stack);
+
+         /*For all new n-bests*/
+         for (k=0;k<N;k++)
+         {
+            spx_word16_t *ct;
+            spx_word32_t err=0;
+            ct = ot[j];
+            /*update target*/
+
+            /*previous target*/
+            for (m=i*subvect_size;m<(i+1)*subvect_size;m++)
+               t[m]=ct[m];
+
+            /* New code: update only enough of the target to calculate error*/
+            {
+               int rind;
+               spx_word16_t *res;
+               spx_word16_t sign=1;
+               rind = best_index[k];
+               if (rind>=shape_cb_size)
+               {
+                  sign=-1;
+                  rind-=shape_cb_size;
+               }
+               res = resp+rind*subvect_size;
+               if (sign>0)
+                  for (m=0;m<subvect_size;m++)
+                     t[subvect_size*i+m] = SUB16(t[subvect_size*i+m], res[m]);
+               else
+                  for (m=0;m<subvect_size;m++)
+                     t[subvect_size*i+m] = ADD16(t[subvect_size*i+m], res[m]);
+            }
+            
+            /*compute error (distance)*/
+            err=odist[j];
+            for (m=i*subvect_size;m<(i+1)*subvect_size;m++)
+               err = MAC16_16(err, t[m],t[m]);
+            /*update n-best list*/
+            if (err<ndist[N-1] || ndist[N-1]<-1)
+            {
+
+               /*previous target (we don't care what happened before*/
+               for (m=(i+1)*subvect_size;m<nsf;m++)
+                  t[m]=ct[m];
+               /* New code: update the rest of the target only if it's worth it */
+               for (m=0;m<subvect_size;m++)
+               {
+                  spx_word16_t g;
+                  int rind;
+                  spx_word16_t sign=1;
+                  rind = best_index[k];
+                  if (rind>=shape_cb_size)
+                  {
+                     sign=-1;
+                     rind-=shape_cb_size;
+                  }
+
+                  q=subvect_size-m;
+#ifdef FIXED_POINT
+                  g=sign*shape_cb[rind*subvect_size+m];
+                  for (n=subvect_size*(i+1);n<nsf;n++,q++)
+                     t[n] = SUB32(t[n],MULT16_16_Q11_32(g,r[q]));
+#else
+                  g=sign*0.03125*shape_cb[rind*subvect_size+m];
+                  for (n=subvect_size*(i+1);n<nsf;n++,q++)
+                     t[n] = SUB32(t[n],g*r[q]);
+#endif
+               }
+
+
+               for (m=0;m<N;m++)
+               {
+                  if (err < ndist[m] || ndist[m]<-1)
+                  {
+                     for (n=N-1;n>m;n--)
+                     {
+                        for (q=(i+1)*subvect_size;q<nsf;q++)
+                           nt[n][q]=nt[n-1][q];
+                        for (q=0;q<nb_subvect;q++)
+                           nind[n][q]=nind[n-1][q];
+                        ndist[n]=ndist[n-1];
+                     }
+                     for (q=(i+1)*subvect_size;q<nsf;q++)
+                        nt[m][q]=t[q];
+                     for (q=0;q<nb_subvect;q++)
+                        nind[m][q]=oind[j][q];
+                     nind[m][i]=best_index[k];
+                     ndist[m]=err;
+                     break;
+                  }
+               }
+            }
+         }
+         if (i==0)
+           break;
+      }
+
+      /*update old-new data*/
+      /* just swap pointers instead of a long copy */
+      {
+         spx_word16_t **tmp2;
+         tmp2=ot;
+         ot=nt;
+         nt=tmp2;
+      }
+      for (j=0;j<N;j++)
+         for (m=0;m<nb_subvect;m++)
+            oind[j][m]=nind[j][m];
+      for (j=0;j<N;j++)
+         odist[j]=ndist[j];
+   }
+
+   /*save indices*/
+   for (i=0;i<nb_subvect;i++)
+   {
+      ind[i]=nind[0][i];
+      speex_bits_pack(bits,ind[i],params->shape_bits+have_sign);
+   }
+   
+   /* Put everything back together */
+   for (i=0;i<nb_subvect;i++)
+   {
+      int rind;
+      spx_word16_t sign=1;
+      rind = ind[i];
+      if (rind>=shape_cb_size)
+      {
+         sign=-1;
+         rind-=shape_cb_size;
+      }
+#ifdef FIXED_POINT
+      if (sign==1)
+      {
+         for (j=0;j<subvect_size;j++)
+            e[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5);
+      } else {
+         for (j=0;j<subvect_size;j++)
+            e[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[rind*subvect_size+j]),SIG_SHIFT-5));
+      }
+#else
+      for (j=0;j<subvect_size;j++)
+         e[subvect_size*i+j]=sign*0.03125*shape_cb[rind*subvect_size+j];
+#endif
+   }   
+   /* Update excitation */
+   for (j=0;j<nsf;j++)
+      exc[j]=ADD32(exc[j],e[j]);
+   
+   /* Update target: only update target if necessary */
+   if (update_target)
+   {
+      syn_percep_zero(e, ak, awk1, awk2, r2, nsf,p, stack);
+      for (j=0;j<nsf;j++)
+         target[j]=SUB32(target[j],r2[j]);
+   }
+}
+
+
+void split_cb_shape_sign_unquant(
+spx_sig_t *exc,
+const void *par,                      /* non-overlapping codebook */
+int   nsf,                      /* number of samples in subframe */
+SpeexBits *bits,
+char *stack
+)
+{
+   int i,j;
+   VARDECL(int *ind);
+   VARDECL(int *signs);
+   const signed char *shape_cb;
+   //int shape_cb_size;
+   int subvect_size, nb_subvect;
+   const split_cb_params *params;
+   int have_sign;
+
+   params = (const split_cb_params *) par;
+   subvect_size = params->subvect_size;
+   nb_subvect = params->nb_subvect;
+   //shape_cb_size = 1<<params->shape_bits;
+   shape_cb = params->shape_cb;
+   have_sign = params->have_sign;
+
+   ALLOC(ind, nb_subvect, int);
+   ALLOC(signs, nb_subvect, int);
+
+   /* Decode codewords and gains */
+   for (i=0;i<nb_subvect;i++)
+   {
+      if (have_sign)
+         signs[i] = speex_bits_unpack_unsigned(bits, 1);
+      else
+         signs[i] = 0;
+      ind[i] = speex_bits_unpack_unsigned(bits, params->shape_bits);
+   }
+   /* Compute decoded excitation */
+   for (i=0;i<nb_subvect;i++)
+   {
+      spx_word16_t s=1;
+      if (signs[i])
+         s=-1;
+#ifdef FIXED_POINT
+      if (s==1)
+      {
+         for (j=0;j<subvect_size;j++)
+            exc[subvect_size*i+j]=SHL32(EXTEND32(shape_cb[ind[i]*subvect_size+j]),SIG_SHIFT-5);
+      } else {
+         for (j=0;j<subvect_size;j++)
+            exc[subvect_size*i+j]=NEG32(SHL32(EXTEND32(shape_cb[ind[i]*subvect_size+j]),SIG_SHIFT-5));
+      }
+#else
+      for (j=0;j<subvect_size;j++)
+         exc[subvect_size*i+j]+=s*0.03125*shape_cb[ind[i]*subvect_size+j];      
+#endif
+   }
+}
+
+void noise_codebook_quant(
+spx_sig_t target[],                    /* target vector */
+spx_coef_t ak[],                       /* LPCs for this subframe */
+spx_coef_t awk1[],                     /* Weighted LPCs for this subframe */
+spx_coef_t awk2[],                     /* Weighted LPCs for this subframe */
+const void *par,                      /* Codebook/search parameters*/
+int   p,                        /* number of LPC coeffs */
+int   nsf,                      /* number of samples in subframe */
+spx_sig_t *exc,
+spx_word16_t *r,
+SpeexBits *bits,
+char *stack,
+int   complexity,
+int   update_target
+)
+{
+   int i;
+   VARDECL(spx_sig_t *tmp);
+   ALLOC(tmp, nsf, spx_sig_t);
+   residue_percep_zero(target, ak, awk1, awk2, tmp, nsf, p, stack);
+
+   for (i=0;i<nsf;i++)
+      exc[i]+=tmp[i];
+   for (i=0;i<nsf;i++)
+      target[i]=0;
+
+}
+
+
+void noise_codebook_unquant(
+spx_sig_t *exc,
+const void *par,                      /* non-overlapping codebook */
+int   nsf,                      /* number of samples in subframe */
+SpeexBits *bits,
+char *stack
+)
+{
+   speex_rand_vec(1, exc, nsf);
+}
diff --git a/utils/iaxclient/lib/libspeex/cb_search.h b/utils/iaxclient/lib/libspeex/cb_search.h
new file mode 100644 (file)
index 0000000..107d5ef
--- /dev/null
@@ -0,0 +1,98 @@
+/* Copyright (C) 2002 Jean-Marc Valin & David Rowe
+   File: cb_search.h
+   Overlapped codebook search
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifndef CB_SEARCH_H
+#define CB_SEARCH_H
+
+#include <speex/speex_bits.h>
+#include "misc.h"
+
+typedef struct split_cb_params {
+   int     subvect_size;
+   int     nb_subvect;
+   const signed char  *shape_cb;
+   int     shape_bits;
+   int     have_sign;
+} split_cb_params;
+
+
+void split_cb_search_shape_sign(
+spx_sig_t target[],                    /* target vector */
+spx_coef_t ak[],                       /* LPCs for this subframe */
+spx_coef_t awk1[],                     /* Weighted LPCs for this subframe */
+spx_coef_t awk2[],                     /* Weighted LPCs for this subframe */
+const void *par,                      /* Codebook/search parameters*/
+int   p,                        /* number of LPC coeffs */
+int   nsf,                      /* number of samples in subframe */
+spx_sig_t *exc,
+spx_word16_t *r,
+SpeexBits *bits,
+char *stack,
+int   complexity,
+int   update_target
+);
+
+void split_cb_shape_sign_unquant(
+spx_sig_t *exc,
+const void *par,                      /* non-overlapping codebook */
+int   nsf,                      /* number of samples in subframe */
+SpeexBits *bits,
+char *stack
+);
+
+
+void noise_codebook_quant(
+spx_sig_t target[],                    /* target vector */
+spx_coef_t ak[],                       /* LPCs for this subframe */
+spx_coef_t awk1[],                     /* Weighted LPCs for this subframe */
+spx_coef_t awk2[],                     /* Weighted LPCs for this subframe */
+const void *par,                      /* Codebook/search parameters*/
+int   p,                        /* number of LPC coeffs */
+int   nsf,                      /* number of samples in subframe */
+spx_sig_t *exc,
+spx_word16_t *r,
+SpeexBits *bits,
+char *stack,
+int   complexity,
+int   update_target
+);
+
+
+void noise_codebook_unquant(
+spx_sig_t *exc,
+const void *par,                      /* non-overlapping codebook */
+int   nsf,                      /* number of samples in subframe */
+SpeexBits *bits,
+char *stack
+);
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/cb_search_arm4.h b/utils/iaxclient/lib/libspeex/cb_search_arm4.h
new file mode 100644 (file)
index 0000000..2452a5c
--- /dev/null
@@ -0,0 +1,129 @@
+/* Copyright (C) 2004 Jean-Marc Valin 
+   File: cb_search.c (ARM4 version)
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+static void compute_weighted_codebook(const signed char *shape_cb, const spx_sig_t *r, spx_word16_t *resp, spx_word16_t *resp2, spx_word32_t *E, int shape_cb_size, int subvect_size, char *stack)
+{
+   int i, j, k;
+  //const signed char *shape;
+   for (i=0;i<shape_cb_size;i+=4)
+   {
+
+      //shape = shape_cb;
+      E[0]=0;
+      E[1]=0;
+      E[2]=0;
+      E[3]=0;
+
+      /* Compute codeword response using convolution with impulse response */
+      for(j=0;j<subvect_size;j++)
+      {
+#if 1
+          spx_word16_t *res;
+          res = resp+j;
+          spx_word32_t resj0,resj1,resj2,resj3;
+          spx_word32_t dead1, dead2, dead3, dead4, dead5, dead6, dead7, dead8;
+          __asm__ __volatile__ (
+                "mov %0, #0 \n\t"
+                "mov %1, #0 \n\t"
+                "mov %2, #0 \n\t"
+                "mov %3, #0 \n\t"
+                ".weighted%=: \n\t"
+                "ldrsb %8, [%6] \n\t"
+                "ldr %10, [%5], #-4 \n\t"
+                "mov %9, %6 \n\t"
+                "ldrsb %11, [%9, %7]! \n\t"
+                "mla %0, %10, %8, %0 \n\t"
+                "ldrsb %8, [%9, %7]! \n\t"
+                "mla %1, %10, %11, %1 \n\t"
+                "ldrsb %11, [%9, %7]! \n\t"
+                "mla %2, %10, %8, %2 \n\t"
+                "subs %4, %4, #1 \n\t"
+                "mla %3, %10, %11, %3 \n\t"
+                "add %6, %6, #1 \n\t"
+                "bne .weighted%= \n\t"
+            : "=r" (resj0), "=r" (resj1), "=r" (resj2), "=r" (resj3),
+          "=r" (dead1), "=r" (dead2), "=r" (dead3), "=r" (dead4),
+          "=r" (dead5), "=r" (dead6), "=r" (dead7), "=r" (dead8)
+            : "4" (j+1), "5" (r+j), "6" (shape_cb), "7" (subvect_size)
+            : "cc", "memory");
+#else
+          spx_word16_t *res;
+          res = resp+j;
+          spx_word32_t resj0=0;
+          spx_word32_t resj1=0;
+          spx_word32_t resj2=0;
+          spx_word32_t resj3=0;
+          for (k=0;k<=j;k++)
+          {
+             const signed char *shape=shape_cb+k;
+             resj0 = MAC16_16(resj0,*shape,r[j-k]);
+             shape += subvect_size;
+             resj1 = MAC16_16(resj1,*shape,r[j-k]);
+             shape += subvect_size;
+             resj2 = MAC16_16(resj2,*shape,r[j-k]);
+             shape += subvect_size;
+             resj3 = MAC16_16(resj3,*shape,r[j-k]);
+             shape += subvect_size;
+          }
+#endif
+
+#ifdef FIXED_POINT
+          resj0 = SHR(resj0, 11);
+          resj1 = SHR(resj1, 11);
+          resj2 = SHR(resj2, 11);
+          resj3 = SHR(resj3, 11);
+#else
+          resj0 *= 0.03125;
+          resj1 *= 0.03125;
+          resj2 *= 0.03125;
+          resj3 *= 0.03125;
+#endif
+
+          /* Compute codeword energy */
+          E[0]=ADD32(E[0],MULT16_16(resj0,resj0));
+          E[1]=ADD32(E[1],MULT16_16(resj1,resj1));
+          E[2]=ADD32(E[2],MULT16_16(resj2,resj2));
+          E[3]=ADD32(E[3],MULT16_16(resj3,resj3));
+          *res = resj0;
+          res += subvect_size;
+          *res = resj1;
+          res += subvect_size;
+          *res = resj2;
+          res += subvect_size;
+          *res = resj3;
+          res += subvect_size;
+      }
+      resp += subvect_size<<2;
+      shape_cb += subvect_size<<2;
+      E+=4;
+   }
+
+}
diff --git a/utils/iaxclient/lib/libspeex/cb_search_sse.h b/utils/iaxclient/lib/libspeex/cb_search_sse.h
new file mode 100644 (file)
index 0000000..5875a58
--- /dev/null
@@ -0,0 +1,81 @@
+/* Copyright (C) 2004 Jean-Marc Valin 
+   File: cb_search.c (SSE version)
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <xmmintrin.h>
+
+static inline void _spx_mm_getr_ps (__m128 U, float *__Z, float *__Y, float *__X, float *__W)
+{
+  union {
+    float __a[4];
+    __m128 __v;
+  } __u;
+  
+  __u.__v = U;
+
+  *__Z = __u.__a[0];
+  *__Y = __u.__a[1];
+  *__X = __u.__a[2];
+  *__W = __u.__a[3];
+
+}
+
+
+static void compute_weighted_codebook(const signed char *shape_cb, const spx_sig_t *_r, float *resp, __m128 *resp2, __m128 *E, int shape_cb_size, int subvect_size, char *stack)
+{
+   int i, j, k;
+   __m128 resj, EE;
+   VARDECL(__m128 *r);
+   VARDECL(__m128 *shape);
+   ALLOC(r, subvect_size, __m128);
+   ALLOC(shape, subvect_size, __m128);
+   for(j=0;j<subvect_size;j++)
+      r[j] = _mm_load_ps1(_r+j);
+   for (i=0;i<shape_cb_size;i+=4)
+   {
+      float *_res = resp+i*subvect_size;
+      const signed char *_shape = shape_cb+i*subvect_size;
+      EE = _mm_setzero_ps();
+      for(j=0;j<subvect_size;j++)
+      {
+         shape[j] = _mm_setr_ps(0.03125*_shape[j], 0.03125*_shape[subvect_size+j], 0.03125*_shape[2*subvect_size+j], 0.03125*_shape[3*subvect_size+j]);
+      }
+      for(j=0;j<subvect_size;j++)
+      {
+         resj = _mm_setzero_ps();
+         for (k=0;k<=j;k++)
+            resj = _mm_add_ps(resj, _mm_mul_ps(shape[k],r[j-k]));
+         _spx_mm_getr_ps(resj, _res+j, _res+subvect_size+j, _res+2*subvect_size+j, _res+3*subvect_size+j);
+         *resp2++ = resj;
+         EE = _mm_add_ps(EE, _mm_mul_ps(resj, resj));
+      }
+      E[i>>2] = EE;
+   }
+}
diff --git a/utils/iaxclient/lib/libspeex/exc_10_16_table.c b/utils/iaxclient/lib/libspeex/exc_10_16_table.c
new file mode 100644 (file)
index 0000000..98ae357
--- /dev/null
@@ -0,0 +1,50 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: exc_10_16_table.c
+   Codebook for excitation in narrowband CELP mode (3200 bps)
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+
+const signed char exc_10_16_table[160] = {
+22,39,14,44,11,35,-2,23,-4,6,
+46,-28,13,-27,-23,12,4,20,-5,9,
+37,-18,-23,23,0,9,-6,-20,4,-1,
+-17,-5,-4,17,0,1,9,-2,1,2,
+2,-12,8,-25,39,15,9,16,-55,-11,
+9,11,5,10,-2,-60,8,13,-6,11,
+-16,27,-47,-12,11,1,16,-7,9,-3,
+-29,9,-14,25,-19,34,36,12,40,-10,
+-3,-24,-14,-37,-21,-35,-2,-36,3,-6,
+67,28,6,-17,-3,-12,-16,-15,-17,-7,
+-59,-36,-13,1,7,1,2,10,2,11,
+13,10,8,-2,7,3,5,4,2,2,
+-3,-8,4,-5,6,7,-42,15,35,-2,
+-46,38,28,-20,-9,1,7,-3,0,-2,
+0,0,0,0,0,0,0,0,0,0,
+-15,-28,52,32,5,-5,-17,-20,-10,-1};
diff --git a/utils/iaxclient/lib/libspeex/exc_10_32_table.c b/utils/iaxclient/lib/libspeex/exc_10_32_table.c
new file mode 100644 (file)
index 0000000..1ee56a2
--- /dev/null
@@ -0,0 +1,66 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: exc_10_32_table.c
+   Codebook for excitation in narrowband CELP mode (4000 bps)
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+
+const signed char exc_10_32_table[320] = {
+7,17,17,27,25,22,12,4,-3,0,
+28,-36,39,-24,-15,3,-9,15,-5,10,
+31,-28,11,31,-21,9,-11,-11,-2,-7,
+-25,14,-22,31,4,-14,19,-12,14,-5,
+4,-7,4,-5,9,0,-2,42,-47,-16,
+1,8,0,9,23,-57,0,28,-11,6,
+-31,55,-45,3,-5,4,2,-2,4,-7,
+-3,6,-2,7,-3,12,5,8,54,-10,
+8,-7,-8,-24,-25,-27,-14,-5,8,5,
+44,23,5,-9,-11,-11,-13,-9,-12,-8,
+-29,-8,-22,6,-15,3,-12,-1,-5,-3,
+34,-1,29,-16,17,-4,12,2,1,4,
+-2,-4,2,-1,11,-3,-52,28,30,-9,
+-32,25,44,-20,-24,4,6,-1,0,0,
+0,0,0,0,0,0,0,0,0,0,
+-25,-10,22,29,13,-13,-22,-13,-4,0,
+-4,-16,10,15,-36,-24,28,25,-1,-3,
+66,-33,-11,-15,6,0,3,4,-2,5,
+24,-20,-47,29,19,-2,-4,-1,0,-1,
+-2,3,1,8,-11,5,5,-57,28,28,
+0,-16,4,-4,12,-6,-1,2,-20,61,
+-9,24,-22,-42,29,6,17,8,4,2,
+-65,15,8,10,5,6,5,3,2,-2,
+-3,5,-9,4,-5,23,13,23,-3,-63,
+3,-5,-4,-6,0,-3,23,-36,-46,9,
+5,5,8,4,9,-5,1,-3,10,1,
+-6,10,-11,24,-47,31,22,-12,14,-10,
+6,11,-7,-7,7,-31,51,-12,-6,7,
+6,-17,9,-11,-20,52,-19,3,-6,-6,
+-8,-5,23,-41,37,1,-21,10,-14,8,
+7,5,-15,-15,23,39,-26,-33,7,2,
+-32,-30,-21,-8,4,12,17,15,14,11};
diff --git a/utils/iaxclient/lib/libspeex/exc_20_32_table.c b/utils/iaxclient/lib/libspeex/exc_20_32_table.c
new file mode 100644 (file)
index 0000000..e4098b8
--- /dev/null
@@ -0,0 +1,66 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: exc_20_32_table.c
+   Codebook for excitation in narrowband CELP mode (2000 bps)
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+
+const signed char exc_20_32_table[640] = {
+12,32,25,46,36,33,9,14,-3,6,1,-8,0,-10,-5,-7,-7,-7,-5,-5,
+31,-27,24,-32,-4,10,-11,21,-3,19,23,-9,22,24,-10,-1,-10,-13,-7,-11,
+42,-33,31,19,-8,0,-10,-16,1,-21,-17,10,-8,14,8,4,11,-2,5,-2,
+-33,11,-16,33,11,-4,9,-4,11,2,6,-5,8,-5,11,-4,-6,26,-36,-16,
+0,4,-2,-8,12,6,-1,34,-46,-22,9,9,21,9,5,-66,-5,26,2,10,
+13,2,19,9,12,-81,3,13,13,0,-14,22,-35,6,-7,-4,6,-6,10,-6,
+-31,38,-33,0,-10,-11,5,-12,12,-17,5,0,-6,13,-9,10,8,25,33,2,
+-12,8,-6,10,-2,21,7,17,43,5,11,-7,-9,-20,-36,-20,-23,-4,-4,-3,
+27,-9,-9,-49,-39,-38,-11,-9,6,5,23,25,5,3,3,4,1,2,-3,-1,
+87,39,17,-21,-9,-19,-9,-15,-13,-14,-17,-11,-10,-11,-8,-6,-1,-3,-3,-1,
+-54,-34,-27,-8,-11,-4,-5,0,0,4,8,6,9,7,9,7,6,5,5,5,
+48,10,19,-10,12,-1,9,-3,2,5,-3,2,-2,-2,0,-2,-26,6,9,-7,
+-16,-9,2,7,7,-5,-43,11,22,-11,-9,34,37,-15,-13,-6,1,-1,1,1,
+-64,56,52,-11,-27,5,4,3,1,2,1,3,-1,-4,-4,-10,-7,-4,-4,2,
+-1,-7,-7,-12,-10,-15,-9,-5,-5,-11,-16,-13,6,16,4,-13,-16,-10,-4,2,
+-47,-13,25,47,19,-14,-20,-8,-17,0,-3,-13,1,6,-17,-14,15,1,10,6,
+-24,0,-10,19,-69,-8,14,49,17,-5,33,-29,3,-4,0,2,-8,5,-6,2,
+120,-56,-12,-47,23,-9,6,-5,1,2,-5,1,-10,4,-1,-1,4,-1,0,-3,
+30,-52,-67,30,22,11,-1,-4,3,0,7,2,0,1,-10,-4,-8,-13,5,1,
+1,-1,5,13,-9,-3,-10,-62,22,48,-4,-6,2,3,5,1,1,4,1,13,
+3,-20,10,-9,13,-2,-4,9,-20,44,-1,20,-32,-67,19,0,28,11,8,2,
+-11,15,-19,-53,31,2,34,10,6,-4,-58,8,10,13,14,1,12,2,0,0,
+-128,37,-8,44,-9,26,-3,18,2,6,11,-1,9,1,5,3,0,1,1,2,
+12,3,-2,-3,7,25,9,18,-6,-37,3,-8,-16,3,-10,-7,17,-34,-44,11,
+17,-15,-3,-16,-1,-13,11,-46,-65,-2,8,13,2,4,4,5,15,5,9,6,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+-9,19,-12,12,-28,38,29,-1,12,2,5,23,-10,3,4,-15,21,-4,3,3,
+6,17,-9,-4,-8,-20,26,5,-10,6,1,-19,18,-15,-12,47,-6,-2,-7,-9,
+-1,-17,-2,-2,-14,30,-14,2,-7,-4,-1,-12,11,-25,16,-3,-12,11,-7,7,
+-17,1,19,-28,31,-7,-10,7,-10,3,12,5,-16,6,24,41,-29,-54,0,1,
+7,-1,5,-6,13,10,-4,-8,8,-9,-27,-53,-38,-1,10,19,17,16,12,12,
+0,3,-7,-4,13,12,-31,-14,6,-5,3,5,17,43,50,25,10,1,-6,-2};
diff --git a/utils/iaxclient/lib/libspeex/exc_5_256_table.c b/utils/iaxclient/lib/libspeex/exc_5_256_table.c
new file mode 100644 (file)
index 0000000..4137996
--- /dev/null
@@ -0,0 +1,290 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: exc_5_256_table.c
+   Codebook for excitation in narrowband CELP mode (12800 bps)
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+
+const signed char exc_5_256_table[1280] = {
+-8,-37,5,-43,5,
+73,61,39,12,-3,
+-61,-32,2,42,30,
+-3,17,-27,9,34,
+20,-1,-5,2,23,
+-7,-46,26,53,-47,
+20,-2,-33,-89,-51,
+-64,27,11,15,-34,
+-5,-56,25,-9,-1,
+-29,1,40,67,-23,
+-16,16,33,19,7,
+14,85,22,-10,-10,
+-12,-7,-1,52,89,
+29,11,-20,-37,-46,
+-15,17,-24,-28,24,
+2,1,0,23,-101,
+23,14,-1,-23,-18,
+9,5,-13,38,1,
+-28,-28,4,27,51,
+-26,34,-40,35,47,
+54,38,-54,-26,-6,
+42,-25,13,-30,-36,
+18,41,-4,-33,23,
+-32,-7,-4,51,-3,
+17,-52,56,-47,36,
+-2,-21,36,10,8,
+-33,31,19,9,-5,
+-40,10,-9,-21,19,
+18,-78,-18,-5,0,
+-26,-36,-47,-51,-44,
+18,40,27,-2,29,
+49,-26,2,32,-54,
+30,-73,54,3,-5,
+36,22,53,10,-1,
+-84,-53,-29,-5,3,
+-44,53,-51,4,22,
+71,-35,-1,33,-5,
+-27,-7,36,17,-23,
+-39,16,-9,-55,-15,
+-20,39,-35,6,-39,
+-14,18,48,-64,-17,
+-15,9,39,81,37,
+-68,37,47,-21,-6,
+-104,13,6,9,-2,
+35,8,-23,18,42,
+45,21,33,-5,-49,
+9,-6,-43,-56,39,
+2,-16,-25,87,1,
+-3,-9,17,-25,-11,
+-9,-1,10,2,-14,
+-14,4,-1,-10,28,
+-23,40,-32,26,-9,
+26,4,-27,-23,3,
+42,-60,1,49,-3,
+27,10,-52,-40,-2,
+18,45,-23,17,-44,
+3,-3,17,-46,52,
+-40,-47,25,75,31,
+-49,53,30,-30,-32,
+-36,38,-6,-15,-16,
+54,-27,-48,3,38,
+-29,-32,-22,-14,-4,
+-23,-13,32,-39,9,
+8,-45,-13,34,-16,
+49,40,32,31,28,
+23,23,32,47,59,
+-68,8,62,44,25,
+-14,-24,-65,-16,36,
+67,-25,-38,-21,4,
+-33,-2,42,5,-63,
+40,11,26,-42,-23,
+-61,79,-31,23,-20,
+10,-32,53,-25,-36,
+10,-26,-5,3,0,
+-71,5,-10,-37,1,
+-24,21,-54,-17,1,
+-29,-25,-15,-27,32,
+68,45,-16,-37,-18,
+-5,1,0,-77,71,
+-6,3,-20,71,-67,
+29,-35,10,-30,19,
+4,16,17,5,0,
+-14,19,2,28,26,
+59,3,2,24,39,
+55,-50,-45,-18,-17,
+33,-35,14,-1,1,
+8,87,-35,-29,0,
+-27,13,-7,23,-13,
+37,-40,50,-35,14,
+19,-7,-14,49,54,
+-5,22,-2,-29,-8,
+-27,38,13,27,48,
+12,-41,-21,-15,28,
+7,-16,-24,-19,-20,
+11,-20,9,2,13,
+23,-20,11,27,-27,
+71,-69,8,2,-6,
+22,12,16,16,9,
+-16,-8,-17,1,25,
+1,40,-37,-33,66,
+94,53,4,-22,-25,
+-41,-42,25,35,-16,
+-15,57,31,-29,-32,
+21,16,-60,45,15,
+-1,7,57,-26,-47,
+-29,11,8,15,19,
+-105,-8,54,27,10,
+-17,6,-12,-1,-10,
+4,0,23,-10,31,
+13,11,10,12,-64,
+23,-3,-8,-19,16,
+52,24,-40,16,10,
+40,5,9,0,-13,
+-7,-21,-8,-6,-7,
+-21,59,16,-53,18,
+-60,11,-47,14,-18,
+25,-13,-24,4,-39,
+16,-28,54,26,-67,
+30,27,-20,-52,20,
+-12,55,12,18,-16,
+39,-14,-6,-26,56,
+-88,-55,12,25,26,
+-37,6,75,0,-34,
+-81,54,-30,1,-7,
+49,-23,-14,21,10,
+-62,-58,-57,-47,-34,
+15,-4,34,-78,31,
+25,-11,7,50,-10,
+42,-63,14,-36,-4,
+57,55,57,53,42,
+-42,-1,15,40,37,
+15,25,-11,6,1,
+31,-2,-6,-1,-7,
+-64,34,28,30,-1,
+3,21,0,-88,-12,
+-56,25,-28,40,8,
+-28,-14,9,12,2,
+-6,-17,22,49,-6,
+-26,14,28,-20,4,
+-12,50,35,40,13,
+-38,-58,-29,17,30,
+22,60,26,-54,-39,
+-12,58,-28,-63,10,
+-21,-8,-12,26,-62,
+6,-10,-11,-22,-6,
+-7,4,1,18,2,
+-70,11,14,4,13,
+19,-24,-34,24,67,
+17,51,-21,13,23,
+54,-30,48,1,-13,
+80,26,-16,-2,13,
+-4,6,-30,29,-24,
+73,-58,30,-27,20,
+-2,-21,41,45,30,
+-27,-3,-5,-18,-20,
+-49,-3,-35,10,42,
+-19,-67,-53,-11,9,
+13,-15,-33,-51,-30,
+15,7,25,-30,4,
+28,-22,-34,54,-29,
+39,-46,20,16,34,
+-4,47,75,1,-44,
+-55,-24,7,-1,9,
+-42,50,-8,-36,41,
+68,0,-4,-10,-23,
+-15,-50,64,36,-9,
+-27,12,25,-38,-47,
+-37,32,-49,51,-36,
+2,-4,69,-26,19,
+7,45,67,46,13,
+-63,46,15,-47,4,
+-41,13,-6,5,-21,
+37,26,-55,-7,33,
+-1,-28,10,-17,-64,
+-14,0,-36,-17,93,
+-3,-9,-66,44,-21,
+3,-12,38,-6,-13,
+-12,19,13,43,-43,
+-10,-12,6,-5,9,
+-49,32,-5,2,4,
+5,15,-16,10,-21,
+8,-62,-8,64,8,
+79,-1,-66,-49,-18,
+5,40,-5,-30,-45,
+1,-6,21,-32,93,
+-18,-30,-21,32,21,
+-18,22,8,5,-41,
+-54,80,22,-10,-7,
+-8,-23,-64,66,56,
+-14,-30,-41,-46,-14,
+-29,-37,27,-14,42,
+-2,-9,-29,34,14,
+33,-14,22,4,10,
+26,26,28,32,23,
+-72,-32,3,0,-14,
+35,-42,-78,-32,6,
+29,-18,-45,-5,7,
+-33,-45,-3,-22,-34,
+8,-8,4,-51,-25,
+-9,59,-78,21,-5,
+-25,-48,66,-15,-17,
+-24,-49,-13,25,-23,
+-64,-6,40,-24,-19,
+-11,57,-33,-8,1,
+10,-52,-54,28,39,
+49,34,-11,-61,-41,
+-43,10,15,-15,51,
+30,15,-51,32,-34,
+-2,-34,14,18,16,
+1,1,-3,-3,1,
+1,-18,6,16,48,
+12,-5,-42,7,36,
+48,7,-20,-10,7,
+12,2,54,39,-38,
+37,54,4,-11,-8,
+-46,-10,5,-10,-34,
+46,-12,29,-37,39,
+36,-11,24,56,17,
+14,20,25,0,-25,
+-28,55,-7,-5,27,
+3,9,-26,-8,6,
+-24,-10,-30,-31,-34,
+18,4,22,21,40,
+-1,-29,-37,-8,-21,
+92,-29,11,-3,11,
+73,23,22,7,4,
+-44,-9,-11,21,-13,
+11,9,-78,-1,47,
+114,-12,-37,-19,-5,
+-11,-22,19,12,-30,
+7,38,45,-21,-8,
+-9,55,-45,56,-21,
+7,17,46,-57,-87,
+-6,27,31,31,7,
+-56,-12,46,21,-5,
+-12,36,3,3,-21,
+43,19,12,-7,9,
+-14,0,-9,-33,-91,
+7,26,3,-11,64,
+83,-31,-46,25,2,
+9,5,2,2,-1,
+20,-17,10,-5,-27,
+-8,20,8,-19,16,
+-21,-13,-31,5,5,
+42,24,9,34,-20,
+28,-61,22,11,-39,
+64,-20,-1,-30,-9,
+-20,24,-25,-24,-29,
+22,-60,6,-5,41,
+-9,-87,14,34,15,
+-57,52,69,15,-3,
+-102,58,16,3,6,
+60,-75,-32,26,7,
+-57,-27,-32,-24,-21,
+-29,-16,62,-46,31,
+30,-27,-15,7,15};
diff --git a/utils/iaxclient/lib/libspeex/exc_5_64_table.c b/utils/iaxclient/lib/libspeex/exc_5_64_table.c
new file mode 100644 (file)
index 0000000..2c66d51
--- /dev/null
@@ -0,0 +1,98 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: exc_5_64_table.c
+   Codebook for excitation in narrowband CELP mode (9600 bps)
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+
+const signed char exc_5_64_table[320]={
+1,5,-15,49,-66,
+-48,-4,50,-44,7,
+37,16,-18,25,-26,
+-26,-15,19,19,-27,
+-47,28,57,5,-17,
+-32,-41,68,21,-2,
+64,56,8,-16,-13,
+-26,-9,-16,11,6,
+-39,25,-19,22,-31,
+20,-45,55,-43,10,
+-16,47,-40,40,-20,
+-51,3,-17,-14,-15,
+-24,53,-20,-46,46,
+27,-68,32,3,-18,
+-5,9,-31,16,-9,
+-10,-1,-23,48,95,
+47,25,-41,-32,-3,
+15,-25,-55,36,41,
+-27,20,5,13,14,
+-22,5,2,-23,18,
+46,-15,17,-18,-34,
+-5,-8,27,-55,73,
+16,2,-1,-17,40,
+-78,33,0,2,19,
+4,53,-16,-15,-16,
+-28,-3,-13,49,8,
+-7,-29,27,-13,32,
+20,32,-61,16,14,
+41,44,40,24,20,
+7,4,48,-60,-77,
+17,-6,-48,65,-15,
+32,-30,-71,-10,-3,
+-6,10,-2,-7,-29,
+-56,67,-30,7,-5,
+86,-6,-10,0,5,
+-31,60,34,-38,-3,
+24,10,-2,30,23,
+24,-41,12,70,-43,
+15,-17,6,13,16,
+-13,8,30,-15,-8,
+5,23,-34,-98,-4,
+-13,13,-48,-31,70,
+12,31,25,24,-24,
+26,-7,33,-16,8,
+5,-11,-14,-8,-65,
+13,10,-2,-9,0,
+-3,-68,5,35,7,
+0,-31,-1,-17,-9,
+-9,16,-37,-18,-1,
+69,-48,-28,22,-21,
+-11,5,49,55,23,
+-86,-36,16,2,13,
+63,-51,30,-11,13,
+24,-18,-6,14,-19,
+1,41,9,-5,27,
+-36,-44,-34,-37,-21,
+-26,31,-39,15,43,
+5,-8,29,20,-8,
+-20,-52,-28,-1,13,
+26,-34,-10,-9,27,
+-8,8,27,-66,4,
+12,-22,49,10,-77,
+32,-18,3,-38,12,
+-3,-1,2,2,0};
diff --git a/utils/iaxclient/lib/libspeex/exc_8_128_table.c b/utils/iaxclient/lib/libspeex/exc_8_128_table.c
new file mode 100644 (file)
index 0000000..17ee64b
--- /dev/null
@@ -0,0 +1,162 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: exc_8_128_table.c
+   Codebook for excitation in narrowband CELP mode (7000 bps)
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+
+const signed char exc_8_128_table[1024] = {
+-14,9,13,-32,2,-10,31,-10,
+-8,-8,6,-4,-1,10,-64,23,
+6,20,13,6,8,-22,16,34,
+7,42,-49,-28,5,26,4,-15,
+41,34,41,32,33,24,23,14,
+8,40,34,4,-24,-41,-19,-15,
+13,-13,33,-54,24,27,-44,33,
+27,-15,-15,24,-19,14,-36,14,
+-9,24,-12,-4,37,-5,16,-34,
+5,10,33,-15,-54,-16,12,25,
+12,1,2,0,3,-1,-4,-4,
+11,2,-56,54,27,-20,13,-6,
+-46,-41,-33,-11,-5,7,12,14,
+-14,-5,8,20,6,3,4,-8,
+-5,-42,11,8,-14,25,-2,2,
+13,11,-22,39,-9,9,5,-45,
+-9,7,-9,12,-7,34,-17,-102,
+7,2,-42,18,35,-9,-34,11,
+-5,-2,3,22,46,-52,-25,-9,
+-94,8,11,-5,-5,-5,4,-7,
+-35,-7,54,5,-32,3,24,-9,
+-22,8,65,37,-1,-12,-23,-6,
+-9,-28,55,-33,14,-3,2,18,
+-60,41,-17,8,-16,17,-11,0,
+-11,29,-28,37,9,-53,33,-14,
+-9,7,-25,-7,-11,26,-32,-8,
+24,-21,22,-19,19,-10,29,-14,
+0,0,0,0,0,0,0,0,
+-5,-52,10,41,6,-30,-4,16,
+32,22,-27,-22,32,-3,-28,-3,
+3,-35,6,17,23,21,8,2,
+4,-45,-17,14,23,-4,-31,-11,
+-3,14,1,19,-11,2,61,-8,
+9,-12,7,-10,12,-3,-24,99,
+-48,23,50,-37,-5,-23,0,8,
+-14,35,-64,-5,46,-25,13,-1,
+-49,-19,-15,9,34,50,25,11,
+-6,-9,-16,-20,-32,-33,-32,-27,
+10,-8,12,-15,56,-14,-32,33,
+3,-9,1,65,-9,-9,-10,-2,
+-6,-23,9,17,3,-28,13,-32,
+4,-2,-10,4,-16,76,12,-52,
+6,13,33,-6,4,-14,-9,-3,
+1,-15,-16,28,1,-15,11,16,
+9,4,-21,-37,-40,-6,22,12,
+-15,-23,-14,-17,-16,-9,-10,-9,
+13,-39,41,5,-9,16,-38,25,
+46,-47,4,49,-14,17,-2,6,
+18,5,-6,-33,-22,44,50,-2,
+1,3,-6,7,7,-3,-21,38,
+-18,34,-14,-41,60,-13,6,16,
+-24,35,19,-13,-36,24,3,-17,
+-14,-10,36,44,-44,-29,-3,3,
+-54,-8,12,55,26,4,-2,-5,
+2,-11,22,-23,2,22,1,-25,
+-39,66,-49,21,-8,-2,10,-14,
+-60,25,6,10,27,-25,16,5,
+-2,-9,26,-13,-20,58,-2,7,
+52,-9,2,5,-4,-15,23,-1,
+-38,23,8,27,-6,0,-27,-7,
+39,-10,-14,26,11,-45,-12,9,
+-5,34,4,-35,10,43,-22,-11,
+56,-7,20,1,10,1,-26,9,
+94,11,-27,-14,-13,1,-11,0,
+14,-5,-6,-10,-4,-15,-8,-41,
+21,-5,1,-28,-8,22,-9,33,
+-23,-4,-4,-12,39,4,-7,3,
+-60,80,8,-17,2,-6,12,-5,
+1,9,15,27,31,30,27,23,
+61,47,26,10,-5,-8,-12,-13,
+5,-18,25,-15,-4,-15,-11,12,
+-2,-2,-16,-2,-6,24,12,11,
+-4,9,1,-9,14,-45,57,12,
+20,-35,26,11,-64,32,-10,-10,
+42,-4,-9,-16,32,24,7,10,
+52,-11,-57,29,0,8,0,-6,
+17,-17,-56,-40,7,20,18,12,
+-6,16,5,7,-1,9,1,10,
+29,12,16,13,-2,23,7,9,
+-3,-4,-5,18,-64,13,55,-25,
+9,-9,24,14,-25,15,-11,-40,
+-30,37,1,-19,22,-5,-31,13,
+-2,0,7,-4,16,-67,12,66,
+-36,24,-8,18,-15,-23,19,0,
+-45,-7,4,3,-13,13,35,5,
+13,33,10,27,23,0,-7,-11,
+43,-74,36,-12,2,5,-8,6,
+-33,11,-16,-14,-5,-7,-3,17,
+-34,27,-16,11,-9,15,33,-31,
+8,-16,7,-6,-7,63,-55,-17,
+11,-1,20,-46,34,-30,6,9,
+19,28,-9,5,-24,-8,-23,-2,
+31,-19,-16,-5,-15,-18,0,26,
+18,37,-5,-15,-2,17,5,-27,
+21,-33,44,12,-27,-9,17,11,
+25,-21,-31,-7,13,33,-8,-25,
+-7,7,-10,4,-6,-9,48,-82,
+-23,-8,6,11,-23,3,-3,49,
+-29,25,31,4,14,16,9,-4,
+-18,10,-26,3,5,-44,-9,9,
+-47,-55,15,9,28,1,4,-3,
+46,6,-6,-38,-29,-31,-15,-6,
+3,0,14,-6,8,-54,-50,33,
+-5,1,-14,33,-48,26,-4,-5,
+-3,-5,-3,-5,-28,-22,77,55,
+-1,2,10,10,-9,-14,-66,-49,
+11,-36,-6,-20,10,-10,16,12,
+4,-1,-16,45,-44,-50,31,-2,
+25,42,23,-32,-22,0,11,20,
+-40,-35,-40,-36,-32,-26,-21,-13,
+52,-22,6,-24,-20,17,-5,-8,
+36,-25,-11,21,-26,6,34,-8,
+7,20,-3,5,-25,-8,18,-5,
+-9,-4,1,-9,20,20,39,48,
+-24,9,5,-65,22,29,4,3,
+-43,-11,32,-6,9,19,-27,-10,
+-47,-14,24,10,-7,-36,-7,-1,
+-4,-5,-5,16,53,25,-26,-29,
+-4,-12,45,-58,-34,33,-5,2,
+-1,27,-48,31,-15,22,-5,4,
+7,7,-25,-3,11,-22,16,-12,
+8,-3,7,-11,45,14,-73,-19,
+56,-46,24,-20,28,-12,-2,-1,
+-36,-3,-33,19,-6,7,2,-15,
+5,-31,-45,8,35,13,20,0,
+-9,48,-13,-43,-3,-13,2,-5,
+72,-68,-27,2,1,-2,-7,5,
+36,33,-40,-12,-4,-5,23,19};
diff --git a/utils/iaxclient/lib/libspeex/filters.c b/utils/iaxclient/lib/libspeex/filters.c
new file mode 100644 (file)
index 0000000..bfe7844
--- /dev/null
@@ -0,0 +1,636 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: filters.c
+   Various analysis/synthesis filters
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "filters.h"
+#include "stack_alloc.h"
+#include "misc.h"
+#include "math_approx.h"
+#include "ltp.h"
+#include <math.h>
+
+void bw_lpc(spx_word16_t gamma, const spx_coef_t *lpc_in, spx_coef_t *lpc_out, int order)
+{
+   int i;
+   spx_word16_t tmp=gamma;
+   lpc_out[0] = lpc_in[0];
+   for (i=1;i<order+1;i++)
+   {
+      lpc_out[i] = MULT16_16_P15(tmp,lpc_in[i]);
+      tmp = MULT16_16_P15(tmp, gamma);
+   }
+}
+
+
+#ifdef FIXED_POINT
+
+/* FIXME: These functions are ugly and probably introduce too much error */
+void signal_mul(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len)
+{
+   int i;
+   for (i=0;i<len;i++)
+   {
+      y[i] = SHL32(MULT16_32_Q14(EXTRACT16(SHR32(x[i],7)),scale),7);
+   }
+}
+
+void signal_div(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len)
+{
+   int i;
+   spx_word16_t scale_1;
+
+   scale = PSHR32(scale, SIG_SHIFT);
+   if (scale<2)
+      scale_1 = 32767;
+   else
+      scale_1 = EXTRACT16(DIV32(32767,scale));
+   for (i=0;i<len;i++)
+   {
+      y[i] = MULT16_32_Q15(scale_1,x[i]);
+   }
+}
+
+#else
+
+void signal_mul(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len)
+{
+   int i;
+   for (i=0;i<len;i++)
+      y[i] = scale*x[i];
+}
+
+void signal_div(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len)
+{
+   int i;
+   float scale_1 = 1/scale;
+   for (i=0;i<len;i++)
+      y[i] = scale_1*x[i];
+}
+#endif
+
+
+
+#ifdef FIXED_POINT
+
+
+
+spx_word16_t compute_rms(const spx_sig_t *x, int len)
+{
+   int i;
+   spx_word32_t sum=0;
+   spx_sig_t max_val=1;
+   int sig_shift;
+
+   for (i=0;i<len;i++)
+   {
+      spx_sig_t tmp = x[i];
+      if (tmp<0)
+         tmp = -tmp;
+      if (tmp > max_val)
+         max_val = tmp;
+   }
+
+   sig_shift=0;
+   while (max_val>16383)
+   {
+      sig_shift++;
+      max_val >>= 1;
+   }
+
+   for (i=0;i<len;i+=4)
+   {
+      spx_word32_t sum2=0;
+      spx_word16_t tmp;
+      tmp = EXTRACT16(SHR32(x[i],sig_shift));
+      sum2 = MAC16_16(sum2,tmp,tmp);
+      tmp = EXTRACT16(SHR32(x[i+1],sig_shift));
+      sum2 = MAC16_16(sum2,tmp,tmp);
+      tmp = EXTRACT16(SHR32(x[i+2],sig_shift));
+      sum2 = MAC16_16(sum2,tmp,tmp);
+      tmp = EXTRACT16(SHR32(x[i+3],sig_shift));
+      sum2 = MAC16_16(sum2,tmp,tmp);
+      sum = ADD32(sum,SHR32(sum2,6));
+   }
+   
+   return EXTRACT16(SHR32(SHL32(EXTEND32(spx_sqrt(1+DIV32(sum,len))),(sig_shift+3)),SIG_SHIFT));
+}
+
+#if defined(ARM4_ASM) || defined(ARM5E_ASM)
+#include "filters_arm4.h"
+#else
+
+
+int normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int len)
+{
+   int i;
+   spx_sig_t max_val=1;
+   int sig_shift;
+   
+   for (i=0;i<len;i++)
+   {
+      spx_sig_t tmp = x[i];
+      if (tmp<0)
+         tmp = NEG32(tmp);
+      if (tmp >= max_val)
+         max_val = tmp;
+   }
+
+   sig_shift=0;
+   while (max_val>max_scale)
+   {
+      sig_shift++;
+      max_val >>= 1;
+   }
+
+   for (i=0;i<len;i++)
+      y[i] = EXTRACT16(SHR32(x[i], sig_shift));
+   
+   return sig_shift;
+}
+
+#ifdef PRECISION16
+void filter_mem2(const spx_sig_t *x, const spx_coef_t *num, const spx_coef_t *den, spx_sig_t *y, int N, int ord, spx_mem_t *mem)
+{
+   int i,j;
+   spx_word16_t xi,yi,nyi;
+
+   for (i=0;i<N;i++)
+   {
+      xi= EXTRACT16(PSHR32(SATURATE(x[i],536870911),SIG_SHIFT));
+      yi = EXTRACT16(PSHR32(SATURATE(ADD32(x[i], SHL32(mem[0],1)),536870911),SIG_SHIFT));
+      nyi = NEG16(yi);
+      for (j=0;j<ord-1;j++)
+      {
+         mem[j] = MAC16_16(MAC16_16(mem[j+1], num[j+1],xi), den[j+1],nyi);
+      }
+      mem[ord-1] = ADD32(MULT16_16(num[ord],xi), MULT16_16(den[ord],nyi));
+      y[i] = SHL32(EXTEND32(yi),SIG_SHIFT);
+   }
+}
+#else
+void filter_mem2(const spx_sig_t *x, const spx_coef_t *num, const spx_coef_t *den, spx_sig_t *y, int N, int ord, spx_mem_t *mem)
+{
+   int i,j;
+   spx_sig_t xi,yi,nyi;
+
+   for (i=0;i<N;i++)
+   {
+      xi=SATURATE(x[i],805306368);
+      yi = SATURATE(ADD32(xi, SHL32(mem[0],2)),805306368);
+      nyi = NEG32(yi);
+      for (j=0;j<ord-1;j++)
+      {
+         mem[j] = MAC16_32_Q15(MAC16_32_Q15(mem[j+1], num[j+1],xi), den[j+1],nyi);
+      }
+      mem[ord-1] = SUB32(MULT16_32_Q15(num[ord],xi), MULT16_32_Q15(den[ord],yi));
+      y[i] = yi;
+   }
+}
+#endif
+
+#ifdef PRECISION16
+void iir_mem2(const spx_sig_t *x, const spx_coef_t *den, spx_sig_t *y, int N, int ord, spx_mem_t *mem)
+{
+   int i,j;
+   spx_word16_t yi,nyi;
+
+   for (i=0;i<N;i++)
+   {
+      yi = EXTRACT16(PSHR32(SATURATE(x[i] + SHL32(mem[0],1),536870911),SIG_SHIFT));
+      nyi = NEG16(yi);
+      for (j=0;j<ord-1;j++)
+      {
+         mem[j] = MAC16_16(mem[j+1],den[j+1],nyi);
+      }
+      mem[ord-1] = MULT16_16(den[ord],nyi);
+      y[i] = SHL32(EXTEND32(yi),SIG_SHIFT);
+   }
+}
+#else
+void iir_mem2(const spx_sig_t *x, const spx_coef_t *den, spx_sig_t *y, int N, int ord, spx_mem_t *mem)
+{
+   int i,j;
+   spx_word32_t xi,yi,nyi;
+
+   for (i=0;i<N;i++)
+   {
+      xi=SATURATE(x[i],805306368);
+      yi = SATURATE(xi + SHL32(mem[0],2),805306368);
+      nyi = NEG32(yi);
+      for (j=0;j<ord-1;j++)
+      {
+         mem[j] = MAC16_32_Q15(mem[j+1],den[j+1],nyi);
+      }
+      mem[ord-1] = MULT16_32_Q15(den[ord],nyi);
+      y[i] = yi;
+   }
+}
+#endif
+
+#endif
+
+
+#ifdef PRECISION16
+void fir_mem2(const spx_sig_t *x, const spx_coef_t *num, spx_sig_t *y, int N, int ord, spx_mem_t *mem)
+{
+   int i,j;
+   spx_word16_t xi,yi;
+
+   for (i=0;i<N;i++)
+   {
+      xi= EXTRACT16(PSHR32(SATURATE(x[i],536870911),SIG_SHIFT));
+      yi = EXTRACT16(PSHR32(SATURATE(x[i] + SHL32(mem[0],1),536870911),SIG_SHIFT));
+      for (j=0;j<ord-1;j++)
+      {
+         mem[j] = MAC16_16(mem[j+1], num[j+1],xi);
+      }
+      mem[ord-1] = MULT16_16(num[ord],xi);
+      y[i] = SHL32(EXTEND32(yi),SIG_SHIFT);
+   }
+}
+#else
+void fir_mem2(const spx_sig_t *x, const spx_coef_t *num, spx_sig_t *y, int N, int ord, spx_mem_t *mem)
+{
+   int i,j;
+   spx_word32_t xi,yi;
+
+   for (i=0;i<N;i++)
+   {
+      xi=SATURATE(x[i],805306368);
+      yi = xi + SHL32(mem[0],2);
+      for (j=0;j<ord-1;j++)
+      {
+         mem[j] = MAC16_32_Q15(mem[j+1], num[j+1],xi);
+      }
+      mem[ord-1] = MULT16_32_Q15(num[ord],xi);
+      y[i] = SATURATE(yi,805306368);
+   }
+}
+#endif
+
+#else
+
+
+
+spx_word16_t compute_rms(const spx_sig_t *x, int len)
+{
+   int i;
+   float sum=0;
+   for (i=0;i<len;i++)
+   {
+      sum += x[i]*x[i];
+   }
+   return sqrt(.1+sum/len);
+}
+
+#ifdef _USE_SSE
+#include "filters_sse.h"
+#else
+
+
+void filter_mem2(const spx_sig_t *x, const spx_coef_t *num, const spx_coef_t *den, spx_sig_t *y, int N, int ord,  spx_mem_t *mem)
+{
+   int i,j;
+   float xi,yi;
+   for (i=0;i<N;i++)
+   {
+      xi=x[i];
+      y[i] = num[0]*xi + mem[0];
+      yi=y[i];
+      for (j=0;j<ord-1;j++)
+      {
+         mem[j] = mem[j+1] + num[j+1]*xi - den[j+1]*yi;
+      }
+      mem[ord-1] = num[ord]*xi - den[ord]*yi;
+   }
+}
+
+
+void iir_mem2(const spx_sig_t *x, const spx_coef_t *den, spx_sig_t *y, int N, int ord, spx_mem_t *mem)
+{
+   int i,j;
+   for (i=0;i<N;i++)
+   {
+      y[i] = x[i] + mem[0];
+      for (j=0;j<ord-1;j++)
+      {
+         mem[j] = mem[j+1] - den[j+1]*y[i];
+      }
+      mem[ord-1] = - den[ord]*y[i];
+   }
+}
+
+
+void fir_mem2(const spx_sig_t *x, const spx_coef_t *num, spx_sig_t *y, int N, int ord, spx_mem_t *mem)
+{
+   int i,j;
+   float xi;
+   for (i=0;i<N;i++)
+   {
+      xi=x[i];
+      y[i] = num[0]*xi + mem[0];
+      for (j=0;j<ord-1;j++)
+      {
+         mem[j] = mem[j+1] + num[j+1]*xi;
+      }
+      mem[ord-1] = num[ord]*xi;
+   }
+}
+#endif
+
+#endif
+
+
+void syn_percep_zero(const spx_sig_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_sig_t *y, int N, int ord, char *stack)
+{
+   int i;
+   VARDECL(spx_mem_t *mem);
+   ALLOC(mem, ord, spx_mem_t);
+   for (i=0;i<ord;i++)
+     mem[i]=0;
+   iir_mem2(xx, ak, y, N, ord, mem);
+   for (i=0;i<ord;i++)
+      mem[i]=0;
+   filter_mem2(y, awk1, awk2, y, N, ord, mem);
+}
+
+void residue_percep_zero(const spx_sig_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_sig_t *y, int N, int ord, char *stack)
+{
+   int i;
+   VARDECL(spx_mem_t *mem);
+   ALLOC(mem, ord, spx_mem_t);
+   for (i=0;i<ord;i++)
+      mem[i]=0;
+   filter_mem2(xx, ak, awk1, y, N, ord, mem);
+   for (i=0;i<ord;i++)
+     mem[i]=0;
+   fir_mem2(y, awk2, y, N, ord, mem);
+}
+
+void compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack)
+{
+   int i,j;
+   spx_word16_t y1, ny1i, ny2i;
+   VARDECL(spx_mem_t *mem1);
+   VARDECL(spx_mem_t *mem2);
+   ALLOC(mem1, ord, spx_mem_t);
+   ALLOC(mem2, ord, spx_mem_t);
+   
+   for (i=0;i<ord+1;i++)
+      y[i] = awk1[i];
+   for (;i<N;i++)
+      y[i] = VERY_SMALL;
+   
+   for (i=0;i<ord;i++)
+      mem1[i] = mem2[i] = 0;
+   for (i=0;i<N;i++)
+   {
+      y1 = ADD16(y[i], EXTRACT16(PSHR32(mem1[0],LPC_SHIFT)));
+      ny1i = NEG16(y1);
+      y[i] = ADD16(SHL16(y1,1), EXTRACT16(PSHR32(mem2[0],LPC_SHIFT)));
+      ny2i = NEG16(y[i]);
+      for (j=0;j<ord-1;j++)
+      {
+         mem1[j] = MAC16_16(mem1[j+1], awk2[j+1],ny1i);
+         mem2[j] = MAC16_16(mem2[j+1], ak[j+1],ny2i);
+      }
+      mem1[ord-1] = MULT16_16(awk2[ord],ny1i);
+      mem2[ord-1] = MULT16_16(ak[ord],ny2i);
+   }
+}
+
+void qmf_decomp(const spx_word16_t *xx, const spx_word16_t *aa, spx_sig_t *y1, spx_sig_t *y2, int N, int M, spx_word16_t *mem, char *stack)
+{
+   int i,j,k,M2;
+   VARDECL(spx_word16_t *a);
+   VARDECL(spx_word16_t *x);
+   spx_word16_t *x2;
+   
+   ALLOC(a, M, spx_word16_t);
+   ALLOC(x, N+M-1, spx_word16_t);
+   x2=x+M-1;
+   M2=M>>1;
+   for (i=0;i<M;i++)
+      a[M-i-1]= aa[i];
+
+   for (i=0;i<M-1;i++)
+      x[i]=mem[M-i-2];
+   for (i=0;i<N;i++)
+      x[i+M-1]=SATURATE(PSHR(xx[i],1),16383);
+   for (i=0,k=0;i<N;i+=2,k++)
+   {
+      y1[k]=0;
+      y2[k]=0;
+      for (j=0;j<M2;j++)
+      {
+         y1[k]=ADD32(y1[k],SHR(MULT16_16(a[j],ADD16(x[i+j],x2[i-j])),1));
+         y2[k]=SUB32(y2[k],SHR(MULT16_16(a[j],SUB16(x[i+j],x2[i-j])),1));
+         j++;
+         y1[k]=ADD32(y1[k],SHR(MULT16_16(a[j],ADD16(x[i+j],x2[i-j])),1));
+         y2[k]=ADD32(y2[k],SHR(MULT16_16(a[j],SUB16(x[i+j],x2[i-j])),1));
+      }
+   }
+   for (i=0;i<M-1;i++)
+     mem[i]=SATURATE(PSHR(xx[N-i-1],1),16383);
+}
+
+
+/* By segher */
+void fir_mem_up(const spx_sig_t *x, const spx_word16_t *a, spx_sig_t *y, int N, int M, spx_word32_t *mem, char *stack)
+   /* assumptions:
+      all odd x[i] are zero -- well, actually they are left out of the array now
+      N and M are multiples of 4 */
+{
+   int i, j;
+   VARDECL(spx_word16_t *xx);
+   
+   ALLOC(xx, M+N-1, spx_word16_t);
+
+   for (i = 0; i < N/2; i++)
+      xx[2*i] = SHR(x[N/2-1-i],SIG_SHIFT+1);
+   for (i = 0; i < M - 1; i += 2)
+      xx[N+i] = mem[i+1];
+
+   for (i = 0; i < N; i += 4) {
+      spx_sig_t y0, y1, y2, y3;
+      spx_word16_t x0;
+
+      y0 = y1 = y2 = y3 = 0;
+      x0 = xx[N-4-i];
+
+      for (j = 0; j < M; j += 4) {
+         spx_word16_t x1;
+         spx_word16_t a0, a1;
+
+         a0 = a[j];
+         a1 = a[j+1];
+         x1 = xx[N-2+j-i];
+
+         y0 = ADD32(y0,SHR(MULT16_16(a0, x1),1));
+         y1 = ADD32(y1,SHR(MULT16_16(a1, x1),1));
+         y2 = ADD32(y2,SHR(MULT16_16(a0, x0),1));
+         y3 = ADD32(y3,SHR(MULT16_16(a1, x0),1));
+
+         a0 = a[j+2];
+         a1 = a[j+3];
+         x0 = xx[N+j-i];
+
+         y0 = ADD32(y0,SHR(MULT16_16(a0, x0),1));
+         y1 = ADD32(y1,SHR(MULT16_16(a1, x0),1));
+         y2 = ADD32(y2,SHR(MULT16_16(a0, x1),1));
+         y3 = ADD32(y3,SHR(MULT16_16(a1, x1),1));
+      }
+      y[i] = y0;
+      y[i+1] = y1;
+      y[i+2] = y2;
+      y[i+3] = y3;
+   }
+
+   for (i = 0; i < M - 1; i += 2)
+      mem[i+1] = xx[i];
+}
+
+
+
+void comb_filter_mem_init (CombFilterMem *mem)
+{
+   mem->last_pitch=0;
+   mem->last_pitch_gain[0]=mem->last_pitch_gain[1]=mem->last_pitch_gain[2]=0;
+   mem->smooth_gain=1;
+}
+
+#ifdef FIXED_POINT
+#define COMB_STEP 32767
+#else
+#define COMB_STEP 1.0
+#endif
+
+void comb_filter(
+spx_sig_t *exc,          /*decoded excitation*/
+spx_sig_t *new_exc,      /*enhanced excitation*/
+spx_coef_t *ak,           /*LPC filter coefs*/
+int p,               /*LPC order*/
+int nsf,             /*sub-frame size*/
+int pitch,           /*pitch period*/
+spx_word16_t *pitch_gain,   /*pitch gain (3-tap)*/
+spx_word16_t  comb_gain,    /*gain of comb filter*/
+CombFilterMem *mem
+)
+{
+   int i;
+   spx_word16_t exc_energy=0, new_exc_energy=0;
+   spx_word16_t gain;
+   spx_word16_t step;
+   spx_word16_t fact;
+
+   /*Compute excitation amplitude prior to enhancement*/
+   exc_energy = compute_rms(exc, nsf);
+   /*for (i=0;i<nsf;i++)
+     exc_energy+=((float)exc[i])*exc[i];*/
+
+   /*Some gain adjustment if pitch is too high or if unvoiced*/
+#ifdef FIXED_POINT
+   {
+      spx_word16_t g = gain_3tap_to_1tap(pitch_gain)+gain_3tap_to_1tap(mem->last_pitch_gain);
+      if (g > 166)
+         comb_gain = MULT16_16_Q15(DIV32_16(SHL(165,15),g), comb_gain);
+      if (g < 64)
+         comb_gain = MULT16_16_Q15(SHL(g, 9), comb_gain);
+   }
+#else
+   {
+      float g=0;
+      g = GAIN_SCALING_1*.5*(gain_3tap_to_1tap(pitch_gain)+gain_3tap_to_1tap(mem->last_pitch_gain));
+      if (g>1.3)
+         comb_gain*=1.3/g;
+      if (g<.5)
+         comb_gain*=2.*g;
+   }
+#endif
+   step = DIV32(COMB_STEP, nsf);
+   fact=0;
+
+   /*Apply pitch comb-filter (filter out noise between pitch harmonics)*/
+   for (i=0;i<nsf;i++)
+   {
+      spx_word32_t exc1, exc2;
+
+      fact = ADD16(fact,step);
+      
+      exc1 = SHL32(MULT16_32_Q15(SHL16(pitch_gain[0],7),exc[i-pitch+1]) +
+                 MULT16_32_Q15(SHL16(pitch_gain[1],7),exc[i-pitch]) +
+                 MULT16_32_Q15(SHL16(pitch_gain[2],7),exc[i-pitch-1]) , 2);
+      exc2 = SHL32(MULT16_32_Q15(SHL16(mem->last_pitch_gain[0],7),exc[i-mem->last_pitch+1]) +
+                 MULT16_32_Q15(SHL16(mem->last_pitch_gain[1],7),exc[i-mem->last_pitch]) +
+                 MULT16_32_Q15(SHL16(mem->last_pitch_gain[2],7),exc[i-mem->last_pitch-1]),2);
+
+      new_exc[i] = exc[i] + MULT16_32_Q15(comb_gain, ADD32(MULT16_32_Q15(fact,exc1), MULT16_32_Q15(SUB16(COMB_STEP,fact), exc2)));
+   }
+
+   mem->last_pitch_gain[0] = pitch_gain[0];
+   mem->last_pitch_gain[1] = pitch_gain[1];
+   mem->last_pitch_gain[2] = pitch_gain[2];
+   mem->last_pitch = pitch;
+
+   /*Amplitude after enhancement*/
+   new_exc_energy = compute_rms(new_exc, nsf);
+
+   if (exc_energy > new_exc_energy)
+      exc_energy = new_exc_energy;
+   
+   gain = DIV32_16(SHL32(EXTEND32(exc_energy),15),ADD16(1,new_exc_energy));
+
+#ifdef FIXED_POINT
+   if (gain < 16384)
+      gain = 16384;
+#else
+   if (gain < .5)
+      gain=.5;
+#endif
+
+#ifdef FIXED_POINT
+   for (i=0;i<nsf;i++)
+   {
+      mem->smooth_gain = ADD16(MULT16_16_Q15(31457,mem->smooth_gain), MULT16_16_Q15(1311,gain));
+      new_exc[i] = MULT16_32_Q15(mem->smooth_gain, new_exc[i]);
+   }
+#else
+   for (i=0;i<nsf;i++)
+   {
+      mem->smooth_gain = .96*mem->smooth_gain + .04*gain;
+      new_exc[i] *= mem->smooth_gain;
+   }
+#endif
+}
diff --git a/utils/iaxclient/lib/libspeex/filters.h b/utils/iaxclient/lib/libspeex/filters.h
new file mode 100644 (file)
index 0000000..de0b284
--- /dev/null
@@ -0,0 +1,89 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: filters.h
+   Various analysis/synthesis filters
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifndef FILTERS_H
+#define FILTERS_H
+
+#include "misc.h"
+
+spx_word16_t compute_rms(const spx_sig_t *x, int len);
+void signal_mul(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len);
+void signal_div(const spx_sig_t *x, spx_sig_t *y, spx_word32_t scale, int len);
+
+#ifdef FIXED_POINT
+
+int normalize16(const spx_sig_t *x, spx_word16_t *y, spx_sig_t max_scale, int len);
+
+#endif
+
+typedef struct CombFilterMem {
+   int   last_pitch;
+   spx_word16_t last_pitch_gain[3];
+   spx_word16_t smooth_gain;
+} CombFilterMem;
+
+
+void qmf_decomp(const spx_word16_t *xx, const spx_word16_t *aa, spx_sig_t *, spx_sig_t *y2, int N, int M, spx_word16_t *mem, char *stack);
+void fir_mem_up(const spx_sig_t *x, const spx_word16_t *a, spx_sig_t *y, int N, int M, spx_word32_t *mem, char *stack);
+
+
+void filter_mem2(const spx_sig_t *x, const spx_coef_t *num, const spx_coef_t *den, spx_sig_t *y, int N, int ord, spx_mem_t *mem);
+void fir_mem2(const spx_sig_t *x, const spx_coef_t *num, spx_sig_t *y, int N, int ord, spx_mem_t *mem);
+void iir_mem2(const spx_sig_t *x, const spx_coef_t *den, spx_sig_t *y, int N, int ord, spx_mem_t *mem);
+
+/* Apply bandwidth expansion on LPC coef */
+void bw_lpc(spx_word16_t , const spx_coef_t *lpc_in, spx_coef_t *lpc_out, int order);
+
+
+
+void syn_percep_zero(const spx_sig_t *x, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_sig_t *y, int N, int ord, char *stack);
+
+void residue_percep_zero(const spx_sig_t *xx, const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_sig_t *y, int N, int ord, char *stack);
+
+void compute_impulse_response(const spx_coef_t *ak, const spx_coef_t *awk1, const spx_coef_t *awk2, spx_word16_t *y, int N, int ord, char *stack);
+
+void comb_filter_mem_init (CombFilterMem *mem);
+
+void comb_filter(
+spx_sig_t *exc,          /*decoded excitation*/
+spx_sig_t *new_exc,      /*enhanced excitation*/
+spx_coef_t *ak,           /*LPC filter coefs*/
+int p,               /*LPC order*/
+int nsf,             /*sub-frame size*/
+int pitch,           /*pitch period*/
+spx_word16_t *pitch_gain,   /*pitch gain (3-tap)*/
+spx_word16_t  comb_gain,    /*gain of comb filter*/
+CombFilterMem *mem
+);
+
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/filters_arm4.h b/utils/iaxclient/lib/libspeex/filters_arm4.h
new file mode 100644 (file)
index 0000000..8a8a73b
--- /dev/null
@@ -0,0 +1,375 @@
+/* Copyright (C) 2004 Jean-Marc Valin 
+   File: filters_arm4.h
+   ARM4-optimized filtering routines
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+int normalize16(const spx_sig_t *x, spx_word16_t *y, int max_scale, int len)
+{
+   int i;
+   spx_sig_t max_val=1;
+   int sig_shift;
+   int dead1, dead2, dead3, dead4, dead5, dead6;
+
+   __asm__ __volatile__ (
+         "\tmov %1, #1 \n"
+         "\tmov %3, #0 \n"
+
+         ".normalize16loop1%=: \n"
+
+         "\tldr %4, [%0], #4 \n"
+         "\tcmps %4, %1 \n"
+         "\tmovgt %1, %4 \n"
+         "\tcmps %4, %3 \n"
+         "\tmovlt %3, %4 \n"
+
+         "\tsubs %2, %2, #1 \n"
+         "\tbne .normalize16loop1%=\n"
+
+         "\trsb %3, %3, #0 \n"
+         "\tcmp %1, %3 \n"
+         "\tmovlt %1, %3 \n"
+   : "=r" (dead1), "=r" (max_val), "=r" (dead3), "=r" (dead4),
+   "=r" (dead5), "=r" (dead6)
+   : "0" (x), "2" (len)
+   : "cc");
+
+   sig_shift=0;
+   while (max_val>max_scale)
+   {
+      sig_shift++;
+      max_val >>= 1;
+   }
+   
+   __asm__ __volatile__ (
+         ".normalize16loop%=: \n"
+
+         "\tldr %4, [%0], #4 \n"
+         "\tldr %5, [%0], #4 \n"
+         "\tmov %4, %4, asr %3 \n"
+         "\tstrh %4, [%1], #2 \n"
+         "\tldr %4, [%0], #4 \n"
+         "\tmov %5, %5, asr %3 \n"
+         "\tstrh %5, [%1], #2 \n"
+         "\tldr %5, [%0], #4 \n"
+         "\tmov %4, %4, asr %3 \n"
+         "\tstrh %4, [%1], #2 \n"
+         "\tsubs %2, %2, #1 \n"
+         "\tmov %5, %5, asr %3 \n"
+         "\tstrh %5, [%1], #2 \n"
+
+         "\tbge .normalize16loop%=\n"
+   : "=r" (dead1), "=r" (dead2), "=r" (dead3), "=r" (dead4),
+   "=r" (dead5), "=r" (dead6)
+   : "0" (x), "1" (y), "2" (len>>2), "3" (sig_shift)
+   : "cc", "memory");
+   return sig_shift;
+}
+
+
+void filter_mem2(const spx_sig_t *x, const spx_coef_t *num, const spx_coef_t *den, spx_sig_t *y, int N, int ord, spx_mem_t *mem)
+{
+   int i,j;
+   spx_sig_t xi,yi,nyi;
+
+   for (i=0;i<N;i++)
+   {
+      int deadm, deadn, deadd, deadidx, x1, y1, dead1, dead2, dead3, dead4, dead5, dead6;
+      xi=SATURATE(x[i],805306368);
+      yi = SATURATE(ADD32(xi, SHL(mem[0],2)),805306368);
+      nyi = -yi;
+      y[i] = yi;
+      __asm__ __volatile__ (
+            "\tldrsh %6, [%1], #2\n"
+            "\tsmull %8, %9, %4, %6\n"
+#ifdef SHORTCUTS
+            "\tldrsh %6, [%2], #2\n"
+            "\tldr %10, [%0, #4]\n"
+            "\tmov %8, %8, lsr #15\n"
+            "\tsmull %7, %11, %5, %6\n"
+            "\tldrsh %6, [%1], #2\n"
+            "\tadd %8, %8, %9, lsl #17\n"
+            "\tadd %10, %10, %8\n"
+            "\tsmull %8, %9, %4, %6\n"
+            "\tadd %10, %10, %7, lsr #15\n"
+            "\tadd %10, %10, %11, lsl #17\n"
+            "\tstr %10, [%0], #4 \n"
+
+            "\tldrsh %6, [%2], #2\n"
+            "\tldr %10, [%0, #4]\n"
+            "\tmov %8, %8, lsr #15\n"
+            "\tsmull %7, %11, %5, %6\n"
+            "\tldrsh %6, [%1], #2\n"
+            "\tadd %8, %8, %9, lsl #17\n"
+            "\tadd %10, %10, %8\n"
+            "\tsmull %8, %9, %4, %6\n"
+            "\tadd %10, %10, %7, lsr #15\n"
+            "\tadd %10, %10, %11, lsl #17\n"
+            "\tstr %10, [%0], #4 \n"
+
+            "\tldrsh %6, [%2], #2\n"
+            "\tldr %10, [%0, #4]\n"
+            "\tmov %8, %8, lsr #15\n"
+            "\tsmull %7, %11, %5, %6\n"
+            "\tldrsh %6, [%1], #2\n"
+            "\tadd %8, %8, %9, lsl #17\n"
+            "\tadd %10, %10, %8\n"
+            "\tsmull %8, %9, %4, %6\n"
+            "\tadd %10, %10, %7, lsr #15\n"
+            "\tadd %10, %10, %11, lsl #17\n"
+            "\tstr %10, [%0], #4 \n"
+
+            "\tldrsh %6, [%2], #2\n"
+            "\tldr %10, [%0, #4]\n"
+            "\tmov %8, %8, lsr #15\n"
+            "\tsmull %7, %11, %5, %6\n"
+            "\tldrsh %6, [%1], #2\n"
+            "\tadd %8, %8, %9, lsl #17\n"
+            "\tadd %10, %10, %8\n"
+            "\tsmull %8, %9, %4, %6\n"
+            "\tadd %10, %10, %7, lsr #15\n"
+            "\tadd %10, %10, %11, lsl #17\n"
+            "\tstr %10, [%0], #4 \n"
+
+            "\tldrsh %6, [%2], #2\n"
+            "\tldr %10, [%0, #4]\n"
+            "\tmov %8, %8, lsr #15\n"
+            "\tsmull %7, %11, %5, %6\n"
+            "\tldrsh %6, [%1], #2\n"
+            "\tadd %8, %8, %9, lsl #17\n"
+            "\tadd %10, %10, %8\n"
+            "\tsmull %8, %9, %4, %6\n"
+            "\tadd %10, %10, %7, lsr #15\n"
+            "\tadd %10, %10, %11, lsl #17\n"
+            "\tstr %10, [%0], #4 \n"
+
+            "\tldrsh %6, [%2], #2\n"
+            "\tldr %10, [%0, #4]\n"
+            "\tmov %8, %8, lsr #15\n"
+            "\tsmull %7, %11, %5, %6\n"
+            "\tldrsh %6, [%1], #2\n"
+            "\tadd %8, %8, %9, lsl #17\n"
+            "\tadd %10, %10, %8\n"
+            "\tsmull %8, %9, %4, %6\n"
+            "\tadd %10, %10, %7, lsr #15\n"
+            "\tadd %10, %10, %11, lsl #17\n"
+            "\tstr %10, [%0], #4 \n"
+
+            "\tldrsh %6, [%2], #2\n"
+            "\tldr %10, [%0, #4]\n"
+            "\tmov %8, %8, lsr #15\n"
+            "\tsmull %7, %11, %5, %6\n"
+            "\tldrsh %6, [%1], #2\n"
+            "\tadd %8, %8, %9, lsl #17\n"
+            "\tadd %10, %10, %8\n"
+            "\tsmull %8, %9, %4, %6\n"
+            "\tadd %10, %10, %7, lsr #15\n"
+            "\tadd %10, %10, %11, lsl #17\n"
+            "\tstr %10, [%0], #4 \n"
+
+            "\tldrsh %6, [%2], #2\n"
+            "\tldr %10, [%0, #4]\n"
+            "\tmov %8, %8, lsr #15\n"
+            "\tsmull %7, %11, %5, %6\n"
+            "\tldrsh %6, [%1], #2\n"
+            "\tadd %8, %8, %9, lsl #17\n"
+            "\tadd %10, %10, %8\n"
+            "\tsmull %8, %9, %4, %6\n"
+            "\tadd %10, %10, %7, lsr #15\n"
+            "\tadd %10, %10, %11, lsl #17\n"
+            "\tstr %10, [%0], #4 \n"
+
+            "\tldrsh %6, [%2], #2\n"
+            "\tldr %10, [%0, #4]\n"
+            "\tmov %8, %8, lsr #15\n"
+            "\tsmull %7, %11, %5, %6\n"
+            "\tldrsh %6, [%1], #2\n"
+            "\tadd %8, %8, %9, lsl #17\n"
+            "\tadd %10, %10, %8\n"
+            "\tsmull %8, %9, %4, %6\n"
+            "\tadd %10, %10, %7, lsr #15\n"
+            "\tadd %10, %10, %11, lsl #17\n"
+            "\tstr %10, [%0], #4 \n"
+
+
+#else
+            ".filterloop%=: \n"
+            "\tldrsh %6, [%2], #2\n"
+            "\tldr %10, [%0, #4]\n"
+            "\tmov %8, %8, lsr #15\n"
+            "\tsmull %7, %11, %5, %6\n"
+            "\tadd %8, %8, %9, lsl #17\n"
+            "\tldrsh %6, [%1], #2\n"
+            "\tadd %10, %10, %8\n"
+            "\tsmull %8, %9, %4, %6\n"
+            "\tadd %10, %10, %7, lsr #15\n"
+            "\tsubs %3, %3, #1\n"
+            "\tadd %10, %10, %11, lsl #17\n"
+            "\tstr %10, [%0], #4 \n"
+            "\t bne .filterloop%=\n"
+#endif
+            "\tmov %8, %8, lsr #15\n"
+            "\tadd %10, %8, %9, lsl #17\n"
+            "\tldrsh %6, [%2], #2\n"
+            "\tsmull %8, %9, %5, %6\n"
+            "\tadd %10, %10, %8, lsr #15\n"
+            "\tadd %10, %10, %9, lsl #17\n"
+            "\tstr %10, [%0], #4 \n"
+
+         : "=r" (deadm), "=r" (deadn), "=r" (deadd), "=r" (deadidx),
+      "=r" (xi), "=r" (nyi), "=r" (dead1), "=r" (dead2),
+      "=r" (dead3), "=r" (dead4), "=r" (dead5), "=r" (dead6)
+         : "0" (mem), "1" (num+1), "2" (den+1), "3" (ord-1), "4" (xi), "5" (nyi)
+         : "cc", "memory");
+   
+   }
+}
+
+void iir_mem2(const spx_sig_t *x, const spx_coef_t *den, spx_sig_t *y, int N, int ord, spx_mem_t *mem)
+{
+   int i,j;
+   spx_sig_t xi,yi,nyi;
+
+   for (i=0;i<N;i++)
+   {
+      int deadm, deadd, deadidx, dead1, dead2, dead3, dead4, dead5, dead6;
+      xi=SATURATE(x[i],805306368);
+      yi = SATURATE(ADD32(xi, SHL(mem[0],2)),805306368);
+      nyi = -yi;
+      y[i] = yi;
+      __asm__ __volatile__ (
+            "\tldrsh %4, [%1], #2\n"
+            "\tsmull %5, %6, %3, %4\n"
+
+#ifdef SHORTCUTS
+                        
+            "\tldrsh %4, [%1], #2\n"
+            "\tmov %5, %5, lsr #15\n"
+            "\tldr %7, [%0, #4]\n"
+            "\tadd %8, %5, %6, lsl #17\n"
+            "\tsmull %5, %6, %3, %4\n"
+            "\tadd %7, %7, %8\n"
+            "\tstr %7, [%0], #4 \n"
+
+                 
+            "\tldrsh %4, [%1], #2\n"
+            "\tmov %5, %5, lsr #15\n"
+            "\tldr %9, [%0, #4]\n"
+            "\tadd %8, %5, %6, lsl #17\n"
+            "\tsmull %5, %6, %3, %4\n"
+            "\tadd %9, %9, %8\n"
+            "\tstr %9, [%0], #4 \n"
+
+            "\tldrsh %4, [%1], #2\n"
+            "\tmov %5, %5, lsr #15\n"
+            "\tldr %7, [%0, #4]\n"
+            "\tadd %8, %5, %6, lsl #17\n"
+            "\tsmull %5, %6, %3, %4\n"
+            "\tadd %7, %7, %8\n"
+            "\tstr %7, [%0], #4 \n"
+
+            
+            "\tldrsh %4, [%1], #2\n"
+            "\tmov %5, %5, lsr #15\n"
+            "\tldr %9, [%0, #4]\n"
+            "\tadd %8, %5, %6, lsl #17\n"
+            "\tsmull %5, %6, %3, %4\n"
+            "\tadd %9, %9, %8\n"
+            "\tstr %9, [%0], #4 \n"
+
+            "\tldrsh %4, [%1], #2\n"
+            "\tmov %5, %5, lsr #15\n"
+            "\tldr %7, [%0, #4]\n"
+            "\tadd %8, %5, %6, lsl #17\n"
+            "\tsmull %5, %6, %3, %4\n"
+            "\tadd %7, %7, %8\n"
+            "\tstr %7, [%0], #4 \n"
+
+            
+            "\tldrsh %4, [%1], #2\n"
+            "\tmov %5, %5, lsr #15\n"
+            "\tldr %9, [%0, #4]\n"
+            "\tadd %8, %5, %6, lsl #17\n"
+            "\tsmull %5, %6, %3, %4\n"
+            "\tadd %9, %9, %8\n"
+            "\tstr %9, [%0], #4 \n"
+
+            "\tldrsh %4, [%1], #2\n"
+            "\tmov %5, %5, lsr #15\n"
+            "\tldr %7, [%0, #4]\n"
+            "\tadd %8, %5, %6, lsl #17\n"
+            "\tsmull %5, %6, %3, %4\n"
+            "\tadd %7, %7, %8\n"
+            "\tstr %7, [%0], #4 \n"
+
+            
+            "\tldrsh %4, [%1], #2\n"
+            "\tmov %5, %5, lsr #15\n"
+            "\tldr %9, [%0, #4]\n"
+            "\tadd %8, %5, %6, lsl #17\n"
+            "\tsmull %5, %6, %3, %4\n"
+            "\tadd %9, %9, %8\n"
+            "\tstr %9, [%0], #4 \n"
+
+            "\tldrsh %4, [%1], #2\n"
+            "\tmov %5, %5, lsr #15\n"
+            "\tldr %7, [%0, #4]\n"
+            "\tadd %8, %5, %6, lsl #17\n"
+            "\tsmull %5, %6, %3, %4\n"
+            "\tadd %7, %7, %8\n"
+            "\tstr %7, [%0], #4 \n"
+
+            
+            
+#else
+            ".iirloop%=: \n"
+            "\tldr %7, [%0, #4]\n"
+
+            "\tldrsh %4, [%1], #2\n"
+            "\tmov %5, %5, lsr #15\n"
+            "\tadd %8, %5, %6, lsl #17\n"
+            "\tsmull %5, %6, %3, %4\n"
+            "\tadd %7, %7, %8\n"
+            "\tstr %7, [%0], #4 \n"
+            "\tsubs %2, %2, #1\n"
+            "\t bne .iirloop%=\n"
+            
+#endif
+            "\tmov %5, %5, lsr #15\n"
+            "\tadd %7, %5, %6, lsl #17\n"
+            "\tstr %7, [%0], #4 \n"
+
+         : "=r" (deadm), "=r" (deadd), "=r" (deadidx), "=r" (nyi),
+      "=r" (dead1), "=r" (dead2), "=r" (dead3), "=r" (dead4),
+      "=r" (dead5), "=r" (dead6)
+         : "0" (mem), "1" (den+1), "2" (ord-1), "3" (nyi)
+         : "cc", "memory");
+   
+   }
+}
diff --git a/utils/iaxclient/lib/libspeex/filters_sse.h b/utils/iaxclient/lib/libspeex/filters_sse.h
new file mode 100644 (file)
index 0000000..d99c033
--- /dev/null
@@ -0,0 +1,333 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: filters.c
+   Various analysis/synthesis filters
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <xmmintrin.h>
+
+void filter_mem2_10(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem)
+{
+   __m128 num[3], den[3], mem[3];
+
+   int i;
+
+   /* Copy numerator, denominator and memory to aligned xmm */
+   for (i=0;i<2;i++)
+   {
+      mem[i] = _mm_loadu_ps(_mem+4*i);
+      num[i] = _mm_loadu_ps(_num+4*i+1);
+      den[i] = _mm_loadu_ps(_den+4*i+1);
+   }
+   mem[2] = _mm_setr_ps(_mem[8], _mem[9], 0, 0);
+   num[2] = _mm_setr_ps(_num[9], _num[10], 0, 0);
+   den[2] = _mm_setr_ps(_den[9], _den[10], 0, 0);
+   
+   for (i=0;i<N;i++)
+   {
+      __m128 xx;
+      __m128 yy;
+      /* Compute next filter result */
+      xx = _mm_load_ps1(x+i);
+      yy = _mm_add_ss(xx, mem[0]);
+      _mm_store_ss(y+i, yy);
+      yy = _mm_shuffle_ps(yy, yy, 0);
+      
+      /* Update memory */
+      mem[0] = _mm_move_ss(mem[0], mem[1]);
+      mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39);
+
+      mem[0] = _mm_add_ps(mem[0], _mm_mul_ps(xx, num[0]));
+      mem[0] = _mm_sub_ps(mem[0], _mm_mul_ps(yy, den[0]));
+
+      mem[1] = _mm_move_ss(mem[1], mem[2]);
+      mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39);
+
+      mem[1] = _mm_add_ps(mem[1], _mm_mul_ps(xx, num[1]));
+      mem[1] = _mm_sub_ps(mem[1], _mm_mul_ps(yy, den[1]));
+
+      mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0xfd);
+
+      mem[2] = _mm_add_ps(mem[2], _mm_mul_ps(xx, num[2]));
+      mem[2] = _mm_sub_ps(mem[2], _mm_mul_ps(yy, den[2]));
+   }
+   /* Put memory back in its place */
+   _mm_storeu_ps(_mem, mem[0]);
+   _mm_storeu_ps(_mem+4, mem[1]);
+   _mm_store_ss(_mem+8, mem[2]);
+   mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0x55);
+   _mm_store_ss(_mem+9, mem[2]);
+}
+
+void filter_mem2_8(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem)
+{
+   __m128 num[2], den[2], mem[2];
+
+   int i;
+
+   /* Copy numerator, denominator and memory to aligned xmm */
+   for (i=0;i<2;i++)
+   {
+      mem[i] = _mm_loadu_ps(_mem+4*i);
+      num[i] = _mm_loadu_ps(_num+4*i+1);
+      den[i] = _mm_loadu_ps(_den+4*i+1);
+   }
+   
+   for (i=0;i<N;i++)
+   {
+      __m128 xx;
+      __m128 yy;
+      /* Compute next filter result */
+      xx = _mm_load_ps1(x+i);
+      yy = _mm_add_ss(xx, mem[0]);
+      _mm_store_ss(y+i, yy);
+      yy = _mm_shuffle_ps(yy, yy, 0);
+      
+      /* Update memory */
+      mem[0] = _mm_move_ss(mem[0], mem[1]);
+      mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39);
+
+      mem[0] = _mm_add_ps(mem[0], _mm_mul_ps(xx, num[0]));
+      mem[0] = _mm_sub_ps(mem[0], _mm_mul_ps(yy, den[0]));
+
+      mem[1] = _mm_sub_ss(mem[1], mem[1]);
+      mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39);
+
+      mem[1] = _mm_add_ps(mem[1], _mm_mul_ps(xx, num[1]));
+      mem[1] = _mm_sub_ps(mem[1], _mm_mul_ps(yy, den[1]));
+   }
+   /* Put memory back in its place */
+   _mm_storeu_ps(_mem, mem[0]);
+   _mm_storeu_ps(_mem+4, mem[1]);
+}
+
+
+
+void filter_mem2(const float *x, const float *_num, const float *_den, float *y, int N, int ord, float *_mem)
+{
+   if(ord==10)
+      filter_mem2_10(x, _num, _den, y, N, ord, _mem);
+   else if (ord==8)
+      filter_mem2_8(x, _num, _den, y, N, ord, _mem);
+}
+
+
+
+void iir_mem2_10(const float *x, const float *_den, float *y, int N, int ord, float *_mem)
+{
+   __m128 den[3], mem[3];
+
+   int i;
+
+   /* Copy numerator, denominator and memory to aligned xmm */
+   for (i=0;i<2;i++)
+   {
+      mem[i] = _mm_loadu_ps(_mem+4*i);
+      den[i] = _mm_loadu_ps(_den+4*i+1);
+   }
+   mem[2] = _mm_setr_ps(_mem[8], _mem[9], 0, 0);
+   den[2] = _mm_setr_ps(_den[9], _den[10], 0, 0);
+   
+   for (i=0;i<N;i++)
+   {
+      __m128 xx;
+      __m128 yy;
+      /* Compute next filter result */
+      xx = _mm_load_ps1(x+i);
+      yy = _mm_add_ss(xx, mem[0]);
+      _mm_store_ss(y+i, yy);
+      yy = _mm_shuffle_ps(yy, yy, 0);
+      
+      /* Update memory */
+      mem[0] = _mm_move_ss(mem[0], mem[1]);
+      mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39);
+
+      mem[0] = _mm_sub_ps(mem[0], _mm_mul_ps(yy, den[0]));
+
+      mem[1] = _mm_move_ss(mem[1], mem[2]);
+      mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39);
+
+      mem[1] = _mm_sub_ps(mem[1], _mm_mul_ps(yy, den[1]));
+
+      mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0xfd);
+
+      mem[2] = _mm_sub_ps(mem[2], _mm_mul_ps(yy, den[2]));
+   }
+   /* Put memory back in its place */
+   _mm_storeu_ps(_mem, mem[0]);
+   _mm_storeu_ps(_mem+4, mem[1]);
+   _mm_store_ss(_mem+8, mem[2]);
+   mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0x55);
+   _mm_store_ss(_mem+9, mem[2]);
+}
+
+
+void iir_mem2_8(const float *x, const float *_den, float *y, int N, int ord, float *_mem)
+{
+   __m128 den[2], mem[2];
+
+   int i;
+
+   /* Copy numerator, denominator and memory to aligned xmm */
+   for (i=0;i<2;i++)
+   {
+      mem[i] = _mm_loadu_ps(_mem+4*i);
+      den[i] = _mm_loadu_ps(_den+4*i+1);
+   }
+   
+   for (i=0;i<N;i++)
+   {
+      __m128 xx;
+      __m128 yy;
+      /* Compute next filter result */
+      xx = _mm_load_ps1(x+i);
+      yy = _mm_add_ss(xx, mem[0]);
+      _mm_store_ss(y+i, yy);
+      yy = _mm_shuffle_ps(yy, yy, 0);
+      
+      /* Update memory */
+      mem[0] = _mm_move_ss(mem[0], mem[1]);
+      mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39);
+
+      mem[0] = _mm_sub_ps(mem[0], _mm_mul_ps(yy, den[0]));
+
+      mem[1] = _mm_sub_ss(mem[1], mem[1]);
+      mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39);
+
+      mem[1] = _mm_sub_ps(mem[1], _mm_mul_ps(yy, den[1]));
+   }
+   /* Put memory back in its place */
+   _mm_storeu_ps(_mem, mem[0]);
+   _mm_storeu_ps(_mem+4, mem[1]);
+}
+
+void iir_mem2(const float *x, const float *_den, float *y, int N, int ord, float *_mem)
+{
+   if(ord==10)
+      iir_mem2_10(x, _den, y, N, ord, _mem);
+   else if (ord==8)
+      iir_mem2_8(x, _den, y, N, ord, _mem);
+}
+
+
+void fir_mem2_10(const float *x, const float *_num, float *y, int N, int ord, float *_mem)
+{
+   __m128 num[3], mem[3];
+
+   int i;
+
+   /* Copy numerator, denominator and memory to aligned xmm */
+   for (i=0;i<2;i++)
+   {
+      mem[i] = _mm_loadu_ps(_mem+4*i);
+      num[i] = _mm_loadu_ps(_num+4*i+1);
+   }
+   mem[2] = _mm_setr_ps(_mem[8], _mem[9], 0, 0);
+   num[2] = _mm_setr_ps(_num[9], _num[10], 0, 0);
+   
+   for (i=0;i<N;i++)
+   {
+      __m128 xx;
+      __m128 yy;
+      /* Compute next filter result */
+      xx = _mm_load_ps1(x+i);
+      yy = _mm_add_ss(xx, mem[0]);
+      _mm_store_ss(y+i, yy);
+      yy = _mm_shuffle_ps(yy, yy, 0);
+      
+      /* Update memory */
+      mem[0] = _mm_move_ss(mem[0], mem[1]);
+      mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39);
+
+      mem[0] = _mm_add_ps(mem[0], _mm_mul_ps(xx, num[0]));
+
+      mem[1] = _mm_move_ss(mem[1], mem[2]);
+      mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39);
+
+      mem[1] = _mm_add_ps(mem[1], _mm_mul_ps(xx, num[1]));
+
+      mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0xfd);
+
+      mem[2] = _mm_add_ps(mem[2], _mm_mul_ps(xx, num[2]));
+   }
+   /* Put memory back in its place */
+   _mm_storeu_ps(_mem, mem[0]);
+   _mm_storeu_ps(_mem+4, mem[1]);
+   _mm_store_ss(_mem+8, mem[2]);
+   mem[2] = _mm_shuffle_ps(mem[2], mem[2], 0x55);
+   _mm_store_ss(_mem+9, mem[2]);
+}
+
+void fir_mem2_8(const float *x, const float *_num, float *y, int N, int ord, float *_mem)
+{
+   __m128 num[2], mem[2];
+
+   int i;
+
+   /* Copy numerator, denominator and memory to aligned xmm */
+   for (i=0;i<2;i++)
+   {
+      mem[i] = _mm_loadu_ps(_mem+4*i);
+      num[i] = _mm_loadu_ps(_num+4*i+1);
+   }
+   
+   for (i=0;i<N;i++)
+   {
+      __m128 xx;
+      __m128 yy;
+      /* Compute next filter result */
+      xx = _mm_load_ps1(x+i);
+      yy = _mm_add_ss(xx, mem[0]);
+      _mm_store_ss(y+i, yy);
+      yy = _mm_shuffle_ps(yy, yy, 0);
+      
+      /* Update memory */
+      mem[0] = _mm_move_ss(mem[0], mem[1]);
+      mem[0] = _mm_shuffle_ps(mem[0], mem[0], 0x39);
+
+      mem[0] = _mm_add_ps(mem[0], _mm_mul_ps(xx, num[0]));
+
+      mem[1] = _mm_sub_ss(mem[1], mem[1]);
+      mem[1] = _mm_shuffle_ps(mem[1], mem[1], 0x39);
+
+      mem[1] = _mm_add_ps(mem[1], _mm_mul_ps(xx, num[1]));
+   }
+   /* Put memory back in its place */
+   _mm_storeu_ps(_mem, mem[0]);
+   _mm_storeu_ps(_mem+4, mem[1]);
+}
+
+
+void fir_mem2(const float *x, const float *_num, float *y, int N, int ord, float *_mem)
+{
+   if(ord==10)
+      fir_mem2_10(x, _num, y, N, ord, _mem);
+   else if (ord==8)
+      fir_mem2_8(x, _num, y, N, ord, _mem);
+}
diff --git a/utils/iaxclient/lib/libspeex/fixed_arm4.h b/utils/iaxclient/lib/libspeex/fixed_arm4.h
new file mode 100644 (file)
index 0000000..64fac38
--- /dev/null
@@ -0,0 +1,208 @@
+/* Copyright (C) 2004 Jean-Marc Valin */
+/**
+   @file fixed_generic.h
+   @brief ARM4 fixed-point operations
+*/
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifndef FIXED_ARM4_H
+#define FIXED_ARM4_H
+
+#define NEG16(x) (-(x))
+#define NEG32(x) (-(x))
+#define EXTRACT16(x) ((spx_word16_t)x)
+#define EXTEND32(x) ((spx_word32_t)x)
+#define SHR16(a,shift) ((a) >> (shift))
+#define SHL16(a,shift) ((a) << (shift))
+#define SHR32(a,shift) ((a) >> (shift))
+#define SHL32(a,shift) ((a) << (shift))
+#define PSHR16(a,shift) (SHR16((a)+(1<<((shift)-1)),shift))
+#define PSHR32(a,shift) (SHR32((a)+(1<<((shift)-1)),shift))
+#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
+#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
+
+#define SHR(a,shift) ((a) >> (shift))
+#define SHL(a,shift) ((a) << (shift))
+#define SATURATE(x,a) ((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))
+#define PSHR(a,shift) (SHR((a)+(1<<((shift)-1)),shift))
+
+#define ADD16(a,b) ((a)+(b))
+#define SUB16(a,b) ((a)-(b))
+#define ADD32(a,b) ((a)+(b))
+#define SUB32(a,b) ((a)-(b))
+#define ADD64(a,b) ((a)+(b))
+
+
+/* result fits in 16 bits */
+#define MULT16_16_16(a,b)     ((a)*(b))
+
+#define MULT16_16(a,b)     ((a)*(b))
+
+
+
+
+#define MAC16_16(c,a,b)     (ADD32((c),MULT16_16((a),(b))))
+#define MULT16_32_Q12(a,b) ADD32(MULT16_16((a),SHR((b),12)), SHR(MULT16_16((a),((b)&0x00000fff)),12))
+#define MULT16_32_Q13(a,b) ADD32(MULT16_16((a),SHR((b),13)), SHR(MULT16_16((a),((b)&0x00001fff)),13))
+//#define MULT16_32_Q14(a,b) ADD32(MULT16_16((a),SHR((b),14)), SHR(MULT16_16((a),((b)&0x00003fff)),14))
+static inline spx_word32_t MULT16_32_Q14(spx_word16_t x, spx_word32_t y) {
+  int res;
+  int dummy;
+  asm (
+        "smull  %0,%1,%2,%3 \n\t"
+        "mov %0, %0, lsr #14 \n\t"
+        "add %0, %0, %1, lsl #18 \n\t"
+   : "=&r"(res), "=&r" (dummy)
+   : "r"(y),"r"((int)x));
+  return(res);
+}
+
+#define MULT16_32_Q11(a,b) ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11))
+#define MAC16_32_Q11(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11)))
+
+//#define MULT16_32_Q15(a,b) ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))
+static inline spx_word32_t MULT16_32_Q15(spx_word16_t x, spx_word32_t y) {
+  int res;
+  int dummy;
+  asm (
+        "smull  %0,%1,%2,%3 \n\t"
+        "mov %0, %0, lsr #15 \n\t"
+        "add %0, %0, %1, lsl #17 \n\t"
+   : "=&r"(res), "=&r" (dummy)
+   : "r"(y),"r"((int)x));
+  return(res);
+}
+
+#define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)))
+
+
+#define MAC16_16_Q11(c,a,b)     (ADD32((c),SHR(MULT16_16((a),(b)),11)))
+#define MAC16_16_Q13(c,a,b)     (ADD32((c),SHR(MULT16_16((a),(b)),13)))
+
+#define MULT16_16_Q11_32(a,b) (SHR(MULT16_16((a),(b)),11))
+#define MULT16_16_Q13(a,b) (SHR(MULT16_16((a),(b)),13))
+#define MULT16_16_Q14(a,b) (SHR(MULT16_16((a),(b)),14))
+#define MULT16_16_Q15(a,b) (SHR(MULT16_16((a),(b)),15))
+
+#define MULT16_16_P13(a,b) (SHR(ADD32(4096,MULT16_16((a),(b))),13))
+#define MULT16_16_P14(a,b) (SHR(ADD32(8192,MULT16_16((a),(b))),14))
+#define MULT16_16_P15(a,b) (SHR(ADD32(16384,MULT16_16((a),(b))),15))
+
+#define MUL_16_32_R15(a,bh,bl) ADD32(MULT16_16((a),(bh)), SHR(MULT16_16((a),(bl)),15))
+
+
+
+static inline short DIV32_16(int a, int b)
+{
+   int res=0;
+   int dead1, dead2, dead3, dead4, dead5;
+   __asm__ __volatile__ (
+         "\teor %5, %0, %1\n"
+         "\tmovs %4, %0\n"
+         "\trsbmi %0, %0, #0 \n"
+         "\tmovs %4, %1\n"
+         "\trsbmi %1, %1, #0 \n"
+         "\tmov %4, #1\n"
+
+         "\tsubs %3, %0, %1, asl #14 \n"
+         "\tmovpl %0, %3 \n"
+         "\torrpl %2, %2, %4, asl #14 \n"
+
+         "\tsubs %3, %0, %1, asl #13 \n"
+         "\tmovpl %0, %3 \n"
+         "\torrpl %2, %2, %4, asl #13 \n"
+
+         "\tsubs %3, %0, %1, asl #12 \n"
+         "\tmovpl %0, %3 \n"
+         "\torrpl %2, %2, %4, asl #12 \n"
+
+         "\tsubs %3, %0, %1, asl #11 \n"
+         "\tmovpl %0, %3 \n"
+         "\torrpl %2, %2, %4, asl #11 \n"
+
+         "\tsubs %3, %0, %1, asl #10 \n"
+         "\tmovpl %0, %3 \n"
+         "\torrpl %2, %2, %4, asl #10 \n"
+
+         "\tsubs %3, %0, %1, asl #9 \n"
+         "\tmovpl %0, %3 \n"
+         "\torrpl %2, %2, %4, asl #9 \n"
+
+         "\tsubs %3, %0, %1, asl #8 \n"
+         "\tmovpl %0, %3 \n"
+         "\torrpl %2, %2, %4, asl #8 \n"
+
+         "\tsubs %3, %0, %1, asl #7 \n"
+         "\tmovpl %0, %3 \n"
+         "\torrpl %2, %2, %4, asl #7 \n"
+
+         "\tsubs %3, %0, %1, asl #6 \n"
+         "\tmovpl %0, %3 \n"
+         "\torrpl %2, %2, %4, asl #6 \n"
+         
+         "\tsubs %3, %0, %1, asl #5 \n"
+         "\tmovpl %0, %3 \n"
+         "\torrpl %2, %2, %4, asl #5 \n"
+
+         "\tsubs %3, %0, %1, asl #4 \n"
+         "\tmovpl %0, %3 \n"
+         "\torrpl %2, %2, %4, asl #4 \n"
+
+         "\tsubs %3, %0, %1, asl #3 \n"
+         "\tmovpl %0, %3 \n"
+         "\torrpl %2, %2, %4, asl #3 \n"
+
+         "\tsubs %3, %0, %1, asl #2 \n"
+         "\tmovpl %0, %3 \n"
+         "\torrpl %2, %2, %4, asl #2 \n"
+
+         "\tsubs %3, %0, %1, asl #1 \n"
+         "\tmovpl %0, %3 \n"
+         "\torrpl %2, %2, %4, asl #1 \n"
+
+         "\tsubs %3, %0, %1 \n"
+         "\tmovpl %0, %3 \n"
+         "\torrpl %2, %2, %4 \n"
+
+         "\tmovs %5, %5, lsr #31 \n"
+         "\trsbne %2, %2, #0 \n"
+   : "=r" (dead1), "=r" (dead2), "=r" (res),
+   "=r" (dead3), "=r" (dead4), "=r" (dead5)
+   : "0" (a), "1" (b), "2" (res)
+   : "cc"
+                        );
+   return res;
+}
+
+#define DIV32(a,b) (((signed int)(a))/((signed int)(b)))
+
+
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/fixed_arm5e.h b/utils/iaxclient/lib/libspeex/fixed_arm5e.h
new file mode 100644 (file)
index 0000000..44479e5
--- /dev/null
@@ -0,0 +1,221 @@
+/* Copyright (C) 2003 Jean-Marc Valin */
+/**
+   @file fixed_generic.h
+   @brief ARM-tuned fixed-point operations
+*/
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifndef FIXED_ARM5E_H
+#define FIXED_ARM5E_H
+
+#define NEG16(x) (-(x))
+#define NEG32(x) (-(x))
+#define EXTRACT16(x) ((spx_word16_t)x)
+#define EXTEND32(x) ((spx_word32_t)x)
+#define SHR16(a,shift) ((a) >> (shift))
+#define SHL16(a,shift) ((a) << (shift))
+#define SHR32(a,shift) ((a) >> (shift))
+#define SHL32(a,shift) ((a) << (shift))
+#define PSHR16(a,shift) (SHR16((a)+(1<<((shift)-1)),shift))
+#define PSHR32(a,shift) (SHR32((a)+(1<<((shift)-1)),shift))
+#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
+#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
+
+#define SHR(a,shift) ((a) >> (shift))
+#define SHL(a,shift) ((a) << (shift))
+#define SATURATE(x,a) ((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))
+#define PSHR(a,shift) (SHR((a)+(1<<((shift)-1)),shift))
+
+
+#define ADD16(a,b) ((short)((short)(a)+(short)(b)))
+#define SUB16(a,b) ((a)-(b))
+#define ADD32(a,b) ((a)+(b))
+#define SUB32(a,b) ((a)-(b))
+#define ADD64(a,b) ((a)+(b))
+
+
+/* result fits in 16 bits */
+#define MULT16_16_16(a,b)     (((short)(a))*((short)(b)))
+
+static inline spx_word32_t MULT16_16(spx_word16_t x, spx_word16_t y) {
+  int res;
+  asm ("smulbb  %0,%1,%2;\n"
+              : "=&r"(res)
+              : "%r"(x),"r"(y));
+  return(res);
+}
+
+static inline spx_word32_t MAC16_16(spx_word32_t a, spx_word16_t x, spx_word32_t y) {
+  int res;
+  asm ("smlabb  %0,%1,%2,%3;\n"
+              : "=&r"(res)
+               : "%r"(x),"r"(y),"r"(a));
+  return(res);
+}
+
+#define MULT16_32_Q12(a,b) ADD32(MULT16_16((a),SHR((b),12)), SHR(MULT16_16((a),((b)&0x00000fff)),12))
+#define MULT16_32_Q13(a,b) ADD32(MULT16_16((a),SHR((b),13)), SHR(MULT16_16((a),((b)&0x00001fff)),13))
+#define MULT16_32_Q14(a,b) ADD32(MULT16_16((a),SHR((b),14)), SHR(MULT16_16((a),((b)&0x00003fff)),14))
+
+static inline spx_word32_t MULT16_32_Q15(spx_word16_t x, spx_word32_t y) {
+  int res;
+  asm ("smulwb  %0,%1,%2;\n"
+              : "=&r"(res)
+               : "%r"(y<<1),"r"(x));
+  return(res);
+}
+static inline spx_word32_t MAC16_32_Q15(spx_word32_t a, spx_word16_t x, spx_word32_t y) {
+  int res;
+  asm ("smlawb  %0,%1,%2,%3;\n"
+              : "=&r"(res)
+               : "%r"(y<<1),"r"(x),"r"(a));
+  return(res);
+}
+static inline spx_word32_t MULT16_32_Q11(spx_word16_t x, spx_word32_t y) {
+  int res;
+  asm ("smulwb  %0,%1,%2;\n"
+              : "=&r"(res)
+               : "%r"(y<<5),"r"(x));
+  return(res);
+}
+static inline spx_word32_t MAC16_32_Q11(spx_word32_t a, spx_word16_t x, spx_word32_t y) {
+  int res;
+  asm ("smlawb  %0,%1,%2,%3;\n"
+              : "=&r"(res)
+               : "%r"(y<<5),"r"(x),"r"(a));
+  return(res);
+}
+
+#define MAC16_16_Q11(c,a,b)     (ADD32((c),SHR(MULT16_16((a),(b)),11)))
+#define MAC16_16_Q13(c,a,b)     (ADD32((c),SHR(MULT16_16((a),(b)),13)))
+
+#define MULT16_16_Q11_32(a,b) (SHR(MULT16_16((a),(b)),11))
+#define MULT16_16_Q13(a,b) (SHR(MULT16_16((a),(b)),13))
+#define MULT16_16_Q14(a,b) (SHR(MULT16_16((a),(b)),14))
+#define MULT16_16_Q15(a,b) (SHR(MULT16_16((a),(b)),15))
+
+#define MULT16_16_P13(a,b) (SHR(ADD32(4096,MULT16_16((a),(b))),13))
+#define MULT16_16_P14(a,b) (SHR(ADD32(8192,MULT16_16((a),(b))),14))
+#define MULT16_16_P15(a,b) (SHR(ADD32(16384,MULT16_16((a),(b))),15))
+
+#define MUL_16_32_R15(a,bh,bl) ADD32(MULT16_16((a),(bh)), SHR(MULT16_16((a),(bl)),15))
+
+
+/*
+#define DIV32_16(a,b) ((short)(((signed int)(a))/((short)(b))))
+*/
+static inline short DIV3216(int a, int b)
+{
+   int res=0;
+   int dead1, dead2, dead3, dead4, dead5;
+   __asm__ __volatile__ (
+         "\teor %5, %0, %1\n"
+         "\tmovs %4, %0\n"
+         "\trsbmi %0, %0, #0 \n"
+         "\tmovs %4, %1\n"
+         "\trsbmi %1, %1, #0 \n"
+         "\tmov %4, #1\n"
+
+         "\tsubs %3, %0, %1, asl #14 \n"
+         "\torrpl %2, %2, %4, asl #14 \n"
+         "\tmovpl %0, %3 \n"
+
+         "\tsubs %3, %0, %1, asl #13 \n"
+         "\torrpl %2, %2, %4, asl #13 \n"
+         "\tmovpl %0, %3 \n"
+
+         "\tsubs %3, %0, %1, asl #12 \n"
+         "\torrpl %2, %2, %4, asl #12 \n"
+         "\tmovpl %0, %3 \n"
+
+         "\tsubs %3, %0, %1, asl #11 \n"
+         "\torrpl %2, %2, %4, asl #11 \n"
+         "\tmovpl %0, %3 \n"
+
+         "\tsubs %3, %0, %1, asl #10 \n"
+         "\torrpl %2, %2, %4, asl #10 \n"
+         "\tmovpl %0, %3 \n"
+
+         "\tsubs %3, %0, %1, asl #9 \n"
+         "\torrpl %2, %2, %4, asl #9 \n"
+         "\tmovpl %0, %3 \n"
+
+         "\tsubs %3, %0, %1, asl #8 \n"
+         "\torrpl %2, %2, %4, asl #8 \n"
+         "\tmovpl %0, %3 \n"
+
+         "\tsubs %3, %0, %1, asl #7 \n"
+         "\torrpl %2, %2, %4, asl #7 \n"
+         "\tmovpl %0, %3 \n"
+
+         "\tsubs %3, %0, %1, asl #6 \n"
+         "\torrpl %2, %2, %4, asl #6 \n"
+         "\tmovpl %0, %3 \n"
+
+         "\tsubs %3, %0, %1, asl #5 \n"
+         "\torrpl %2, %2, %4, asl #5 \n"
+         "\tmovpl %0, %3 \n"
+
+         "\tsubs %3, %0, %1, asl #4 \n"
+         "\torrpl %2, %2, %4, asl #4 \n"
+         "\tmovpl %0, %3 \n"
+
+         "\tsubs %3, %0, %1, asl #3 \n"
+         "\torrpl %2, %2, %4, asl #3 \n"
+         "\tmovpl %0, %3 \n"
+
+         "\tsubs %3, %0, %1, asl #2 \n"
+         "\torrpl %2, %2, %4, asl #2 \n"
+         "\tmovpl %0, %3 \n"
+
+         "\tsubs %3, %0, %1, asl #1 \n"
+         "\torrpl %2, %2, %4, asl #1 \n"
+         "\tmovpl %0, %3 \n"
+
+         "\tsubs %3, %0, %1 \n"
+         "\torrpl %2, %2, %4 \n"
+         "\tmovpl %0, %3 \n"
+         
+         "\tmovs %5, %5, lsr #31 \n"
+         "\trsbne %2, %2, #0 \n"
+   : "=r" (dead1), "=r" (dead2), "=r" (res),
+   "=r" (dead3), "=r" (dead4), "=r" (dead5)
+   : "0" (a), "1" (b), "2" (res)
+   : "memory", "cc"
+                        );
+   return res;
+}
+
+
+#define DIV32(a,b) (((signed int)(a))/((signed int)(b)))
+
+
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/fixed_debug.h b/utils/iaxclient/lib/libspeex/fixed_debug.h
new file mode 100644 (file)
index 0000000..ee003dd
--- /dev/null
@@ -0,0 +1,440 @@
+/* Copyright (C) 2003 Jean-Marc Valin */
+/**
+   @file fixed_debug.h
+   @brief Fixed-point operations with debugging
+*/
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifndef FIXED_DEBUG_H
+#define FIXED_DEBUG_H
+
+#include <stdio.h>
+
+extern long long spx_mips;
+#define MIPS_INC spx_mips++,
+
+#define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768)
+#define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL)
+
+static inline short NEG16(int x)
+{
+   int res;
+   if (!VERIFY_SHORT(x))
+   {
+      fprintf (stderr, "NEG16: input is not short: %d\n", (int)x);
+   }
+   res = -x;
+   if (!VERIFY_SHORT(res))
+      fprintf (stderr, "NEG16: output is not short: %d\n", (int)res);
+   spx_mips++;
+   return res;
+}
+static inline int NEG32(long long x)
+{
+   long long res;
+   if (!VERIFY_INT(x))
+   {
+      fprintf (stderr, "NEG16: input is not int: %d\n", (int)x);
+   }
+   res = -x;
+   if (!VERIFY_INT(res))
+      fprintf (stderr, "NEG16: output is not int: %d\n", (int)res);
+   spx_mips++;
+   return res;
+}
+
+static inline short EXTRACT16(int x)
+{
+   int res;
+   if (!VERIFY_SHORT(x))
+   {
+      fprintf (stderr, "EXTRACT16: input is not short: %d\n", x);
+   }
+   res = x;
+   spx_mips++;
+   return res;
+}
+
+static inline int EXTEND32(int x)
+{
+   int res;
+   if (!VERIFY_SHORT(x))
+   {
+      fprintf (stderr, "EXTRACT16: input is not short: %d\n", x);
+   }
+   res = x;
+   spx_mips++;
+   return res;
+}
+
+static inline short SHR16(int a, int shift) 
+{
+   int res;
+   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
+   {
+      fprintf (stderr, "SHR16: inputs are not short: %d %d\n", a, shift);
+   }
+   res = a>>shift;
+   if (!VERIFY_SHORT(res))
+      fprintf (stderr, "SHR16: output is not short: %d\n", res);
+   spx_mips++;
+   return res;
+}
+static inline short SHL16(int a, int shift) 
+{
+   int res;
+   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
+   {
+      fprintf (stderr, "SHR16: inputs are not short: %d %d\n", a, shift);
+   }
+   res = a<<shift;
+   if (!VERIFY_SHORT(res))
+      fprintf (stderr, "SHR16: output is not short: %d\n", res);
+   spx_mips++;
+   return res;
+}
+
+static inline int SHR32(long long a, int shift) 
+{
+   long long  res;
+   if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
+   {
+      fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int)a, shift);
+   }
+   res = a>>shift;
+   if (!VERIFY_INT(res))
+      fprintf (stderr, "SHR32: output is not int: %d\n", (int)res);
+   spx_mips++;
+   return res;
+}
+static inline int SHL32(long long a, int shift) 
+{
+   long long  res;
+   if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
+   {
+      fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int)a, shift);
+   }
+   res = a<<shift;
+   if (!VERIFY_INT(res))
+      fprintf (stderr, "SHR32: output is not int: %d\n", (int)res);
+   spx_mips++;
+   return res;
+}
+
+
+#define PSHR16(a,shift) (SHR16(ADD16(a,(1<<((shift)-1))),shift))
+#define PSHR32(a,shift) (SHR32(ADD32(a,(1<<((shift)-1))),shift))
+#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
+#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
+
+#define SHR(a,shift) ((a) >> (shift))
+#define SHL(a,shift) ((a) << (shift))
+
+static inline short ADD16(int a, int b) 
+{
+   int res;
+   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
+   {
+      fprintf (stderr, "ADD16: inputs are not short: %d %d\n", a, b);
+   }
+   res = a+b;
+   if (!VERIFY_SHORT(res))
+      fprintf (stderr, "ADD16: output is not short: %d\n", res);
+   spx_mips++;
+   return res;
+}
+static inline short SUB16(int a, int b) 
+{
+   int res;
+   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
+   {
+      fprintf (stderr, "SUB16: inputs are not short: %d %d\n", a, b);
+   }
+   res = a-b;
+   if (!VERIFY_SHORT(res))
+      fprintf (stderr, "SUB16: output is not short: %d\n", res);
+   spx_mips++;
+   return res;
+}
+
+static inline int ADD32(long long a, long long b) 
+{
+   long long res;
+   if (!VERIFY_INT(a) || !VERIFY_INT(b))
+   {
+      fprintf (stderr, "ADD32: inputs are not int: %d %d\n", (int)a, (int)b);
+   }
+   res = a+b;
+   if (!VERIFY_INT(res))
+      fprintf (stderr, "ADD32: output is not int: %d\n", (int)res);
+   spx_mips++;
+   return res;
+}
+
+static inline int SUB32(long long a, long long b) 
+{
+   long long res;
+   if (!VERIFY_INT(a) || !VERIFY_INT(b))
+   {
+      fprintf (stderr, "SUB32: inputs are not int: %d %d\n", (int)a, (int)b);
+   }
+   res = a-b;
+   if (!VERIFY_INT(res))
+      fprintf (stderr, "SUB32: output is not int: %d\n", (int)res);
+   spx_mips++;
+   return res;
+}
+
+#define ADD64(a,b) (MIPS_INC(a)+(b))
+
+#define PSHR(a,shift) (SHR((a)+(1<<((shift)-1)),shift))
+
+/* result fits in 16 bits */
+static inline short MULT16_16_16(int a, int b) 
+{
+   int res;
+   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
+   {
+      fprintf (stderr, "MULT16_16_16: inputs are not short: %d %d\n", a, b);
+   }
+   res = a*b;
+   if (!VERIFY_SHORT(res))
+      fprintf (stderr, "MULT16_16_16: output is not short: %d\n", res);
+   spx_mips++;
+   return res;
+}
+
+static inline int MULT16_16(int a, int b) 
+{
+   long long res;
+   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
+   {
+      fprintf (stderr, "MULT16_16: inputs are not short: %d %d\n", a, b);
+   }
+   res = ((long long)a)*b;
+   if (!VERIFY_INT(res))
+      fprintf (stderr, "MULT16_16: output is not int: %d\n", (int)res);
+   spx_mips++;
+   return res;
+}
+
+#define MAC16_16(c,a,b)     (spx_mips--,ADD32((c),MULT16_16((a),(b))))
+#define MAC16_16_Q11(c,a,b)     (ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),11))))
+#define MAC16_16_Q13(c,a,b)     (ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),13))))
+
+static inline int MULT16_32_QX(int a, long long b, int Q)
+{
+   long long res;
+   if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
+   {
+      fprintf (stderr, "MULT16_32_Q%d: inputs are not short+int: %d %d\n", Q, (int)a, (int)b);
+   }
+   res = (((long long)a)*(long long)b) >> Q;
+   if (!VERIFY_INT(res))
+      fprintf (stderr, "MULT16_32_Q%d: output is not int: %d*%d=%d\n", Q, (int)a, (int)b,(int)res);
+   spx_mips+=5;
+   return res;
+}
+
+
+#define MULT16_32_Q11(a,b) MULT16_32_QX(a,b,11)
+#define MAC16_32_Q11(c,a,b) ADD32((c),MULT16_32_Q11((a),(b)))
+#define MULT16_32_Q12(a,b) MULT16_32_QX(a,b,12)
+#define MULT16_32_Q13(a,b) MULT16_32_QX(a,b,13)
+#define MULT16_32_Q14(a,b) MULT16_32_QX(a,b,14)
+#define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15)
+#define MAC16_32_Q15(c,a,b) ADD32((c),MULT16_32_Q15((a),(b)))
+
+static inline int SATURATE(int a, int b)
+{
+   if (a>b)
+      a=b;
+   if (a<-b)
+      a = -b;
+   return a;
+}
+
+static inline int MULT16_16_Q11_32(int a, int b) 
+{
+   long long res;
+   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
+   {
+      fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b);
+   }
+   res = ((long long)a)*b;
+   res >>= 11;
+   if (!VERIFY_INT(res))
+      fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res);
+   spx_mips+=3;
+   return res;
+}
+static inline short MULT16_16_Q13(int a, int b) 
+{
+   long long res;
+   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
+   {
+      fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b);
+   }
+   res = ((long long)a)*b;
+   res >>= 13;
+   if (!VERIFY_SHORT(res))
+      fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res);
+   spx_mips+=3;
+   return res;
+}
+static inline short MULT16_16_Q14(int a, int b) 
+{
+   long long res;
+   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
+   {
+      fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b);
+   }
+   res = ((long long)a)*b;
+   res >>= 14;
+   if (!VERIFY_SHORT(res))
+      fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res);
+   spx_mips+=3;
+   return res;
+}
+static inline short MULT16_16_Q15(int a, int b) 
+{
+   long long res;
+   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
+   {
+      fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d\n", a, b);
+   }
+   res = ((long long)a)*b;
+   res >>= 15;
+   if (!VERIFY_SHORT(res))
+      fprintf (stderr, "MULT16_16_Q15: output is not short: %d\n", (int)res);
+   spx_mips+=3;
+   return res;
+}
+
+static inline short MULT16_16_P13(int a, int b) 
+{
+   long long res;
+   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
+   {
+      fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b);
+   }
+   res = ((long long)a)*b;
+   res += 4096;
+   if (!VERIFY_INT(res))
+      fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res);
+   res >>= 13;
+   if (!VERIFY_SHORT(res))
+      fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res);
+   spx_mips+=4;
+   return res;
+}
+static inline short MULT16_16_P14(int a, int b) 
+{
+   long long res;
+   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
+   {
+      fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b);
+   }
+   res = ((long long)a)*b;
+   res += 8192;
+   if (!VERIFY_INT(res))
+      fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res);
+   res >>= 14;
+   if (!VERIFY_SHORT(res))
+      fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res);
+   spx_mips+=4;
+   return res;
+}
+static inline short MULT16_16_P15(int a, int b) 
+{
+   long long res;
+   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
+   {
+      fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b);
+   }
+   res = ((long long)a)*b;
+   res += 16384;
+   if (!VERIFY_INT(res))
+      fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res);
+   res >>= 15;
+   if (!VERIFY_SHORT(res))
+      fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res);
+   spx_mips+=4;
+   return res;
+}
+
+
+static inline int DIV32_16(long long a, long long b) 
+{
+   long long res;
+   if (b==0)
+   {
+      fprintf(stderr, "DIV32_16: divide by zero: %d/%d\n", (int)a, (int)b);
+      return 0;
+   }
+   if (!VERIFY_INT(a) || !VERIFY_SHORT(b))
+   {
+      fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d\n", (int)a, (int)b);
+   }
+   res = a/b;
+   if (!VERIFY_SHORT(res))
+   {
+      fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d\n", (int)a,(int)b,(int)res);
+      if (res>32767)
+         res = 32767;
+      if (res<-32768)
+         res = -32768;
+   }
+   spx_mips+=20;
+   return res;
+}
+static inline int DIV32(long long a, long long b) 
+{
+   long long res;
+   if (b==0)
+   {
+      fprintf(stderr, "DIV32: divide by zero: %d/%d\n", (int)a, (int)b);
+      return 0;
+   }
+
+   if (!VERIFY_INT(a) || !VERIFY_INT(b))
+   {
+      fprintf (stderr, "DIV32: inputs are not int/short: %d %d\n", (int)a, (int)b);
+   }
+   res = a/b;
+   if (!VERIFY_INT(res))
+      fprintf (stderr, "DIV32: output is not int: %d\n", (int)res);
+   spx_mips+=36;
+   return res;
+}
+
+
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/fixed_generic.h b/utils/iaxclient/lib/libspeex/fixed_generic.h
new file mode 100644 (file)
index 0000000..6a40ad4
--- /dev/null
@@ -0,0 +1,103 @@
+/* Copyright (C) 2003 Jean-Marc Valin */
+/**
+   @file fixed_generic.h
+   @brief Generic fixed-point operations
+*/
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifndef FIXED_GENERIC_H
+#define FIXED_GENERIC_H
+
+#define NEG16(x) (-(x))
+#define NEG32(x) (-(x))
+#define EXTRACT16(x) ((spx_word16_t)x)
+#define EXTEND32(x) ((spx_word32_t)x)
+#define SHR16(a,shift) ((a) >> (shift))
+#define SHL16(a,shift) ((a) << (shift))
+#define SHR32(a,shift) ((a) >> (shift))
+#define SHL32(a,shift) ((a) << (shift))
+#define PSHR16(a,shift) (SHR16((a)+(1<<((shift)-1)),shift))
+#define PSHR32(a,shift) (SHR32((a)+(1<<((shift)-1)),shift))
+#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
+#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
+
+#define SHR(a,shift) ((a) >> (shift))
+#define SHL(a,shift) ((spx_word32_t)(a) << (shift))
+#define PSHR(a,shift) (SHR((a)+(1<<((shift)-1)),shift))
+#define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
+
+static inline spx_word32_t slow_saturate(spx_word32_t x, spx_word16_t a)
+{
+  return (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)));
+}
+
+#define ADD16(a,b) ((spx_word16_t)((spx_word16_t)(a)+(spx_word16_t)(b)))
+#define SUB16(a,b) ((spx_word16_t)(a)-(spx_word16_t)(b))
+#define ADD32(a,b) ((spx_word32_t)(a)+(spx_word32_t)(b))
+#define SUB32(a,b) ((spx_word32_t)(a)-(spx_word32_t)(b))
+#define ADD64(a,b) ((spx_word64_t)(a)+(spx_word64_t)(b))
+
+
+/* result fits in 16 bits */
+#define MULT16_16_16(a,b)     ((((spx_word16_t)(a))*((spx_word16_t)(b))))
+
+/* (spx_word32_t)(spx_word16_t) gives TI compiler a hint that it's 16x16->32 multiply */
+#define MULT16_16(a,b)     (((spx_word32_t)(spx_word16_t)(a))*((spx_word32_t)(spx_word16_t)(b)))
+
+#define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b))))
+#define MULT16_32_Q12(a,b) ADD32(MULT16_16((a),SHR((b),12)), SHR(MULT16_16((a),((b)&0x00000fff)),12))
+#define MULT16_32_Q13(a,b) ADD32(MULT16_16((a),SHR((b),13)), SHR(MULT16_16((a),((b)&0x00001fff)),13))
+#define MULT16_32_Q14(a,b) ADD32(MULT16_16((a),SHR((b),14)), SHR(MULT16_16((a),((b)&0x00003fff)),14))
+
+#define MULT16_32_Q11(a,b) ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11))
+#define MAC16_32_Q11(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11)))
+
+#define MULT16_32_Q15(a,b) ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))
+#define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)))
+
+
+#define MAC16_16_Q11(c,a,b)     (ADD32((c),SHR(MULT16_16((a),(b)),11)))
+#define MAC16_16_Q13(c,a,b)     (ADD32((c),SHR(MULT16_16((a),(b)),13)))
+
+#define MULT16_16_Q11_32(a,b) (SHR(MULT16_16((a),(b)),11))
+#define MULT16_16_Q13(a,b) (SHR(MULT16_16((a),(b)),13))
+#define MULT16_16_Q14(a,b) (SHR(MULT16_16((a),(b)),14))
+#define MULT16_16_Q15(a,b) (SHR(MULT16_16((a),(b)),15))
+
+#define MULT16_16_P13(a,b) (SHR(ADD32(4096,MULT16_16((a),(b))),13))
+#define MULT16_16_P14(a,b) (SHR(ADD32(8192,MULT16_16((a),(b))),14))
+#define MULT16_16_P15(a,b) (SHR(ADD32(16384,MULT16_16((a),(b))),15))
+
+#define MUL_16_32_R15(a,bh,bl) ADD32(MULT16_16((a),(bh)), SHR(MULT16_16((a),(bl)),15))
+
+#define DIV32_16(a,b) ((spx_word16_t)(((spx_word32_t)(a))/((spx_word16_t)(b))))
+#define DIV32(a,b) (((spx_word32_t)(a))/((spx_word32_t)(b)))
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/gain_table.c b/utils/iaxclient/lib/libspeex/gain_table.c
new file mode 100644 (file)
index 0000000..54a5407
--- /dev/null
@@ -0,0 +1,160 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: gain_table.c
+   Codebook for 3-tap pitch prediction gain (128 entries)
+  
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are
+   met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.  
+
+   2. 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.
+
+   3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+*/
+
+const signed char gain_cdbk_nb[384] = {
+-32,-32,-32,
+-28,-67,-5,
+-42,-6,-32,
+-57,-10,-54,
+-16,27,-41,
+19,-19,-40,
+-45,24,-21,
+-8,-14,-18,
+1,14,-58,
+-18,-88,-39,
+-38,21,-18,
+-19,20,-43,
+10,17,-48,
+-52,-58,-13,
+-44,-1,-11,
+-12,-11,-34,
+14,0,-46,
+-37,-35,-34,
+-25,44,-30,
+6,-4,-63,
+-31,43,-41,
+-23,30,-43,
+-43,26,-14,
+-33,1,-13,
+-13,18,-37,
+-46,-73,-45,
+-36,24,-25,
+-36,-11,-20,
+-25,12,-18,
+-36,-69,-59,
+-45,6,8,
+-22,-14,-24,
+-1,13,-44,
+-39,-48,-26,
+-32,31,-37,
+-33,15,-46,
+-24,30,-36,
+-41,31,-23,
+-50,22,-4,
+-22,2,-21,
+-17,30,-34,
+-7,-60,-28,
+-38,42,-28,
+-44,-11,21,
+-16,8,-44,
+-39,-55,-43,
+-11,-35,26,
+-9,0,-34,
+-8,121,-81,
+7,-16,-22,
+-37,33,-31,
+-27,-7,-36,
+-34,70,-57,
+-37,-11,-48,
+-40,17,-1,
+-33,6,-6,
+-9,0,-20,
+-21,69,-33,
+-29,33,-31,
+-55,12,-1,
+-33,27,-22,
+-50,-33,-47,
+-50,54,51,
+-1,-5,-44,
+-4,22,-40,
+-39,-66,-25,
+-33,1,-26,
+-24,-23,-25,
+-11,21,-45,
+-25,-45,-19,
+-43,105,-16,
+5,-21,1,
+-16,11,-33,
+-13,-99,-4,
+-37,33,-15,
+-25,37,-63,
+-36,24,-31,
+-53,-56,-38,
+-41,-4,4,
+-33,13,-30,
+49,52,-94,
+-5,-30,-15,
+1,38,-40,
+-23,12,-36,
+-17,40,-47,
+-37,-41,-39,
+-49,34,0,
+-18,-7,-4,
+-16,17,-27,
+30,5,-62,
+4,48,-68,
+-43,11,-11,
+-18,19,-15,
+-23,-62,-39,
+-42,10,-2,
+-21,-13,-13,
+-9,13,-47,
+-23,-62,-24,
+-44,60,-21,
+-18,-3,-52,
+-22,22,-36,
+-75,57,16,
+-19,3,10,
+-29,23,-38,
+-5,-62,-51,
+-51,40,-18,
+-42,13,-24,
+-34,14,-20,
+-56,-75,-26,
+-26,32,15,
+-26,17,-29,
+-7,28,-52,
+-12,-30,5,
+-5,-48,-5,
+2,2,-43,
+21,16,16,
+-25,-45,-32,
+-43,18,-10,
+9,0,-1,
+-1,7,-30,
+19,-48,-4,
+-28,25,-29,
+-22,0,-31,
+-32,17,-10,
+-64,-41,-62,
+-52,15,16,
+-30,-22,-32,
+-7,9,-38};
diff --git a/utils/iaxclient/lib/libspeex/gain_table_lbr.c b/utils/iaxclient/lib/libspeex/gain_table_lbr.c
new file mode 100644 (file)
index 0000000..24357f0
--- /dev/null
@@ -0,0 +1,64 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: gain_table_lbr.c
+   Codebook for 3-tap pitch prediction gain (32 entries)
+  
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are
+   met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.  
+
+   2. 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.
+
+   3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+*/
+
+const signed char gain_cdbk_lbr[96] = {
+-32,-32,-32,
+-31,-58,-16,
+-41,-24,-43,
+-56,-22,-55,
+-13,33,-41,
+-4,-39,-9,
+-41,15,-12,
+-8,-15,-12,
+1,2,-44,
+-22,-66,-42,
+-38,28,-23,
+-21,14,-37,
+0,21,-50,
+-53,-71,-27,
+-37,-1,-19,
+-19,-5,-28,
+6,65,-44,
+-33,-48,-33,
+-40,57,-14,
+-17,4,-45,
+-31,38,-33,
+-23,28,-40,
+-43,29,-12,
+-34,13,-23,
+-16,15,-27,
+-14,-82,-15,
+-31,25,-32,
+-21,5,-5,
+-47,-63,-51,
+-46,12,3,
+-28,-17,-29,
+-10,14,-40};
diff --git a/utils/iaxclient/lib/libspeex/hexc_10_32_table.c b/utils/iaxclient/lib/libspeex/hexc_10_32_table.c
new file mode 100644 (file)
index 0000000..8dd408f
--- /dev/null
@@ -0,0 +1,66 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: hexc_10_32_table.c
+   Codebook for high-band excitation in SB-CELP mode (4000 bps)
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+const signed char hexc_10_32_table[320] = {
+-3, -2, -1, 0, -4, 5, 35, -40, -9, 13, 
+-44, 5, -27, -1, -7, 6, -11, 7, -8, 7, 
+19, -14, 15, -4, 9, -10, 10, -8, 10, -9, 
+-1, 1, 0, 0, 2, 5, -18, 22, -53, 50, 
+1, -23, 50, -36, 15, 3, -13, 14, -10, 6, 
+1, 5, -3, 4, -2, 5, -32, 25, 5, -2, 
+-1, -4, 1, 11, -29, 26, -6, -15, 30, -18, 
+0, 15, -17, 40, -41, 3, 9, -2, -2, 3, 
+-3, -1, -5, 2, 21, -6, -16, -21, 23, 2, 
+60, 15, 16, -16, -9, 14, 9, -1, 7, -9, 
+0, 1, 1, 0, -1, -6, 17, -28, 54, -45, 
+-1, 1, -1, -6, -6, 2, 11, 26, -29, -2, 
+46, -21, 34, 12, -23, 32, -23, 16, -10, 3, 
+66, 19, -20, 24, 7, 11, -3, 0, -3, -1, 
+-50, -46, 2, -18, -3, 4, -1, -2, 3, -3, 
+-19, 41, -36, 9, 11, -24, 21, -16, 9, -3, 
+-25, -3, 10, 18, -9, -2, -5, -1, -5, 6, 
+-4, -3, 2, -26, 21, -19, 35, -15, 7, -13, 
+17, -19, 39, -43, 48, -31, 16, -9, 7, -2, 
+-5, 3, -4, 9, -19, 27, -55, 63, -35, 10, 
+26, -44, -2, 9, 4, 1, -6, 8, -9, 5, 
+-8, -1, -3, -16, 45, -42, 5, 15, -16, 10, 
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+-16, 24, -55, 47, -38, 27, -19, 7, -3, 1, 
+16, 27, 20, -19, 18, 5, -7, 1, -5, 2, 
+-6, 8, -22, 0, -3, -3, 8, -1, 7, -8, 
+1, -3, 5, 0, 17, -48, 58, -52, 29, -7, 
+-2, 3, -10, 6, -26, 58, -31, 1, -6, 3, 
+93, -29, 39, 3, 17, 5, 6, -1, -1, -1, 
+27, 13, 10, 19, -7, -34, 12, 10, -4, 9, 
+-76, 9, 8, -28, -2, -11, 2, -1, 3, 1, 
+-83, 38, -39, 4, -16, -6, -2, -5, 5, -2, 
+};
diff --git a/utils/iaxclient/lib/libspeex/hexc_table.c b/utils/iaxclient/lib/libspeex/hexc_table.c
new file mode 100644 (file)
index 0000000..268408a
--- /dev/null
@@ -0,0 +1,162 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: hexc_table.c
+   Codebook for high-band excitation in SB-CELP mode (8000 bps with sign)
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+const signed char hexc_table[1024] = {
+-24, 21, -20, 5, -5, -7, 14, -10, 
+2, -27, 16, -20, 0, -32, 26, 19, 
+8, -11, -41, 31, 28, -27, -32, 34, 
+42, 34, -17, 22, -10, 13, -29, 18, 
+-12, -26, -24, 11, 22, 5, -5, -5, 
+54, -68, -43, 57, -25, 24, 4, 4, 
+26, -8, -12, -17, 54, 30, -45, 1, 
+10, -15, 18, -41, 11, 68, -67, 37, 
+-16, -24, -16, 38, -22, 6, -29, 30, 
+66, -27, 5, 7, -16, 13, 2, -12, 
+-7, -3, -20, 36, 4, -28, 9, 3, 
+32, 48, 26, 39, 3, 0, 7, -21, 
+-13, 5, -82, -7, 73, -20, 34, -9, 
+-5, 1, -1, 10, -5, -10, -1, 9, 
+1, -9, 10, 0, -14, 11, -1, -2, 
+-1, 11, 20, 96, -81, -22, -12, -9, 
+-58, 9, 24, -30, 26, -35, 27, -12, 
+13, -18, 56, -59, 15, -7, 23, -15, 
+-1, 6, -25, 14, -22, -20, 47, -11, 
+16, 2, 38, -23, -19, -30, -9, 40, 
+-11, 5, 4, -6, 8, 26, -21, -11, 
+127, 4, 1, 6, -9, 2, -7, -2, 
+-3, 7, -5, 10, -19, 7, -106, 91, 
+-3, 9, -4, 21, -8, 26, -80, 8, 
+1, -2, -10, -17, -17, -27, 32, 71, 
+6, -29, 11, -23, 54, -38, 29, -22, 
+39, 87, -31, -12, -20, 3, -2, -2, 
+2, 20, 0, -1, -35, 27, 9, -6, 
+-12, 3, -12, -6, 13, 1, 14, -22, 
+-59, -15, -17, -25, 13, -7, 7, 3, 
+0, 1, -7, 6, -3, 61, -37, -23, 
+-23, -29, 38, -31, 27, 1, -8, 2, 
+-27, 23, -26, 36, -34, 5, 24, -24, 
+-6, 7, 3, -59, 78, -62, 44, -16, 
+1, 6, 0, 17, 8, 45, 0, -110, 
+6, 14, -2, 32, -77, -56, 62, -3, 
+3, -13, 4, -16, 102, -15, -36, -1, 
+9, -113, 6, 23, 0, 9, 9, 5, 
+-8, -1, -14, 5, -12, 121, -53, -27, 
+-8, -9, 22, -13, 3, 2, -3, 1, 
+-2, -71, 95, 38, -19, 15, -16, -5, 
+71, 10, 2, -32, -13, -5, 15, -1, 
+-2, -14, -85, 30, 29, 6, 3, 2, 
+0, 0, 0, 0, 0, 0, 0, 0, 
+2, -65, -56, -9, 18, 18, 23, -14, 
+-2, 0, 12, -29, 26, -12, 1, 2, 
+-12, -64, 90, -6, 4, 1, 5, -5, 
+-110, -3, -31, 22, -29, 9, 0, 8, 
+-40, -5, 21, -5, -5, 13, 10, -18, 
+40, 1, 35, -20, 30, -28, 11, -6, 
+19, 7, 14, 18, -64, 9, -6, 16, 
+51, 68, 8, 16, 12, -8, 0, -9, 
+20, -22, 25, 7, -4, -13, 41, -35, 
+93, -18, -54, 11, -1, 1, -9, 4, 
+-66, 66, -31, 20, -22, 25, -23, 11, 
+10, 9, 19, 15, 11, -5, -31, -10, 
+-23, -28, -6, -6, -3, -4, 5, 3, 
+-28, 22, -11, -42, 25, -25, -16, 41, 
+34, 47, -6, 2, 42, -19, -22, 5, 
+-39, 32, 6, -35, 22, 17, -30, 8, 
+-26, -11, -11, 3, -12, 33, 33, -37, 
+21, -1, 6, -4, 3, 0, -5, 5, 
+12, -12, 57, 27, -61, -3, 20, -17, 
+2, 0, 4, 0, -2, -33, -58, 81, 
+-23, 39, -10, -5, 2, 6, -7, 5, 
+4, -3, -2, -13, -23, -72, 107, 15, 
+-5, 0, -7, -3, -6, 5, -4, 15, 
+47, 12, -31, 25, -16, 8, 22, -25, 
+-62, -56, -18, 14, 28, 12, 2, -11, 
+74, -66, 41, -20, -7, 16, -20, 16, 
+-8, 0, -16, 4, -19, 92, 12, -59, 
+-14, -39, 49, -25, -16, 23, -27, 19, 
+-3, -33, 19, 85, -29, 6, -7, -10, 
+16, -7, -12, 1, -6, 2, 4, -2, 
+64, 10, -25, 41, -2, -31, 15, 0, 
+110, 50, 69, 35, 28, 19, -10, 2, 
+-43, -49, -56, -15, -16, 10, 3, 12, 
+-1, -8, 1, 26, -12, -1, 7, -11, 
+-27, 41, 25, 1, -11, -18, 22, -7, 
+-1, -47, -8, 23, -3, -17, -7, 18, 
+-125, 59, -5, 3, 18, 1, 2, 3, 
+27, -35, 65, -53, 50, -46, 37, -21, 
+-28, 7, 14, -37, -5, -5, 12, 5, 
+-8, 78, -19, 21, -6, -16, 8, -7, 
+5, 2, 7, 2, 10, -6, 12, -60, 
+44, 11, -36, -32, 31, 0, 2, -2, 
+2, 1, -3, 7, -10, 17, -21, 10, 
+6, -2, 19, -2, 59, -38, -86, 38, 
+8, -41, -30, -45, -33, 7, 15, 28, 
+29, -7, 24, -40, 7, 7, 5, -2, 
+9, 24, -23, -18, 6, -29, 30, 2, 
+28, 49, -11, -46, 10, 43, -13, -9, 
+-1, -3, -7, -7, -17, -6, 97, -33, 
+-21, 3, 5, 1, 12, -43, -8, 28, 
+7, -43, -7, 17, -20, 19, -1, 2, 
+-13, 9, 54, 34, 9, -28, -11, -9, 
+-17, 110, -59, 44, -26, 0, 3, -12, 
+-47, 73, -34, -43, 38, -33, 16, -5, 
+-46, -4, -6, -2, -25, 19, -29, 28, 
+-13, 5, 14, 27, -40, -43, 4, 32, 
+-13, -2, -35, -4, 112, -42, 9, -12, 
+37, -28, 17, 14, -19, 35, -39, 23, 
+3, -14, -1, -57, -5, 94, -9, 3, 
+-39, 5, 30, -10, -32, 42, -13, -14, 
+-97, -63, 30, -9, 1, -7, 12, 5, 
+20, 17, -9, -36, -30, 25, 47, -9, 
+-15, 12, -22, 98, -8, -50, 15, -27, 
+21, -16, -11, 2, 12, -10, 10, -3, 
+33, 36, -96, 0, -17, 31, -9, 9, 
+3, -20, 13, -11, 8, -4, 10, -10, 
+9, 1, 112, -70, -27, 5, -21, 2, 
+-57, -3, -29, 10, 19, -21, 21, -10, 
+-66, -3, 91, -35, 30, -12, 0, -7, 
+59, -28, 26, 2, 14, -18, 1, 1, 
+11, 17, 20, -54, -59, 27, 4, 29, 
+32, 5, 19, 12, -4, 1, 7, -10, 
+5, -2, 10, 0, 23, -5, 28, -104, 
+46, 11, 16, 3, 29, 1, -8, -14, 
+1, 7, -50, 88, -62, 26, 8, -17, 
+-14, 50, 0, 32, -12, -3, -27, 18, 
+-8, -5, 8, 3, -20, -11, 37, -12, 
+9, 33, 46, -101, -1, -4, 1, 6, 
+-1, 28, -42, -15, 16, 5, -1, -2, 
+-55, 85, 38, -9, -4, 11, -2, -9, 
+-6, 3, -20, -10, -77, 89, 24, -3, 
+-104, -57, -26, -31, -20, -6, -9, 14, 
+20, -23, 46, -15, -31, 28, 1, -15, 
+-2, 6, -2, 31, 45, -76, 23, -25, 
+};
diff --git a/utils/iaxclient/lib/libspeex/high_lsp_tables.c b/utils/iaxclient/lib/libspeex/high_lsp_tables.c
new file mode 100644 (file)
index 0000000..e82e875
--- /dev/null
@@ -0,0 +1,163 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: high_lsp_tables.c
+   Codebooks for high-band LSPs in SB-CELP mode
+  
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are
+   met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.  
+
+   2. 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.
+
+   3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+*/
+const signed char high_lsp_cdbk[512]={
+39,12,-14,-20,-29,-61,-67,-76,
+-32,-71,-67,68,77,46,34,5,
+-13,-48,-46,-72,-81,-84,-60,-58,
+-40,-28,82,93,68,45,29,3,
+-19,-47,-28,-43,-35,-30,-8,-13,
+-39,-91,-91,-123,-96,10,10,-6,
+-18,-55,-60,-91,-56,-36,-27,-16,
+-48,-75,40,28,-10,-28,35,9,
+37,19,1,-20,-31,-41,-18,-25,
+-35,-68,-80,45,27,-1,47,13,
+0,-29,-35,-57,-50,-79,-73,-38,
+-19,5,35,14,-10,-23,16,-8,
+5,-24,-40,-62,-23,-27,-22,-16,
+-18,-46,-72,-77,43,21,33,1,
+-80,-70,-70,-64,-56,-52,-39,-33,
+-31,-38,-19,-19,-15,32,33,-2,
+7,-15,-15,-24,-23,-33,-41,-56,
+-24,-57,5,89,64,41,27,5,
+-9,-47,-60,-97,-97,-124,-20,-9,
+-44,-73,31,29,-4,64,48,7,
+-35,-57,0,-3,-26,-47,-3,-6,
+-40,-76,-79,-48,12,81,55,10,
+9,-24,-43,-73,-57,-69,16,5,
+-28,-53,18,29,20,0,-4,-11,
+6,-13,23,7,-17,-35,-37,-37,
+-30,-68,-63,6,24,-9,-14,3,
+21,-13,-27,-57,-49,-80,-24,-41,
+-5,-16,-5,1,45,25,12,-7,
+3,-15,-6,-16,-15,-8,6,-13,
+-42,-81,-80,-87,14,1,-10,-3,
+-43,-69,-46,-24,-28,-29,36,6,
+-43,-56,-12,12,54,79,43,9,
+54,22,2,8,-12,-43,-46,-52,
+-38,-69,-89,-5,75,38,33,5,
+-13,-53,-62,-87,-89,-113,-99,-55,
+-34,-37,62,55,33,16,21,-2,
+-17,-46,-29,-38,-38,-48,-39,-42,
+-36,-75,-72,-88,-48,-30,21,2,
+-15,-57,-64,-98,-84,-76,25,1,
+-46,-80,-12,18,-7,3,34,6,
+38,31,23,4,-1,20,14,-15,
+-43,-78,-91,-24,14,-3,54,16,
+0,-27,-28,-44,-56,-83,-92,-89,
+-3,34,56,41,36,22,20,-8,
+-7,-35,-42,-62,-49,3,12,-10,
+-50,-87,-96,-66,92,70,38,9,
+-70,-71,-62,-42,-39,-43,-11,-7,
+-50,-79,-58,-50,-31,32,31,-6,
+-4,-25,7,-17,-38,-70,-58,-27,
+-43,-83,-28,59,36,20,31,2,
+-27,-71,-80,-109,-98,-75,-33,-32,
+-31,-2,33,15,-6,43,33,-5,
+0,-22,-10,-27,-34,-49,-11,-20,
+-41,-91,-100,-121,-39,57,41,10,
+-19,-50,-38,-59,-60,-70,-18,-20,
+-8,-31,-8,-15,1,-14,-26,-25,
+33,21,32,17,1,-19,-19,-26,
+-58,-81,-35,-22,45,30,11,-11,
+3,-26,-48,-87,-67,-83,-58,3,
+-1,-26,-20,44,10,25,39,5,
+-9,-35,-27,-38,7,10,4,-9,
+-42,-85,-102,-127,52,44,28,10,
+-47,-61,-40,-39,-17,-1,-10,-33,
+-42,-74,-48,21,-4,70,52,10};
+
+
+const signed char high_lsp_cdbk2[512]={
+-36,-62,6,-9,-10,-14,-56,23,
+1,-26,23,-48,-17,12,8,-7,
+23,29,-36,-28,-6,-29,-17,-5,
+40,23,10,10,-46,-13,36,6,
+4,-30,-29,62,32,-32,-1,22,
+-14,1,-4,-22,-45,2,54,4,
+-30,-57,-59,-12,27,-3,-31,8,
+-9,5,10,-14,32,66,19,9,
+2,-25,-37,23,-15,18,-38,-31,
+5,-9,-21,15,0,22,62,30,
+15,-12,-14,-46,77,21,33,3,
+34,29,-19,50,2,11,9,-38,
+-12,-37,62,1,-15,54,32,6,
+2,-24,20,35,-21,2,19,24,
+-13,55,4,9,39,-19,30,-1,
+-21,73,54,33,8,18,3,15,
+6,-19,-47,6,-3,-48,-50,1,
+26,20,8,-23,-50,65,-14,-55,
+-17,-31,-37,-28,53,-1,-17,-53,
+1,57,11,-8,-25,-30,-37,64,
+5,-52,-45,15,23,31,15,14,
+-25,24,33,-2,-44,-56,-18,6,
+-21,-43,4,-12,17,-37,20,-10,
+34,15,2,15,55,21,-11,-31,
+-6,46,25,16,-9,-25,-8,-62,
+28,17,20,-32,-29,26,30,25,
+-19,2,-16,-17,26,-51,2,50,
+42,19,-66,23,29,-2,3,19,
+-19,-37,32,15,6,30,-34,13,
+11,-5,40,31,10,-42,4,-9,
+26,-9,-70,17,-2,-23,20,-22,
+-55,51,-24,-31,22,-22,15,-13,
+3,-10,-28,-16,56,4,-63,11,
+-18,-15,-18,-38,-35,16,-7,34,
+-1,-21,-49,-47,9,-37,7,8,
+69,55,20,6,-33,-45,-10,-9,
+6,-9,12,71,15,-3,-42,-7,
+-24,32,-35,-2,-42,-17,-5,0,
+-2,-33,-54,13,-12,-34,47,23,
+19,55,7,-8,74,31,14,16,
+-23,-26,19,12,-18,-49,-28,-31,
+-20,2,-14,-20,-47,78,40,13,
+-23,-11,21,-6,18,1,47,5,
+38,35,32,46,22,8,13,16,
+-14,18,51,19,40,39,11,-26,
+-1,-17,47,2,-53,-15,31,-22,
+38,21,-15,-16,5,-33,53,15,
+-38,86,11,-3,-24,49,13,-4,
+-11,-18,28,20,-12,-27,-26,35,
+-25,-35,-3,-20,-61,30,10,-55,
+-12,-22,-52,-54,-14,19,-32,-12,
+45,15,-8,-48,-9,11,-32,8,
+-16,-34,-13,51,18,38,-2,-32,
+-17,22,-2,-18,-28,-70,59,27,
+-28,-19,-10,-20,-9,-9,-8,-21,
+21,-8,35,-2,45,-3,-9,12,
+0,30,7,-39,43,27,-38,-91,
+30,26,19,-55,-4,63,14,-17,
+13,9,13,2,7,4,6,61,
+72,-1,-17,29,-1,-22,-17,8,
+-28,-37,63,44,41,3,2,14,
+9,-6,75,-8,-7,-12,-15,-12,
+13,9,-4,30,-22,-65,15,0,
+-45,4,-4,1,5,22,11,23};
diff --git a/utils/iaxclient/lib/libspeex/include/speex/speex.h b/utils/iaxclient/lib/libspeex/include/speex/speex.h
new file mode 100644 (file)
index 0000000..6eb1124
--- /dev/null
@@ -0,0 +1,410 @@
+/* Copyright (C) 2002 Jean-Marc Valin*/
+/**
+  @file speex.h
+  @brief Describes the different modes of the codec
+*/
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+
+*/
+
+#ifndef SPEEX_H
+#define SPEEX_H
+
+#include "speex/speex_bits.h"
+#include "speex/speex_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Values allowed for *ctl() requests */
+
+/** Set enhancement on/off (decoder only) */
+#define SPEEX_SET_ENH 0
+/** Get enhancement state (decoder only) */
+#define SPEEX_GET_ENH 1
+
+/*Would be SPEEX_SET_FRAME_SIZE, but it's (currently) invalid*/
+/** Obtain frame size used by encoder/decoder */
+#define SPEEX_GET_FRAME_SIZE 3
+
+/** Set quality value */
+#define SPEEX_SET_QUALITY 4
+/** Get current quality setting */
+/* #define SPEEX_GET_QUALITY 5 -- Doesn't make much sense, does it? */
+
+/** Set sub-mode to use */
+#define SPEEX_SET_MODE 6
+/** Get current sub-mode in use */
+#define SPEEX_GET_MODE 7
+
+/** Set low-band sub-mode to use (wideband only)*/
+#define SPEEX_SET_LOW_MODE 8
+/** Get current low-band mode in use (wideband only)*/
+#define SPEEX_GET_LOW_MODE 9
+
+/** Set high-band sub-mode to use (wideband only)*/
+#define SPEEX_SET_HIGH_MODE 10
+/** Get current high-band mode in use (wideband only)*/
+#define SPEEX_GET_HIGH_MODE 11
+
+/** Set VBR on (1) or off (0) */
+#define SPEEX_SET_VBR 12
+/** Get VBR status (1 for on, 0 for off) */
+#define SPEEX_GET_VBR 13
+
+/** Set quality value for VBR encoding (0-10) */
+#define SPEEX_SET_VBR_QUALITY 14
+/** Get current quality value for VBR encoding (0-10) */
+#define SPEEX_GET_VBR_QUALITY 15
+
+/** Set complexity of the encoder (0-10) */
+#define SPEEX_SET_COMPLEXITY 16
+/** Get current complexity of the encoder (0-10) */
+#define SPEEX_GET_COMPLEXITY 17
+
+/** Set bit-rate used by the encoder (or lower) */
+#define SPEEX_SET_BITRATE 18
+/** Get current bit-rate used by the encoder or decoder */
+#define SPEEX_GET_BITRATE 19
+
+/**Define a handler function for in-band Speex request*/
+#define SPEEX_SET_HANDLER 20
+
+/**Define a handler function for in-band user-defined request*/
+#define SPEEX_SET_USER_HANDLER 22
+
+/** Set sampling rate used in bit-rate computation */
+#define SPEEX_SET_SAMPLING_RATE 24
+/** Get sampling rate used in bit-rate computation */
+#define SPEEX_GET_SAMPLING_RATE 25
+
+/** Reset the encoder/decoder memories to zero*/
+#define SPEEX_RESET_STATE 26
+
+/** Get VBR info (mostly used internally) */
+#define SPEEX_GET_RELATIVE_QUALITY 29
+
+/** Set VAD status (1 for on, 0 for off) */
+#define SPEEX_SET_VAD 30
+
+/** Get VAD status (1 for on, 0 for off) */
+#define SPEEX_GET_VAD 31
+
+/** Set Average Bit-Rate (ABR) to n bits per seconds */
+#define SPEEX_SET_ABR 32
+/** Get Average Bit-Rate (ABR) setting (in bps) */
+#define SPEEX_GET_ABR 33
+
+/** Set DTX status (1 for on, 0 for off) */
+#define SPEEX_SET_DTX 34
+/** Get DTX status (1 for on, 0 for off) */
+#define SPEEX_GET_DTX 35
+
+/** Set submode encoding in each frame (1 for yes, 0 for no, setting to no breaks the standard) */
+#define SPEEX_SET_SUBMODE_ENCODING 36
+/** */
+#define SPEEX_GET_SUBMODE_ENCODING 37
+
+/*#define SPEEX_SET_LOOKAHEAD 38*/
+/** Returns the lookahead used by Speex */
+#define SPEEX_GET_LOOKAHEAD 39
+
+/** Sets tuning for packet-loss concealment (expected loss rate) */
+#define SPEEX_SET_PLC_TUNING 40
+/** Gets tuning for PLC */
+#define SPEEX_GET_PLC_TUNING 41
+
+/* Used internally, not to be used in applications */
+/** Used internally*/
+#define SPEEX_GET_PI_GAIN 100
+/** Used internally*/
+#define SPEEX_GET_EXC     101
+/** Used internally*/
+#define SPEEX_GET_INNOV   102
+/** Used internally*/
+#define SPEEX_GET_DTX_STATUS   103
+
+
+/* Preserving compatibility:*/
+/** Equivalent to SPEEX_SET_ENH */
+#define SPEEX_SET_PF 0
+/** Equivalent to SPEEX_GET_ENH */
+#define SPEEX_GET_PF 1
+
+
+
+
+/* Values allowed for mode queries */
+/** Query the frame size of a mode */
+#define SPEEX_MODE_FRAME_SIZE 0
+
+/** Query the size of an encoded frame for a particular sub-mode */
+#define SPEEX_SUBMODE_BITS_PER_FRAME 1
+
+
+
+#define SPEEX_LIB_GET_MAJOR_VERSION 1
+#define SPEEX_LIB_GET_MINOR_VERSION 3
+#define SPEEX_LIB_GET_MICRO_VERSION 5
+#define SPEEX_LIB_GET_EXTRA_VERSION 7
+#define SPEEX_LIB_GET_VERSION_STRING 9
+
+/*#define SPEEX_LIB_SET_ALLOC_FUNC 10
+#define SPEEX_LIB_GET_ALLOC_FUNC 11
+#define SPEEX_LIB_SET_FREE_FUNC 12
+#define SPEEX_LIB_GET_FREE_FUNC 13
+
+#define SPEEX_LIB_SET_WARNING_FUNC 14
+#define SPEEX_LIB_GET_WARNING_FUNC 15
+#define SPEEX_LIB_SET_ERROR_FUNC 16
+#define SPEEX_LIB_GET_ERROR_FUNC 17
+*/
+
+/** Number of defined modes in Speex */
+#define SPEEX_NB_MODES 3
+
+/** modeID for the defined narrowband mode */
+#define SPEEX_MODEID_NB 0
+
+/** modeID for the defined wideband mode */
+#define SPEEX_MODEID_WB 1
+
+/** modeID for the defined ultra-wideband mode */
+#define SPEEX_MODEID_UWB 2
+
+#ifdef EPIC_48K
+/** modeID for the Epic 48K mode */
+#define SPEEX_MODEID_NB_48K 1000
+#endif
+
+struct SpeexMode;
+
+
+/* Prototypes for mode function pointers */
+
+/** Encoder state initialization function */
+typedef void *(*encoder_init_func)(const struct SpeexMode *mode);
+
+/** Encoder state destruction function */
+typedef void (*encoder_destroy_func)(void *st);
+
+/** Main encoding function */
+typedef int (*encode_func)(void *state, void *in, SpeexBits *bits);
+
+/** Function for controlling the encoder options */
+typedef int (*encoder_ctl_func)(void *state, int request, void *ptr);
+
+/** Decoder state initialization function */
+typedef void *(*decoder_init_func)(const struct SpeexMode *mode);
+
+/** Decoder state destruction function */
+typedef void (*decoder_destroy_func)(void *st);
+
+/** Main decoding function */
+typedef int  (*decode_func)(void *state, SpeexBits *bits, void *out);
+
+/** Function for controlling the decoder options */
+typedef int (*decoder_ctl_func)(void *state, int request, void *ptr);
+
+
+/** Query function for a mode */
+typedef int (*mode_query_func)(const void *mode, int request, void *ptr);
+
+/** Struct defining a Speex mode */ 
+typedef struct SpeexMode {
+   /** Pointer to the low-level mode data */
+   const void *mode;
+
+   /** Pointer to the mode query function */
+   mode_query_func query;
+   
+   /** The name of the mode (you should not rely on this to identify the mode)*/
+   const char *modeName;
+
+   /**ID of the mode*/
+   int modeID;
+
+   /**Version number of the bitstream (incremented every time we break
+    bitstream compatibility*/
+   int bitstream_version;
+
+   /** Pointer to encoder initialization function */
+   encoder_init_func enc_init;
+
+   /** Pointer to encoder destruction function */
+   encoder_destroy_func enc_destroy;
+
+   /** Pointer to frame encoding function */
+   encode_func enc;
+
+   /** Pointer to decoder initialization function */
+   decoder_init_func dec_init;
+
+   /** Pointer to decoder destruction function */
+   decoder_destroy_func dec_destroy;
+
+   /** Pointer to frame decoding function */
+   decode_func dec;
+
+   /** ioctl-like requests for encoder */
+   encoder_ctl_func enc_ctl;
+
+   /** ioctl-like requests for decoder */
+   decoder_ctl_func dec_ctl;
+
+} SpeexMode;
+
+/**
+ * Returns a handle to a newly created Speex encoder state structure. For now, 
+ * the "mode" argument can be &nb_mode or &wb_mode . In the future, more modes 
+ * may be added. Note that for now if you have more than one channels to 
+ * encode, you need one state per channel.
+ *
+ * @param mode The mode to use (either speex_nb_mode or speex_wb.mode) 
+ * @return A newly created encoder
+ */
+void *speex_encoder_init(const SpeexMode *mode);
+
+/** Frees all resources associated to an existing Speex encoder state. 
+ * @param state Encoder state to be destroyed */
+void speex_encoder_destroy(void *state);
+
+/** Uses an existing encoder state to encode one frame of speech pointed to by
+    "in". The encoded bit-stream is saved in "bits".
+ @param state Encoder state
+ @param in Frame that will be encoded with a +-2^15 range
+ @param bits Bit-stream where the data will be written
+ */
+int speex_encode(void *state, float *in, SpeexBits *bits);
+
+/** Uses an existing encoder state to encode one frame of speech pointed to by
+    "in". The encoded bit-stream is saved in "bits".
+ @param state Encoder state
+ @param in Frame that will be encoded with a +-2^15 range
+ @param bits Bit-stream where the data will be written
+ */
+int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits);
+
+/** Used like the ioctl function to control the encoder parameters
+ *
+ * @param state Encoder state
+ * @param request ioctl-type request (one of the SPEEX_* macros)
+ * @param ptr Data exchanged to-from function
+ * @return 0 if frame needs not be transmitted (DTX only), 1 otherwise
+ */
+int speex_encoder_ctl(void *state, int request, void *ptr);
+
+
+/** Returns a handle to a newly created decoder state structure. For now, 
+ * the mode argument can be &nb_mode or &wb_mode . In the future, more modes
+ * may be added.  Note that for now if you have more than one channels to
+ * decode, you need one state per channel.
+ *
+ * @param mode Speex mode (one of speex_nb_mode or speex_wb_mode)
+ * @return A newly created decoder state
+ */ 
+void *speex_decoder_init(const SpeexMode *mode);
+
+/** Frees all resources associated to an existing decoder state.
+ *
+ * @param state State to be destroyed
+ */
+void speex_decoder_destroy(void *state);
+
+/** Uses an existing decoder state to decode one frame of speech from
+ * bit-stream bits. The output speech is saved written to out.
+ *
+ * @param state Decoder state
+ * @param bits Bit-stream from which to decode the frame (NULL if the packet was lost)
+ * @param out Where to write the decoded frame
+ * @return return status (0 for no error, -1 for end of stream, -2 other)
+ */
+int speex_decode(void *state, SpeexBits *bits, float *out);
+
+/** Uses an existing decoder state to decode one frame of speech from
+ * bit-stream bits. The output speech is saved written to out.
+ *
+ * @param state Decoder state
+ * @param bits Bit-stream from which to decode the frame (NULL if the packet was lost)
+ * @param out Where to write the decoded frame
+ * @return return status (0 for no error, -1 for end of stream, -2 other)
+ */
+int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out);
+
+/** Used like the ioctl function to control the encoder parameters
+ *
+ * @param state Decoder state
+ * @param request ioctl-type request (one of the SPEEX_* macros)
+ * @param ptr Data exchanged to-from function
+ * @return 0 for no error, 1 if a terminator is reached, 2 for another error
+ */
+int speex_decoder_ctl(void *state, int request, void *ptr);
+
+
+/** Query function for mode information
+ *
+ * @param mode Speex mode
+ * @param request ioctl-type request (one of the SPEEX_* macros)
+ * @param ptr Data exchanged to-from function
+ */
+int speex_mode_query(const SpeexMode *mode, int request, void *ptr);
+
+/** Functions for controlling the behavior of libspeex
+ * @param request ioctl-type request (one of the SPEEX_LIB_* macros)
+ * @param ptr Data exchanged to-from function
+ */
+int speex_lib_ctl(int request, void *ptr);
+
+/** Default narrowband mode */
+extern const SpeexMode speex_nb_mode;
+
+/** Default wideband mode */
+extern const SpeexMode speex_wb_mode;
+
+/** Default "ultra-wideband" mode */
+extern const SpeexMode speex_uwb_mode;
+
+#ifdef EPIC_48K
+/** 4.8 kbps narrowband mode */
+extern const SpeexMode speex_nb_48k_mode;
+#endif
+
+/** List of all modes available */
+extern const SpeexMode * const speex_mode_list[SPEEX_NB_MODES];
+
+/** Obtain one of the modes available */
+const SpeexMode * speex_lib_get_mode (int mode);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/include/speex/speex_bits.h b/utils/iaxclient/lib/libspeex/include/speex/speex_bits.h
new file mode 100644 (file)
index 0000000..b77202f
--- /dev/null
@@ -0,0 +1,151 @@
+/* Copyright (C) 2002 Jean-Marc Valin */
+/**
+   @file speex_bits.h
+   @brief Handles bit packing/unpacking
+*/
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+
+*/
+
+#ifndef BITS_H
+#define BITS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Bit-packing data structure representing (part of) a bit-stream. */
+typedef struct SpeexBits {
+   char *chars;   /**< "raw" data */
+   int   nbBits;  /**< Total number of bits stored in the stream*/
+   int   charPtr; /**< Position of the byte "cursor" */
+   int   bitPtr;  /**< Position of the bit "cursor" within the current char */
+   int   owner;   /**< Does the struct "own" the "raw" buffer (member "chars") */
+   int   overflow;/**< Set to one if we try to read past the valid data */
+   int   buf_size;/**< Allocated size for buffer */
+   int   reserved1; /**< Reserved for future use */
+   void *reserved2; /**< Reserved for future use */
+} SpeexBits;
+
+/** Initializes and allocates resources for a SpeexBits struct */
+void speex_bits_init(SpeexBits *bits);
+
+/** Initializes SpeexBits struct using a pre-allocated buffer*/
+void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size);
+
+/** Frees all resources associated to a SpeexBits struct. Right now this does nothing since no resources are allocated, but this could change in the future.*/
+void speex_bits_destroy(SpeexBits *bits);
+
+/** Resets bits to initial value (just after initialization, erasing content)*/
+void speex_bits_reset(SpeexBits *bits);
+
+/** Rewind the bit-stream to the beginning (ready for read) without erasing the content */
+void speex_bits_rewind(SpeexBits *bits);
+
+/** Initializes the bit-stream from the data in an area of memory */
+void speex_bits_read_from(SpeexBits *bits, char *bytes, int len);
+
+/** Append bytes to the bit-stream
+ * @param bits Bit-stream to operate on
+ * @param bytes pointer to the bytes what will be appended
+ * @param len Number of bytes of append
+ */
+void speex_bits_read_whole_bytes(SpeexBits *bits, char *bytes, int len);
+
+/** Write the content of a bit-stream to an area of memory */
+int speex_bits_write(SpeexBits *bits, char *bytes, int max_len);
+
+/** Like speex_bits_write, but writes only the complete bytes in the stream. Also removes the written bytes from the stream */
+int speex_bits_write_whole_bytes(SpeexBits *bits, char *bytes, int max_len);
+
+/** Append bits to the bit-stream
+ * @param bits Bit-stream to operate on
+ * @param data Value to append as integer
+ * @param nbBits number of bits to consider in "data"
+ */
+void speex_bits_pack(SpeexBits *bits, int data, int nbBits);
+
+/** Interpret the next bits in the bit-stream as a signed integer
+ *
+ * @param bits Bit-stream to operate on
+ * @param nbBits Number of bits to interpret
+ * @return A signed integer represented by the bits read
+ */
+int speex_bits_unpack_signed(SpeexBits *bits, int nbBits);
+
+/** Interpret the next bits in the bit-stream as an unsigned integer
+ *
+ * @param bits Bit-stream to operate on
+ * @param nbBits Number of bits to interpret
+ * @return An unsigned integer represented by the bits read
+ */
+unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits);
+
+/** Returns the number of bytes in the bit-stream, including the last one even if it is not "full"
+ *
+ * @param bits Bit-stream to operate on
+ * @return Number of bytes in the stream
+ */
+int speex_bits_nbytes(SpeexBits *bits);
+
+/** Same as speex_bits_unpack_unsigned, but without modifying the cursor position */
+unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits);
+
+/** Get the value of the next bit in the stream, without modifying the
+ * "cursor" position 
+ * 
+ * @param bits Bit-stream to operate on
+ */
+int speex_bits_peek(SpeexBits *bits);
+
+/** Advances the position of the "bit cursor" in the stream 
+ *
+ * @param bits Bit-stream to operate on
+ * @param n Number of bits to advance
+ */
+void speex_bits_advance(SpeexBits *bits, int n);
+
+/** Returns the number of bits remaining to be read in a stream
+ *
+ * @param bits Bit-stream to operate on
+ */
+int speex_bits_remaining(SpeexBits *bits);
+
+/** Insert a terminator so that the data can be sent as a packet while auto-detecting 
+ * the number of frames in each packet 
+ *
+ * @param bits Bit-stream to operate on
+ */
+void speex_bits_insert_terminator(SpeexBits *bits);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/include/speex/speex_callbacks.h b/utils/iaxclient/lib/libspeex/include/speex/speex_callbacks.h
new file mode 100644 (file)
index 0000000..f6334f2
--- /dev/null
@@ -0,0 +1,128 @@
+/* Copyright (C) 2002 Jean-Marc Valin*/
+/**
+  @file speex_callbacks.h
+  @brief Describes callback handling and in-band signalling
+*/
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+
+*/
+
+#ifndef SPEEX_CALLBACKS_H
+#define SPEEX_CALLBACKS_H
+
+#include "speex.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Total number of callbacks */
+#define SPEEX_MAX_CALLBACKS 16
+
+/* Describes all the in-band requests */
+
+/*These are 1-bit requests*/
+/** Request for perceptual enhancement (1 for on, 0 for off) */
+#define SPEEX_INBAND_ENH_REQUEST         0
+/** Reserved */
+#define SPEEX_INBAND_RESERVED1           1
+
+/*These are 4-bit requests*/
+/** Request for a mode change */
+#define SPEEX_INBAND_MODE_REQUEST        2
+/** Request for a low mode change */
+#define SPEEX_INBAND_LOW_MODE_REQUEST    3
+/** Request for a high mode change */
+#define SPEEX_INBAND_HIGH_MODE_REQUEST   4
+/** Request for VBR (1 on, 0 off) */
+#define SPEEX_INBAND_VBR_QUALITY_REQUEST 5
+/** Request to be sent acknowledge */
+#define SPEEX_INBAND_ACKNOWLEDGE_REQUEST 6
+/** Request for VBR (1 for on, 0 for off) */
+#define SPEEX_INBAND_VBR_REQUEST         7
+
+/*These are 8-bit requests*/
+/** Send a character in-band */
+#define SPEEX_INBAND_CHAR                8
+/** Intensity stereo information */
+#define SPEEX_INBAND_STEREO              9
+
+/*These are 16-bit requests*/
+/** Transmit max bit-rate allowed */
+#define SPEEX_INBAND_MAX_BITRATE         10
+
+/*These are 32-bit requests*/
+/** Acknowledge packet reception */
+#define SPEEX_INBAND_ACKNOWLEDGE         12
+
+/** Callback function type */
+typedef int (*speex_callback_func)(SpeexBits *bits, void *state, void *data);
+
+/** Callback information */
+typedef struct SpeexCallback {
+   int callback_id;             /**< ID associated to the callback */
+   speex_callback_func func;    /**< Callback handler function */
+   void *data;                  /**< Data that will be sent to the handler */
+   void *reserved1;             /**< Reserved for future use */
+   int   reserved2;             /**< Reserved for future use */
+} SpeexCallback;
+
+/** Handle in-band request */
+int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state);
+
+/** Standard handler for mode request (change mode, no questions asked) */
+int speex_std_mode_request_handler(SpeexBits *bits, void *state, void *data);
+
+/** Standard handler for high mode request (change high mode, no questions asked) */
+int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data);
+
+/** Standard handler for in-band characters (write to stderr) */
+int speex_std_char_handler(SpeexBits *bits, void *state, void *data);
+
+/** Default handler for user-defined requests: in this case, just ignore */
+int speex_default_user_handler(SpeexBits *bits, void *state, void *data);
+
+
+
+
+int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data);
+
+int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data);
+
+int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data);
+
+int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/include/speex/speex_config_types.h b/utils/iaxclient/lib/libspeex/include/speex/speex_config_types.h
new file mode 100644 (file)
index 0000000..bd54854
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef __SPEEX_TYPES_H__
+#define __SPEEX_TYPES_H__
+
+/* these are filled in by configure */
+typedef short spx_int16_t;
+typedef unsigned short spx_uint16_t;
+typedef int spx_int32_t;
+typedef unsigned int spx_uint32_t;
+
+#endif
+
diff --git a/utils/iaxclient/lib/libspeex/include/speex/speex_echo.h b/utils/iaxclient/lib/libspeex/include/speex/speex_echo.h
new file mode 100644 (file)
index 0000000..39a3c73
--- /dev/null
@@ -0,0 +1,98 @@
+/* Copyright (C) Jean-Marc Valin
+
+   File: speex_echo.h
+
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are
+   met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+
+   2. 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.
+
+   3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+*/
+
+#ifndef SPEEX_ECHO_H
+#define SPEEX_ECHO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct drft_lookup;
+
+typedef struct SpeexEchoState {
+   int frame_size;           /**< Number of samples processed each time */
+   int window_size;
+   int M;
+   int cancel_count;
+   int adapted;
+   float adapt_rate;
+   float sum_adapt;
+   float Sey;
+   float Syy;
+   float See;
+   
+   float *x;
+   float *X;
+   float *d;
+   float *D;
+   float *y;
+   float *y2;
+   float *last_y;
+   float *Yps;
+   float *Y;
+   float *Y2;
+   float *E;
+   float *PHI;
+   float * W;
+   float *power;
+   float *power_1;
+   float *grad;
+   float *Rf;
+   float *Yf;
+   float *Xf;
+   float *fratio;
+   float *regul;
+
+   struct drft_lookup *fft_lookup;
+
+
+} SpeexEchoState;
+
+
+/** Creates a new echo canceller state */
+SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length);
+
+/** Destroys an echo canceller state */
+void speex_echo_state_destroy(SpeexEchoState *st);
+
+/** Performs echo cancellation a frame */
+void speex_echo_cancel(SpeexEchoState *st, short *ref, short *echo, short *out, float *Y);
+
+/** Reset the echo canceller state */
+void speex_echo_state_reset(SpeexEchoState *st);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/include/speex/speex_header.h b/utils/iaxclient/lib/libspeex/include/speex/speex_header.h
new file mode 100644 (file)
index 0000000..32fb81f
--- /dev/null
@@ -0,0 +1,86 @@
+/* Copyright (C) 2002 Jean-Marc Valin */
+/**
+   @file speex_header.h
+   @brief Describes the Speex header
+*/
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+
+*/
+
+
+#ifndef SPEEX_HEADER_H
+#define SPEEX_HEADER_H
+
+#include "speex/speex_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct SpeexMode;
+
+#define SPEEX_HEADER_STRING_LENGTH 8
+
+/** Maximum number of characters for encoding the Speex version number in the header */
+#define SPEEX_HEADER_VERSION_LENGTH 20
+
+/** Speex header info for file-based formats */
+typedef struct SpeexHeader {
+   char speex_string[SPEEX_HEADER_STRING_LENGTH];   /**< Identifies a Speex bit-stream, always set to "Speex   " */
+   char speex_version[SPEEX_HEADER_VERSION_LENGTH]; /**< Speex version */ 
+   spx_int32_t speex_version_id;       /**< Version for Speex (for checking compatibility) */
+   spx_int32_t header_size;            /**< Total size of the header ( sizeof(SpeexHeader) ) */
+   spx_int32_t rate;                   /**< Sampling rate used */
+   spx_int32_t mode;                   /**< Mode used (0 for narrowband, 1 for wideband) */
+   spx_int32_t mode_bitstream_version; /**< Version ID of the bit-stream */
+   spx_int32_t nb_channels;            /**< Number of channels encoded */
+   spx_int32_t bitrate;                /**< Bit-rate used */
+   spx_int32_t frame_size;             /**< Size of frames */
+   spx_int32_t vbr;                    /**< 1 for a VBR encoding, 0 otherwise */
+   spx_int32_t frames_per_packet;      /**< Number of frames stored per Ogg packet */
+   spx_int32_t extra_headers;          /**< Number of additional headers after the comments */
+   spx_int32_t reserved1;              /**< Reserved for future use, must be zero */
+   spx_int32_t reserved2;              /**< Reserved for future use, must be zero */
+} SpeexHeader;
+
+/** Initializes a SpeexHeader using basic information */
+void speex_init_header(SpeexHeader *header, int rate, int nb_channels, const struct SpeexMode *m);
+
+/** Creates the header packet from the header itself (mostly involves endianness conversion) */
+char *speex_header_to_packet(SpeexHeader *header, int *size);
+
+/** Creates a SpeexHeader from a packet */
+SpeexHeader *speex_packet_to_header(char *packet, int size);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/include/speex/speex_jitter.h b/utils/iaxclient/lib/libspeex/include/speex/speex_jitter.h
new file mode 100644 (file)
index 0000000..0099cc1
--- /dev/null
@@ -0,0 +1,87 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: speex_jitter.h
+
+   Adaptive jitter buffer for Speex
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+
+*/
+
+#ifndef SPEEX_JITTER_H
+#define SPEEX_JITTER_H
+
+#include "speex.h"
+#include "speex_bits.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SPEEX_JITTER_MAX_PACKET_SIZE 1500
+#define SPEEX_JITTER_MAX_BUFFER_SIZE 20
+
+#define MAX_MARGIN 12
+
+typedef struct SpeexJitter {
+   int buffer_size;
+   int pointer_timestamp;
+
+   SpeexBits current_packet;
+   int valid_bits;
+
+   char buf[SPEEX_JITTER_MAX_BUFFER_SIZE][SPEEX_JITTER_MAX_PACKET_SIZE];
+   int timestamp[SPEEX_JITTER_MAX_BUFFER_SIZE];
+   int len[SPEEX_JITTER_MAX_BUFFER_SIZE];
+
+   void *dec;
+   int frame_size;
+   int frame_time;
+   int reset_state;
+   
+   int lost_count;
+   float shortterm_margin[MAX_MARGIN];
+   float longterm_margin[MAX_MARGIN];
+   float loss_rate;
+} SpeexJitter;
+
+void speex_jitter_init(SpeexJitter *jitter, void *decoder, int sampling_rate);
+
+void speex_jitter_destroy(SpeexJitter *jitter);
+
+void speex_jitter_put(SpeexJitter *jitter, char *packet, int len, int time);
+
+void speex_jitter_get(SpeexJitter *jitter, short *out, int *current_timestamp);
+
+int speex_jitter_get_pointer_timestamp(SpeexJitter *jitter);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/include/speex/speex_noglobals.h b/utils/iaxclient/lib/libspeex/include/speex/speex_noglobals.h
new file mode 100644 (file)
index 0000000..1d46993
--- /dev/null
@@ -0,0 +1,60 @@
+/* Copyright (C) 2004 CSIRO Australia */
+/* Copyright (C) 2002 Jean-Marc Valin*/
+/**
+  @file speex_noglobals.h
+  @brief Dynamically allocates the different modes of the codec
+*/
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+
+*/
+
+#ifndef SPEEX_NOGLOBALS_H
+#define SPEEX_NOGLOBALS_H
+
+/* See README.symbian in the Speex source distribution for information
+ * on using this API */
+
+typedef struct SpeexMode SpeexMode;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Instantiate a mode */
+const SpeexMode * speex_mode_new (int modeID);
+
+/** Destroy a mode */
+void speex_mode_destroy (const SpeexMode * mode);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/include/speex/speex_preprocess.h b/utils/iaxclient/lib/libspeex/include/speex/speex_preprocess.h
new file mode 100644 (file)
index 0000000..391d156
--- /dev/null
@@ -0,0 +1,156 @@
+/* Copyright (C) 2003 Epic Games 
+   Written by Jean-Marc Valin
+
+   File: speex_preprocess.h
+
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are
+   met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+
+   2. 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.
+
+   3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+*/
+
+#ifndef SPEEX_PREPROCESS_H
+#define SPEEX_PREPROCESS_H
+
+#include "speex/speex_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct drft_lookup;
+
+typedef struct SpeexPreprocessState {
+   int    frame_size;        /**< Number of samples processed each time */
+   int    ps_size;           /**< Number of points in the power spectrum */
+   int    sampling_rate;     /**< Sampling rate of the input/output */
+   
+   /* parameters */
+   int    denoise_enabled;
+   int    agc_enabled;
+   float  agc_level;
+   int    vad_enabled;
+   int    dereverb_enabled;
+   float  reverb_decay;
+   float  reverb_level;
+   float  speech_prob_start;
+   float  speech_prob_continue;
+   
+   float *frame;             /**< Processing frame (2*ps_size) */
+   float *ps;                /**< Current power spectrum */
+   float *gain2;             /**< Adjusted gains */
+   float *window;            /**< Analysis/Synthesis window */
+   float *noise;             /**< Noise estimate */
+   float *reverb_estimate;   /**< Estimate of reverb energy */
+   float *old_ps;            /**< Power spectrum for last frame */
+   float *gain;              /**< Ephraim Malah gain */
+   float *prior;             /**< A-priori SNR */
+   float *post;              /**< A-posteriori SNR */
+
+   float *S;                 /**< Smoothed power spectrum */
+   float *Smin;              /**< See Cohen paper */
+   float *Stmp;              /**< See Cohen paper */
+   float *update_prob;       /**< Propability of speech presence for noise update */
+
+   float *zeta;              /**< Smoothed a priori SNR */
+   float  Zpeak;
+   float  Zlast;
+
+   float *loudness_weight;   /**< Perceptual loudness curve */
+
+   float *echo_noise;
+
+   float *noise_bands;
+   float *noise_bands2;
+   int    noise_bandsN;
+   float *speech_bands;
+   float *speech_bands2;
+   int    speech_bandsN;
+
+   float *inbuf;             /**< Input buffer (overlapped analysis) */
+   float *outbuf;            /**< Output buffer (for overlap and add) */
+
+   float  speech_prob;
+   int    last_speech;
+   float  loudness;          /**< loudness estimate */
+   float  loudness2;         /**< loudness estimate */
+   int    nb_adapt;          /**< Number of frames used for adaptation so far */
+   int    nb_loudness_adapt; /**< Number of frames used for loudness adaptation so far */
+   int    consec_noise;      /**< Number of consecutive noise frames */
+   int    nb_preprocess;     /**< Number of frames processed so far */
+   struct drft_lookup *fft_lookup;   /**< Lookup table for the FFT */
+
+} SpeexPreprocessState;
+
+/** Creates a new preprocessing state */
+SpeexPreprocessState *speex_preprocess_state_init(int frame_size, int sampling_rate);
+
+/** Destroys a denoising state */
+void speex_preprocess_state_destroy(SpeexPreprocessState *st);
+
+/** Preprocess a frame */
+int speex_preprocess(SpeexPreprocessState *st, spx_int16_t *x, float *echo);
+
+/** Preprocess a frame */
+void speex_preprocess_estimate_update(SpeexPreprocessState *st, spx_int16_t *x, float *echo);
+
+/** Used like the ioctl function to control the preprocessor parameters */
+int speex_preprocess_ctl(SpeexPreprocessState *st, int request, void *ptr);
+
+
+
+#define SPEEX_PREPROCESS_SET_DENOISE 0
+#define SPEEX_PREPROCESS_GET_DENOISE 1
+
+#define SPEEX_PREPROCESS_SET_AGC 2
+#define SPEEX_PREPROCESS_GET_AGC 3
+
+#define SPEEX_PREPROCESS_SET_VAD 4
+#define SPEEX_PREPROCESS_GET_VAD 5
+
+#define SPEEX_PREPROCESS_SET_AGC_LEVEL 6
+#define SPEEX_PREPROCESS_GET_AGC_LEVEL 7
+
+#define SPEEX_PREPROCESS_SET_DEREVERB 8
+#define SPEEX_PREPROCESS_GET_DEREVERB 9
+
+#define SPEEX_PREPROCESS_SET_DEREVERB_LEVEL 10
+#define SPEEX_PREPROCESS_GET_DEREVERB_LEVEL 11
+
+#define SPEEX_PREPROCESS_SET_DEREVERB_DECAY 12
+#define SPEEX_PREPROCESS_GET_DEREVERB_DECAY 13
+
+#define SPEEX_PREPROCESS_SET_PROB_START 14
+#define SPEEX_PREPROCESS_GET_PROB_START 15
+
+#define SPEEX_PREPROCESS_SET_PROB_CONTINUE 16
+#define SPEEX_PREPROCESS_GET_PROB_CONTINUE 17
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/include/speex/speex_stereo.h b/utils/iaxclient/lib/libspeex/include/speex/speex_stereo.h
new file mode 100644 (file)
index 0000000..0b70021
--- /dev/null
@@ -0,0 +1,78 @@
+/* Copyright (C) 2002 Jean-Marc Valin*/
+/**
+   @file speex_stereo.h
+   @brief Describes the handling for intensity stereo
+*/
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifndef STEREO_H
+#define STEREO_H
+
+#include "speex/speex_types.h"
+#include "speex/speex_bits.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** State used for decoding (intensity) stereo information */
+typedef struct SpeexStereoState {
+   float balance;      /**< Left/right balance info */
+   float e_ratio;      /**< Ratio of energies: E(left+right)/[E(left)+E(right)]  */
+   float smooth_left;  /**< Smoothed left channel gain */
+   float smooth_right; /**< Smoothed right channel gain */
+   float reserved1;    /**< Reserved for future use */
+   float reserved2;    /**< Reserved for future use */
+} SpeexStereoState;
+
+/** Initialization value for a stereo state */
+#define SPEEX_STEREO_STATE_INIT {1,.5,1,1}
+
+/** Transforms a stereo frame into a mono frame and stores intensity stereo info in 'bits' */
+void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits);
+
+/** Transforms a stereo frame into a mono frame and stores intensity stereo info in 'bits' */
+void speex_encode_stereo_int(spx_int16_t *data, int frame_size, SpeexBits *bits);
+
+/** Transforms a mono frame into a stereo frame using intensity stereo info */
+void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *stereo);
+
+/** Transforms a mono frame into a stereo frame using intensity stereo info */
+void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *stereo);
+
+/** Callback handler for intensity stereo info */
+int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/include/speex/speex_types.h b/utils/iaxclient/lib/libspeex/include/speex/speex_types.h
new file mode 100644 (file)
index 0000000..86311b8
--- /dev/null
@@ -0,0 +1,120 @@
+/* speex_types.h taken from libogg */
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: #ifdef jail to whip a few platforms into the UNIX ideal.
+ last mod: $Id: speex_types.h 529 2005-12-31 15:19:30Z coppice $
+
+ ********************************************************************/
+#ifndef _SPEEX_TYPES_H
+#define _SPEEX_TYPES_H
+
+#if defined(WIN32)  ||  defined(_WIN32_WCE)
+
+#  if defined(__CYGWIN__)
+#    include <_G_config.h>
+     typedef _G_int64_t spx_int64_t;
+     typedef _G_int32_t spx_int32_t;
+     typedef _G_uint32_t spx_uint32_t;
+     typedef _G_int16_t spx_int16_t;
+     typedef _G_uint16_t spx_uint16_t;
+#  elif defined(__MINGW32__)
+     typedef short spx_int16_t;                                                                             
+     typedef unsigned short spx_uint16_t;                                                                   
+     typedef int spx_int32_t;                                                                               
+     typedef unsigned int spx_uint32_t;                                                                     
+     typedef long long spx_int64_t;                                                                         
+     typedef unsigned long long spx_uint64_t;  
+#  elif defined(__MWERKS__)
+     typedef long long spx_int64_t;
+     typedef int spx_int32_t;
+     typedef unsigned int spx_uint32_t;
+     typedef short spx_int16_t;
+     typedef unsigned short spx_uint16_t;
+#  else
+     /* MSVC/Borland */
+     typedef __int64 spx_int64_t;
+     typedef __int32 spx_int32_t;
+     typedef unsigned __int32 spx_uint32_t;
+     typedef __int16 spx_int16_t;
+     typedef unsigned __int16 spx_uint16_t;
+#  endif
+
+#elif defined(__MACOS__)
+
+#  include <sys/types.h>
+   typedef SInt16 spx_int16_t;
+   typedef UInt16 spx_uint16_t;
+   typedef SInt32 spx_int32_t;
+   typedef UInt32 spx_uint32_t;
+   typedef SInt64 spx_int64_t;
+
+#elif defined(__MACOSX__) /* MacOS X Framework build */
+
+#  include <sys/types.h>
+   typedef int16_t spx_int16_t;
+   typedef u_int16_t spx_uint16_t;
+   typedef int32_t spx_int32_t;
+   typedef u_int32_t spx_uint32_t;
+   typedef int64_t spx_int64_t;
+
+#elif defined(__BEOS__)
+
+   /* Be */
+#  include <inttypes.h>
+   typedef int16_t spx_int16_t;
+   typedef u_int16_t spx_uint16_t;
+   typedef int32_t spx_int32_t;
+   typedef u_int32_t spx_uint32_t;
+   typedef int64_t spx_int64_t;
+
+#elif defined (__EMX__)
+
+   /* OS/2 GCC */
+   typedef short spx_int16_t;
+   typedef unsigned short spx_uint16_t;
+   typedef int spx_int32_t;
+   typedef unsigned int spx_uint32_t;
+   typedef long long spx_int64_t;
+
+#elif defined (DJGPP)
+
+   /* DJGPP */
+   typedef short spx_int16_t;
+   typedef int spx_int32_t;
+   typedef unsigned int spx_uint32_t;
+   typedef long long spx_int64_t;
+
+#elif defined(R5900)
+
+   /* PS2 EE */
+   typedef long spx_int64_t;
+   typedef int spx_int32_t;
+   typedef unsigned spx_uint32_t;
+   typedef short spx_int16_t;
+
+#elif defined(__SYMBIAN32__)
+
+   /* Symbian GCC */
+   typedef signed short spx_int16_t;
+   typedef unsigned short spx_uint16_t;
+   typedef signed int spx_int32_t;
+   typedef unsigned int spx_uint32_t;
+   typedef long long int spx_int64_t;
+
+#else
+
+#  include <speex/speex_config_types.h>
+
+#endif
+
+#endif  /* _SPEEX_TYPES_H */
diff --git a/utils/iaxclient/lib/libspeex/jitter.c b/utils/iaxclient/lib/libspeex/jitter.c
new file mode 100644 (file)
index 0000000..362d7d5
--- /dev/null
@@ -0,0 +1,315 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: speex_jitter.h
+
+   Adaptive jitter buffer for Speex
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#include "misc.h"
+#include <speex/speex.h>
+#include <speex/speex_bits.h>
+#include <speex/speex_jitter.h>
+#include <stdio.h>
+
+#define LATE_BINS 4
+
+void speex_jitter_init(SpeexJitter *jitter, void *decoder, int sampling_rate)
+{
+   int i;
+   for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
+   {
+      jitter->len[i]=-1;
+      jitter->timestamp[i]=-1;
+   }
+
+   jitter->dec = decoder;
+   speex_decoder_ctl(decoder, SPEEX_GET_FRAME_SIZE, &jitter->frame_size);
+   jitter->frame_time = 1000*jitter->frame_size / sampling_rate;
+
+   speex_bits_init(&jitter->current_packet);
+   jitter->valid_bits = 0;
+
+   jitter->buffer_size = 4;
+
+   jitter->pointer_timestamp = -jitter->frame_time * jitter->buffer_size;
+   jitter->reset_state = 1;
+   jitter->lost_count = 0;
+   jitter->loss_rate = 0;
+}
+
+void speex_jitter_destroy(SpeexJitter *jitter)
+{
+}
+
+
+void speex_jitter_put(SpeexJitter *jitter, char *packet, int len, int timestamp)
+{
+   int i,j;
+   int arrival_margin;
+
+   if (jitter->reset_state)
+   {
+      jitter->reset_state=0;
+      jitter->pointer_timestamp = timestamp-jitter->frame_time * jitter->buffer_size;
+      for (i=0;i<MAX_MARGIN;i++)
+      {
+         jitter->shortterm_margin[i] = 0;
+         jitter->longterm_margin[i] = 0;
+      }
+      for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
+      {
+         jitter->len[i]=-1;
+         jitter->timestamp[i]=-1;
+      }
+      fprintf(stderr, "reset to %d\n", timestamp);
+   }
+   
+   /* Cleanup buffer (remove old packets that weren't played) */
+   for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
+   {
+      if (jitter->timestamp[i]<jitter->pointer_timestamp)
+      {
+         jitter->len[i]=-1;
+         /*if (jitter->timestamp[i] != -1)
+            fprintf (stderr, "discarding %d %d\n", jitter->timestamp[i], jitter->pointer_timestamp);*/
+      }
+   }
+
+   /*Find an empty slot in the buffer*/
+   for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
+   {
+      if (jitter->len[i]==-1)
+         break;
+   }
+
+   /*fprintf(stderr, "%d %d %f\n", timestamp, jitter->pointer_timestamp, jitter->drift_average);*/
+   if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
+   {
+      int earliest=jitter->timestamp[0];
+      i=0;
+      for (j=1;j<SPEEX_JITTER_MAX_BUFFER_SIZE;j++)
+      {
+         if (jitter->timestamp[j]<earliest)
+         {
+            earliest = jitter->timestamp[j];
+            i=j;
+         }
+      }
+      /*fprintf (stderr, "Buffer is full, discarding earliest frame %d (currently at %d)\n", timestamp, jitter->pointer_timestamp);*/
+      /*No place left in the buffer*/
+      
+      /*skip some frame(s) */
+      /*return;*/
+   }
+   
+   /* Copy packet in buffer */
+   if (len>SPEEX_JITTER_MAX_PACKET_SIZE)
+      len=SPEEX_JITTER_MAX_PACKET_SIZE;
+   for (j=0;j<len/BYTES_PER_CHAR;j++)
+      jitter->buf[i][j]=packet[j];
+   jitter->timestamp[i]=timestamp;
+   jitter->len[i]=len;
+   
+   /* Don't count late packets when adjusting the synchro (we're taking care of them elsewhere) */
+   /*if (timestamp <= jitter->pointer_timestamp)
+   {
+      fprintf (stderr, "frame for timestamp %d arrived too late (at time %d)\n", timestamp, jitter->pointer_timestamp);
+   }*/
+
+   /* Adjust the buffer size depending on network conditions */
+   arrival_margin = (timestamp - jitter->pointer_timestamp - jitter->frame_time);
+   
+   if (arrival_margin >= -LATE_BINS*jitter->frame_time)
+   {
+      int int_margin;
+      for (i=0;i<MAX_MARGIN;i++)
+      {
+         jitter->shortterm_margin[i] *= .98;
+         jitter->longterm_margin[i] *= .995;
+      }
+      int_margin = (arrival_margin + LATE_BINS*jitter->frame_time)/jitter->frame_time;
+      if (int_margin>MAX_MARGIN-1)
+         int_margin = MAX_MARGIN-1;
+      if (int_margin>=0)
+      {
+         jitter->shortterm_margin[int_margin] += .02;
+         jitter->longterm_margin[int_margin] += .005;
+      }
+   }
+   
+   /*fprintf (stderr, "margin : %d %d %f %f %f %f\n", arrival_margin, jitter->buffer_size, 100*jitter->loss_rate, 100*jitter->late_ratio, 100*jitter->ontime_ratio, 100*jitter->early_ratio);*/
+}
+
+void speex_jitter_get(SpeexJitter *jitter, short *out, int *current_timestamp)
+{
+   int i;
+   int ret;
+   float late_ratio_short;
+   float late_ratio_long;
+   float ontime_ratio_short;
+   float ontime_ratio_long;
+   float early_ratio_short;
+   float early_ratio_long;
+   
+   late_ratio_short = 0;
+   late_ratio_long = 0;
+   for (i=0;i<LATE_BINS;i++)
+   {
+      late_ratio_short += jitter->shortterm_margin[i];
+      late_ratio_long += jitter->longterm_margin[i];
+   }
+   ontime_ratio_short = jitter->shortterm_margin[LATE_BINS];
+   ontime_ratio_long = jitter->longterm_margin[LATE_BINS];
+   early_ratio_short = early_ratio_long = 0;
+   for (i=LATE_BINS+1;i<MAX_MARGIN;i++)
+   {
+      early_ratio_short += jitter->shortterm_margin[i];
+      early_ratio_long += jitter->longterm_margin[i];
+   }
+   if (0&&jitter->pointer_timestamp%1000==0)
+   {
+      fprintf (stderr, "%f %f %f %f %f %f\n", early_ratio_short, early_ratio_long, ontime_ratio_short, ontime_ratio_long, late_ratio_short, late_ratio_long);
+      /*fprintf (stderr, "%f %f\n", early_ratio_short + ontime_ratio_short + late_ratio_short, early_ratio_long + ontime_ratio_long + late_ratio_long);*/
+   }
+   
+   if (late_ratio_short > .1 || late_ratio_long > .03)
+   {
+      jitter->shortterm_margin[MAX_MARGIN-1] += jitter->shortterm_margin[MAX_MARGIN-2];
+      jitter->longterm_margin[MAX_MARGIN-1] += jitter->longterm_margin[MAX_MARGIN-2];
+      for (i=MAX_MARGIN-2;i>=0;i--)
+      {
+         jitter->shortterm_margin[i+1] = jitter->shortterm_margin[i];
+         jitter->longterm_margin[i+1] = jitter->longterm_margin[i];         
+      }
+      jitter->shortterm_margin[0] = 0;
+      jitter->longterm_margin[0] = 0;            
+      /*fprintf (stderr, "interpolate frame\n");*/
+      speex_decode_int(jitter->dec, NULL, out);
+      if (current_timestamp)
+         *current_timestamp = jitter->pointer_timestamp;
+      return;
+   }
+   
+   /* Increment timestamp */
+   jitter->pointer_timestamp += jitter->frame_time;
+   
+   if (late_ratio_short + ontime_ratio_short < .005 && late_ratio_long + ontime_ratio_long < .01 && early_ratio_short > .8)
+   {
+      jitter->shortterm_margin[0] += jitter->shortterm_margin[1];
+      jitter->longterm_margin[0] += jitter->longterm_margin[1];
+      for (i=1;i<MAX_MARGIN-1;i++)
+      {
+         jitter->shortterm_margin[i] = jitter->shortterm_margin[i+1];
+         jitter->longterm_margin[i] = jitter->longterm_margin[i+1];         
+      }
+      jitter->shortterm_margin[MAX_MARGIN-1] = 0;
+      jitter->longterm_margin[MAX_MARGIN-1] = 0;      
+      /*fprintf (stderr, "drop frame\n");*/
+      jitter->pointer_timestamp += jitter->frame_time;
+   }
+
+   if (current_timestamp)
+      *current_timestamp = jitter->pointer_timestamp;
+
+   /* Send zeros while we fill in the buffer */
+   if (jitter->pointer_timestamp<0)
+   {
+      for (i=0;i<jitter->frame_size;i++)
+         out[i]=0;
+      return;
+   }
+   
+   /* Search the buffer for a packet with the right timestamp */
+   for (i=0;i<SPEEX_JITTER_MAX_BUFFER_SIZE;i++)
+   {
+      if (jitter->len[i]!=-1 && jitter->timestamp[i]==jitter->pointer_timestamp)
+         break;
+   }
+   
+   if (i==SPEEX_JITTER_MAX_BUFFER_SIZE)
+   {
+      /* No packet found */
+      if (jitter->valid_bits)
+      {
+         /* Try decoding last received packet */
+         ret = speex_decode_int(jitter->dec, &jitter->current_packet, out);
+         if (ret == 0)
+         {
+            jitter->lost_count = 0;
+            return;
+         } else {
+            jitter->valid_bits = 0;
+         }
+      }
+
+      /*fprintf (stderr, "lost/late frame %d\n", jitter->pointer_timestamp);*/
+      /*Packet is late or lost*/
+      speex_decode_int(jitter->dec, NULL, out);
+      jitter->lost_count++;
+      if (jitter->lost_count>=25)
+      {
+         jitter->lost_count = 0;
+         jitter->reset_state = 1;
+         speex_decoder_ctl(jitter->dec, SPEEX_RESET_STATE, NULL);
+      }
+      jitter->loss_rate = .999*jitter->loss_rate + .001;
+   } else {
+      jitter->lost_count = 0;
+      /* Found the right packet */
+      speex_bits_read_from(&jitter->current_packet, jitter->buf[i], jitter->len[i]);
+      jitter->len[i]=-1;
+      /* Decode packet */
+      ret = speex_decode_int(jitter->dec, &jitter->current_packet, out);
+      if (ret == 0)
+      {
+         jitter->valid_bits = 1;
+      } else {
+         /* Error while decoding */
+         for (i=0;i<jitter->frame_size;i++)
+            out[i]=0;
+      }
+      jitter->loss_rate = .999*jitter->loss_rate;
+   }
+
+
+}
+
+int speex_jitter_get_pointer_timestamp(SpeexJitter *jitter)
+{
+   return jitter->pointer_timestamp;
+}
diff --git a/utils/iaxclient/lib/libspeex/lbr_48k_tables.c b/utils/iaxclient/lib/libspeex/lbr_48k_tables.c
new file mode 100644 (file)
index 0000000..2e6db3f
--- /dev/null
@@ -0,0 +1,678 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: lbr_48k_tables.c
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+int dummy_epic_48k_variable=0;
+#ifdef EPIC_48K
+
+const signed char gain_cdbk_ulbr[192] = {
+-31, -48, -30, 
+-19, -10, -18, 
+-33, -22, -45, 
+-5, -56, -43, 
+-30, -56, -3, 
+-59, -17, -52, 
+-41, -60, -58, 
+-64, -47, -22, 
+-30, -31, -31, 
+-29, -14, -31, 
+-22, -37, -58, 
+-31, -44, 13, 
+-37, 0, 1, 
+-46, -55, -35, 
+-56, -14, -53, 
+-8, 1, -36, 
+-29, -15, -27, 
+-29, -39, -28, 
+-43, -5, 3, 
+-51, -27, -54, 
+10, -46, -36, 
+3, -3, -42, 
+-27, 16, -22, 
+-34, -52, 13, 
+-31, -21, -28, 
+-34, -45, -40, 
+-20, -48, 4, 
+-40, -27, 16, 
+-6, 11, -44, 
+-35, 12, -5, 
+19, -33, -37, 
+-29, 18, -32, 
+-29, -23, -19, 
+16, -47, -28, 
+-34, -30, 17, 
+-20, 2, -26, 
+-38, -40, -36, 
+15, -14, -40, 
+-39, 14, -9, 
+-15, 25, -39, 
+-26, 19, -32, 
+-39, 17, -14, 
+10, -36, -26, 
+14, -13, -40, 
+-29, -21, -12, 
+-8, 19, -39, 
+-36, -18, 15, 
+-32, -38, -38, 
+-19, 4, -23, 
+-38, -7, 11, 
+9, -10, -39, 
+-37, 24, -19, 
+-34, -5, -8, 
+-20, 23, -41, 
+-4, 17, -31, 
+-17, -26, -26, 
+-24, 28, -36, 
+-7, 15, -39, 
+-42, 16, -11, 
+-29, 14, -6, 
+-36, 28, -27, 
+-21, 5, -26, 
+11, -9, -39, 
+-38, -7, 13, 
+};
+
+
+const signed char exc_12_32_table[384] = {
+34, 55, 9, 55, 4, 44, -2, 25, 4, -6, 13, -22, 
+20, 26, -13, -56, -37, 18, 5, 28, 4, 10, 6, -7, 
+37, -24, -31, 22, 12, -6, -4, -7, 2, 0, -3, -2, 
+-16, -13, -1, 9, -2, 4, 6, 5, -3, 3, 8, -1, 
+-1, -6, -2, -1, 8, 24, 19, 33, -73, -53, 6, -18, 
+14, 7, 11, 8, -33, -94, -5, 7, 0, 44, 1, 19, 
+-9, -7, -34, -16, 8, 2, 5, 0, 3, 1, -2, 3, 
+-22, 6, -2, 12, 16, 30, 39, 25, 25, 2, 10, -2, 
+-1, -40, -6, -51, -5, -48, -9, -33, -14, -1, -24, 15, 
+104, 39, 12, -9, -20, -12, -30, -10, -31, -7, -30, -8, 
+-71, -53, -4, -11, 9, -10, 7, -10, 10, -1, 11, 8, 
+24, 14, 6, -3, 10, 8, 8, 11, -6, 11, 0, -2, 
+-6, -2, 1, -1, -3, 8, -41, 27, 57, -7, 11, -16, 
+-61, 50, 10, -10, 4, -13, 14, -7, 1, 5, -4, 4, 
+0, 2, -1, -2, -1, 1, 1, 0, -1, -1, -2, -3, 
+-3, -15, 69, 60, 10, -10, -10, -29, -21, -7, -16, 2, 
+24, -32, 24, -18, -14, -2, -11, 11, -6, 10, 1, 3, 
+24, -10, 14, 18, -13, 17, -16, 4, -3, -21, -3, -11, 
+-19, 12, -14, 26, 20, -9, 24, -15, 18, 1, -32, -2, 
+-1, 8, -3, 4, 11, -47, 7, 46, -4, -10, -10, -2, 
+-24, 29, -33, 6, -20, -3, 0, -12, 5, -30, 8, -13, 
+28, 9, 5, -11, 0, -14, -13, -22, -12, -8, -4, 1, 
+-6, 28, 45, -18, -31, -5, 1, 2, 1, 5, 0, -3, 
+-19, -10, 10, 27, 8, -16, -28, -9, 2, -5, 8, -1, 
+100, -49, 4, -43, 25, -7, 1, 9, -13, 13, -18, 13, 
+-1, -1, 0, 2, -2, -8, 9, -46, -7, 70, 23, 7, 
+-103, 20, 8, 42, -5, 21, -4, 4, 1, -8, 16, -8, 
+3, 3, 8, 4, 7, -3, -3, -4, 9, 6, 2, 13, 
+6, 3, -15, 11, -43, 31, 40, -13, 12, -21, -2, -3, 
+-10, -9, 16, -35, 31, -3, -12, 8, -34, 7, 12, 22, 
+-3, -4, -7, -12, 24, 53, -19, -43, 4, -3, -4, 6, 
+-18, -30, -58, -17, -11, 17, 23, 34, 30, 28, 28, 15, 
+};
+
+
+const signed char cdbk_lsp_vlbr[5120]={
+23, 34, 108, 100, 102, 82, 69, 48, 52, 25,
+0, -37, -55, -78, -111, -79, 58, 57, 45, 32,
+27, -9, -12, -14, -41, -29, -17, -41, 44, 35,
+-24, -68, -72, 61, 100, 73, 100, 80, 70, 37,
+12, -5, 22, 11, -10, -40, -33, -17, 19, 12,
+-20, -57, -94, -92, 56, 71, 48, 31, 22, -5,
+41, 28, 6, -6, -12, -39, -18, -16, -30, -23,
+65, 54, 41, 28, 23, 9, 26, 18, 22, 6,
+17, -16, -33, -54, -87, -79, 8, -8, 44, 35,
+-20, -62, -78, 22, 78, 47, 44, 33, 26, 14,
+8, 1, 45, 47, 72, 68, 55, 31, 36, 17,
+-27, -68, -86, -65, -10, 23, 8, -22, -31, 25,
+-4, -38, -55, -68, -96, -118, -39, 30, 28, 31,
+-21, -66, -47, 99, 91, 68, 78, 56, 64, 36,
+33, 22, 13, -13, -36, -22, 44, 37, 54, 33,
+-31, -76, -106, -100, -5, 21, 7, -17, 13, 48,
+-26, -65, -84, -84, -46, 67, 97, 66, 58, 31,
+-20, -52, -32, -20, 3, 16, 27, 40, 54, 29,
+-6, -35, -56, -64, -8, -31, -36, 21, 26, -3,
+32, 23, 1, -23, -19, -44, -45, -7, 10, -10,
+-24, -55, 2, 67, 72, 85, 90, 74, 77, 45,
+-21, -58, -45, -49, 16, 34, 13, -15, -16, 16,
+8, -31, -34, -61, -83, 10, 24, 8, 56, 25,
+-8, -49, -74, -95, -123, -77, 6, 40, 46, 42,
+-21, -60, -59, -34, -12, 27, 8, -19, -48, -17,
+-25, -66, -78, -73, -81, -16, 14, 0, -2, 33,
+78, 79, 69, 49, 44, 32, 50, 44, 46, 22,
+24, 9, -4, -18, -37, -56, 22, 34, 22, 11,
+-19, -59, -85, -41, 46, 72, 60, 33, 29, -3,
+-21, -66, -70, 65, 92, 57, 61, 41, 40, 23,
+-4, -41, -60, -72, -102, -106, 4, 56, 57, 31,
+-5, -48, -62, -91, -109, 1, 76, 54, 72, 39,
+-21, -61, -86, -46, -34, -39, 42, 25, 15, 12,
+5, -16, -36, -56, 5, 18, 11, 13, 52, 23,
+12, -6, 30, 40, 59, 40, 27, 8, 19, 6,
+25, 8, -9, -19, -25, -53, -40, -38, -46, -4,
+-17, -59, -83, 2, 58, 29, 18, -2, -17, -5,
+-35, -80, -111, -117, -41, -9, 14, 23, 36, 56,
+48, 67, 93, 71, 77, 91, 110, 95, 83, 47,
+-25, -62, -97, -93, 76, 96, 73, 52, 61, 28,
+-9, -55, -46, 49, 33, 8, 1, -25, 28, 23,
+-10, -47, -60, -45, -62, -58, 56, 57, 48, 28,
+34, 12, -9, 0, 34, 4, 6, 11, 3, -18,
+21, -9, -16, -13, -39, -41, 14, -8, 33, 28,
+-7, -49, -61, 15, 34, 3, 2, -13, -28, -17,
+-14, -50, -46, -65, -76, -13, -10, -29, -30, 22,
+-28, -68, -97, -98, -8, 38, 36, 26, 25, 15,
+6, -33, -9, 1, -28, -11, -19, -24, 61, 36,
+-15, -60, -19, 81, 58, 52, 42, 28, 66, 36,
+-15, -52, -71, -15, 11, -13, 38, 28, 11, -4,
+34, 1, -9, -27, -57, -19, 36, 6, 14, 0,
+-1, -43, -14, 16, -12, -5, -14, -29, -33, -32,
+-13, -57, -75, -100, -111, 1, 2, 13, 48, 33,
+12, 16, 100, 85, 69, 49, 40, 29, 46, 23,
+-4, -26, -41, -44, -7, -26, -39, -27, 18, 0,
+-4, -47, -51, 17, 7, -19, 13, -10, -16, 9,
+-24, -63, -93, -53, 25, 14, 73, 51, 35, 8,
+-34, -77, -106, -83, -51, -47, 2, 12, 41, 53,
+-13, -47, -67, -44, 42, 20, 24, 33, 21, -3,
+11, -15, -29, -51, -79, -88, 22, 56, 43, 20,
+11, -22, -37, -1, 61, 40, 28, 24, 22, -6,
+-3, -33, -50, -66, -93, -100, -16, -16, 3, 41,
+-18, -58, -82, -5, 95, 78, 56, 39, 30, 1,
+-6, -47, -28, -26, -36, 49, 55, 51, 71, 35,
+-6, -50, -42, -4, -32, -1, -1, -18, 67, 40,
+-23, -63, -56, -48, -32, 0, -14, -43, -46, 25,
+-17, -61, -63, 13, -1, 28, 23, 10, 67, 36,
+45, 92, 124, 111, 108, 86, 77, 56, 57, 28,
+50, 35, 13, 3, -2, -32, 3, 14, 6, -8,
+12, -17, -24, -42, -67, -23, 67, 49, 64, 38,
+-21, -60, -90, -45, 32, 6, 7, -3, -15, 9,
+-16, -62, -73, 50, 46, 18, 7, -13, 63, 39,
+19, -16, -19, 20, 5, -15, 16, -9, 5, 8,
+-11, -46, -42, -39, -55, -68, -62, -27, -18, 23,
+-23, -61, -67, -71, -29, 44, 32, 10, -15, -12,
+-6, -45, -43, -40, -67, -22, 42, 19, 61, 38,
+9, -13, -38, -37, 40, 30, 15, 9, 11, -16,
+0, -18, -29, -34, -17, -44, -50, -3, 47, 15,
+-3, -46, -26, 20, -10, 16, 20, -2, 43, 18,
+-23, -46, 46, 91, 99, 100, 99, 79, 72, 42,
+-1, -44, -33, -36, -56, 22, 17, 4, 71, 37,
+0, -38, -49, 0, -1, -30, -21, -35, -44, -6,
+-32, -74, -101, -98, -14, -21, -23, 7, 26, 45,
+8, -28, -44, -63, -96, -84, 34, 21, 13, 23,
+10, -24, -38, -17, -29, -53, -16, -41, -14, 23,
+-19, -61, -76, -12, 97, 99, 79, 60, 59, 25,
+5, -11, -26, -54, -26, -8, -13, 3, 25, 4,
+17, 16, 4, -24, -1, 42, 60, 63, 70, 37,
+10, -27, -22, -43, -62, -7, -16, 10, 75, 40,
+-26, -64, -96, -106, -3, 73, 73, 46, 55, 29,
+-2, -45, -43, 45, 46, 17, 37, 10, 30, 32,
+21, -2, -18, -28, -47, -63, -38, -56, -3, 27,
+-17, -48, -9, 9, 3, 28, 50, 58, 73, 44,
+8, -14, -32, -56, -81, -106, -35, 41, 53, 26,
+1, -38, -51, -66, -100, -61, 32, 17, 66, 42,
+17, 5, -6, -21, -26, -52, -36, 23, 56, 22,
+6, -20, -31, -22, -19, -48, 16, 38, 22, -2,
+-25, -67, -93, -51, 82, 62, 71, 69, 63, 35,
+-12, -51, -71, -60, -76, -91, -14, 41, 35, 20,
+-16, -31, 22, 32, 55, 80, 98, 91, 85, 49,
+-21, -63, -92, -6, 57, 27, 36, 11, 60, 39,
+-7, -45, -67, -81, -114, -110, 0, 24, 23, 45,
+-18, -55, -61, -56, -60, -64, -32, -2, 58, 36,
+-3, -33, -51, -24, 19, -10, -19, 4, 14, -15,
+-19, -59, -81, -12, 7, -12, 36, 16, 48, 36,
+17, -13, -32, -49, -78, -95, -1, -3, -10, 25,
+15, 5, 41, 59, 108, 101, 103, 81, 70, 35,
+-14, -52, -37, 15, 93, 83, 66, 50, 47, 15,
+-3, -31, -49, -52, -9, -31, -10, 37, 62, 27,
+-15, -56, -82, -17, 75, 56, 36, 22, 7, -16,
+-24, -63, -93, -84, 25, 94, 98, 65, 60, 31,
+-2, -45, -39, -61, -61, 48, 35, 32, 54, 18,
+-19, -51, -45, -57, -28, -8, 10, 14, 38, 26,
+-2, -46, -38, 45, 26, 22, 48, 21, 63, 40,
+-22, -61, -73, -75, -67, -31, 13, 18, 51, 34,
+-12, -2, -1, -17, -3, -27, -3, 6, -1, -15,
+-16, -59, -78, 10, 36, 9, 4, -18, 33, 22,
+-25, -62, -97, -107, 39, 87, 69, 46, 42, 12,
+11, -7, -30, -36, 19, 2, -10, -7, -4, -24,
+11, -8, 25, 28, 28, 5, -4, -10, 5, -2,
+-10, -48, -37, -17, -38, -9, -2, -19, -30, -22,
+-23, -61, -79, -81, -2, 15, -4, 17, 20, 2,
+25, -14, -3, -10, -38, 1, 14, -14, -9, -27,
+2, -18, -38, -36, -11, -39, -36, -28, -36, -11,
+32, 59, 127, 124, 127, 108, 91, 68, 64, 34,
+3, -32, -37, -10, -25, -46, 12, 1, -17, -24,
+-29, -69, -102, -100, 2, -7, 11, 14, 1, 31,
+30, -6, -4, -16, -44, -5, 3, -9, 66, 40,
+-9, -45, -52, -5, 37, 19, 26, 6, 51, 32,
+-31, -73, -96, -45, -25, -37, -15, -16, 32, 39,
+3, -15, 18, 21, 28, 33, 58, 58, 69, 42,
+-31, -73, -99, -99, -48, 14, 21, 5, 2, 39,
+7, -35, -20, 29, 2, -8, -8, -28, 38, 26,
+-5, -39, -64, -36, 15, -15, -11, -21, -23, 5,
+-8, -51, -56, 15, -1, -14, -8, -31, 36, 22,
+-8, -53, -68, -98, -101, 42, 49, 38, 41, 12,
+10, -27, -22, 4, -23, -21, 30, -1, 22, 26,
+-13, -56, -42, 31, 9, -1, -10, -2, 22, -4,
+15, 8, 56, 57, 45, 55, 57, 46, 72, 44,
+-7, -53, -26, 53, 21, 17, 0, 0, 74, 41,
+3, -18, -2, 0, 19, 17, 42, 36, 47, 26,
+24, -7, -23, -34, -62, -60, 6, -22, 18, 25,
+-11, -42, -46, -61, -83, -99, -67, -11, 28, 39,
+30, -3, -10, -1, -24, -30, -1, -28, 15, 18,
+19, -15, -10, -6, -35, -26, 33, 10, 56, 39,
+-13, -53, -82, -42, 53, 37, 18, 10, -3, -21,
+-21, -60, -89, -46, 89, 94, 71, 46, 42, 9,
+-2, -34, -44, -46, -64, -84, -1, 37, 16, 0,
+-17, -51, -65, -64, -7, -17, -29, -11, 52, 27,
+22, -15, -16, -39, -55, 26, 36, 21, 62, 28,
+-2, -26, -38, -49, -55, -80, -75, 8, 20, 9,
+-6, -47, -61, -82, -103, -17, -15, -25, 53, 40,
+-8, -47, -66, -18, 56, 43, 25, 29, 39, 3,
+-27, -66, -86, -69, -50, -59, -34, -1, 19, 42,
+3, -20, 2, 21, 72, 57, 52, 36, 31, 7,
+-12, -49, -61, -13, -1, -33, 5, 37, 26, 2,
+-27, -69, -92, -62, 2, 43, 88, 67, 64, 36,
+0, -40, -4, -6, -20, 43, 33, 25, 50, 20,
+14, -20, -30, -44, -73, -37, -24, -47, 26, 20,
+31, 53, 111, 118, 127, 126, 121, 99, 85, 46,
+-14, -45, -51, -39, 24, 5, -6, 17, 46, 14,
+-4, -43, -45, -70, -63, 8, 14, 58, 78, 39,
+-8, -47, -66, -84, -114, -55, 10, -8, 32, 40,
+28, 22, 42, 26, 8, -21, -16, -6, 22, 10,
+24, 10, 34, 31, 35, 31, 46, 39, 59, 36,
+-4, -43, -62, -10, 20, -14, 2, 14, -6, -19,
+-21, -62, -89, -22, 62, 33, 30, 16, 15, 15,
+0, -22, -31, -45, -58, -80, -66, 13, 68, 34,
+-16, -45, -6, 7, -6, -17, -14, -15, 2, 2,
+10, -5, -22, -38, -40, -70, -60, -15, -23, 0,
+22, -11, -22, -39, -67, -25, 30, 5, 58, 37,
+-21, -47, 6, 43, 37, 45, 65, 66, 73, 43,
+2, -25, -40, -53, -72, -94, -35, 24, 9, 8,
+-3, 0, -3, -9, 4, -23, -10, 20, 43, 14,
+-2, -41, -60, -9, 57, 32, 17, 16, 6, -19,
+1, -31, -36, -36, -54, -68, -77, -75, 21, 37,
+-19, -32, 79, 90, 92, 81, 67, 47, 52, 28,
+-6, -36, -57, -62, 27, 40, 21, 11, 9, -19,
+-10, -47, -49, -59, -74, -18, -14, -30, 25, 18,
+-23, -69, -82, 60, 66, 40, 75, 54, 65, 38,
+-19, -57, -92, -68, 66, 58, 34, 18, 1, -16,
+-29, -68, -99, -88, -37, -38, 13, 8, 5, 40,
+-22, -63, -75, 14, 15, 7, 75, 58, 59, 34,
+-23, -62, -82, -39, -31, -53, -27, 5, -3, 20,
+13, -26, -20, 22, 2, -3, 35, 13, 54, 39,
+32, 5, -13, -22, -45, -58, -1, -20, -19, 7,
+30, 46, 70, 55, 89, 88, 91, 67, 56, 28,
+-13, -50, -63, -25, -28, -50, -23, -32, -34, 19,
+-13, -54, -65, -9, -20, -37, 29, 6, 11, 25,
+0, -40, -55, -78, -107, -25, 47, 20, 34, 16,
+-20, -58, -96, -103, 38, 43, 27, 30, 15, -1,
+-16, -49, -52, -66, -80, -57, -44, -39, 6, 38,
+0, -38, 5, 13, -8, 23, 24, 1, 7, -9,
+-18, -56, -64, -7, 38, 13, 11, 32, 28, 0,
+14, -3, -20, -17, 4, -26, -34, -8, 19, -9,
+-23, -60, -83, -38, -8, -32, 11, 19, -1, -5,
+-5, -47, -12, 56, 38, 22, 18, -8, -5, -8,
+18, -4, -24, -16, 27, 2, -6, 5, 25, -5,
+13, 0, -19, -35, -23, -45, -59, -30, 19, 3,
+19, -12, -23, 1, -7, -35, -14, -32, -23, 4,
+-23, -64, -67, -22, -27, -5, -5, -20, 20, 5,
+20, 11, 83, 92, 85, 89, 69, 53, 80, 48,
+15, -2, -21, -29, -18, -48, -52, -12, -11, -21,
+-6, -38, -55, -68, -9, 33, 22, 19, 25, -1,
+-8, -46, -49, -67, -64, 16, 8, -6, 32, 15,
+3, -25, -46, -46, 39, 50, 34, 21, 46, 14,
+8, -33, -37, -68, -82, 31, 34, 13, 19, -6,
+33, 0, 5, -7, -32, 2, 22, -3, 35, 17,
+-23, -62, -91, -64, 6, 3, 36, 26, 7, -3,
+-12, -54, -60, 26, 46, 16, 30, 22, 8, -4,
+-23, -61, -40, 31, 58, 73, 88, 77, 74, 41,
+-2, -42, -49, 13, 5, -15, 22, -4, 26, 27,
+-13, -54, -39, 18, 2, -8, -12, 34, 56, 23,
+-20, -31, 27, 23, 24, 28, 39, 33, 47, 27,
+36, 17, -4, -20, -30, -61, -8, 20, 0, -15,
+-10, -51, -72, -82, -111, -73, 34, 25, 19, 38,
+-10, -45, -63, -55, -46, -75, -45, 34, 34, 12,
+6, -18, 29, 26, 7, -9, 0, 5, 38, 22,
+-7, -52, -16, 69, 43, 26, 23, 2, 51, 34,
+-12, -51, -59, -78, -88, 15, 20, 0, -14, 12,
+-3, -36, -59, -45, 60, 49, 28, 20, 16, -13,
+-28, -70, -90, 9, 67, 48, 90, 77, 70, 38,
+-10, -39, -58, -54, 15, -12, 3, 35, 27, -3,
+12, -1, 28, 29, 55, 53, 80, 65, 51, 23,
+-17, -61, -39, 74, 56, 43, 75, 51, 58, 36,
+-30, -71, -93, -43, -29, -26, 4, -19, -14, 37,
+3, -13, -31, -38, 11, -5, -22, -11, 43, 14,
+-25, -65, -80, -79, -71, 3, 37, 32, 20, 9,
+-20, -60, -77, -26, 18, 43, 44, 24, 22, -3,
+-4, -42, -22, -19, -45, -32, -35, -39, -46, 1,
+-25, -59, -27, -10, -7, -4, 7, 13, 25, 12,
+8, -25, -32, -47, -74, -32, 27, 6, 25, 7,
+41, 40, 62, 64, 64, 50, 54, 42, 49, 25,
+-21, -63, -88, -21, 16, -3, -4, -26, 57, 38,
+8, -25, -34, 2, -8, -28, 2, -22, 12, 23,
+-19, -49, 10, 71, 84, 71, 66, 48, 42, 22,
+-20, -58, -89, -57, 62, 44, 33, 36, 25, -1,
+-22, -55, -27, 1, 43, 37, 46, 50, 51, 26,
+1, -38, -46, 22, 34, 4, 20, -2, 3, 9,
+-4, -42, -49, -75, -89, -24, -25, 19, 71, 39,
+5, -28, -45, -43, -63, -75, -17, -38, 14, 30,
+-4, -36, -62, -59, -29, -43, -4, -16, 11, 23,
+-19, -57, -82, -39, 26, 2, -2, 20, 11, -10,
+-28, -68, -92, -70, 9, -1, -15, -30, 11, 31,
+1, -22, -41, -49, -30, -58, -48, 8, 4, -9,
+38, 41, 108, 115, 96, 98, 103, 84, 86, 51,
+15, 1, 58, 46, 26, 6, 16, 18, 41, 24,
+4, -34, -14, -27, -42, 20, 18, 2, 23, 1,
+-22, -59, -83, -70, -22, -42, -26, 29, 29, 15,
+-14, -34, 11, -1, -21, -35, -3, 1, 29, 16,
+-16, -57, -78, -7, 17, -13, 8, -13, -6, 22,
+-22, -32, -21, -20, 20, -4, 10, 13, 12, -4,
+8, -30, -30, -46, -71, -4, 3, -11, 4, -11,
+16, 5, -15, -21, 3, -23, -25, -19, -28, -32,
+-28, -68, -98, -101, -34, 19, 71, 52, 49, 30,
+-18, -57, -82, -56, -56, -66, 15, 12, 1, 29,
+-21, -62, -76, -27, -33, -38, 18, 30, 54, 32,
+3, -36, -10, -17, -34, -3, -8, 32, 63, 27,
+1, -30, -44, -20, -13, -49, -25, 3, -14, -18,
+-26, -68, -80, -46, -28, 17, 42, 37, 58, 34,
+30, 26, 57, 55, 49, 25, 16, 3, 24, 11,
+35, 35, 67, 57, 60, 82, 114, 103, 93, 55,
+18, -8, -23, -32, -53, -68, 15, 11, -6, -7,
+-2, -43, -29, 0, -28, -5, -5, -15, 25, -1,
+4, -13, -35, -45, 14, -6, -2, 19, 16, -9,
+-30, -72, -93, -93, -73, -10, -15, 6, 30, 45,
+-23, -58, -50, -55, -74, -60, -23, 0, 6, 21,
+-4, -40, -63, -24, 7, -19, 4, -18, 27, 28,
+-12, 1, 88, 76, 74, 88, 93, 90, 80, 44,
+-13, -59, -43, 52, 27, 21, 15, 12, 42, 11,
+22, -14, -17, -33, -57, -4, 5, -18, 40, 18,
+-3, -23, -43, -44, 8, -16, -14, -4, -20, -29,
+35, 45, 75, 82, 111, 117, 125, 105, 89, 51,
+-3, -38, -57, -30, 79, 71, 48, 33, 33, 0,
+-17, -62, -57, 66, 67, 35, 29, 5, 22, 17,
+3, -31, -34, -21, -44, -49, 42, 23, 24, 26,
+-23, -62, -74, -49, -30, -30, -37, -50, 9, 35,
+-17, -57, -71, -81, -45, 61, 58, 37, 31, 9,
+3, -7, 28, 14, -2, 0, 40, 41, 58, 33,
+-11, -51, -74, -17, 40, 12, 8, 13, -4, -22,
+-16, -46, -31, -35, -49, -49, -26, -9, -7, -7,
+17, -9, -24, -41, -68, -73, 38, 33, 19, 16,
+-15, -50, -47, -16, -24, -21, 59, 56, 53, 30,
+-14, -54, -57, 2, -17, -33, -34, -21, 4, -4,
+-23, -62, -93, -72, 48, 31, 21, 6, 3, 17,
+-18, -63, -79, 44, 68, 36, 45, 20, 57, 37,
+-29, -72, -99, -111, -86, -31, 7, 25, 39, 55,
+-14, -49, -53, -63, -80, -31, 24, 13, 1, -1,
+-9, -45, -55, -27, -31, -63, -23, 25, 13, -5,
+-20, -61, -80, 7, 44, 16, 54, 40, 32, 17,
+24, 7, -8, -43, -62, -54, -11, 7, 35, 27,
+-12, -55, -59, -48, -69, -4, -1, -12, 68, 39,
+-12, -31, 52, 63, 53, 34, 29, 22, 36, 19,
+-26, -66, -97, -79, 50, 41, 40, 48, 54, 28,
+-2, -37, -41, -2, -11, -30, 29, 16, 4, -2,
+40, 49, 56, 37, 39, 40, 64, 59, 67, 39,
+11, -5, 20, 14, 25, 16, 25, 22, 37, 17,
+-3, -43, -46, -10, -35, -38, -35, -39, 67, 43,
+-7, -47, -33, -39, -60, -12, -18, 11, 43, 11,
+-25, -65, -91, -76, -91, -81, 0, 13, 34, 50,
+-9, -50, -52, 17, 0, -4, 43, 18, 63, 42,
+-8, -15, 15, 41, 56, 35, 51, 45, 51, 29,
+0, -14, -24, -36, -43, -70, -39, 27, 33, 5,
+-25, -62, -81, -66, -12, -26, -16, -4, -13, 21,
+-29, -68, -60, -24, -3, 11, 18, 19, 30, 20,
+1, -35, -42, -30, -57, -51, 13, -17, 3, 22,
+-8, -27, -12, -2, -7, -21, 36, 41, 34, 12,
+-17, -56, -62, -72, -73, -17, -26, 9, 16, 13,
+11, -21, -37, -3, 16, -17, 1, -3, -18, -19,
+15, -20, -19, -22, -49, -30, -7, -29, 3, -2,
+17, -4, 11, 6, 51, 40, 36, 34, 48, 22,
+-19, -55, -29, 37, 68, 49, 45, 33, 42, 23,
+7, -30, -22, 3, -22, -36, -36, -54, 20, 22,
+20, 2, -15, -39, -59, -85, -10, 37, 21, 2,
+-15, -54, -77, -54, 74, 70, 48, 32, 51, 20,
+-25, -64, -70, -75, -52, 17, 6, -20, -30, 26,
+-13, -55, -15, 39, 16, 42, 30, 33, 62, 28,
+-21, -56, -30, -35, 6, 13, -4, -29, 33, 27,
+-17, -55, -75, -31, 3, -28, -26, 16, 18, -4,
+-13, -44, -60, -52, -9, -36, -38, 1, -9, -9,
+-12, -50, -77, -70, 43, 47, 28, 13, 43, 16,
+-13, -57, -80, -104, -113, -30, 43, 45, 52, 39,
+3, -28, -42, -37, -58, -67, 23, 4, 38, 33,
+-21, -64, -74, -22, 43, 83, 81, 56, 62, 32,
+34, 26, 23, 9, 14, 17, 26, 16, 37, 19,
+-5, -48, -49, -75, -65, 9, -6, 41, 45, 15,
+32, 30, 63, 83, 90, 91, 100, 84, 85, 52,
+-19, -54, -68, -71, 11, 30, 13, 1, 63, 37,
+44, 76, 99, 87, 117, 113, 103, 77, 64, 32,
+-16, -45, -12, 30, 27, 15, 57, 49, 42, 22,
+9, -15, -31, -28, -36, -61, -13, -18, -33, -5,
+-12, -55, -8, 82, 64, 47, 42, 21, 27, 9,
+-15, -56, -74, -12, -19, -28, 7, -16, 53, 38,
+-7, -45, -64, -55, -74, -80, 35, 45, 24, 15,
+-25, -48, -34, -42, -6, -27, -9, 9, 13, -7,
+-25, -65, -84, -35, 30, 14, 24, 39, 48, 28,
+-22, -62, -86, -51, 64, 104, 94, 61, 62, 31,
+16, -15, -25, -28, -55, -56, -10, -23, 52, 36,
+10, -10, -22, -46, -71, -92, -45, -13, 16, 26,
+-22, -65, -84, 17, 85, 55, 66, 48, 55, 31,
+-1, -38, -33, -25, -49, -15, 18, -10, 41, 30,
+-3, -24, -47, -60, -30, -46, -17, -13, -27, 1,
+-7, -41, -61, -54, -50, -78, -28, 5, -2, 20,
+17, -12, -27, -4, 8, -27, -5, 23, 14, -12,
+-36, -81, -111, -75, -17, -9, 9, 9, 39, 49,
+-13, -59, -54, 68, 51, 32, 35, 14, 64, 38,
+-11, -44, -69, -57, 11, -11, -5, 3, -16, -15,
+34, 36, 41, 16, -8, -24, 11, 23, 48, 28,
+-17, -42, 8, 17, 45, 69, 71, 55, 49, 23,
+3, -30, -46, -64, -95, -109, 2, 39, 19, 19,
+25, -13, -7, 16, -11, -5, 8, -11, 52, 33,
+-8, -37, -57, -60, 13, 7, -14, -4, 20, -7,
+7, -31, 9, 44, 20, 22, 29, 10, 52, 31,
+3, -22, -36, -53, -80, -77, -35, -41, 54, 41,
+-21, -59, -87, -83, 12, 69, 57, 36, 32, 2,
+6, -14, -34, -42, -4, -32, -27, 10, 4, -20,
+-11, -56, -59, 25, 8, -5, -9, -26, 68, 43,
+22, 13, 40, 39, 73, 81, 95, 88, 82, 45,
+-18, -62, -79, 28, 60, 28, 29, 3, 23, 25,
+6, -31, -39, -55, -85, -32, 7, -17, 48, 30,
+7, -24, -42, -8, 39, 10, 7, 11, 1, -20,
+-1, -36, -26, -30, -48, 2, 46, 26, 35, 14,
+-17, -57, -56, -10, -4, 26, 22, 6, -4, -16,
+-18, -55, -59, -67, -86, -50, 3, 29, 29, 16,
+-25, -61, -33, 2, 26, 25, 23, 10, 24, 16,
+26, 15, -8, -20, 6, -21, -16, 3, 0, -22,
+13, -17, -26, -12, -31, -48, 15, -3, 1, 14,
+4, -27, -33, -21, -29, -53, -52, -64, -42, 22,
+-11, -41, -42, -40, -42, -64, 0, 48, 50, 19,
+-13, -47, -42, -56, -50, 10, 3, -9, -30, -16,
+-4, -47, -12, 14, -13, 21, 13, 6, 73, 40,
+-15, -50, -63, -41, -31, -55, -60, -13, 28, 15,
+-6, -50, -56, -81, -95, 30, 29, 21, 71, 35,
+-14, -58, -65, 37, 40, 9, 18, -10, -4, 20,
+31, 33, 79, 106, 119, 103, 100, 77, 64, 33,
+14, 7, 56, 81, 97, 85, 85, 61, 45, 20,
+-24, -66, -74, -51, -17, 16, 5, -21, 22, 26,
+-1, -25, -38, -24, -2, -35, -26, 21, 34, 1,
+20, 15, 75, 59, 39, 26, 48, 43, 50, 29,
+26, 1, -15, -4, -9, -38, 9, 2, -9, -8,
+20, 14, 19, 13, 2, -16, 24, 25, 19, 3,
+-8, -41, -58, -78, -109, -106, -27, 9, 53, 46,
+17, 5, -13, -25, -24, -54, -20, 2, -21, -25,
+-11, -50, -48, 19, 10, -7, 46, 26, 24, 17,
+-28, -68, -69, -50, -49, -33, -7, 10, 20, 21,
+4, -36, -21, 38, 19, 1, 25, -3, 20, 22,
+-18, -58, -87, -44, 82, 73, 49, 31, 19, -7,
+-21, -61, -78, -44, -58, -66, -9, -23, 10, 40,
+-25, -66, -76, -33, -33, 6, 16, -6, -21, 5,
+-27, -69, -77, 5, -2, -7, 6, 9, 24, 6,
+1, -41, -41, -58, -79, 25, 69, 43, 68, 36,
+-28, -67, -85, -71, -34, 0, 14, 12, -2, 4,
+-2, -33, -55, -37, 37, 25, 6, 6, 29, -4,
+-8, -25, -11, -9, 40, 23, 17, 25, 37, 12,
+-21, -27, 52, 60, 47, 58, 76, 70, 69, 38,
+23, 15, 22, -8, -32, -50, -10, 3, 31, 21,
+-10, -44, -67, -61, -29, -54, 8, 39, 21, 4,
+31, 18, 30, 36, 46, 28, 50, 42, 35, 13,
+-21, -57, -24, -16, -15, 14, 3, -25, -17, 20,
+23, 6, 24, 35, 90, 72, 64, 55, 55, 23,
+7, -28, -42, -19, -36, -50, -15, -40, 29, 28,
+-21, -59, -66, -59, -6, 85, 83, 53, 54, 26,
+2, -20, -42, -52, -27, -49, 5, 9, -9, -8,
+-18, -56, -84, -72, 24, 51, 32, 20, 13, -10,
+-13, -53, -64, -39, -63, -40, 24, 0, 34, 29,
+0, -31, -45, -63, -90, -53, 3, -18, -9, 24,
+-13, -57, -71, 27, 19, -3, 25, -3, 45, 35,
+12, -9, -26, -40, -51, -78, -24, 11, -9, -6,
+-12, -49, -45, -33, -50, -48, -46, -52, 2, 25,
+-14, -56, -84, -108, -122, -50, 4, 22, 42, 53,
+-6, -44, -54, -28, -41, -61, 19, 25, 6, 1,
+-32, -75, -95, -38, -1, -15, 7, 14, 23, 23,
+11, 12, 37, 30, 38, 51, 80, 80, 82, 47,
+-19, -56, -69, -82, -98, -64, -29, 2, 28, 42,
+-18, -49, 3, 34, 41, 39, 32, 18, 21, 7,
+-8, 23, 39, 30, 30, 27, 41, 36, 44, 23,
+-16, -49, -69, -46, 1, -27, 41, 48, 35, 15,
+6, -32, -36, 5, -17, -30, 2, -16, 51, 35,
+-23, -64, -91, -21, 71, 44, 52, 44, 40, 21,
+-22, -55, -40, -20, 62, 52, 38, 29, 27, 5,
+-27, -69, -75, -6, -8, 3, -2, -30, -42, 13,
+2, -29, -42, -10, 29, 2, 15, 30, 26, 0,
+-27, -69, -85, -75, -54, -8, -14, -31, 16, 42,
+-2, -44, -54, -75, -101, -6, 4, -3, 32, 13,
+7, -3, -22, -43, -14, -27, -24, -11, -14, -12,
+-18, -57, -85, -66, 47, 86, 75, 45, 42, 10,
+18, 3, 39, 76, 80, 48, 48, 41, 44, 21,
+-13, -51, -73, -22, -15, -41, 3, -4, -22, 3,
+-10, -50, -63, -9, -23, -42, -6, -30, 11, 28,
+15, -11, -29, -39, -57, -71, -23, -40, -33, 20,
+-2, -40, -48, -5, -21, -25, 31, 7, 53, 35,
+-19, -63, -72, 39, 34, 16, 37, 17, 54, 31,
+-18, -49, -28, -27, -40, -29, 4, 4, 19, 11,
+-1, -43, -41, 24, 15, -12, -4, -31, -4, 23,
+-11, -46, -79, -74, 34, 21, 9, 15, 3, -13,
+-16, -51, -56, -55, 8, 62, 50, 30, 43, 14,
+-1, -25, -27, -32, -46, -62, -66, -36, 53, 32,
+-12, -49, -77, -50, 2, -21, 23, 6, 14, 21,
+-5, -47, -58, -77, -105, -14, 30, 9, 73, 44,
+-24, -52, -4, 10, 13, 13, 27, 27, 42, 24,
+-10, -38, -27, -15, -24, -52, -53, 1, 14, -6,
+-17, -45, -13, 2, 19, 53, 83, 79, 76, 43,
+-21, -62, -86, -48, 40, 17, 14, -9, 40, 30,
+-1, -32, -51, -33, -3, -35, 2, 17, -2, -12,
+-21, -60, -85, -70, 33, 73, 58, 37, 67, 36,
+-1, -45, -39, 37, 17, 3, 18, -8, 53, 35,
+-8, -47, -65, -61, -87, -93, 9, 9, 2, 33,
+-13, -55, -56, -19, -29, 14, 17, 6, 55, 28,
+5, 1, -7, -23, -26, -56, -39, 14, 11, -13,
+-28, -69, -89, -74, -83, -45, 1, 0, 16, 45,
+-3, 5, 91, 104, 119, 111, 97, 76, 72, 39,
+19, 5, -12, -34, -41, -72, -67, 14, 21, 1,
+-17, -49, 15, 27, 13, 6, 2, 12, 27, 10,
+-10, -30, 18, 36, 93, 87, 87, 69, 58, 26,
+37, 32, 64, 54, 53, 67, 78, 73, 80, 48,
+48, 46, 38, 9, -1, 8, 47, 44, 58, 33,
+-23, -61, -88, -76, 27, 14, 9, 36, 36, 10,
+-24, -66, -88, -97, -55, 20, 19, 16, 52, 31,
+4, -16, -1, -8, 2, 0, 15, 13, 29, 14,
+-9, -44, -66, -72, 8, 32, 37, 38, 46, 16,
+-22, -65, -62, 30, 22, 51, 57, 45, 68, 38,
+-4, -42, -53, -33, -54, -53, -4, -18, 62, 40,
+-5, -37, -61, -41, 35, 15, -2, -3, -12, -28,
+-18, -65, -55, 90, 80, 49, 44, 21, 59, 36,
+5, -16, -31, -32, -37, -62, -19, -11, 9, 16,
+-22, -60, -67, -51, -61, -35, -5, -18, -27, 24,
+-18, -55, -39, -42, -40, 20, 25, 6, 6, 7,
+0, -25, -42, -50, -59, -84, -31, -13, -22, 17,
+-32, -73, -100, -89, -21, -10, 18, 38, 31, 23,
+-15, -54, -57, -13, -18, -41, -32, 17, 50, 21,
+-16, -57, -71, -10, -8, -26, -38, -47, 42, 25,
+-17, -58, -82, -7, 33, 3, 30, 11, 13, 24,
+-23, -61, -97, -83, 82, 81, 57, 39, 31, 2,
+26, 32, 104, 86, 62, 55, 77, 70, 74, 43,
+-8, -29, -33, -52, -74, -73, -17, 14, 39, 25,
+-21, -60, -68, -22, 43, 37, 51, 54, 64, 36,
+-5, -30, -50, -52, 22, 7, 10, 13, 0, -20,
+-15, -53, -61, -34, -50, -25, 15, 6, 0, -14,
+-10, -51, -60, 20, 77, 50, 34, 22, 8, -8,
+-8, -45, -52, -59, -76, -35, -43, -49, 47, 40,
+41, 44, 53, 40, 41, 30, 38, 31, 46, 24,
+19, 3, -15, -26, -16, -45, -13, 24, 18, -5,
+-3, -39, -54, -35, -49, -70, 2, -6, -19, 15,
+-13, -53, -36, 6, -3, 45, 50, 30, 33, 10,
+15, -25, -16, -4, -32, 7, 23, 6, 67, 36,
+-21, -58, -87, -71, 10, -12, -16, 19, 10, 0,
+9, -15, -6, 25, 31, 7, 30, 28, 20, 2,
+2, -28, -42, -50, -67, -75, 12, 12, -4, 8,
+-17, -63, -58, 56, 49, 36, 60, 38, 37, 14,
+-13, -48, -38, -29, -44, -25, -20, -33, 38, 20,
+2, -37, -42, -1, -18, -42, 3, -17, -19, 12,
+-20, -60, -73, -7, 12, -13, -22, -38, 4, 10,
+-8, -41, -63, -65, 42, 63, 45, 31, 31, 0,
+-4, -46, -38, -9, -35, 15, 50, 27, 67, 39,
+3, -7, -13, -34, -51, -47, 9, 39, 54, 29,
+-29, -71, -89, -52, -39, -6, 3, 2, 38, 28,
+-14, -42, -13, -15, -19, 0, 20, 12, 37, 25,
+11, -26, -24, -40, -65, -11, -13, -27, 65, 37,
+0, -31, -46, -17, -21, -45, 11, -2, 25, 24,
+51, 91, 102, 87, 85, 63, 57, 42, 48, 23,
+-4, -34, -56, -70, -10, -14, 4, 18, 3, -8,
+-23, -59, -39, -44, -42, -14, -10, -23, -4, 17,
+-2, 4, 35, 63, 69, 75, 82, 63, 78, 48,
+-17, -55, -60, -3, -4, -19, 4, -4, -18, -29,
+2, -20, -36, -50, -32, -59, -16, 30, 16, -6,
+-12, -47, 24, 68, 45, 46, 41, 32, 65, 37,
+-4, -40, -54, -67, -96, -66, -9, -25, 42, 38,
+-15, 13, 58, 58, 84, 104, 119, 104, 89, 51,
+-15, -24, -9, -24, -27, -50, -7, 28, 29, 6,
+-7, -33, -35, -49, -65, -53, -37, -10, 33, 14,
+31, 19, 46, 72, 67, 45, 83, 68, 63, 41,
+-14, -53, -59, -17, 55, 79, 64, 39, 43, 10,
+};
+
+const signed char cdbk_lsp2_vlbr[160]={
+-20, -30, -24, 17, 7, -13, -21, 61, 56, 16,
+12, 1, 10, 77, 32, 3, 7, 3, -25, -31,
+-4, 2, -36, -83, 18, 5, -5, 5, 11, 23,
+-2, -1, -11, -12, -20, -28, 68, 50, -17, -20,
+5, 2, 1, 20, 17, 4, -52, -66, 36, 24,
+-4, -10, 7, -15, -32, 80, 37, 8, -13, -29,
+33, 37, 28, 15, 8, 14, 35, 18, 50, 36,
+-4, -1, 4, -7, 3, 3, -11, -58, -75, 13,
+13, 21, 24, -11, -12, -38, -72, 33, 15, -12,
+-44, -17, 83, 21, 2, 7, 0, 4, 0, -1,
+-25, -42, -51, 33, 20, 15, 30, -13, 9, 32,
+6, 2, -8, 7, -38, -77, 6, -13, -7, 32,
+48, 57, 32, -12, -10, -4, 2, -15, -29, -29,
+2, 10, -9, -16, 79, 44, 7, 12, -5, -18,
+-23, -29, -35, -3, -3, -18, -34, -3, -39, -50,
+-5, -10, -8, -37, -76, 11, -4, -19, 30, 16,
+};
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/lpc.c b/utils/iaxclient/lib/libspeex/lpc.c
new file mode 100644 (file)
index 0000000..dd30183
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+  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
+
+
+   Code modified by Jean-Marc Valin
+
+   Speex License:
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+
+/* LPC analysis
+ *
+ * The next two functions calculate linear prediction coefficients
+ * and/or the related reflection coefficients from the first P_MAX+1
+ * values of the autocorrelation function.
+ */
+
+/* Invented by N. Levinson in 1947, modified by J. Durbin in 1959.
+ */
+
+#include "lpc.h"
+
+/* returns minimum mean square error    */
+spx_word32_t _spx_lpc(
+spx_coef_t       *lpc, /* out: [0...p-1] LPC coefficients      */
+const spx_word16_t *ac,  /* in:  [0...p] autocorrelation values  */
+int          p
+)
+{
+   int i, j;  
+   spx_word16_t r;
+   spx_word16_t error = ac[0];
+
+   if (ac[0] == 0)
+   {
+      for (i = 0; i < p; i++)
+         lpc[i] = 0;
+      return 0;
+   }
+
+   for (i = 0; i < p; i++) {
+
+      /* Sum up this iteration's reflection coefficient */
+      spx_word32_t rr = NEG32(SHL32(EXTEND32(ac[i + 1]),13));
+      for (j = 0; j < i; j++) 
+         rr = SUB32(rr,MULT16_16(lpc[j],ac[i - j]));
+#ifdef FIXED_POINT
+      r = DIV32_16(rr,ADD16(error,16));
+#else
+      r = rr/(error+.003*ac[0]);
+#endif
+      /*  Update LPC coefficients and total error */
+      lpc[i] = r;
+      for (j = 0; j < i>>1; j++) 
+      {
+         spx_word16_t tmp  = lpc[j];
+         lpc[j]     = MAC16_16_Q13(lpc[j],r,lpc[i-1-j]);
+         lpc[i-1-j] = MAC16_16_Q13(lpc[i-1-j],r,tmp);
+      }
+      if (i & 1) 
+         lpc[j] = MAC16_16_Q13(lpc[j],lpc[j],r);
+
+      error = SUB16(error,MULT16_16_Q13(r,MULT16_16_Q13(error,r)));
+   }
+   return error;
+}
+
+
+#ifdef FIXED_POINT
+
+/* Compute the autocorrelation
+ *                      ,--,
+ *              ac(i) = >  x(n) * x(n-i)  for all n
+ *                      `--'
+ * for lags between 0 and lag-1, and x == 0 outside 0...n-1
+ */
+
+void _spx_autocorr(
+const spx_word16_t *x,   /*  in: [0...n-1] samples x   */
+spx_word16_t       *ac,  /* out: [0...lag-1] ac values */
+int          lag, 
+int          n
+)
+{
+   spx_word32_t d;
+   int i, j;
+   spx_word32_t ac0=1;
+   int shift, ac_shift;
+   
+   for (j=0;j<n;j++)
+      ac0 = ADD32(ac0,SHR32(MULT16_16(x[j],x[j]),8));
+   ac0 = ADD32(ac0,n);
+   shift = 8;
+   while (shift && ac0<0x40000000)
+   {
+      shift--;
+      ac0 <<= 1;
+   }
+   ac_shift = 18;
+   while (ac_shift && ac0<0x40000000)
+   {
+      ac_shift--;
+      ac0 <<= 1;
+   }
+   
+   
+   for (i=0;i<lag;i++)
+   {
+      d=0;
+      for (j=i;j<n;j++)
+      {
+         d = ADD32(d,SHR32(MULT16_16(x[j],x[j-i]), shift));
+      }
+      
+      ac[i] = SHR32(d, ac_shift);
+   }
+}
+
+
+#else
+
+
+
+/* Compute the autocorrelation
+ *                      ,--,
+ *              ac(i) = >  x(n) * x(n-i)  for all n
+ *                      `--'
+ * for lags between 0 and lag-1, and x == 0 outside 0...n-1
+ */
+void _spx_autocorr(
+const spx_word16_t *x,   /*  in: [0...n-1] samples x   */
+float       *ac,  /* out: [0...lag-1] ac values */
+int          lag, 
+int          n
+)
+{
+   float d;
+   int i;
+   while (lag--) 
+   {
+      for (i = lag, d = 0; i < n; i++) 
+         d += x[i] * x[i-lag];
+      ac[lag] = d;
+   }
+   ac[0] += 10;
+}
+
+#endif
+
+
diff --git a/utils/iaxclient/lib/libspeex/lpc.h b/utils/iaxclient/lib/libspeex/lpc.h
new file mode 100644 (file)
index 0000000..6050447
--- /dev/null
@@ -0,0 +1,51 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: lpc.h
+   Functions for LPC (Linear Prediction Coefficients) analysis
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifndef LPC_H
+#define LPC_H
+
+#include "misc.h"
+
+void _spx_autocorr(
+              const spx_word16_t * x,   /*  in: [0...n-1] samples x   */
+              spx_word16_t *ac,   /* out: [0...lag-1] ac values */
+              int lag, int   n);
+
+spx_word32_t                      /* returns minimum mean square error    */
+_spx_lpc(
+    spx_coef_t       * lpc, /*      [0...p-1] LPC coefficients      */
+    const spx_word16_t * ac,  /*  in: [0...p] autocorrelation values  */
+    int p
+    );
+
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/lsp.c b/utils/iaxclient/lib/libspeex/lsp.c
new file mode 100644 (file)
index 0000000..ecb9755
--- /dev/null
@@ -0,0 +1,621 @@
+/*---------------------------------------------------------------------------*\
+Original copyright
+       FILE........: AKSLSPD.C
+       TYPE........: Turbo C
+       COMPANY.....: Voicetronix
+       AUTHOR......: David Rowe
+       DATE CREATED: 24/2/93
+
+Heavily modified by Jean-Marc Valin (fixed-point, optimizations, 
+                                     additional functions, ...)
+
+   This file contains functions for converting Linear Prediction
+   Coefficients (LPC) to Line Spectral Pair (LSP) and back. Note that the
+   LSP coefficients are not in radians format but in the x domain of the
+   unit circle.
+
+   Speex License:
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#ifdef _MSC_VER
+#include "winpoop.h"
+#endif
+#include <math.h>
+#include "lsp.h"
+#include "stack_alloc.h"
+#include "math_approx.h"
+
+#ifndef M_PI
+#define M_PI           3.14159265358979323846  /* pi */
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#ifdef FIXED_POINT
+
+#define C1 8192
+#define C2 -4096
+#define C3 340
+#define C4 -10
+
+static spx_word16_t spx_cos(spx_word16_t x)
+{
+   spx_word16_t x2;
+
+   if (x<12868)
+   {
+      x2 = MULT16_16_P13(x,x);
+      return ADD32(C1, MULT16_16_P13(x2, ADD32(C2, MULT16_16_P13(x2, ADD32(C3, MULT16_16_P13(C4, x2))))));
+   } else {
+      x = SUB16(25736,x);
+      x2 = MULT16_16_P13(x,x);
+      return SUB32(-C1, MULT16_16_P13(x2, ADD32(C2, MULT16_16_P13(x2, ADD32(C3, MULT16_16_P13(C4, x2))))));
+      /*return SUB32(-C1, MULT16_16_Q13(x2, ADD32(C2, MULT16_16_Q13(C3, x2))));*/
+   }
+}
+
+
+#define FREQ_SCALE 16384
+
+/*#define ANGLE2X(a) (32768*cos(((a)/8192.)))*/
+#define ANGLE2X(a) (SHL16(spx_cos(a),2))
+
+/*#define X2ANGLE(x) (acos(.00006103515625*(x))*LSP_SCALING)*/
+#define X2ANGLE(x) (spx_acos(x))
+
+#else
+
+/*#define C1 0.99940307
+#define C2 -0.49558072
+#define C3 0.03679168*/
+
+#define C1 0.9999932946f
+#define C2 -0.4999124376f
+#define C3 0.0414877472f
+#define C4 -0.0012712095f
+
+
+#define SPX_PI_2 1.5707963268
+static inline spx_word16_t spx_cos(spx_word16_t x)
+{
+   if (x<SPX_PI_2)
+   {
+      x *= x;
+      return C1 + x*(C2+x*(C3+C4*x));
+   } else {
+      x = M_PI-x;
+      x *= x;
+      return NEG16(C1 + x*(C2+x*(C3+C4*x)));
+   }
+}
+#define FREQ_SCALE 1.
+#define ANGLE2X(a) (spx_cos(a))
+#define X2ANGLE(x) (acos(x))
+
+#endif
+
+
+/*---------------------------------------------------------------------------*\
+
+       FUNCTION....: cheb_poly_eva()
+
+       AUTHOR......: David Rowe
+       DATE CREATED: 24/2/93
+
+    This function evaluates a series of Chebyshev polynomials
+
+\*---------------------------------------------------------------------------*/
+
+#ifdef FIXED_POINT
+
+static inline spx_word32_t cheb_poly_eva(spx_word32_t *coef,spx_word16_t x,int m,char *stack)
+/*  float coef[]       coefficients of the polynomial to be evaluated  */
+/*  float x            the point where polynomial is to be evaluated   */
+/*  int m              order of the polynomial                         */
+{
+    int i;
+    VARDECL(spx_word16_t *T);
+    spx_word32_t sum;
+    int m2=m>>1;
+    VARDECL(spx_word16_t *coefn);
+
+    /*Prevents overflows*/
+    if (x>16383)
+       x = 16383;
+    if (x<-16383)
+       x = -16383;
+
+    /* Allocate memory for Chebyshev series formulation */
+    ALLOC(T, m2+1, spx_word16_t);
+    ALLOC(coefn, m2+1, spx_word16_t);
+
+    for (i=0;i<m2+1;i++)
+    {
+       coefn[i] = coef[i];
+       /*printf ("%f ", coef[i]);*/
+    }
+    /*printf ("\n");*/
+
+    /* Initialise values */
+    T[0]=16384;
+    T[1]=x;
+
+    /* Evaluate Chebyshev series formulation using iterative approach  */
+    /* Evaluate polynomial and return value also free memory space */
+    sum = ADD32(coefn[m2], MULT16_16_P14(coefn[m2-1],x));
+    /*x *= 2;*/
+    for(i=2;i<=m2;i++)
+    {
+       T[i] = SUB16(MULT16_16_Q13(x,T[i-1]), T[i-2]);
+       sum = ADD32(sum, MULT16_16_P14(coefn[m2-i],T[i]));
+       /*printf ("%f ", sum);*/
+    }
+    
+    /*printf ("\n");*/
+    return sum;
+}
+#else
+static float cheb_poly_eva(spx_word32_t *coef,float x,int m,char *stack)
+/*  float coef[]       coefficients of the polynomial to be evaluated  */
+/*  float x            the point where polynomial is to be evaluated   */
+/*  int m              order of the polynomial                         */
+{
+    int i;
+    VARDECL(float *T);
+    float sum;
+    int m2=m>>1;
+
+    /* Allocate memory for Chebyshev series formulation */
+    ALLOC(T, m2+1, float);
+
+    /* Initialise values */
+    T[0]=1;
+    T[1]=x;
+
+    /* Evaluate Chebyshev series formulation using iterative approach  */
+    /* Evaluate polynomial and return value also free memory space */
+    sum = coef[m2] + coef[m2-1]*x;
+    x *= 2;
+    for(i=2;i<=m2;i++)
+    {
+       T[i] = x*T[i-1] - T[i-2];
+       sum += coef[m2-i] * T[i];
+    }
+    
+    return sum;
+}
+#endif
+
+/*---------------------------------------------------------------------------*\
+
+       FUNCTION....: lpc_to_lsp()
+
+       AUTHOR......: David Rowe
+       DATE CREATED: 24/2/93
+
+    This function converts LPC coefficients to LSP
+    coefficients.
+
+\*---------------------------------------------------------------------------*/
+
+#ifdef FIXED_POINT
+#define SIGN_CHANGE(a,b) (((a)&0x70000000)^((b)&0x70000000)||(b==0))
+#else
+#define SIGN_CHANGE(a,b) (((a)*(b))<0.0)
+#endif
+
+
+int lpc_to_lsp (spx_coef_t *a,int lpcrdr,spx_lsp_t *freq,int nb,spx_word16_t delta, char *stack)
+/*  float *a                   lpc coefficients                        */
+/*  int lpcrdr                 order of LPC coefficients (10)          */
+/*  float *freq                LSP frequencies in the x domain         */
+/*  int nb                     number of sub-intervals (4)             */
+/*  float delta                        grid spacing interval (0.02)            */
+
+
+{
+    spx_word16_t temp_xr,xl,xr,xm=0;
+    spx_word32_t psuml,psumr,psumm,temp_psumr/*,temp_qsumr*/;
+    int i,j,m,flag,k;
+    VARDECL(spx_word32_t *Q);                  /* ptrs for memory allocation           */
+    VARDECL(spx_word32_t *P);
+    spx_word32_t *px;                  /* ptrs of respective P'(z) & Q'(z)     */
+    spx_word32_t *qx;
+    spx_word32_t *p;
+    spx_word32_t *q;
+    spx_word32_t *pt;                  /* ptr used for cheb_poly_eval()
+                               whether P' or Q'                        */
+    int roots=0;               /* DR 8/2/94: number of roots found     */
+    flag = 1;                  /*  program is searching for a root when,
+                               1 else has found one                    */
+    m = lpcrdr/2;              /* order of P'(z) & Q'(z) polynomials   */
+
+    /* Allocate memory space for polynomials */
+    ALLOC(Q, (m+1), spx_word32_t);
+    ALLOC(P, (m+1), spx_word32_t);
+
+    /* determine P'(z)'s and Q'(z)'s coefficients where
+      P'(z) = P(z)/(1 + z^(-1)) and Q'(z) = Q(z)/(1-z^(-1)) */
+
+    px = P;                      /* initialise ptrs                    */
+    qx = Q;
+    p = px;
+    q = qx;
+
+#ifdef FIXED_POINT
+    *px++ = LPC_SCALING;
+    *qx++ = LPC_SCALING;
+    for(i=1;i<=m;i++){
+       *px++ = SUB32(ADD32(EXTEND32(a[i]),EXTEND32(a[lpcrdr+1-i])), *p++);
+       *qx++ = ADD32(SUB32(EXTEND32(a[i]),EXTEND32(a[lpcrdr+1-i])), *q++);
+    }
+    px = P;
+    qx = Q;
+    for(i=0;i<m;i++)
+    {
+       /*if (fabs(*px)>=32768)
+          speex_warning_int("px", *px);
+       if (fabs(*qx)>=32768)
+       speex_warning_int("qx", *qx);*/
+       *px = PSHR32(*px,2);
+       *qx = PSHR32(*qx,2);
+       px++;
+       qx++;
+    }
+    /* The reason for this lies in the way cheb_poly_eva() is implemented for fixed-point */
+    P[m] = PSHR32(P[m],3);
+    Q[m] = PSHR32(Q[m],3);
+#else
+    *px++ = LPC_SCALING;
+    *qx++ = LPC_SCALING;
+    for(i=1;i<=m;i++){
+       *px++ = (a[i]+a[lpcrdr+1-i]) - *p++;
+       *qx++ = (a[i]-a[lpcrdr+1-i]) + *q++;
+    }
+    px = P;
+    qx = Q;
+    for(i=0;i<m;i++){
+       *px = 2**px;
+       *qx = 2**qx;
+       px++;
+       qx++;
+    }
+#endif
+
+    px = P;                    /* re-initialise ptrs                   */
+    qx = Q;
+
+    /* Search for a zero in P'(z) polynomial first and then alternate to Q'(z).
+    Keep alternating between the two polynomials as each zero is found         */
+
+    xr = 0;                    /* initialise xr to zero                */
+    xl = FREQ_SCALE;                   /* start at point xl = 1                */
+
+
+    for(j=0;j<lpcrdr;j++){
+       if(j&1)                 /* determines whether P' or Q' is eval. */
+           pt = qx;
+       else
+           pt = px;
+
+       psuml = cheb_poly_eva(pt,xl,lpcrdr,stack);      /* evals poly. at xl    */
+       flag = 1;
+       while(flag && (xr >= -FREQ_SCALE)){
+           spx_word16_t dd;
+           /* Modified by JMV to provide smaller steps around x=+-1 */
+#ifdef FIXED_POINT
+           dd = MULT16_16_Q15(delta,SUB16(FREQ_SCALE, MULT16_16_Q14(MULT16_16_Q14(xl,xl),14000)));
+           if (psuml<512 && psuml>-512)
+              dd = PSHR16(dd,1);
+#else
+           dd=delta*(1-.9*xl*xl);
+           if (fabs(psuml)<.2)
+              dd *= .5;
+#endif
+           xr = SUB16(xl, dd);                         /* interval spacing     */
+           psumr = cheb_poly_eva(pt,xr,lpcrdr,stack);/* poly(xl-delta_x)       */
+           temp_psumr = psumr;
+           temp_xr = xr;
+
+    /* if no sign change increment xr and re-evaluate poly(xr). Repeat til
+    sign change.
+    if a sign change has occurred the interval is bisected and then
+    checked again for a sign change which determines in which
+    interval the zero lies in.
+    If there is no sign change between poly(xm) and poly(xl) set interval
+    between xm and xr else set interval between xl and xr and repeat till
+    root is located within the specified limits                        */
+
+           if(SIGN_CHANGE(psumr,psuml))
+            {
+               roots++;
+
+               psumm=psuml;
+               for(k=0;k<=nb;k++){
+#ifdef FIXED_POINT
+                   xm = ADD16(PSHR16(xl,1),PSHR16(xr,1));              /* bisect the interval  */
+#else
+                    xm = .5*(xl+xr);           /* bisect the interval  */
+#endif
+                   psumm=cheb_poly_eva(pt,xm,lpcrdr,stack);
+                   /*if(psumm*psuml>0.)*/
+                   if(!SIGN_CHANGE(psumm,psuml))
+                    {
+                       psuml=psumm;
+                       xl=xm;
+                   } else {
+                       psumr=psumm;
+                       xr=xm;
+                   }
+               }
+
+              /* once zero is found, reset initial interval to xr      */
+              freq[j] = X2ANGLE(xm);
+              xl = xm;
+              flag = 0;                /* reset flag for next search   */
+           }
+           else{
+               psuml=temp_psumr;
+               xl=temp_xr;
+           }
+       }
+    }
+    return(roots);
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+       FUNCTION....: lsp_to_lpc()
+
+       AUTHOR......: David Rowe
+       DATE CREATED: 24/2/93
+
+    lsp_to_lpc: This function converts LSP coefficients to LPC
+    coefficients.
+
+\*---------------------------------------------------------------------------*/
+
+#ifdef FIXED_POINT
+
+void lsp_to_lpc(spx_lsp_t *freq,spx_coef_t *ak,int lpcrdr, char *stack)
+/*  float *freq        array of LSP frequencies in the x domain        */
+/*  float *ak          array of LPC coefficients                       */
+/*  int lpcrdr         order of LPC coefficients                       */
+
+
+{
+    int i,j;
+    spx_word32_t xout1,xout2,xin1,xin2;
+    VARDECL(spx_word32_t *Wp);
+    spx_word32_t *pw,*n1,*n2,*n3,*n4=NULL;
+    VARDECL(spx_word16_t *freqn);
+    int m = lpcrdr>>1;
+    
+    ALLOC(freqn, lpcrdr, spx_word16_t);
+    for (i=0;i<lpcrdr;i++)
+       freqn[i] = ANGLE2X(freq[i]);
+
+    ALLOC(Wp, 4*m+2, spx_word32_t);
+    pw = Wp;
+
+
+    /* initialise contents of array */
+
+    for(i=0;i<=4*m+1;i++){             /* set contents of buffer to 0 */
+       *pw++ = 0;
+    }
+
+    /* Set pointers up */
+
+    pw = Wp;
+    xin1 = 1048576;
+    xin2 = 1048576;
+
+    /* reconstruct P(z) and Q(z) by  cascading second order
+      polynomials in form 1 - 2xz(-1) +z(-2), where x is the
+      LSP coefficient */
+
+    for(j=0;j<=lpcrdr;j++){
+       spx_word16_t *fr=freqn;
+       for(i=0;i<m;i++){
+           n1 = pw+(i<<2);
+           n2 = n1 + 1;
+           n3 = n2 + 1;
+           n4 = n3 + 1;
+           xout1 = ADD32(SUB32(xin1, MULT16_32_Q14(*fr,*n1)), *n2);
+            fr++;
+            xout2 = ADD32(SUB32(xin2, MULT16_32_Q14(*fr,*n3)), *n4);
+            fr++;
+           *n2 = *n1;
+           *n4 = *n3;
+           *n1 = xin1;
+           *n3 = xin2;
+           xin1 = xout1;
+           xin2 = xout2;
+       }
+       xout1 = xin1 + *(n4+1);
+       xout2 = xin2 - *(n4+2);
+        /* FIXME: perhaps apply bandwidth expansion in case of overflow? */
+        /*FIXME: Is it OK to have a long constant? */
+        if (xout1 + xout2>SHL(32766,8))
+           ak[j] = 32767;
+        else if (xout1 + xout2 < -SHL(32766,8))
+           ak[j] = -32767;
+        else
+           ak[j] = EXTRACT16(PSHR32(ADD32(xout1,xout2),8));
+       *(n4+1) = xin1;
+       *(n4+2) = xin2;
+
+       xin1 = 0;
+       xin2 = 0;
+    }
+}
+#else
+
+void lsp_to_lpc(spx_lsp_t *freq,spx_coef_t *ak,int lpcrdr, char *stack)
+/*  float *freq        array of LSP frequencies in the x domain        */
+/*  float *ak          array of LPC coefficients                       */
+/*  int lpcrdr         order of LPC coefficients                       */
+
+
+{
+    int i,j;
+    float xout1,xout2,xin1,xin2;
+    VARDECL(float *Wp);
+    float *pw,*n1,*n2,*n3,*n4=NULL;
+    VARDECL(float *x_freq);
+    int m = lpcrdr>>1;
+
+    ALLOC(Wp, 4*m+2, float);
+    pw = Wp;
+
+    /* initialise contents of array */
+
+    for(i=0;i<=4*m+1;i++){             /* set contents of buffer to 0 */
+       *pw++ = 0.0;
+    }
+
+    /* Set pointers up */
+
+    pw = Wp;
+    xin1 = 1.0;
+    xin2 = 1.0;
+
+    ALLOC(x_freq, lpcrdr, float);
+    for (i=0;i<lpcrdr;i++)
+       x_freq[i] = ANGLE2X(freq[i]);
+
+    /* reconstruct P(z) and Q(z) by  cascading second order
+      polynomials in form 1 - 2xz(-1) +z(-2), where x is the
+      LSP coefficient */
+
+    for(j=0;j<=lpcrdr;j++){
+       int i2=0;
+       for(i=0;i<m;i++,i2+=2){
+           n1 = pw+(i*4);
+           n2 = n1 + 1;
+           n3 = n2 + 1;
+           n4 = n3 + 1;
+           xout1 = xin1 - 2.f*x_freq[i2] * *n1 + *n2;
+           xout2 = xin2 - 2.f*x_freq[i2+1] * *n3 + *n4;
+           *n2 = *n1;
+           *n4 = *n3;
+           *n1 = xin1;
+           *n3 = xin2;
+           xin1 = xout1;
+           xin2 = xout2;
+       }
+       xout1 = xin1 + *(n4+1);
+       xout2 = xin2 - *(n4+2);
+       ak[j] = (xout1 + xout2)*0.5f;
+       *(n4+1) = xin1;
+       *(n4+2) = xin2;
+
+       xin1 = 0.0;
+       xin2 = 0.0;
+    }
+
+}
+#endif
+
+
+#ifdef FIXED_POINT
+
+/*Makes sure the LSPs are stable*/
+void lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin)
+{
+   int i;
+   spx_word16_t m = margin;
+   spx_word16_t m2 = 25736-margin;
+  
+   if (lsp[0]<m)
+      lsp[0]=m;
+   if (lsp[len-1]>m2)
+      lsp[len-1]=m2;
+   for (i=1;i<len-1;i++)
+   {
+      if (lsp[i]<lsp[i-1]+m)
+         lsp[i]=lsp[i-1]+m;
+
+      if (lsp[i]>lsp[i+1]-m)
+         lsp[i]= SHR16(lsp[i],1) + SHR16(lsp[i+1]-m,1);
+   }
+}
+
+
+void lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes)
+{
+   int i;
+   spx_word16_t tmp = DIV32_16(SHL32(1 + subframe,14),nb_subframes);
+   spx_word16_t tmp2 = 16384-tmp;
+   for (i=0;i<len;i++)
+   {
+      interp_lsp[i] = MULT16_16_P14(tmp2,old_lsp[i]) + MULT16_16_P14(tmp,new_lsp[i]);
+   }
+}
+
+#else
+
+/*Makes sure the LSPs are stable*/
+void lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin)
+{
+   int i;
+   if (lsp[0]<LSP_SCALING*margin)
+      lsp[0]=LSP_SCALING*margin;
+   if (lsp[len-1]>LSP_SCALING*(M_PI-margin))
+      lsp[len-1]=LSP_SCALING*(M_PI-margin);
+   for (i=1;i<len-1;i++)
+   {
+      if (lsp[i]<lsp[i-1]+LSP_SCALING*margin)
+         lsp[i]=lsp[i-1]+LSP_SCALING*margin;
+
+      if (lsp[i]>lsp[i+1]-LSP_SCALING*margin)
+         lsp[i]= .5f* (lsp[i] + lsp[i+1]-LSP_SCALING*margin);
+   }
+}
+
+
+void lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes)
+{
+   int i;
+   float tmp = (1.0f + subframe)/nb_subframes;
+   for (i=0;i<len;i++)
+   {
+      interp_lsp[i] = (1-tmp)*old_lsp[i] + tmp*new_lsp[i];
+   }
+}
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/lsp.h b/utils/iaxclient/lib/libspeex/lsp.h
new file mode 100644 (file)
index 0000000..dbc8ecf
--- /dev/null
@@ -0,0 +1,60 @@
+/*---------------------------------------------------------------------------*\
+Original Copyright
+       FILE........: AK2LSPD.H
+       TYPE........: Turbo C header file
+       COMPANY.....: Voicetronix
+       AUTHOR......: James Whitehall
+       DATE CREATED: 21/11/95
+
+Modified by Jean-Marc Valin
+
+    This file contains functions for converting Linear Prediction
+    Coefficients (LPC) to Line Spectral Pair (LSP) and back. Note that the
+    LSP coefficients are not in radians format but in the x domain of the
+    unit circle.
+
+\*---------------------------------------------------------------------------*/
+/* Speex License:
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifndef __AK2LSPD__
+#define __AK2LSPD__
+
+#include "misc.h"
+
+int lpc_to_lsp (spx_coef_t *a, int lpcrdr, spx_lsp_t *freq, int nb, spx_word16_t delta, char *stack);
+void lsp_to_lpc(spx_lsp_t *freq, spx_coef_t *ak, int lpcrdr, char *stack);
+
+/*Added by JMV*/
+void lsp_enforce_margin(spx_lsp_t *lsp, int len, spx_word16_t margin);
+
+void lsp_interpolate(spx_lsp_t *old_lsp, spx_lsp_t *new_lsp, spx_lsp_t *interp_lsp, int len, int subframe, int nb_subframes);
+
+#endif /* __AK2LSPD__ */
diff --git a/utils/iaxclient/lib/libspeex/lsp_tables_nb.c b/utils/iaxclient/lib/libspeex/lsp_tables_nb.c
new file mode 100644 (file)
index 0000000..16f2e1b
--- /dev/null
@@ -0,0 +1,360 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: lsp_tables_nb.c
+   Codebooks for LSPs in narrowband CELP mode
+  
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are
+   met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.  
+
+   2. 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.
+
+   3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+*/
+
+const signed char cdbk_nb[640]={
+30,19,38,34,40,32,46,43,58,43,
+5,-18,-25,-40,-33,-55,-52,20,34,28,
+-20,-63,-97,-92,61,53,47,49,53,75,
+-14,-53,-77,-79,0,-3,-5,19,22,26,
+-9,-53,-55,66,90,72,85,68,74,52,
+-4,-41,-58,-31,-18,-31,27,32,30,18,
+24,3,8,5,-12,-3,26,28,74,63,
+-2,-39,-67,-77,-106,-74,59,59,73,65,
+44,40,71,72,82,83,98,88,89,60,
+-6,-31,-47,-48,-13,-39,-9,7,2,79,
+-1,-39,-60,-17,87,81,65,50,45,19,
+-21,-67,-91,-87,-41,-50,7,18,39,74,
+10,-31,-28,39,24,13,23,5,56,45,
+29,10,-5,-13,-11,-35,-18,-8,-10,-8,
+-25,-71,-77,-21,2,16,50,63,87,87,
+5,-32,-40,-51,-68,0,12,6,54,34,
+5,-12,32,52,68,64,69,59,65,45,
+14,-16,-31,-40,-65,-67,41,49,47,37,
+-11,-52,-75,-84,-4,57,48,42,42,33,
+-11,-51,-68,-6,13,0,8,-8,26,32,
+-23,-53,0,36,56,76,97,105,111,97,
+-1,-28,-39,-40,-43,-54,-44,-40,-18,35,
+16,-20,-19,-28,-42,29,47,38,74,45,
+3,-29,-48,-62,-80,-104,-33,56,59,59,
+10,17,46,72,84,101,117,123,123,106,
+-7,-33,-49,-51,-70,-67,-27,-31,70,67,
+-16,-62,-85,-20,82,71,86,80,85,74,
+-19,-58,-75,-45,-29,-33,-18,-25,45,57,
+-12,-42,-5,12,28,36,52,64,81,82,
+13,-9,-27,-28,22,3,2,22,26,6,
+-6,-44,-51,2,15,10,48,43,49,34,
+-19,-62,-84,-89,-102,-24,8,17,61,68,
+39,24,23,19,16,-5,12,15,27,15,
+-8,-44,-49,-60,-18,-32,-28,52,54,62,
+-8,-48,-77,-70,66,101,83,63,61,37,
+-12,-50,-75,-64,33,17,13,25,15,77,
+1,-42,-29,72,64,46,49,31,61,44,
+-8,-47,-54,-46,-30,19,20,-1,-16,0,
+16,-12,-18,-9,-26,-27,-10,-22,53,45,
+-10,-47,-75,-82,-105,-109,8,25,49,77,
+50,65,114,117,124,118,115,96,90,61,
+-9,-45,-63,-60,-75,-57,8,11,20,29,
+0,-35,-49,-43,40,47,35,40,55,38,
+-24,-76,-103,-112,-27,3,23,34,52,75,
+8,-29,-43,12,63,38,35,29,24,8,
+25,11,1,-15,-18,-43,-7,37,40,21,
+-20,-56,-19,-19,-4,-2,11,29,51,63,
+-2,-44,-62,-75,-89,30,57,51,74,51,
+50,46,68,64,65,52,63,55,65,43,
+18,-9,-26,-35,-55,-69,3,6,8,17,
+-15,-61,-86,-97,1,86,93,74,78,67,
+-1,-38,-66,-48,48,39,29,25,17,-1,
+13,13,29,39,50,51,69,82,97,98,
+-2,-36,-46,-27,-16,-30,-13,-4,-7,-4,
+25,-5,-11,-6,-25,-21,33,12,31,29,
+-8,-38,-52,-63,-68,-89,-33,-1,10,74,
+-2,-15,59,91,105,105,101,87,84,62,
+-7,-33,-50,-35,-54,-47,25,17,82,81,
+-13,-56,-83,21,58,31,42,25,72,65,
+-24,-66,-91,-56,9,-2,21,10,69,75,
+2,-24,11,22,25,28,38,34,48,33,
+7,-29,-26,17,15,-1,14,0,-2,0,
+-6,-41,-67,6,-2,-9,19,2,85,74,
+-22,-67,-84,-71,-50,3,11,-9,2,62};
+
+const signed char cdbk_nb_low1[320]={
+-34,-52,-15,45,2,
+23,21,52,24,-33,
+-9,-1,9,-44,-41,
+-13,-17,44,22,-17,
+-6,-4,-1,22,38,
+26,16,2,50,27,
+-35,-34,-9,-41,6,
+0,-16,-34,51,8,
+-14,-31,-49,15,-33,
+45,49,33,-11,-37,
+-62,-54,45,11,-5,
+-72,11,-1,-12,-11,
+24,27,-11,-43,46,
+43,33,-12,-9,-1,
+1,-4,-23,-57,-71,
+11,8,16,17,-8,
+-20,-31,-41,53,48,
+-16,3,65,-24,-8,
+-23,-32,-37,-32,-49,
+-10,-17,6,38,5,
+-9,-17,-46,8,52,
+3,6,45,40,39,
+-7,-6,-34,-74,31,
+8,1,-16,43,68,
+-11,-19,-31,4,6,
+0,-6,-17,-16,-38,
+-16,-30,2,9,-39,
+-16,-1,43,-10,48,
+3,3,-16,-31,-3,
+62,68,43,13,3,
+-10,8,20,-56,12,
+12,-2,-18,22,-15,
+-40,-36,1,7,41,
+0,1,46,-6,-62,
+-4,-12,-2,-11,-83,
+-13,-2,91,33,-10,
+0,4,-11,-16,79,
+32,37,14,9,51,
+-21,-28,-56,-34,0,
+21,9,-26,11,28,
+-42,-54,-23,-2,-15,
+31,30,8,-39,-66,
+-39,-36,31,-28,-40,
+-46,35,40,22,24,
+33,48,23,-34,14,
+40,32,17,27,-3,
+25,26,-13,-61,-17,
+11,4,31,60,-6,
+-26,-41,-64,13,16,
+-26,54,31,-11,-23,
+-9,-11,-34,-71,-21,
+-34,-35,55,50,29,
+-22,-27,-50,-38,57,
+33,42,57,48,26,
+11,0,-49,-31,26,
+-4,-14,5,78,37,
+17,0,-49,-12,-23,
+26,14,2,2,-43,
+-17,-12,10,-8,-4,
+8,18,12,-6,20,
+-12,-6,-13,-25,34,
+15,40,49,7,8,
+13,20,20,-19,-22,
+-2,-8,2,51,-51};
+
+const signed char cdbk_nb_low2[320]={
+-6,53,-21,-24,4,
+26,17,-4,-37,25,
+17,-36,-13,31,3,
+-6,27,15,-10,31,
+28,26,-10,-10,-40,
+16,-7,15,13,41,
+-9,0,-4,50,-6,
+-7,14,38,22,0,
+-48,2,1,-13,-19,
+32,-3,-60,11,-17,
+-1,-24,-34,-1,35,
+-5,-27,28,44,13,
+25,15,42,-11,15,
+51,35,-36,20,8,
+-4,-12,-29,19,-47,
+49,-15,-4,16,-29,
+-39,14,-30,4,25,
+-9,-5,-51,-14,-3,
+-40,-32,38,5,-9,
+-8,-4,-1,-22,71,
+-3,14,26,-18,-22,
+24,-41,-25,-24,6,
+23,19,-10,39,-26,
+-27,65,45,2,-7,
+-26,-8,22,-12,16,
+15,16,-35,-5,33,
+-21,-8,0,23,33,
+34,6,21,36,6,
+-7,-22,8,-37,-14,
+31,38,11,-4,-3,
+-39,-32,-8,32,-23,
+-6,-12,16,20,-28,
+-4,23,13,-52,-1,
+22,6,-33,-40,-6,
+4,-62,13,5,-26,
+35,39,11,2,57,
+-11,9,-20,-28,-33,
+52,-5,-6,-2,22,
+-14,-16,-48,35,1,
+-58,20,13,33,-1,
+-74,56,-18,-22,-31,
+12,6,-14,4,-2,
+-9,-47,10,-3,29,
+-17,-5,61,14,47,
+-12,2,72,-39,-17,
+92,64,-53,-51,-15,
+-30,-38,-41,-29,-28,
+27,9,36,9,-35,
+-42,81,-21,20,25,
+-16,-5,-17,-35,21,
+15,-28,48,2,-2,
+9,-19,29,-40,30,
+-18,-18,18,-16,-57,
+15,-20,-12,-15,-37,
+-15,33,-39,21,-22,
+-13,35,11,13,-38,
+-63,29,23,-27,32,
+18,3,-26,42,33,
+-64,-66,-17,16,56,
+2,36,3,31,21,
+-41,-39,8,-57,14,
+37,-2,19,-36,-19,
+-23,-29,-16,1,-3,
+-8,-10,31,64,-65};
+
+const signed char cdbk_nb_high1[320]={
+-26,-8,29,21,4,
+19,-39,33,-7,-36,
+56,54,48,40,29,
+-4,-24,-42,-66,-43,
+-60,19,-2,37,41,
+-10,-37,-60,-64,18,
+-22,77,73,40,25,
+4,19,-19,-66,-2,
+11,5,21,14,26,
+-25,-86,-4,18,1,
+26,-37,10,37,-1,
+24,-12,-59,-11,20,
+-6,34,-16,-16,42,
+19,-28,-51,53,32,
+4,10,62,21,-12,
+-34,27,4,-48,-48,
+-50,-49,31,-7,-21,
+-42,-25,-4,-43,-22,
+59,2,27,12,-9,
+-6,-16,-8,-32,-58,
+-16,-29,-5,41,23,
+-30,-33,-46,-13,-10,
+-38,52,52,1,-17,
+-9,10,26,-25,-6,
+33,-20,53,55,25,
+-32,-5,-42,23,21,
+66,5,-28,20,9,
+75,29,-7,-42,-39,
+15,3,-23,21,6,
+11,1,-29,14,63,
+10,54,26,-24,-51,
+-49,7,-23,-51,15,
+-66,1,60,25,10,
+0,-30,-4,-15,17,
+19,59,40,4,-5,
+33,6,-22,-58,-70,
+-5,23,-6,60,44,
+-29,-16,-47,-29,52,
+-19,50,28,16,35,
+31,36,0,-21,6,
+21,27,22,42,7,
+-66,-40,-8,7,19,
+46,0,-4,60,36,
+45,-7,-29,-6,-32,
+-39,2,6,-9,33,
+20,-51,-34,18,-6,
+19,6,11,5,-19,
+-29,-2,42,-11,-45,
+-21,-55,57,37,2,
+-14,-67,-16,-27,-38,
+69,48,19,2,-17,
+20,-20,-16,-34,-17,
+-25,-61,10,73,45,
+16,-40,-64,-17,-29,
+-22,56,17,-39,8,
+-11,8,-25,-18,-13,
+-19,8,54,57,36,
+-17,-26,-4,6,-21,
+40,42,-4,20,31,
+53,10,-34,-53,31,
+-17,35,0,15,-6,
+-20,-63,-73,22,25,
+29,17,8,-29,-39,
+-69,18,15,-15,-5};
+
+const signed char cdbk_nb_high2[320]={
+11,47,16,-9,-46,
+-32,26,-64,34,-5,
+38,-7,47,20,2,
+-73,-99,-3,-45,20,
+70,-52,15,-6,-7,
+-82,31,21,47,51,
+39,-3,9,0,-41,
+-7,-15,-54,2,0,
+27,-31,9,-45,-22,
+-38,-24,-24,8,-33,
+23,5,50,-36,-17,
+-18,-51,-2,13,19,
+43,12,-15,-12,61,
+38,38,7,13,0,
+6,-1,3,62,9,
+27,22,-33,38,-35,
+-9,30,-43,-9,-32,
+-1,4,-4,1,-5,
+-11,-8,38,31,11,
+-10,-42,-21,-37,1,
+43,15,-13,-35,-19,
+-18,15,23,-26,59,
+1,-21,53,8,-41,
+-50,-14,-28,4,21,
+25,-28,-40,5,-40,
+-41,4,51,-33,-8,
+-8,1,17,-60,12,
+25,-41,17,34,43,
+19,45,7,-37,24,
+-15,56,-2,35,-10,
+48,4,-47,-2,5,
+-5,-54,5,-3,-33,
+-10,30,-2,-44,-24,
+-38,9,-9,42,4,
+6,-56,44,-16,9,
+-40,-26,18,-20,10,
+28,-41,-21,-4,13,
+-18,32,-30,-3,37,
+15,22,28,50,-40,
+3,-29,-64,7,51,
+-19,-11,17,-27,-40,
+-64,24,-12,-7,-27,
+3,37,48,-1,2,
+-9,-38,-34,46,1,
+27,-6,19,-13,26,
+10,34,20,25,40,
+50,-6,-7,30,9,
+-24,0,-23,71,-61,
+22,58,-34,-4,2,
+-49,-33,25,30,-8,
+-6,-16,77,2,38,
+-8,-35,-6,-30,56,
+78,31,33,-20,13,
+-39,20,22,4,21,
+-8,4,-6,10,-83,
+-41,9,-25,-43,15,
+-7,-12,-34,-39,-37,
+-33,19,30,16,-33,
+42,-25,25,-68,44,
+-15,-11,-4,23,50,
+14,4,-39,-43,20,
+-30,60,9,-20,7,
+16,19,-33,37,29,
+16,-35,7,38,-27};
diff --git a/utils/iaxclient/lib/libspeex/ltp.c b/utils/iaxclient/lib/libspeex/ltp.c
new file mode 100644 (file)
index 0000000..6b633d3
--- /dev/null
@@ -0,0 +1,828 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: ltp.c
+   Long-Term Prediction functions
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <math.h>
+#include "ltp.h"
+#include "stack_alloc.h"
+#include "filters.h"
+#include <speex/speex_bits.h>
+#include "math_approx.h"
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+
+#ifdef _USE_SSE
+#include "ltp_sse.h"
+#elif defined (ARM4_ASM) || defined(ARM5E_ASM)
+#include "ltp_arm4.h"
+#else
+
+static spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len)
+{
+   spx_word32_t sum=0;
+   len >>= 2;
+   while(len--)
+   {
+      spx_word32_t part=0;
+      part = MAC16_16(part,*x++,*y++);
+      part = MAC16_16(part,*x++,*y++);
+      part = MAC16_16(part,*x++,*y++);
+      part = MAC16_16(part,*x++,*y++);
+      /* HINT: If you had a 40-bit accumulator, you could shift only at the end */
+      sum = ADD32(sum,SHR32(part,6));
+   }
+   return sum;
+}
+
+#if 0 /* HINT: Enable this for machines with enough registers (i.e. not x86) */
+static void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack)
+{
+   int i,j;
+   for (i=0;i<nb_pitch;i+=4)
+   {
+      /* Compute correlation*/
+      /*corr[nb_pitch-1-i]=inner_prod(x, _y+i, len);*/
+      spx_word32_t sum1=0;
+      spx_word32_t sum2=0;
+      spx_word32_t sum3=0;
+      spx_word32_t sum4=0;
+      const spx_word16_t *y = _y+i;
+      const spx_word16_t *x = _x;
+      spx_word16_t y0, y1, y2, y3;
+      /*y0=y[0];y1=y[1];y2=y[2];y3=y[3];*/
+      y0=*y++;
+      y1=*y++;
+      y2=*y++;
+      y3=*y++;
+      for (j=0;j<len;j+=4)
+      {
+         spx_word32_t part1;
+         spx_word32_t part2;
+         spx_word32_t part3;
+         spx_word32_t part4;
+         part1 = MULT16_16(*x,y0);
+         part2 = MULT16_16(*x,y1);
+         part3 = MULT16_16(*x,y2);
+         part4 = MULT16_16(*x,y3);
+         x++;
+         y0=*y++;
+         part1 = MAC16_16(part1,*x,y1);
+         part2 = MAC16_16(part2,*x,y2);
+         part3 = MAC16_16(part3,*x,y3);
+         part4 = MAC16_16(part4,*x,y0);
+         x++;
+         y1=*y++;
+         part1 = MAC16_16(part1,*x,y2);
+         part2 = MAC16_16(part2,*x,y3);
+         part3 = MAC16_16(part3,*x,y0);
+         part4 = MAC16_16(part4,*x,y1);
+         x++;
+         y2=*y++;
+         part1 = MAC16_16(part1,*x,y3);
+         part2 = MAC16_16(part2,*x,y0);
+         part3 = MAC16_16(part3,*x,y1);
+         part4 = MAC16_16(part4,*x,y2);
+         x++;
+         y3=*y++;
+         
+         sum1 = ADD32(sum1,SHR32(part1,6));
+         sum2 = ADD32(sum2,SHR32(part2,6));
+         sum3 = ADD32(sum3,SHR32(part3,6));
+         sum4 = ADD32(sum4,SHR32(part4,6));
+      }
+      corr[nb_pitch-1-i]=sum1;
+      corr[nb_pitch-2-i]=sum2;
+      corr[nb_pitch-3-i]=sum3;
+      corr[nb_pitch-4-i]=sum4;
+   }
+
+}
+#else
+static void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack)
+{
+   int i;
+   for (i=0;i<nb_pitch;i++)
+   {
+      /* Compute correlation*/
+      corr[nb_pitch-1-i]=inner_prod(_x, _y+i, len);
+   }
+
+}
+#endif
+
+
+
+#endif
+
+void open_loop_nbest_pitch(spx_sig_t *sw, int start, int end, int len, int *pitch, spx_word16_t *gain, int N, char *stack)
+{
+   int i,j,k;
+   VARDECL(spx_word32_t *best_score);
+   spx_word32_t e0;
+   VARDECL(spx_word32_t *corr);
+   VARDECL(spx_word32_t *energy);
+   VARDECL(spx_word32_t *score);
+#ifdef FIXED_POINT
+   VARDECL(spx_word16_t *swn2);
+#endif
+   spx_word16_t *swn;
+
+   ALLOC(best_score, N, spx_word32_t);
+   ALLOC(corr, end-start+1, spx_word32_t);
+   ALLOC(energy, end-start+2, spx_word32_t);
+   ALLOC(score, end-start+1, spx_word32_t);
+
+#ifdef FIXED_POINT
+   ALLOC(swn2, end+len, spx_word16_t);
+   normalize16(sw-end, swn2, 16384, end+len);
+   swn = swn2 + end;
+#else
+   swn = sw;
+#endif
+
+   for (i=0;i<N;i++)
+   {
+        best_score[i]=-1;
+        pitch[i]=start;
+   }
+
+
+   energy[0]=inner_prod(swn-start, swn-start, len);
+   e0=inner_prod(swn, swn, len);
+   for (i=start;i<=end;i++)
+   {
+      /* Update energy for next pitch*/
+      energy[i-start+1] = SUB32(ADD32(energy[i-start],SHR32(MULT16_16(swn[-i-1],swn[-i-1]),6)), SHR32(MULT16_16(swn[-i+len-1],swn[-i+len-1]),6));
+   }
+
+   pitch_xcorr(swn, swn-end, corr, len, end-start+1, stack);
+
+#ifdef FIXED_POINT
+   {
+      VARDECL(spx_word16_t *corr16);
+      VARDECL(spx_word16_t *ener16);
+      ALLOC(corr16, end-start+1, spx_word16_t);
+      ALLOC(ener16, end-start+1, spx_word16_t);
+      normalize16(corr, corr16, 16384, end-start+1);
+      normalize16(energy, ener16, 16384, end-start+1);
+
+      for (i=start;i<=end;i++)
+      {
+         spx_word16_t g;
+         spx_word32_t tmp;
+         tmp = corr16[i-start];
+         if (tmp>0)
+         {
+            if (SHR16(corr16[i-start],4)>ener16[i-start])
+               tmp = SHL32(EXTEND32(ener16[i-start]),14);
+            else if (-SHR16(corr16[i-start],4)>ener16[i-start])
+               tmp = -SHL32(EXTEND32(ener16[i-start]),14);
+            else
+               tmp = SHL32(tmp,10);
+            g = DIV32_16(tmp, 8+ener16[i-start]);
+            score[i-start] = MULT16_16(corr16[i-start],g);
+         } else
+         {
+            score[i-start] = 1;
+         }
+      }
+   }
+#else
+   for (i=start;i<=end;i++)
+   {
+      float g = corr[i-start]/(1+energy[i-start]);
+      if (g>16)
+         g = 16;
+      else if (g<-16)
+         g = -16;
+      score[i-start] = g*corr[i-start];
+   }
+#endif
+
+   /* Extract best scores */
+   for (i=start;i<=end;i++)
+   {
+      if (score[i-start]>best_score[N-1])
+      {
+         for (j=0;j<N;j++)
+         {
+            if (score[i-start] > best_score[j])
+            {
+               for (k=N-1;k>j;k--)
+               {
+                  best_score[k]=best_score[k-1];
+                  pitch[k]=pitch[k-1];
+               }
+               best_score[j]=score[i-start];
+               pitch[j]=i;
+               break;
+            }
+         }
+      }
+   }
+
+   /* Compute open-loop gain */
+   if (gain)
+   {
+       for (j=0;j<N;j++)
+       {
+          spx_word16_t g;
+          i=pitch[j];
+          g = DIV32(corr[i-start], 10+SHR32(MULT16_16(spx_sqrt(e0),spx_sqrt(energy[i-start])),6));
+          /* FIXME: g = max(g,corr/energy) */
+                   if (g<0)
+                   g = 0;
+             gain[j]=g;
+       }
+   }
+}
+
+
+/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */
+static spx_word64_t pitch_gain_search_3tap(
+const spx_sig_t target[],       /* Target vector */
+const spx_coef_t ak[],          /* LPCs for this subframe */
+const spx_coef_t awk1[],        /* Weighted LPCs #1 for this subframe */
+const spx_coef_t awk2[],        /* Weighted LPCs #2 for this subframe */
+spx_sig_t exc[],                /* Excitation */
+const void *par,
+int   pitch,                    /* Pitch value */
+int   p,                        /* Number of LPC coeffs */
+int   nsf,                      /* Number of samples in subframe */
+SpeexBits *bits,
+char *stack,
+const spx_sig_t *exc2,
+const spx_word16_t *r,
+spx_sig_t *new_target,
+int  *cdbk_index,
+int cdbk_offset,
+int plc_tuning
+)
+{
+   int i,j;
+   VARDECL(spx_sig_t *tmp1);
+   VARDECL(spx_sig_t *tmp2);
+   spx_sig_t *x[3];
+   spx_sig_t *e[3];
+   spx_word32_t corr[3];
+   spx_word32_t A[3][3];
+   int   gain_cdbk_size;
+   const signed char *gain_cdbk;
+   spx_word16_t gain[3];
+   spx_word64_t err;
+
+   const ltp_params *params;
+   params = (const ltp_params*) par;
+   gain_cdbk_size = 1<<params->gain_bits;
+   gain_cdbk = params->gain_cdbk + 3*gain_cdbk_size*cdbk_offset;
+   ALLOC(tmp1, 3*nsf, spx_sig_t);
+   ALLOC(tmp2, 3*nsf, spx_sig_t);
+
+   x[0]=tmp1;
+   x[1]=tmp1+nsf;
+   x[2]=tmp1+2*nsf;
+   
+   e[0]=tmp2;
+   e[1]=tmp2+nsf;
+   e[2]=tmp2+2*nsf;
+   for (i=2;i>=0;i--)
+   {
+      int pp=pitch+1-i;
+      for (j=0;j<nsf;j++)
+      {
+         if (j-pp<0)
+            e[i][j]=exc2[j-pp];
+         else if (j-pp-pitch<0)
+            e[i][j]=exc2[j-pp-pitch];
+         else
+            e[i][j]=0;
+      }
+
+      if (i==2)
+         syn_percep_zero(e[i], ak, awk1, awk2, x[i], nsf, p, stack);
+      else {
+         for (j=0;j<nsf-1;j++)
+            x[i][j+1]=x[i+1][j];
+         x[i][0]=0;
+         for (j=0;j<nsf;j++)
+         {
+            x[i][j]=ADD32(x[i][j],SHL32(MULT16_32_Q15(r[j], e[i][0]),1));
+         }
+      }
+   }
+
+#ifdef FIXED_POINT
+   {
+      /* If using fixed-point, we need to normalize the signals first */
+      spx_word16_t *y[3];
+      VARDECL(spx_word16_t *ytmp);
+      VARDECL(spx_word16_t *t);
+
+      spx_sig_t max_val=1;
+      int sig_shift;
+      
+      ALLOC(ytmp, 3*nsf, spx_word16_t);
+#if 0
+      ALLOC(y[0], nsf, spx_word16_t);
+      ALLOC(y[1], nsf, spx_word16_t);
+      ALLOC(y[2], nsf, spx_word16_t);
+#else
+      y[0] = ytmp;
+      y[1] = ytmp+nsf;
+      y[2] = ytmp+2*nsf;
+#endif
+      ALLOC(t, nsf, spx_word16_t);
+      for (j=0;j<3;j++)
+      {
+         for (i=0;i<nsf;i++)
+         {
+            spx_sig_t tmp = x[j][i];
+            if (tmp<0)
+               tmp = -tmp;
+            if (tmp > max_val)
+               max_val = tmp;
+         }
+      }
+      for (i=0;i<nsf;i++)
+      {
+         spx_sig_t tmp = target[i];
+         if (tmp<0)
+            tmp = -tmp;
+         if (tmp > max_val)
+            max_val = tmp;
+      }
+
+      sig_shift=0;
+      while (max_val>16384)
+      {
+         sig_shift++;
+         max_val >>= 1;
+      }
+
+      for (j=0;j<3;j++)
+      {
+         for (i=0;i<nsf;i++)
+         {
+            y[j][i] = EXTRACT16(SHR32(x[j][i],sig_shift));
+         }
+      }
+      for (i=0;i<nsf;i++)
+      {
+         t[i] = EXTRACT16(SHR32(target[i],sig_shift));
+      }
+
+      for (i=0;i<3;i++)
+         corr[i]=inner_prod(y[i],t,nsf);
+      
+      for (i=0;i<3;i++)
+         for (j=0;j<=i;j++)
+            A[i][j]=A[j][i]=inner_prod(y[i],y[j],nsf);
+   }
+#else
+   {
+      for (i=0;i<3;i++)
+         corr[i]=inner_prod(x[i],target,nsf);
+      
+      for (i=0;i<3;i++)
+         for (j=0;j<=i;j++)
+            A[i][j]=A[j][i]=inner_prod(x[i],x[j],nsf);
+   }
+#endif
+
+   {
+      spx_word32_t C[9];
+      const signed char *ptr=gain_cdbk;
+      int best_cdbk=0;
+      spx_word32_t best_sum=0;
+      C[0]=corr[2];
+      C[1]=corr[1];
+      C[2]=corr[0];
+      C[3]=A[1][2];
+      C[4]=A[0][1];
+      C[5]=A[0][2];      
+      C[6]=A[2][2];
+      C[7]=A[1][1];
+      C[8]=A[0][0];
+      
+      /*plc_tuning *= 2;*/
+      if (plc_tuning<2)
+         plc_tuning=2;
+#ifdef FIXED_POINT
+      C[0] = MAC16_32_Q15(C[0],MULT16_16_16(plc_tuning,-327),C[0]);
+      C[1] = MAC16_32_Q15(C[1],MULT16_16_16(plc_tuning,-327),C[1]);
+      C[2] = MAC16_32_Q15(C[2],MULT16_16_16(plc_tuning,-327),C[2]);
+#else
+      C[0]*=1-.01*plc_tuning;
+      C[1]*=1-.01*plc_tuning;
+      C[2]*=1-.01*plc_tuning;
+      C[6]*=.5*(1+.01*plc_tuning);
+      C[7]*=.5*(1+.01*plc_tuning);
+      C[8]*=.5*(1+.01*plc_tuning);
+#endif
+      for (i=0;i<gain_cdbk_size;i++)
+      {
+         spx_word32_t sum=0;
+         spx_word16_t g0,g1,g2;
+         spx_word16_t pitch_control=64;
+         spx_word16_t gain_sum;
+         
+         ptr = gain_cdbk+3*i;
+         g0=ADD16((spx_word16_t)ptr[0],32);
+         g1=ADD16((spx_word16_t)ptr[1],32);
+         g2=ADD16((spx_word16_t)ptr[2],32);
+
+         gain_sum = g1;
+         if (g0>0)
+            gain_sum += g0;
+         if (g2>0)
+            gain_sum += g2;
+         if (gain_sum > 64)
+         {
+            gain_sum = SUB16(gain_sum, 64);
+            if (gain_sum > 127)
+               gain_sum = 127;
+#ifdef FIXED_POINT
+            pitch_control =  SUB16(64,EXTRACT16(PSHR32(MULT16_16(64,MULT16_16_16(plc_tuning, gain_sum)),10)));
+#else
+            pitch_control = 64*(1.-.001*plc_tuning*gain_sum);
+#endif
+            if (pitch_control < 0)
+               pitch_control = 0;
+         }
+         
+         sum = ADD32(sum,MULT16_32_Q14(MULT16_16_16(g0,pitch_control),C[0]));
+         sum = ADD32(sum,MULT16_32_Q14(MULT16_16_16(g1,pitch_control),C[1]));
+         sum = ADD32(sum,MULT16_32_Q14(MULT16_16_16(g2,pitch_control),C[2]));
+         sum = SUB32(sum,MULT16_32_Q14(MULT16_16_16(g0,g1),C[3]));
+         sum = SUB32(sum,MULT16_32_Q14(MULT16_16_16(g2,g1),C[4]));
+         sum = SUB32(sum,MULT16_32_Q14(MULT16_16_16(g2,g0),C[5]));
+         sum = SUB32(sum,MULT16_32_Q15(MULT16_16_16(g0,g0),C[6]));
+         sum = SUB32(sum,MULT16_32_Q15(MULT16_16_16(g1,g1),C[7]));
+         sum = SUB32(sum,MULT16_32_Q15(MULT16_16_16(g2,g2),C[8]));
+         /* We could force "safe" pitch values to handle packet loss better */
+
+         if (sum>best_sum || i==0)
+         {
+            best_sum=sum;
+            best_cdbk=i;
+         }
+      }
+#ifdef FIXED_POINT
+      gain[0] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*3]);
+      gain[1] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*3+1]);
+      gain[2] = ADD16(32,(spx_word16_t)gain_cdbk[best_cdbk*3+2]);
+      /*printf ("%d %d %d %d\n",gain[0],gain[1],gain[2], best_cdbk);*/
+#else
+      gain[0] = 0.015625*gain_cdbk[best_cdbk*3]  + .5;
+      gain[1] = 0.015625*gain_cdbk[best_cdbk*3+1]+ .5;
+      gain[2] = 0.015625*gain_cdbk[best_cdbk*3+2]+ .5;
+#endif
+      *cdbk_index=best_cdbk;
+   }
+
+#ifdef FIXED_POINT
+   for (i=0;i<nsf;i++)
+     exc[i]=SHL32(ADD32(ADD32(MULT16_32_Q15(SHL16(gain[0],7),e[2][i]), MULT16_32_Q15(SHL16(gain[1],7),e[1][i])),
+                        MULT16_32_Q15(SHL16(gain[2],7),e[0][i])), 2);
+   
+   err=0;
+   for (i=0;i<nsf;i++)
+   {
+      spx_word16_t perr2;
+      spx_sig_t tmp = SHL32(ADD32(ADD32(MULT16_32_Q15(SHL16(gain[0],7),x[2][i]),MULT16_32_Q15(SHL16(gain[1],7),x[1][i])),
+                                  MULT16_32_Q15(SHL16(gain[2],7),x[0][i])),2);
+      spx_sig_t perr=SUB32(target[i],tmp);
+      new_target[i] = SUB32(target[i], tmp);
+      perr2 = EXTRACT16(PSHR32(perr,15));
+      err = ADD64(err,MULT16_16(perr2,perr2));
+      
+   }
+#else
+   for (i=0;i<nsf;i++)
+      exc[i]=gain[0]*e[2][i]+gain[1]*e[1][i]+gain[2]*e[0][i];
+   
+   err=0;
+   for (i=0;i<nsf;i++)
+   {
+      spx_sig_t tmp = gain[2]*x[0][i]+gain[1]*x[1][i]+gain[0]*x[2][i];
+      new_target[i] = target[i] - tmp;
+      err+=new_target[i]*new_target[i];
+   }
+#endif
+
+   return err;
+}
+
+
+/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */
+int pitch_search_3tap(
+spx_sig_t target[],                 /* Target vector */
+spx_sig_t *sw,
+spx_coef_t ak[],                     /* LPCs for this subframe */
+spx_coef_t awk1[],                   /* Weighted LPCs #1 for this subframe */
+spx_coef_t awk2[],                   /* Weighted LPCs #2 for this subframe */
+spx_sig_t exc[],                    /* Excitation */
+const void *par,
+int   start,                    /* Smallest pitch value allowed */
+int   end,                      /* Largest pitch value allowed */
+spx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */
+int   p,                        /* Number of LPC coeffs */
+int   nsf,                      /* Number of samples in subframe */
+SpeexBits *bits,
+char *stack,
+spx_sig_t *exc2,
+spx_word16_t *r,
+int complexity,
+int cdbk_offset,
+int plc_tuning
+)
+{
+   int i,j;
+   int cdbk_index, pitch=0, best_gain_index=0;
+   VARDECL(spx_sig_t *best_exc);
+   VARDECL(spx_sig_t *new_target);
+   VARDECL(spx_sig_t *best_target);
+   int best_pitch=0;
+   spx_word64_t err, best_err=-1;
+   int N;
+   const ltp_params *params;
+   VARDECL(int *nbest);
+
+   N=complexity;
+   if (N>10)
+      N=10;
+   if (N<1)
+      N=1;
+
+   ALLOC(nbest, N, int);
+   params = (const ltp_params*) par;
+
+   if (end<start)
+   {
+      speex_bits_pack(bits, 0, params->pitch_bits);
+      speex_bits_pack(bits, 0, params->gain_bits);
+      for (i=0;i<nsf;i++)
+         exc[i]=0;
+      return start;
+   }
+   
+   ALLOC(best_exc, nsf, spx_sig_t);
+   ALLOC(new_target, nsf, spx_sig_t);
+   ALLOC(best_target, nsf, spx_sig_t);
+   
+   if (N>end-start+1)
+      N=end-start+1;
+   open_loop_nbest_pitch(sw, start, end, nsf, nbest, NULL, N, stack);
+   for (i=0;i<N;i++)
+   {
+      pitch=nbest[i];
+      for (j=0;j<nsf;j++)
+         exc[j]=0;
+      err=pitch_gain_search_3tap(target, ak, awk1, awk2, exc, par, pitch, p, nsf,
+                                 bits, stack, exc2, r, new_target, &cdbk_index, cdbk_offset, plc_tuning);
+      if (err<best_err || best_err<0)
+      {
+         for (j=0;j<nsf;j++)
+            best_exc[j]=exc[j];
+         for (j=0;j<nsf;j++)
+            best_target[j]=new_target[j];
+         best_err=err;
+         best_pitch=pitch;
+         best_gain_index=cdbk_index;
+      }
+   }
+   
+   /*printf ("pitch: %d %d\n", best_pitch, best_gain_index);*/
+   speex_bits_pack(bits, best_pitch-start, params->pitch_bits);
+   speex_bits_pack(bits, best_gain_index, params->gain_bits);
+   /*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/
+   for (i=0;i<nsf;i++)
+      exc[i]=best_exc[i];
+   for (i=0;i<nsf;i++)
+      target[i]=best_target[i];
+
+   return pitch;
+}
+
+void pitch_unquant_3tap(
+spx_sig_t exc[],                    /* Excitation */
+int   start,                    /* Smallest pitch value allowed */
+int   end,                      /* Largest pitch value allowed */
+spx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */
+const void *par,
+int   nsf,                      /* Number of samples in subframe */
+int *pitch_val,
+spx_word16_t *gain_val,
+SpeexBits *bits,
+char *stack,
+int count_lost,
+int subframe_offset,
+spx_word16_t last_pitch_gain,
+int cdbk_offset
+)
+{
+   int i;
+   int pitch;
+   int gain_index;
+   spx_word16_t gain[3];
+   const signed char *gain_cdbk;
+   int gain_cdbk_size;
+   const ltp_params *params;
+
+   params = (const ltp_params*) par;
+   gain_cdbk_size = 1<<params->gain_bits;
+   gain_cdbk = params->gain_cdbk + 3*gain_cdbk_size*cdbk_offset;
+
+   pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits);
+   pitch += start;
+   gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits);
+   /*printf ("decode pitch: %d %d\n", pitch, gain_index);*/
+#ifdef FIXED_POINT
+   gain[0] = 32+(spx_word16_t)gain_cdbk[gain_index*3];
+   gain[1] = 32+(spx_word16_t)gain_cdbk[gain_index*3+1];
+   gain[2] = 32+(spx_word16_t)gain_cdbk[gain_index*3+2];
+#else
+   gain[0] = 0.015625*gain_cdbk[gain_index*3]+.5;
+   gain[1] = 0.015625*gain_cdbk[gain_index*3+1]+.5;
+   gain[2] = 0.015625*gain_cdbk[gain_index*3+2]+.5;
+#endif
+
+   if (count_lost && pitch > subframe_offset)
+   {
+      float gain_sum;
+      if (1) {
+        float tmp = count_lost < 4 ? GAIN_SCALING_1*last_pitch_gain : 0.4 * GAIN_SCALING_1 * last_pitch_gain;
+         if (tmp>.95)
+            tmp=.95;
+         gain_sum = GAIN_SCALING_1*gain_3tap_to_1tap(gain);
+
+        if (gain_sum > tmp) {
+           float fact = tmp/gain_sum;
+           for (i=0;i<3;i++)
+              gain[i]*=fact;
+
+        }
+
+      }
+
+   }
+
+   *pitch_val = pitch;
+   gain_val[0]=gain[0];
+   gain_val[1]=gain[1];
+   gain_val[2]=gain[2];
+
+   {
+      spx_sig_t *e[3];
+      VARDECL(spx_sig_t *tmp2);
+      ALLOC(tmp2, 3*nsf, spx_sig_t);
+      e[0]=tmp2;
+      e[1]=tmp2+nsf;
+      e[2]=tmp2+2*nsf;
+      
+      for (i=0;i<3;i++)
+      {
+         int j;
+         int pp=pitch+1-i;
+#if 0
+         for (j=0;j<nsf;j++)
+         {
+            if (j-pp<0)
+               e[i][j]=exc[j-pp];
+            else if (j-pp-pitch<0)
+               e[i][j]=exc[j-pp-pitch];
+            else
+               e[i][j]=0;
+         }
+#else
+         {
+            int tmp1, tmp3;
+            tmp1=nsf;
+            if (tmp1>pp)
+               tmp1=pp;
+            for (j=0;j<tmp1;j++)
+               e[i][j]=exc[j-pp];
+            tmp3=nsf;
+            if (tmp3>pp+pitch)
+               tmp3=pp+pitch;
+            for (j=tmp1;j<tmp3;j++)
+               e[i][j]=exc[j-pp-pitch];
+            for (j=tmp3;j<nsf;j++)
+               e[i][j]=0;
+         }
+#endif
+      }
+
+#ifdef FIXED_POINT
+      {
+         for (i=0;i<nsf;i++)
+            exc[i]=SHL32(ADD32(ADD32(MULT16_32_Q15(SHL16(gain[0],7),e[2][i]), MULT16_32_Q15(SHL16(gain[1],7),e[1][i])),
+                               MULT16_32_Q15(SHL16(gain[2],7),e[0][i])), 2);
+      }
+#else
+      for (i=0;i<nsf;i++)
+         exc[i]=VERY_SMALL+gain[0]*e[2][i]+gain[1]*e[1][i]+gain[2]*e[0][i];
+#endif
+   }
+}
+
+
+/** Forced pitch delay and gain */
+int forced_pitch_quant(
+spx_sig_t target[],                 /* Target vector */
+spx_sig_t *sw,
+spx_coef_t ak[],                     /* LPCs for this subframe */
+spx_coef_t awk1[],                   /* Weighted LPCs #1 for this subframe */
+spx_coef_t awk2[],                   /* Weighted LPCs #2 for this subframe */
+spx_sig_t exc[],                    /* Excitation */
+const void *par,
+int   start,                    /* Smallest pitch value allowed */
+int   end,                      /* Largest pitch value allowed */
+spx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */
+int   p,                        /* Number of LPC coeffs */
+int   nsf,                      /* Number of samples in subframe */
+SpeexBits *bits,
+char *stack,
+spx_sig_t *exc2,
+spx_word16_t *r,
+int complexity,
+int cdbk_offset,
+int plc_tuning
+)
+{
+   int i;
+   float coef = GAIN_SCALING_1*pitch_coef;
+   if (coef>.99)
+      coef=.99;
+   for (i=0;i<nsf;i++)
+   {
+      exc[i]=exc[i-start]*coef;
+   }
+   return start;
+}
+
+/** Unquantize forced pitch delay and gain */
+void forced_pitch_unquant(
+spx_sig_t exc[],                    /* Excitation */
+int   start,                    /* Smallest pitch value allowed */
+int   end,                      /* Largest pitch value allowed */
+spx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */
+const void *par,
+int   nsf,                      /* Number of samples in subframe */
+int *pitch_val,
+spx_word16_t *gain_val,
+SpeexBits *bits,
+char *stack,
+int count_lost,
+int subframe_offset,
+spx_word16_t last_pitch_gain,
+int cdbk_offset
+)
+{
+   int i;
+   float coef = GAIN_SCALING_1*pitch_coef;
+   if (coef>.99)
+      coef=.99;
+   for (i=0;i<nsf;i++)
+   {
+      exc[i]=exc[i-start]*coef;
+   }
+   *pitch_val = start;
+   gain_val[0]=gain_val[2]=0;
+   gain_val[1] = pitch_coef;
+}
diff --git a/utils/iaxclient/lib/libspeex/ltp.h b/utils/iaxclient/lib/libspeex/ltp.h
new file mode 100644 (file)
index 0000000..9895356
--- /dev/null
@@ -0,0 +1,131 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: ltp.h
+   Long-Term Prediction functions
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <speex/speex_bits.h>
+#include "misc.h"
+
+typedef struct ltp_params {
+   const signed char *gain_cdbk;
+   int     gain_bits;
+   int     pitch_bits;
+} ltp_params;
+
+#ifdef FIXED_POINT
+#define gain_3tap_to_1tap(g) (ABS(g[1]) + (g[0]>0 ? g[0] : -SHR16(g[0],1)) + (g[2]>0 ? g[2] : -SHR16(g[2],1)))
+#else
+#define gain_3tap_to_1tap(g) (ABS(g[1]) + (g[0]>0 ? g[0] : -.5*g[0]) + (g[2]>0 ? g[2] : -.5*g[2]))
+#endif
+
+void open_loop_nbest_pitch(spx_sig_t *sw, int start, int end, int len, int *pitch, spx_word16_t *gain, int N, char *stack);
+
+
+/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */
+int pitch_search_3tap(
+spx_sig_t target[],                 /* Target vector */
+spx_sig_t *sw,
+spx_coef_t ak[],                     /* LPCs for this subframe */
+spx_coef_t awk1[],                   /* Weighted LPCs #1 for this subframe */
+spx_coef_t awk2[],                   /* Weighted LPCs #2 for this subframe */
+spx_sig_t exc[],                    /* Overlapping codebook */
+const void *par,
+int   start,                    /* Smallest pitch value allowed */
+int   end,                      /* Largest pitch value allowed */
+spx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */
+int   p,                        /* Number of LPC coeffs */
+int   nsf,                      /* Number of samples in subframe */
+SpeexBits *bits,
+char *stack,
+spx_sig_t *exc2,
+spx_word16_t *r,
+int   complexity,
+int   cdbk_offset,
+int plc_tuning
+);
+
+/*Unquantize adaptive codebook and update pitch contribution*/
+void pitch_unquant_3tap(
+spx_sig_t exc[],                    /* Excitation */
+int   start,                    /* Smallest pitch value allowed */
+int   end,                      /* Largest pitch value allowed */
+spx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */
+const void *par,
+int   nsf,                      /* Number of samples in subframe */
+int *pitch_val,
+spx_word16_t *gain_val,
+SpeexBits *bits,
+char *stack,
+int lost,
+int subframe_offset,
+spx_word16_t last_pitch_gain,
+int cdbk_offset
+);
+
+/** Forced pitch delay and gain */
+int forced_pitch_quant(
+spx_sig_t target[],                 /* Target vector */
+spx_sig_t *sw,
+spx_coef_t ak[],                     /* LPCs for this subframe */
+spx_coef_t awk1[],                   /* Weighted LPCs #1 for this subframe */
+spx_coef_t awk2[],                   /* Weighted LPCs #2 for this subframe */
+spx_sig_t exc[],                    /* Excitation */
+const void *par,
+int   start,                    /* Smallest pitch value allowed */
+int   end,                      /* Largest pitch value allowed */
+spx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */
+int   p,                        /* Number of LPC coeffs */
+int   nsf,                      /* Number of samples in subframe */
+SpeexBits *bits,
+char *stack,
+spx_sig_t *exc2,
+spx_word16_t *r,
+int complexity,
+int cdbk_offset,
+int plc_tuning
+);
+
+/** Unquantize forced pitch delay and gain */
+void forced_pitch_unquant(
+spx_sig_t exc[],                    /* Excitation */
+int   start,                    /* Smallest pitch value allowed */
+int   end,                      /* Largest pitch value allowed */
+spx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */
+const void *par,
+int   nsf,                      /* Number of samples in subframe */
+int *pitch_val,
+spx_word16_t *gain_val,
+SpeexBits *bits,
+char *stack,
+int lost,
+int subframe_offset,
+spx_word16_t last_pitch_gain,
+int cdbk_offset
+);
diff --git a/utils/iaxclient/lib/libspeex/ltp_arm4.h b/utils/iaxclient/lib/libspeex/ltp_arm4.h
new file mode 100644 (file)
index 0000000..462ab95
--- /dev/null
@@ -0,0 +1,183 @@
+/* Copyright (C) 2004 Jean-Marc Valin 
+   File: ltp.c
+   Lont-Term Prediction functions (SSE version)
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+static spx_word32_t inner_prod(const spx_word16_t *x, const spx_word16_t *y, int len)
+{
+   spx_word32_t sum1=0,sum2=0;
+   spx_word16_t *deadx, *deady;
+   int deadlen, dead1, dead2, dead3, dead4, dead5, dead6;
+   __asm__ __volatile__ (
+         "\tldrsh %5, [%0], #2 \n"
+         "\tldrsh %6, [%1], #2 \n"
+         ".inner_prod_loop%=:\n"
+         "\tsub %7, %7, %7\n"
+         "\tsub %10, %10, %10\n"
+
+         "\tldrsh %8, [%0], #2 \n"
+         "\tldrsh %9, [%1], #2 \n"
+         "\tmla %7, %5, %6, %7\n"
+         "\tldrsh %5, [%0], #2 \n"
+         "\tldrsh %6, [%1], #2 \n"
+         "\tmla %10, %8, %9, %10\n"
+         "\tldrsh %8, [%0], #2 \n"
+         "\tldrsh %9, [%1], #2 \n"
+         "\tmla %7, %5, %6, %7\n"
+         "\tldrsh %5, [%0], #2 \n"
+         "\tldrsh %6, [%1], #2 \n"
+         "\tmla %10, %8, %9, %10\n"
+
+         "\tldrsh %8, [%0], #2 \n"
+         "\tldrsh %9, [%1], #2 \n"
+         "\tmla %7, %5, %6, %7\n"
+         "\tldrsh %5, [%0], #2 \n"
+         "\tldrsh %6, [%1], #2 \n"
+         "\tmla %10, %8, %9, %10\n"
+         "\tldrsh %8, [%0], #2 \n"
+         "\tldrsh %9, [%1], #2 \n"
+         "\tmla %7, %5, %6, %7\n"
+         "\tldrsh %5, [%0], #2 \n"
+         "\tldrsh %6, [%1], #2 \n"
+         "\tmla %10, %8, %9, %10\n"
+
+         "\tsubs %4, %4, #1\n"
+         "\tadd %2, %2, %7, asr #5\n"
+         "\tadd %3, %3, %10, asr #5\n"
+         "\tbne .inner_prod_loop%=\n"
+   : "=r" (deadx), "=r" (deady), "=r" (sum1),  "=r" (sum2), "=r" (deadlen),
+   "=r" (dead1), "=r" (dead2), "=r" (dead3), "=r" (dead4), "=r" (dead5), "=r" (dead6)
+   : "0" (x), "1" (y), "2" (sum1), "3" (sum2), "4" (len>>3)
+   : "cc"
+                        );
+   return (sum1+sum2)>>1;
+}
+         
+static void pitch_xcorr(const spx_word16_t *_x, const spx_word16_t *_y, spx_word32_t *corr, int len, int nb_pitch, char *stack)
+{
+   int i,j;
+   for (i=0;i<nb_pitch;i+=4)
+   {
+      /* Compute correlation*/
+      //corr[nb_pitch-1-i]=inner_prod(x, _y+i, len);
+      spx_word32_t sum1=0;
+      spx_word32_t sum2=0;
+      spx_word32_t sum3=0;
+      spx_word32_t sum4=0;
+      const spx_word16_t *y = _y+i;
+      const spx_word16_t *x = _x;
+      spx_word32_t y0, y1, y2, y3;
+      y0=*y++;
+      y1=*y++;
+      y2=*y++;
+      y3=*y++;
+      for (j=0;j<len;j+=4)
+      {
+         spx_word32_t part1, part2, part3, part4, x0;
+         spx_word32_t dead1;
+         __asm__ __volatile__ (
+#ifdef SHORTCUTS
+               "\tldrsh %10, [%8], #4 \n"
+               "\tmul %4, %10, %0 \n"
+               "\tldrsh %15, [%8], #4 \n"
+               "\tmul %5, %10, %1 \n"
+               "\tldrsh %0, [%9], #2 \n"
+               "\tmul %6, %10, %2 \n"
+               "\tldrsh %1, [%9], #2 \n"
+               "\tmul %7, %10, %3 \n"
+               
+               
+               "\tmla %4, %15, %2, %4 \n"
+               "\tldrsh %2, [%9], #2 \n"
+               "\tmla %5, %15, %3, %5 \n"
+               "\tldrsh %3, [%9], #2 \n"
+               "\tmla %6, %15, %0, %6 \n"
+               "\tmla %7, %15, %1, %7 \n"
+
+#else
+               "\tldrsh %10, [%8], #2 \n"
+               "\tmul %4, %10, %0 \n"
+               "\tmul %5, %10, %1 \n"
+               "\tmul %6, %10, %2 \n"
+               "\tmul %7, %10, %3 \n"
+
+               "\tldrsh %10, [%8], #2 \n"
+               "\tldrsh %0, [%9], #2 \n"
+               "\tmla %4, %10, %1, %4 \n"
+               "\tmla %5, %10, %2, %5 \n"
+               "\tmla %6, %10, %3, %6 \n"
+               "\tmla %7, %10, %0, %7 \n"
+
+               "\tldrsh %10, [%8], #2 \n"
+               "\tldrsh %1, [%9], #2 \n"
+               "\tmla %4, %10, %2, %4 \n"
+               "\tmla %5, %10, %3, %5 \n"
+               "\tmla %6, %10, %0, %6 \n"
+               "\tmla %7, %10, %1, %7 \n"
+
+               "\tldrsh %10, [%8], #2 \n"
+               "\tldrsh %2, [%9], #2 \n"
+               "\tmla %4, %10, %3, %4 \n"
+               "\tmla %5, %10, %0, %5 \n"
+               "\tmla %6, %10, %1, %6 \n"
+               "\tmla %7, %10, %2, %7 \n"
+
+               "\tldrsh %3, [%9], #2 \n"
+#endif
+
+               "\tldr %10, %11 \n"
+               "\tldr %15, %12 \n"
+               "\tadd %4, %10, %4, asr #6 \n"
+               "\tstr %4, %11 \n"
+               "\tldr %10, %13 \n"
+               "\tadd %5, %15, %5, asr #6 \n"
+               "\tstr %5, %12 \n"
+               "\tldr %15, %14 \n"
+               "\tadd %6, %10, %6, asr #6 \n"
+               "\tadd %7, %15, %7, asr #6 \n"
+               "\tstr %6, %13 \n"
+               "\tstr %7, %14 \n"
+
+            : "=r" (y0), "=r" (y1), "=r" (y2), "=r" (y3),
+         "=r" (part1),  "=r" (part2),  "=r" (part3),  "=r" (part4),
+         "=r" (x), "=r" (y), "=r" (x0),
+         "=m" (sum1), "=m" (sum2), "=m" (sum3), "=m" (sum4), "=r" (dead1)
+            : "0" (y0), "1" (y1), "2" (y2), "3" (y3),
+            "8" (x), "9" (y),
+            "11" (sum1), "12" (sum2), "13" (sum3), "14" (sum4)
+            : "cc", "memory"
+                              );
+      }
+      corr[nb_pitch-1-i]=sum1;
+      corr[nb_pitch-2-i]=sum2;
+      corr[nb_pitch-3-i]=sum3;
+      corr[nb_pitch-4-i]=sum4;
+   }
+
+}
diff --git a/utils/iaxclient/lib/libspeex/ltp_sse.h b/utils/iaxclient/lib/libspeex/ltp_sse.h
new file mode 100644 (file)
index 0000000..abbdead
--- /dev/null
@@ -0,0 +1,88 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: ltp.c
+   Lont-Term Prediction functions (SSE version)
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include <xmmintrin.h>
+
+static float inner_prod(const float *a, const float *b, int len)
+{
+   int i;
+   float ret;
+   __m128 sum = _mm_setzero_ps();
+   for (i=0;i<(len>>2);i+=2)
+   {
+      sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+0), _mm_loadu_ps(b+0)));
+      sum = _mm_add_ps(sum, _mm_mul_ps(_mm_loadu_ps(a+4), _mm_loadu_ps(b+4)));
+      a += 8;
+      b += 8;
+   }
+   sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
+   sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
+   _mm_store_ss(&ret, sum);
+   return ret;
+}
+
+static void pitch_xcorr(const float *_x, const float *_y, float *corr, int len, int nb_pitch, char *stack)
+{
+   int i, offset;
+   VARDECL(__m128 *x);
+   VARDECL(__m128 *y);
+   int N, L;
+   N = len>>2;
+   L = nb_pitch>>2;
+   ALLOC(x, N, __m128);
+   ALLOC(y, N+L, __m128);
+   for (i=0;i<N;i++)
+      x[i] = _mm_loadu_ps(_x+(i<<2));
+   for (offset=0;offset<4;offset++)
+   {
+      for (i=0;i<N+L;i++)
+         y[i] = _mm_loadu_ps(_y+(i<<2)+offset);
+      for (i=0;i<L;i++)
+      {
+         int j;
+         __m128 sum, *xx, *yy;
+         sum = _mm_setzero_ps();
+         yy = y+i;
+         xx = x;
+         for (j=0;j<N;j+=2)
+         {
+            sum = _mm_add_ps(sum, _mm_mul_ps(xx[0], yy[0]));
+            sum = _mm_add_ps(sum, _mm_mul_ps(xx[1], yy[1]));
+            xx += 2;
+            yy += 2;
+         }
+         sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
+         sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
+         _mm_store_ss(corr+nb_pitch-1-(i<<2)-offset, sum);
+      }
+   }
+}
diff --git a/utils/iaxclient/lib/libspeex/math_approx.c b/utils/iaxclient/lib/libspeex/math_approx.c
new file mode 100644 (file)
index 0000000..2ed9dcd
--- /dev/null
@@ -0,0 +1,131 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: math_approx.c
+   Various math approximation functions for Speex
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "math_approx.h"
+#include "misc.h"
+
+#ifdef FIXED_POINT
+
+/* sqrt(x) ~= 0.22178 + 1.29227*x - 0.77070*x^2 + 0.25723*x^3 (for .25 < x < 1) */
+#define C0 3634
+#define C1 21173
+#define C2 -12627
+#define C3 4215
+
+spx_word16_t spx_sqrt(spx_word32_t x)
+{
+   int k=0;
+   spx_word32_t rt;
+
+   if (x==0)
+      return 0;
+#if 1
+   if (x>16777216)
+   {
+      x>>=10;
+      k+=5;
+   }
+   if (x>1048576)
+   {
+      x>>=6;
+      k+=3;
+   }
+   if (x>262144)
+   {
+      x>>=4;
+      k+=2;
+   }
+   if (x>32768)
+   {
+      x>>=2;
+      k+=1;
+   }
+   if (x>16384)
+   {
+      x>>=2;
+      k+=1;
+   }
+#else
+   while (x>16384)
+   {
+      x>>=2;
+      k++;
+      }
+#endif
+   while (x<4096)
+   {
+      x<<=2;
+      k--;
+   }
+   rt = ADD16(C0, MULT16_16_Q14(x, ADD16(C1, MULT16_16_Q14(x, ADD16(C2, MULT16_16_Q14(x, (C3)))))));
+   if (k>0)
+      rt <<= k;
+   else
+      rt >>= -k;
+   rt >>=7;
+   return rt;
+}
+
+/* log(x) ~= -2.18151 + 4.20592*x - 2.88938*x^2 + 0.86535*x^3 (for .5 < x < 1) */
+
+
+#define A1 16469
+#define A2 2242
+#define A3 1486
+
+spx_word16_t spx_acos(spx_word16_t x)
+{
+   int s=0;
+   spx_word16_t ret;
+   spx_word16_t sq;
+   if (x<0)
+   {
+      s=1;
+      x = NEG16(x);
+   }
+   x = SUB16(16384,x);
+   
+   x = x >> 1;
+   sq = MULT16_16_Q13(x, ADD16(A1, MULT16_16_Q13(x, ADD16(A2, MULT16_16_Q13(x, (A3))))));
+   ret = spx_sqrt(SHL32(EXTEND32(sq),13));
+   
+   /*ret = spx_sqrt(67108864*(-1.6129e-04 + 2.0104e+00*f + 2.7373e-01*f*f + 1.8136e-01*f*f*f));*/
+   if (s)
+      ret = SUB16(25736,ret);
+   return ret;
+}
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/math_approx.h b/utils/iaxclient/lib/libspeex/math_approx.h
new file mode 100644 (file)
index 0000000..1c84f5c
--- /dev/null
@@ -0,0 +1,46 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: math_approx.c
+   Various math approximation functions for Speex
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifndef MATH_APPROX_H
+#define MATH_APPROX_H
+
+#include "misc.h"
+
+#ifdef FIXED_POINT
+spx_word16_t spx_sqrt(spx_word32_t x);
+spx_word16_t spx_acos(spx_word16_t x);
+#else
+#define spx_sqrt sqrt
+#define spx_acos acos
+#endif
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/mdf.c b/utils/iaxclient/lib/libspeex/mdf.c
new file mode 100644 (file)
index 0000000..7de5936
--- /dev/null
@@ -0,0 +1,534 @@
+/* Copyright (C) Jean-Marc Valin
+
+   File: speex_echo.c
+   Echo cancelling based on the MDF algorithm described in:
+
+   J. S. Soo, K. K. Pang Multidelay block frequency adaptive filter, 
+   IEEE Trans. Acoust. Speech Signal Process., Vol. ASSP-38, No. 2, 
+   February 1990.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are
+   met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+
+   2. 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.
+
+   3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#ifdef _MSC_VER
+#include "winpoop.h"
+#endif
+#include "misc.h"
+#include "speex/speex_echo.h"
+#include "smallft.h"
+#include <math.h>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#define BETA .65
+
+#ifndef min
+#define min(a,b) ((a)<(b) ? (a) : (b))
+#define max(a,b) ((a)>(b) ? (a) : (b))
+#endif
+
+/** Compute inner product of two real vectors */
+static inline float inner_prod(float *x, float *y, int N)
+{
+   int i;
+   float ret=0;
+   for (i=0;i<N;i++)
+      ret += x[i]*y[i];
+   return ret;
+}
+
+/** Compute power spectrum of a half-complex (packed) vector */
+static inline void power_spectrum(float *X, float *ps, int N)
+{
+   int i, j;
+   ps[0]=X[0]*X[0];
+   for (i=1,j=1;i<N-1;i+=2,j++)
+   {
+      ps[j] =  X[i]*X[i] + X[i+1]*X[i+1];
+   }
+   ps[j]=X[i]*X[i];
+}
+
+/** Compute cross-power spectrum of a half-complex (packed) vectors and add to acc */
+static inline void spectral_mul_accum(float *X, float *Y, float *acc, int N)
+{
+   int i;
+   acc[0] += X[0]*Y[0];
+   for (i=1;i<N-1;i+=2)
+   {
+      acc[i] += (X[i]*Y[i] - X[i+1]*Y[i+1]);
+      acc[i+1] += (X[i+1]*Y[i] + X[i]*Y[i+1]);
+   }
+   acc[i] += X[i]*Y[i];
+}
+
+/** Compute cross-power spectrum of a half-complex (packed) vector with conjugate */
+static inline void spectral_mul_conj(float *X, float *Y, float *prod, int N)
+{
+   int i;
+   prod[0] = X[0]*Y[0];
+   for (i=1;i<N-1;i+=2)
+   {
+      prod[i] = (X[i]*Y[i] + X[i+1]*Y[i+1]);
+      prod[i+1] = (-X[i+1]*Y[i] + X[i]*Y[i+1]);
+   }
+   prod[i] = X[i]*Y[i];
+}
+
+
+/** Compute weighted cross-power spectrum of a half-complex (packed) vector with conjugate */
+static inline void weighted_spectral_mul_conj(float *w, float *X, float *Y, float *prod, int N)
+{
+   int i, j;
+   prod[0] = w[0]*X[0]*Y[0];
+   for (i=1,j=1;i<N-1;i+=2,j++)
+   {
+      prod[i] = w[j]*(X[i]*Y[i] + X[i+1]*Y[i+1]);
+      prod[i+1] = w[j]*(-X[i+1]*Y[i] + X[i]*Y[i+1]);
+   }
+   prod[i] = w[j]*X[i]*Y[i];
+}
+
+
+/** Creates a new echo canceller state */
+SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length)
+{
+   int i,j,N,M;
+   SpeexEchoState *st = (SpeexEchoState *)speex_alloc(sizeof(SpeexEchoState));
+
+   st->frame_size = frame_size;
+   st->window_size = 2*frame_size;
+   N = st->window_size;
+   M = st->M = (filter_length+st->frame_size-1)/frame_size;
+   st->cancel_count=0;
+   st->adapt_rate = .01f;
+   st->sum_adapt = 0;
+   st->Sey = 0;
+   st->Syy = 0;
+   st->See = 0;
+         
+   st->fft_lookup = (struct drft_lookup*)speex_alloc(sizeof(struct drft_lookup));
+   spx_drft_init(st->fft_lookup, N);
+   
+   st->x = (float*)speex_alloc(N*sizeof(float));
+   st->d = (float*)speex_alloc(N*sizeof(float));
+   st->y = (float*)speex_alloc(N*sizeof(float));
+   st->y2 = (float*)speex_alloc(N*sizeof(float));
+   st->Yps = (float*)speex_alloc(N*sizeof(float));
+   st->last_y = (float*)speex_alloc(N*sizeof(float));
+   st->Yf = (float*)speex_alloc((st->frame_size+1)*sizeof(float));
+   st->Rf = (float*)speex_alloc((st->frame_size+1)*sizeof(float));
+   st->Xf = (float*)speex_alloc((st->frame_size+1)*sizeof(float));
+   st->fratio = (float*)speex_alloc((st->frame_size+1)*sizeof(float));
+   st->regul = (float*)speex_alloc(N*sizeof(float));
+
+   st->X = (float*)speex_alloc(M*N*sizeof(float));
+   st->D = (float*)speex_alloc(N*sizeof(float));
+   st->Y = (float*)speex_alloc(N*sizeof(float));
+   st->Y2 = (float*)speex_alloc(N*sizeof(float));
+   st->E = (float*)speex_alloc(N*sizeof(float));
+   st->W = (float*)speex_alloc(M*N*sizeof(float));
+   st->PHI = (float*)speex_alloc(M*N*sizeof(float));
+   st->power = (float*)speex_alloc((frame_size+1)*sizeof(float));
+   st->power_1 = (float*)speex_alloc((frame_size+1)*sizeof(float));
+   st->grad = (float*)speex_alloc(N*M*sizeof(float));
+   
+   for (i=0;i<N*M;i++)
+   {
+      st->W[i] = st->PHI[i] = 0;
+   }
+   
+   st->regul[0] = (.01+(10.)/((4.)*(4.)))/M;
+   for (i=1,j=1;i<N-1;i+=2,j++)
+   {
+      st->regul[i] = .01+((10.)/((j+4.)*(j+4.)))/M;
+      st->regul[i+1] = .01+((10.)/((j+4.)*(j+4.)))/M;
+   }
+   st->regul[i] = .01+((10.)/((j+4.)*(j+4.)))/M;
+         
+   st->adapted = 0;
+   return st;
+}
+
+/** Resets echo canceller state */
+void speex_echo_state_reset(SpeexEchoState *st)
+{
+   int i, M, N;
+   st->cancel_count=0;
+   st->adapt_rate = .01f;
+   N = st->window_size;
+   M = st->M;
+   for (i=0;i<N*M;i++)
+   {
+      st->W[i] = 0;
+      st->X[i] = 0;
+   }
+   for (i=0;i<=st->frame_size;i++)
+      st->power[i] = 0;
+   
+   st->adapted = 0;
+   st->adapt_rate = .01f;
+   st->sum_adapt = 0;
+   st->Sey = 0;
+   st->Syy = 0;
+   st->See = 0;
+
+}
+
+/** Destroys an echo canceller state */
+void speex_echo_state_destroy(SpeexEchoState *st)
+{
+   spx_drft_clear(st->fft_lookup);
+   speex_free(st->fft_lookup);
+   speex_free(st->x);
+   speex_free(st->d);
+   speex_free(st->y);
+   speex_free(st->last_y);
+   speex_free(st->Yps);
+   speex_free(st->Yf);
+   speex_free(st->Rf);
+   speex_free(st->Xf);
+   speex_free(st->fratio);
+   speex_free(st->regul);
+
+   speex_free(st->X);
+   speex_free(st->D);
+   speex_free(st->Y);
+   speex_free(st->E);
+   speex_free(st->W);
+   speex_free(st->PHI);
+   speex_free(st->power);
+   speex_free(st->power_1);
+   speex_free(st->grad);
+
+   speex_free(st);
+}
+
+      
+/** Performs echo cancellation on a frame */
+void speex_echo_cancel(SpeexEchoState *st, short *ref, short *echo, short *out, float *Yout)
+{
+   int i,j,m;
+   int N,M;
+   float scale;
+   float ESR;
+   float SER;
+   //float Sry=0
+   float Srr=0,Syy=0,Sey=0,See=0,Sxx=0;
+   float leak_estimate;
+   
+   leak_estimate = .1+(.9/(1+2*st->sum_adapt));
+         
+   N = st->window_size;
+   M = st->M;
+   scale = 1.0f/N;
+   st->cancel_count++;
+
+   /* Copy input data to buffer */
+   for (i=0;i<st->frame_size;i++)
+   {
+      st->x[i] = st->x[i+st->frame_size];
+      st->x[i+st->frame_size] = echo[i];
+
+      st->d[i] = st->d[i+st->frame_size];
+      st->d[i+st->frame_size] = ref[i];
+   }
+
+   /* Shift memory: this could be optimized eventually*/
+   for (i=0;i<N*(M-1);i++)
+      st->X[i]=st->X[i+N];
+
+   /* Copy new echo frame */
+   for (i=0;i<N;i++)
+      st->X[(M-1)*N+i]=st->x[i];
+
+   /* Convert x (echo input) to frequency domain */
+   spx_drft_forward(st->fft_lookup, &st->X[(M-1)*N]);
+
+   /* Compute filter response Y */
+   for (i=0;i<N;i++)
+      st->Y[i] = 0;
+   for (j=0;j<M;j++)
+      spectral_mul_accum(&st->X[j*N], &st->W[j*N], st->Y, N);
+   
+   /* Convert Y (filter response) to time domain */
+   for (i=0;i<N;i++)
+      st->y[i] = st->Y[i];
+   spx_drft_backward(st->fft_lookup, st->y);
+   for (i=0;i<N;i++)
+      st->y[i] *= scale;
+
+   /* Transform d (reference signal) to frequency domain */
+   for (i=0;i<N;i++)
+      st->D[i]=st->d[i];
+   spx_drft_forward(st->fft_lookup, st->D);
+
+   /* Compute error signal (signal with echo removed) */ 
+   for (i=0;i<st->frame_size;i++)
+   {
+      float tmp_out;
+      tmp_out = (float)ref[i] - st->y[i+st->frame_size];
+      
+      st->E[i] = 0;
+      st->E[i+st->frame_size] = tmp_out;
+      
+      /* Saturation */
+      if (tmp_out>32767)
+         tmp_out = 32767;
+      else if (tmp_out<-32768)
+         tmp_out = -32768;
+      out[i] = tmp_out;
+   }
+   
+   /* This bit of code provides faster adaptation by doing a projection of the previous gradient on the 
+      "MMSE surface" */
+   if (1)
+   {
+      float Sge, Sgg, Syy;
+      float gain;
+      Syy = inner_prod(st->y+st->frame_size, st->y+st->frame_size, st->frame_size);
+      for (i=0;i<N;i++)
+         st->Y2[i] = 0;
+      for (j=0;j<M;j++)
+         spectral_mul_accum(&st->X[j*N], &st->PHI[j*N], st->Y2, N);
+      for (i=0;i<N;i++)
+         st->y2[i] = st->Y2[i];
+      spx_drft_backward(st->fft_lookup, st->y2);
+      for (i=0;i<N;i++)
+         st->y2[i] *= scale;
+      Sge = inner_prod(st->y2+st->frame_size, st->E+st->frame_size, st->frame_size);
+      Sgg = inner_prod(st->y2+st->frame_size, st->y2+st->frame_size, st->frame_size);
+      /* Compute projection gain */
+      gain = Sge/(N+.03*Syy+Sgg);
+      if (gain>2)
+         gain = 2;
+      if (gain < -2)
+         gain = -2;
+      
+      /* Apply gain to weights, echo estimates, output */
+      for (i=0;i<N;i++)
+         st->Y[i] += gain*st->Y2[i];
+      for (i=0;i<st->frame_size;i++)
+      {
+         st->y[i+st->frame_size] += gain*st->y2[i+st->frame_size];
+         st->E[i+st->frame_size] -= gain*st->y2[i+st->frame_size];
+      }
+      for (i=0;i<M*N;i++)
+         st->W[i] += gain*st->PHI[i];
+   }
+
+   /* Compute power spectrum of output (D-Y) and filter response (Y) */
+   for (i=0;i<N;i++)
+      st->D[i] -= st->Y[i];
+   power_spectrum(st->D, st->Rf, N);
+   power_spectrum(st->Y, st->Yf, N);
+   
+   /* Compute frequency-domain adaptation mask */
+   for (j=0;j<=st->frame_size;j++)
+   {
+      float r;
+      r = leak_estimate*st->Yf[j] / (1+st->Rf[j]);
+      if (r>1)
+         r = 1;
+      st->fratio[j] = r;
+   }
+
+   /* Compute a bunch of correlations */
+   //Sry = inner_prod(st->y+st->frame_size, st->d+st->frame_size, st->frame_size);
+   Sey = inner_prod(st->y+st->frame_size, st->E+st->frame_size, st->frame_size);
+   See = inner_prod(st->E+st->frame_size, st->E+st->frame_size, st->frame_size);
+   Syy = inner_prod(st->y+st->frame_size, st->y+st->frame_size, st->frame_size);
+   Srr = inner_prod(st->d+st->frame_size, st->d+st->frame_size, st->frame_size);
+   Sxx = inner_prod(st->x+st->frame_size, st->x+st->frame_size, st->frame_size);
+
+   /* Compute smoothed cross-correlation and energy */   
+   st->Sey = .98*st->Sey + .02*Sey;
+   st->Syy = .98*st->Syy + .02*Syy;
+   st->See = .98*st->See + .02*See;
+   
+   /* Check if filter is completely mis-adapted (if so, reset filter) */
+   if (st->Sey/(1+st->Syy + .01*st->See) < -1)
+   {
+      /*fprintf (stderr, "reset at %d\n", st->cancel_count);*/
+      speex_echo_state_reset(st);
+      return;
+   }
+
+   SER = Srr / (1+Sxx);
+   ESR = leak_estimate*Syy / (1+See);
+   if (ESR>1)
+      ESR = 1;
+#if 1
+   /* If over-cancellation (creating echo with 180 phase) damp filter */
+   if (st->Sey/(1+st->Syy) < -.1 && (ESR > .3))
+   {
+      for (i=0;i<M*N;i++)
+         st->W[i] *= .95;
+      st->Sey *= .5;
+      /*fprintf (stderr, "corrected down\n");*/
+   }
+#endif
+#if 1
+   /* If under-cancellation (leaving echo with 0 phase) scale filter up */
+   if (st->Sey/(1+st->Syy) > .1 && (ESR > .1 || SER < 10))
+   {
+      for (i=0;i<M*N;i++)
+         st->W[i] *= 1.05;
+      st->Sey *= .5;
+      /*fprintf (stderr, "corrected up %d\n", st->cancel_count);*/
+   }
+#endif
+   
+   /* We consider that the filter is adapted if the following is true*/
+   if (ESR>.6 && st->sum_adapt > 1)
+   {
+      /*if (!st->adapted)
+         fprintf(stderr, "Adapted at %d %f\n", st->cancel_count, st->sum_adapt);*/
+      st->adapted = 1;
+   }
+   
+   /* Update frequency-dependent energy ratio with the total energy ratio */
+   for (i=0;i<=st->frame_size;i++)
+   {
+      st->fratio[i]  = (.2*ESR+.8*min(.005+ESR,st->fratio[i]));
+   }   
+
+   if (st->adapted)
+   {
+      st->adapt_rate = .95f/(2+M);
+   } else {
+      /* Temporary adaption rate if filter is not adapted correctly */
+      if (SER<.1)
+         st->adapt_rate =.8/(2+M);
+      else if (SER<1)
+         st->adapt_rate =.4/(2+M);
+      else if (SER<10)
+         st->adapt_rate =.2/(2+M);
+      else if (SER<30)
+         st->adapt_rate =.08/(2+M);
+      else
+         st->adapt_rate = 0;
+   }
+   
+   /* How much have we adapted so far? */
+   st->sum_adapt += st->adapt_rate;
+
+   /* Compute echo power in each frequency bin */
+   {
+      float ss = 1.0f/st->cancel_count;
+      if (ss < .3/M)
+         ss=.3/M;
+      power_spectrum(&st->X[(M-1)*N], st->Xf, N);
+      /* Smooth echo energy estimate over time */
+      for (j=0;j<=st->frame_size;j++)
+         st->power[j] = (1-ss)*st->power[j] + ss*st->Xf[j];
+      
+      
+      /* Combine adaptation rate to the the inverse energy estimate */
+      if (st->adapted)
+      {
+         /* If filter is adapted, include the frequency-dependent ratio too */
+         for (i=0;i<=st->frame_size;i++)
+            st->power_1[i] = st->adapt_rate*st->fratio[i] /(1.f+st->power[i]);
+      } else {
+         for (i=0;i<=st->frame_size;i++)
+            st->power_1[i] = st->adapt_rate/(1.f+st->power[i]);
+      }
+   }
+
+   
+   /* Convert error to frequency domain */
+   spx_drft_forward(st->fft_lookup, st->E);
+
+   /* Do some regularization (prevents problems when system is ill-conditoned) */
+   for (m=0;m<M;m++)
+      for (i=0;i<N;i++)
+         st->W[m*N+i] *= 1-st->regul[i]*ESR;
+   
+   /* Compute weight gradient */
+   for (j=0;j<M;j++)
+   {
+      weighted_spectral_mul_conj(st->power_1, &st->X[j*N], st->E, st->PHI+N*j, N);
+   }
+
+   /* Gradient descent */
+   for (i=0;i<M*N;i++)
+      st->W[i] += st->PHI[i];
+   
+   /* AUMDF weight constraint */
+   for (j=0;j<M;j++)
+   {
+      /* Remove the "if" to make this an MDF filter */
+      if (st->cancel_count%M == j)
+      {
+         spx_drft_backward(st->fft_lookup, &st->W[j*N]);
+         for (i=0;i<N;i++)
+            st->W[j*N+i]*=scale;
+         for (i=st->frame_size;i<N;i++)
+         {
+            st->W[j*N+i]=0;
+         }
+         spx_drft_forward(st->fft_lookup, &st->W[j*N]);
+      }
+   }
+
+   /* Compute spectrum of estimated echo for use in an echo post-filter (if necessary)*/
+   if (Yout)
+   {
+      if (st->adapted)
+      {
+         /* If the filter is adapted, take the filtered echo */
+         for (i=0;i<st->frame_size;i++)
+            st->last_y[i] = st->last_y[st->frame_size+i];
+         for (i=0;i<st->frame_size;i++)
+            st->last_y[st->frame_size+i] = st->y[st->frame_size+i];
+      } else {
+         /* If filter isn't adapted yet, all we can do is take the echo signal directly */
+         for (i=0;i<N;i++)
+            st->last_y[i] = st->x[i];
+      }
+      
+      /* Apply hanning window (should pre-compute it)*/
+      for (i=0;i<N;i++)
+         st->Yps[i] = (.5-.5*cos(2*M_PI*i/N))*st->last_y[i];
+      
+      /* Compute power spectrum of the echo */
+      spx_drft_forward(st->fft_lookup, st->Yps);
+      power_spectrum(st->Yps, st->Yps, N);
+      
+      /* Estimate residual echo */
+      for (i=0;i<=st->frame_size;i++)
+         Yout[i] = 2*leak_estimate*st->Yps[i];
+   }
+
+}
+
diff --git a/utils/iaxclient/lib/libspeex/medfilter.c b/utils/iaxclient/lib/libspeex/medfilter.c
new file mode 100644 (file)
index 0000000..b562b3c
--- /dev/null
@@ -0,0 +1,97 @@
+/* Copyright (C) 2004 Jean-Marc Valin
+   File medfilter.c
+   Median filter
+
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
+   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+#include "medfilter.h"
+#include "misc.h"
+
+MedianFilter *median_filter_new(int N)
+{
+   MedianFilter *f = speex_alloc(sizeof(MedianFilter));
+   f->N = N;
+   f->ids = speex_alloc(sizeof(int)*N);
+   f->val = speex_alloc(sizeof(float)*N);
+   f->filled = 0;
+   return f;
+}
+
+void median_filter_update(MedianFilter *f, float val)
+{
+   int i=0;
+   int insert = 0;
+   while (insert<f->filled && f->val[insert] < val)
+   {
+      insert++;
+   }
+   if (f->filled == f->N)
+   {
+      int remove;
+      for (remove=0;remove<f->N;remove++)
+         if (f->ids[remove] == 0)
+            break;
+      if (insert>remove)
+         insert--;
+      if (insert > remove)
+      {
+         for (i=remove;i<insert;i++)
+         {
+            f->val[i] = f->val[i+1];
+            f->ids[i] = f->ids[i+1];
+         }
+      } else if (insert < remove)
+      {
+         for (i=remove;i>insert;i--)
+         {
+            f->val[i] = f->val[i-1];
+            f->ids[i] = f->ids[i-1];
+         }
+      }
+      for (i=0;i<f->filled;i++)
+         f->ids[i]--;
+   } else {
+      for (i=f->filled;i>insert;i--)
+      {
+         f->val[i] = f->val[i-1];
+         f->ids[i] = f->ids[i-1];
+      }
+      f->filled++;
+   }
+   f->val[insert]=val;
+   f->ids[insert]=f->filled-1;
+}
+
+float median_filter_get(MedianFilter *f)
+{
+   return f->val[f->filled>>1];
+}
+
diff --git a/utils/iaxclient/lib/libspeex/medfilter.h b/utils/iaxclient/lib/libspeex/medfilter.h
new file mode 100644 (file)
index 0000000..e34065b
--- /dev/null
@@ -0,0 +1,49 @@
+/* Copyright (C) 2004 Jean-Marc Valin
+   File medfilter.h
+   Median filter
+
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+
+*/
+
+#ifndef MEDFILTER_H
+#define MEDFILTER_H
+
+typedef struct {
+   int N;
+   int filled;
+   int *ids;
+   float *val;
+} MedianFilter;
+
+MedianFilter *median_filter_new(int N);
+void median_filter_update(MedianFilter *f, float val);
+float median_filter_get(MedianFilter *f);
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/misc.c b/utils/iaxclient/lib/libspeex/misc.c
new file mode 100644 (file)
index 0000000..01c9495
--- /dev/null
@@ -0,0 +1,178 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: mics.c
+   Various utility routines for Speex
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "misc.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifndef RELEASE
+void print_vec(float *vec, int len, char *name)
+{
+   int i;
+   printf ("%s ", name);
+   for (i=0;i<len;i++)
+      printf (" %f", vec[i]);
+   printf ("\n");
+}
+#endif
+
+#ifdef FIXED_DEBUG
+long long spx_mips=0;
+#endif
+
+
+spx_uint32_t be_int(spx_uint32_t i)
+{
+   spx_uint32_t ret=i;
+#ifndef WORDS_BIGENDIAN
+   ret =  i>>24;
+   ret += (i>>8)&0x0000ff00;
+   ret += (i<<8)&0x00ff0000;
+   ret += (i<<24);
+#endif
+   return ret;
+}
+
+spx_uint32_t le_int(spx_uint32_t i)
+{
+   spx_uint32_t ret=i;
+#ifdef WORDS_BIGENDIAN
+   ret =  i>>24;
+   ret += (i>>8)&0x0000ff00;
+   ret += (i<<8)&0x00ff0000;
+   ret += (i<<24);
+#endif
+   return ret;
+}
+
+#if BYTES_PER_CHAR == 2
+void speex_memcpy_bytes(char *dst, char *src, int nbytes)
+{
+  int i;
+  int nchars = nbytes/BYTES_PER_CHAR;
+  for (i=0;i<nchars;i++)
+    dst[i]=src[i];
+  if (nbytes & 1) {
+    /* copy in the last byte */
+    int last_i = nchars;
+    char last_dst_char = dst[last_i];
+    char last_src_char = src[last_i];
+    last_dst_char &= 0xff00;
+    last_dst_char |= (last_src_char & 0x00ff);
+    dst[last_i] = last_dst_char;
+  }
+}
+void speex_memset_bytes(char *dst, char c, int nbytes)
+{
+  int i;
+  spx_int16_t cc = ((c << 8) | c);
+  int nchars = nbytes/BYTES_PER_CHAR;
+  for (i=0;i<nchars;i++)
+    dst[i]=cc;
+  if (nbytes & 1) {
+    /* copy in the last byte */
+    int last_i = nchars;
+    char last_dst_char = dst[last_i];
+    last_dst_char &= 0xff00;
+    last_dst_char |= (c & 0x00ff);
+    dst[last_i] = last_dst_char;
+  }
+}
+#else
+void speex_memcpy_bytes(char *dst, char *src, int nbytes)
+{
+  memcpy(dst, src, nbytes);
+}
+void speex_memset_bytes(char *dst, char src, int nbytes)
+{
+  memset(dst, src, nbytes);
+}
+#endif
+
+void *speex_alloc (int size)
+{
+   return calloc(size,1);
+}
+
+void *speex_realloc (void *ptr, int size)
+{
+   return realloc(ptr, size);
+}
+
+void speex_free (void *ptr)
+{
+   free(ptr);
+}
+
+void *speex_move (void *dest, void *src, int n)
+{
+   return memmove(dest,src,n);
+}
+
+void speex_error(const char *str)
+{
+   fprintf (stderr, "Fatal error: %s\n", str);
+   exit(1);
+}
+
+void speex_warning(const char *str)
+{
+   fprintf (stderr, "warning: %s\n", str);
+}
+
+void speex_warning_int(const char *str, int val)
+{
+   fprintf (stderr, "warning: %s %d\n", str, val);
+}
+
+void speex_rand_vec(float std, spx_sig_t *data, int len)
+{
+   int i;
+   for (i=0;i<len;i++)
+      data[i]+=SIG_SCALING*3*std*((((float)rand())/RAND_MAX)-.5);
+}
+
+float speex_rand(float std)
+{
+   return 3*std*((((float)rand())/RAND_MAX)-.5);
+}
+
+void _speex_putc(int ch, void *file)
+{
+   FILE *f = (FILE *)file;
+   fprintf(f, "%c", ch);
+}
diff --git a/utils/iaxclient/lib/libspeex/misc.h b/utils/iaxclient/lib/libspeex/misc.h
new file mode 100644 (file)
index 0000000..73a4149
--- /dev/null
@@ -0,0 +1,82 @@
+/* Copyright (C) 2002 Jean-Marc Valin */
+/**
+   @file misc.h
+   @brief Various compatibility routines for Speex
+*/
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifndef MISC_H
+#define MISC_H
+
+#ifndef SPEEX_VERSION
+#define SPEEX_MAJOR_VERSION 1
+#define SPEEX_MINOR_VERSION 1
+#define SPEEX_MICRO_VERSION 8
+#define SPEEX_EXTRA_VERSION ""
+#define SPEEX_VERSION "speex-1.1.8"
+#endif
+
+#include "arch.h"
+
+#ifndef RELEASE
+void print_vec(float *vec, int len, char *name);
+#endif
+
+spx_uint32_t be_int(spx_uint32_t i);
+spx_uint32_t le_int(spx_uint32_t i);
+
+/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_free */
+void *speex_alloc (int size);
+
+/** Speex wrapper for realloc. To do your own dynamic allocation, all you need to do is replace this function, speex_alloc and speex_free */
+void *speex_realloc (void *ptr, int size);
+
+/** Speex wrapper for calloc. To do your own dynamic allocation, all you need to do is replace this function, speex_realloc and speex_alloc */
+void speex_free (void *ptr);
+
+/** Speex wrapper for mem_move */
+void *speex_move (void *dest, void *src, int n);
+
+void speex_memcpy_bytes(char *dst, char *src, int nbytes);
+void speex_memset_bytes(char *dst, char src, int nbytes);
+
+void speex_error(const char *str);
+
+void speex_warning(const char *str);
+
+void speex_warning_int(const char *str, int val);
+
+void speex_rand_vec(float std, spx_sig_t *data, int len);
+
+float speex_rand(float std);
+
+void _speex_putc(int ch, void *file);
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/modes.c b/utils/iaxclient/lib/libspeex/modes.c
new file mode 100644 (file)
index 0000000..1914457
--- /dev/null
@@ -0,0 +1,722 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: modes.c
+
+   Describes the different modes of the codec
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "modes.h"
+#include "ltp.h"
+#include "quant_lsp.h"
+#include "cb_search.h"
+#include "sb_celp.h"
+#include "nb_celp.h"
+#include "vbr.h"
+#include "misc.h"
+#include <math.h>
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define MAX_IN_SAMPLES 640
+
+const SpeexMode * const speex_mode_list[SPEEX_NB_MODES] = {&speex_nb_mode, &speex_wb_mode, &speex_uwb_mode};
+
+/* Extern declarations for all codebooks we use here */
+extern const signed char gain_cdbk_nb[];
+extern const signed char gain_cdbk_lbr[];
+extern const signed char hexc_table[];
+extern const signed char exc_5_256_table[];
+extern const signed char exc_5_64_table[];
+extern const signed char exc_8_128_table[];
+extern const signed char exc_10_32_table[];
+extern const signed char exc_10_16_table[];
+extern const signed char exc_20_32_table[];
+extern const signed char hexc_10_32_table[];
+
+
+/* Parameters for Long-Term Prediction (LTP)*/
+static const ltp_params ltp_params_nb = {
+   gain_cdbk_nb,
+   7,
+   7
+};
+
+/* Parameters for Long-Term Prediction (LTP)*/
+static const ltp_params ltp_params_vlbr = {
+   gain_cdbk_lbr,
+   5,
+   0
+};
+
+/* Parameters for Long-Term Prediction (LTP)*/
+static const ltp_params ltp_params_lbr = {
+   gain_cdbk_lbr,
+   5,
+   7
+};
+
+/* Parameters for Long-Term Prediction (LTP)*/
+static const ltp_params ltp_params_med = {
+   gain_cdbk_lbr,
+   5,
+   7
+};
+
+/* Split-VQ innovation parameters for very low bit-rate narrowband */
+static const split_cb_params split_cb_nb_vlbr = {
+   10,               /*subvect_size*/
+   4,               /*nb_subvect*/
+   exc_10_16_table, /*shape_cb*/
+   4,               /*shape_bits*/
+   0,
+};
+
+/* Split-VQ innovation parameters for very low bit-rate narrowband */
+static const split_cb_params split_cb_nb_ulbr = {
+   20,               /*subvect_size*/
+   2,               /*nb_subvect*/
+   exc_20_32_table, /*shape_cb*/
+   5,               /*shape_bits*/
+   0,
+};
+
+/* Split-VQ innovation parameters for low bit-rate narrowband */
+static const split_cb_params split_cb_nb_lbr = {
+   10,              /*subvect_size*/
+   4,               /*nb_subvect*/
+   exc_10_32_table, /*shape_cb*/
+   5,               /*shape_bits*/
+   0,
+};
+
+
+/* Split-VQ innovation parameters narrowband */
+static const split_cb_params split_cb_nb = {
+   5,               /*subvect_size*/
+   8,               /*nb_subvect*/
+   exc_5_64_table, /*shape_cb*/
+   6,               /*shape_bits*/
+   0,
+};
+
+/* Split-VQ innovation parameters narrowband */
+static const split_cb_params split_cb_nb_med = {
+   8,               /*subvect_size*/
+   5,               /*nb_subvect*/
+   exc_8_128_table, /*shape_cb*/
+   7,               /*shape_bits*/
+   0,
+};
+
+/* Split-VQ innovation for low-band wideband */
+static const split_cb_params split_cb_sb = {
+   5,               /*subvect_size*/
+   8,              /*nb_subvect*/
+   exc_5_256_table,    /*shape_cb*/
+   8,               /*shape_bits*/
+   0,
+};
+
+#ifndef DISABLE_WIDEBAND
+
+/* Split-VQ innovation for high-band wideband */
+static const split_cb_params split_cb_high = {
+   8,               /*subvect_size*/
+   5,               /*nb_subvect*/
+   hexc_table,       /*shape_cb*/
+   7,               /*shape_bits*/
+   1,
+};
+
+
+/* Split-VQ innovation for high-band wideband */
+static const split_cb_params split_cb_high_lbr = {
+   10,               /*subvect_size*/
+   4,               /*nb_subvect*/
+   hexc_10_32_table,       /*shape_cb*/
+   5,               /*shape_bits*/
+   0,
+};
+
+#endif
+
+/* 2150 bps "vocoder-like" mode for comfort noise */
+static const SpeexSubmode nb_submode1 = {
+   0,
+   1,
+   0,
+   0,
+   /* LSP quantization */
+   lsp_quant_lbr,
+   lsp_unquant_lbr,
+   /* No pitch quantization */
+   forced_pitch_quant,
+   forced_pitch_unquant,
+   NULL,
+   /* No innovation quantization (noise only) */
+   noise_codebook_quant,
+   noise_codebook_unquant,
+   NULL,
+#ifdef FIXED_POINT
+   22938, 22938, 0, -1,
+#else
+   .7, .7, 0, -1,
+#endif
+   43
+};
+
+/* 3.95 kbps very low bit-rate mode */
+static const SpeexSubmode nb_submode8 = {
+   0,
+   1,
+   0,
+   0,
+   /*LSP quantization*/
+   lsp_quant_lbr,
+   lsp_unquant_lbr,
+   /*No pitch quantization*/
+   forced_pitch_quant,
+   forced_pitch_unquant,
+   NULL,
+   /*Innovation quantization*/
+   split_cb_search_shape_sign,
+   split_cb_shape_sign_unquant,
+   &split_cb_nb_ulbr,
+#ifdef FIXED_POINT
+   22938, 16384, 11796, 21299,
+#else
+   0.7, 0.5, .36, .65,
+#endif
+   79
+};
+
+/* 5.95 kbps very low bit-rate mode */
+static const SpeexSubmode nb_submode2 = {
+   0,
+   0,
+   0,
+   0,
+   /*LSP quantization*/
+   lsp_quant_lbr,
+   lsp_unquant_lbr,
+   /*No pitch quantization*/
+   pitch_search_3tap,
+   pitch_unquant_3tap,
+   &ltp_params_vlbr,
+   /*Innovation quantization*/
+   split_cb_search_shape_sign,
+   split_cb_shape_sign_unquant,
+   &split_cb_nb_vlbr,
+#ifdef FIXED_POINT
+   22938, 16384, 11796, 18022,
+#else
+   0.7, 0.5, .36, .55,
+#endif
+   119
+};
+
+/* 8 kbps low bit-rate mode */
+static const SpeexSubmode nb_submode3 = {
+   -1,
+   0,
+   1,
+   0,
+   /*LSP quantization*/
+   lsp_quant_lbr,
+   lsp_unquant_lbr,
+   /*Pitch quantization*/
+   pitch_search_3tap,
+   pitch_unquant_3tap,
+   &ltp_params_lbr,
+   /*Innovation quantization*/
+   split_cb_search_shape_sign,
+   split_cb_shape_sign_unquant,
+   &split_cb_nb_lbr,
+#ifdef FIXED_POINT
+   22938, 18022, 9830, 14746,
+#else
+   0.7, 0.55, .30, .45,
+#endif
+   160
+};
+
+/* 11 kbps medium bit-rate mode */
+static const SpeexSubmode nb_submode4 = {
+   -1,
+   0,
+   1,
+   0,
+   /*LSP quantization*/
+   lsp_quant_lbr,
+   lsp_unquant_lbr,
+   /*Pitch quantization*/
+   pitch_search_3tap,
+   pitch_unquant_3tap,
+   &ltp_params_med,
+   /*Innovation quantization*/
+   split_cb_search_shape_sign,
+   split_cb_shape_sign_unquant,
+   &split_cb_nb_med,
+#ifdef FIXED_POINT
+   22938, 20644, 5243, 11469,
+#else
+   0.7, 0.63, .16, .35,
+#endif
+   220
+};
+
+/* 15 kbps high bit-rate mode */
+static const SpeexSubmode nb_submode5 = {
+   -1,
+   0,
+   3,
+   0,
+   /*LSP quantization*/
+   lsp_quant_nb,
+   lsp_unquant_nb,
+   /*Pitch quantization*/
+   pitch_search_3tap,
+   pitch_unquant_3tap,
+   &ltp_params_nb,
+   /*Innovation quantization*/
+   split_cb_search_shape_sign,
+   split_cb_shape_sign_unquant,
+   &split_cb_nb,
+#ifdef FIXED_POINT
+   22938, 21299, 3932, 8192,
+#else
+   0.7, 0.65, .12, .25,
+#endif
+   300
+};
+
+/* 18.2 high bit-rate mode */
+static const SpeexSubmode nb_submode6 = {
+   -1,
+   0,
+   3,
+   0,
+   /*LSP quantization*/
+   lsp_quant_nb,
+   lsp_unquant_nb,
+   /*Pitch quantization*/
+   pitch_search_3tap,
+   pitch_unquant_3tap,
+   &ltp_params_nb,
+   /*Innovation quantization*/
+   split_cb_search_shape_sign,
+   split_cb_shape_sign_unquant,
+   &split_cb_sb,
+#ifdef FIXED_POINT
+   22282, 21299, 2294, 3277,
+#else
+   0.68, 0.65, .07, .1,
+#endif
+   364
+};
+
+/* 24.6 kbps high bit-rate mode */
+static const SpeexSubmode nb_submode7 = {
+   -1,
+   0,
+   3,
+   1,
+   /*LSP quantization*/
+   lsp_quant_nb,
+   lsp_unquant_nb,
+   /*Pitch quantization*/
+   pitch_search_3tap,
+   pitch_unquant_3tap,
+   &ltp_params_nb,
+   /*Innovation quantization*/
+   split_cb_search_shape_sign,
+   split_cb_shape_sign_unquant,
+   &split_cb_nb,
+#ifdef FIXED_POINT
+   21299, 21299, 0, -1,
+#else
+   0.65, 0.65, .0, -1,
+#endif
+   492
+};
+
+
+/* Default mode for narrowband */
+static const SpeexNBMode nb_mode = {
+   160,    /*frameSize*/
+   40,     /*subframeSize*/
+   10,     /*lpcSize*/
+   17,     /*pitchStart*/
+   144,    /*pitchEnd*/
+#ifdef FIXED_POINT
+   29491, 19661, /* gamma1, gamma2 */
+#else
+   0.9, 0.6, /* gamma1, gamma2 */
+#endif
+   .012,   /*lag_factor*/
+   1.0002, /*lpc_floor*/
+#ifdef EPIC_48K
+   0,
+#endif
+   {NULL, &nb_submode1, &nb_submode2, &nb_submode3, &nb_submode4, &nb_submode5, &nb_submode6, &nb_submode7,
+   &nb_submode8, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+   5,
+   {1, 8, 2, 3, 3, 4, 4, 5, 5, 6, 7}
+};
+
+
+/* Default mode for narrowband */
+const SpeexMode speex_nb_mode = {
+   &nb_mode,
+   nb_mode_query,
+   "narrowband",
+   0,
+   4,
+   &nb_encoder_init,
+   &nb_encoder_destroy,
+   &nb_encode,
+   &nb_decoder_init,
+   &nb_decoder_destroy,
+   &nb_decode,
+   &nb_encoder_ctl,
+   &nb_decoder_ctl,
+};
+
+
+/* Wideband part */
+
+static const SpeexSubmode wb_submode1 = {
+   0,
+   0,
+   1,
+   0,
+   /*LSP quantization*/
+   lsp_quant_high,
+   lsp_unquant_high,
+   /*Pitch quantization*/
+   NULL,
+   NULL,
+   NULL,
+   /*No innovation quantization*/
+   NULL,
+   NULL,
+   NULL,
+#ifdef FIXED_POINT
+   24576, 24576, 0, -1,
+#else
+   .75, .75, .0, -1,
+#endif
+   36
+};
+
+
+static const SpeexSubmode wb_submode2 = {
+   0,
+   0,
+   1,
+   0,
+   /*LSP quantization*/
+   lsp_quant_high,
+   lsp_unquant_high,
+   /*Pitch quantization*/
+   NULL,
+   NULL,
+   NULL,
+   /*Innovation quantization*/
+   split_cb_search_shape_sign,
+   split_cb_shape_sign_unquant,
+#ifdef DISABLE_WIDEBAND
+   NULL,
+#else
+   &split_cb_high_lbr,
+#endif
+#ifdef FIXED_POINT
+   27853, 19661, 8192, -1,
+#else
+   .85, .6, .25, -1,
+#endif
+   112
+};
+
+
+static const SpeexSubmode wb_submode3 = {
+   0,
+   0,
+   1,
+   0,
+   /*LSP quantization*/
+   lsp_quant_high,
+   lsp_unquant_high,
+   /*Pitch quantization*/
+   NULL,
+   NULL,
+   NULL,
+   /*Innovation quantization*/
+   split_cb_search_shape_sign,
+   split_cb_shape_sign_unquant,
+#ifdef DISABLE_WIDEBAND
+   NULL,
+#else
+   &split_cb_high,
+#endif
+
+#ifdef FIXED_POINT
+   24576, 22938, 1638, -1,
+#else
+   .75, .7, .05, -1,
+#endif
+   192
+};
+
+static const SpeexSubmode wb_submode4 = {
+   0,
+   0,
+   1,
+   1,
+   /*LSP quantization*/
+   lsp_quant_high,
+   lsp_unquant_high,
+   /*Pitch quantization*/
+   NULL,
+   NULL,
+   NULL,
+   /*Innovation quantization*/
+   split_cb_search_shape_sign,
+   split_cb_shape_sign_unquant,
+#ifdef DISABLE_WIDEBAND
+   NULL,
+#else
+   &split_cb_high,
+#endif
+#ifdef FIXED_POINT
+   24576, 24576, 0, -1,
+#else
+   .75, .75, .0, -1,
+#endif
+   352
+};
+
+
+/* Split-band wideband CELP mode*/
+static const SpeexSBMode sb_wb_mode = {
+   &speex_nb_mode,
+   160,    /*frameSize*/
+   40,     /*subframeSize*/
+   8,     /*lpcSize*/
+   640,    /*bufSize*/
+#ifdef FIXED_POINT
+   29491, 19661, /* gamma1, gamma2 */
+#else
+   0.9, 0.6, /* gamma1, gamma2 */
+#endif
+   .001,   /*lag_factor*/
+   1.0001, /*lpc_floor*/
+   0.9,
+   {NULL, &wb_submode1, &wb_submode2, &wb_submode3, &wb_submode4, NULL, NULL, NULL},
+   3,
+   {1, 8, 2, 3, 4, 5, 5, 6, 6, 7, 7},
+   {1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4},
+   vbr_hb_thresh,
+   5
+};
+
+
+const SpeexMode speex_wb_mode = {
+   &sb_wb_mode,
+   wb_mode_query,
+   "wideband (sub-band CELP)",
+   1,
+   4,
+   &sb_encoder_init,
+   &sb_encoder_destroy,
+   &sb_encode,
+   &sb_decoder_init,
+   &sb_decoder_destroy,
+   &sb_decode,
+   &sb_encoder_ctl,
+   &sb_decoder_ctl,
+};
+
+
+
+/* "Ultra-wideband" mode stuff */
+
+
+
+/* Split-band "ultra-wideband" (32 kbps) CELP mode*/
+static const SpeexSBMode sb_uwb_mode = {
+   &speex_wb_mode,
+   320,    /*frameSize*/
+   80,     /*subframeSize*/
+   8,     /*lpcSize*/
+   1280,    /*bufSize*/
+#ifdef FIXED_POINT
+   29491, 19661, /* gamma1, gamma2 */
+#else
+   0.9, 0.6, /* gamma1, gamma2 */
+#endif
+   .002,   /*lag_factor*/
+   1.0001, /*lpc_floor*/
+   0.7,
+   {NULL, &wb_submode1, NULL, NULL, NULL, NULL, NULL, NULL},
+   1,
+   {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
+   {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
+   vbr_uhb_thresh,
+   2
+};
+
+
+const SpeexMode speex_uwb_mode = {
+   &sb_uwb_mode,
+   wb_mode_query,
+   "ultra-wideband (sub-band CELP)",
+   2,
+   4,
+   &sb_encoder_init,
+   &sb_encoder_destroy,
+   &sb_encode,
+   &sb_decoder_init,
+   &sb_decoder_destroy,
+   &sb_decode,
+   &sb_encoder_ctl,
+   &sb_decoder_ctl,
+};
+
+
+
+
+#ifdef EPIC_48K
+
+extern const signed char gain_cdbk_ulbr[];
+extern const signed char exc_12_32_table[];
+
+/* Parameters for Long-Term Prediction (LTP)*/
+static const ltp_params ltp_params_48k = {
+   gain_cdbk_ulbr,
+   3,
+   0
+};
+
+static const split_cb_params split_cb_nb_48k = {
+   12,               /*subvect_size*/
+   4,               /*nb_subvect*/
+   exc_12_32_table, /*shape_cb*/
+   5,               /*shape_bits*/
+   0,
+};
+
+
+/* 4.8 kbps very low bit-rate mode */
+static const SpeexSubmode nb_48k_submode = {
+   0,
+   0,
+   0,
+   0,
+   /*LSP quantization*/
+   lsp_quant_48k,
+   lsp_unquant_48k,
+   /*No pitch quantization*/
+   pitch_search_3tap,
+   pitch_unquant_3tap,
+   &ltp_params_48k,
+   /*Innovation quantization*/
+   split_cb_search_shape_sign,
+   split_cb_shape_sign_unquant,
+   &split_cb_nb_48k,
+#ifdef FIXED_POINT
+   22938, 16384, 11796, 18022,
+#else
+   0.7, 0.5, .36, .55,
+#endif
+   144
+};
+
+
+/* Special, non-standard 4.8 kbps mode */
+static const SpeexNBMode nb_48k_mode = {
+   240,    /*frameSize*/
+   48,     /*subframeSize*/
+   10,     /*lpcSize*/
+   640,    /*bufSize*/
+   17,     /*pitchStart*/
+   144,    /*pitchEnd*/
+   0.9,    /*gamma1*/
+   0.6,    /*gamma2*/
+   .01,   /*lag_factor*/
+   1.0003, /*lpc_floor*/
+   1,
+   {NULL, NULL, &nb_48k_submode, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+   2,
+   {2,2,2,2,2,2,2,2,2,2,2}
+};
+
+
+/* Default mode for narrowband */
+const SpeexMode speex_nb_48k_mode = {
+   &nb_48k_mode,
+   nb_mode_query,
+   "narrowband 4.8 kbps",
+   1000,
+   4,
+   &nb_encoder_init,
+   &nb_encoder_destroy,
+   &nb_encode,
+   &nb_decoder_init,
+   &nb_decoder_destroy,
+   &nb_decode,
+   &nb_encoder_ctl,
+   &nb_decoder_ctl,
+};
+
+
+#endif
+
+int speex_mode_query(const SpeexMode *mode, int request, void *ptr)
+{
+   return mode->query(mode->mode, request, ptr);
+}
+
+const SpeexMode * speex_lib_get_mode (int mode)
+{
+#ifdef EPIC_48K
+  if (mode == SPEEX_MODEID_NB_48K) return &speex_nb_48k_mode;
+#endif
+
+  if (mode < 0 || mode > SPEEX_NB_MODES) return NULL;
+
+  return speex_mode_list[mode];
+}
diff --git a/utils/iaxclient/lib/libspeex/modes.h b/utils/iaxclient/lib/libspeex/modes.h
new file mode 100644 (file)
index 0000000..e1c9468
--- /dev/null
@@ -0,0 +1,153 @@
+/* Copyright (C) 2002 Jean-Marc Valin */
+/**
+   @file modes.h
+   @brief Describes the different modes of the codec
+*/
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+
+*/
+
+#ifndef MODES_H
+#define MODES_H
+
+#include <speex/speex.h>
+#include <speex/speex_bits.h>
+#include "misc.h"
+
+#define NB_SUBMODES 16
+#define NB_SUBMODE_BITS 4
+
+#define SB_SUBMODES 8
+#define SB_SUBMODE_BITS 3
+
+
+/** Quantizes LSPs */
+typedef void (*lsp_quant_func)(spx_lsp_t *, spx_lsp_t *, int, SpeexBits *);
+
+/** Decodes quantized LSPs */
+typedef void (*lsp_unquant_func)(spx_lsp_t *, int, SpeexBits *);
+
+
+/** Long-term predictor quantization */
+typedef int (*ltp_quant_func)(spx_sig_t *, spx_sig_t *, spx_coef_t *, spx_coef_t *, 
+                              spx_coef_t *, spx_sig_t *, const void *, int, int, spx_word16_t, 
+                              int, int, SpeexBits*, char *, spx_sig_t *, spx_word16_t *, int, int, int);
+
+/** Long-term un-quantize */
+typedef void (*ltp_unquant_func)(spx_sig_t *, int, int, spx_word16_t, const void *, int, int *,
+                                 spx_word16_t *, SpeexBits*, char*, int, int, spx_word16_t, int);
+
+
+/** Innovation quantization function */
+typedef void (*innovation_quant_func)(spx_sig_t *, spx_coef_t *, spx_coef_t *, spx_coef_t *, const void *, int, int, 
+                                      spx_sig_t *, spx_word16_t *, SpeexBits *, char *, int, int);
+
+/** Innovation unquantization function */
+typedef void (*innovation_unquant_func)(spx_sig_t *, const void *, int, SpeexBits*, char *);
+
+/** Description of a Speex sub-mode (wither narrowband or wideband */
+typedef struct SpeexSubmode {
+   int     lbr_pitch;          /**< Set to -1 for "normal" modes, otherwise encode pitch using a global pitch and allowing a +- lbr_pitch variation (for low not-rates)*/
+   int     forced_pitch_gain;  /**< Use the same (forced) pitch gain for all sub-frames */
+   int     have_subframe_gain; /**< Number of bits to use as sub-frame innovation gain */
+   int     double_codebook;    /**< Apply innovation quantization twice for higher quality (and higher bit-rate)*/
+   /*LSP functions*/
+   lsp_quant_func    lsp_quant; /**< LSP quantization function */
+   lsp_unquant_func  lsp_unquant; /**< LSP unquantization function */
+
+   /*Lont-term predictor functions*/
+   ltp_quant_func    ltp_quant; /**< Long-term predictor (pitch) quantizer */
+   ltp_unquant_func  ltp_unquant; /**< Long-term predictor (pitch) un-quantizer */
+   const void             *ltp_params; /**< Pitch parameters (options) */
+
+   /*Quantization of innovation*/
+   innovation_quant_func innovation_quant; /**< Innovation quantization */
+   innovation_unquant_func innovation_unquant; /**< Innovation un-quantization */
+   const void             *innovation_params; /**< Innovation quantization parameters*/
+
+   /*Synthesis filter enhancement*/
+   spx_word16_t      lpc_enh_k1; /**< Enhancer constant */
+   spx_word16_t      lpc_enh_k2; /**< Enhancer constant */
+   spx_word16_t      lpc_enh_k3; /**< Enhancer constant */
+   spx_word16_t      comb_gain;  /**< Gain of enhancer comb filter */
+
+   int               bits_per_frame; /**< Number of bits per frame after encoding*/
+} SpeexSubmode;
+
+/** Struct defining the encoding/decoding mode*/
+typedef struct SpeexNBMode {
+   int     frameSize;      /**< Size of frames used for encoding */
+   int     subframeSize;   /**< Size of sub-frames used for encoding */
+   int     lpcSize;        /**< Order of LPC filter */
+   int     pitchStart;     /**< Smallest pitch value allowed */
+   int     pitchEnd;       /**< Largest pitch value allowed */
+
+   spx_word16_t gamma1;    /**< Perceptual filter parameter #1 */
+   spx_word16_t gamma2;    /**< Perceptual filter parameter #2 */
+   float   lag_factor;     /**< Lag-windowing parameter */
+   float   lpc_floor;      /**< Noise floor for LPC analysis */
+
+#ifdef EPIC_48K
+   int     lbr48k;         /**< 1 for the special 4.8 kbps mode */
+#endif
+
+   const SpeexSubmode *submodes[NB_SUBMODES]; /**< Sub-mode data for the mode */
+   int     defaultSubmode; /**< Default sub-mode to use when encoding */
+   int     quality_map[11]; /**< Mode corresponding to each quality setting */
+} SpeexNBMode;
+
+
+/** Struct defining the encoding/decoding mode for SB-CELP (wideband) */
+typedef struct SpeexSBMode {
+   const SpeexMode *nb_mode;    /**< Embedded narrowband mode */
+   int     frameSize;     /**< Size of frames used for encoding */
+   int     subframeSize;  /**< Size of sub-frames used for encoding */
+   int     lpcSize;       /**< Order of LPC filter */
+   int     bufSize;       /**< Signal buffer size in encoder */
+   spx_word16_t gamma1;   /**< Perceptual filter parameter #1 */
+   spx_word16_t gamma2;   /**< Perceptual filter parameter #1 */
+   float   lag_factor;    /**< Lag-windowing parameter */
+   float   lpc_floor;     /**< Noise floor for LPC analysis */
+   float   folding_gain;
+
+   const SpeexSubmode *submodes[SB_SUBMODES]; /**< Sub-mode data for the mode */
+   int     defaultSubmode; /**< Default sub-mode to use when encoding */
+   int     low_quality_map[11]; /**< Mode corresponding to each quality setting */
+   int     quality_map[11]; /**< Mode corresponding to each quality setting */
+   const float (*vbr_thresh)[11];
+   int     nb_modes;
+} SpeexSBMode;
+
+int speex_encode_native(void *state, spx_word16_t *in, SpeexBits *bits);
+int speex_decode_native(void *state, SpeexBits *bits, spx_word16_t *out);
+
+int nb_mode_query(const void *mode, int request, void *ptr);
+int wb_mode_query(const void *mode, int request, void *ptr);
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/modes_noglobals.c b/utils/iaxclient/lib/libspeex/modes_noglobals.c
new file mode 100644 (file)
index 0000000..2126af1
--- /dev/null
@@ -0,0 +1,1145 @@
+/* Copyright (C) 2004 CSIRO Australia
+   File: modes_noglobals.c
+
+   Hacked by Conrad Parker, based on modes.c:
+   Copyright (C) 2002 Jean-Marc Valin 
+
+   Describes the different modes of the codec. This file differs from
+   modes.c in that SpeexMode structures are dynamically allocated,
+   rather than being statically defined. This introduces some minor
+   API changes which are described in the file README.symbian in the
+   top level of the Speex source distribution.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "modes.h"
+#include "ltp.h"
+#include "quant_lsp.h"
+#include "cb_search.h"
+#include "sb_celp.h"
+#include "nb_celp.h"
+#include "vbr.h"
+#include "misc.h"
+#include <math.h>
+#include <string.h>
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* Extern declarations for all codebooks we use here */
+extern const signed char gain_cdbk_nb[];
+extern const signed char gain_cdbk_lbr[];
+extern const signed char hexc_table[];
+extern const signed char exc_5_256_table[];
+extern const signed char exc_5_64_table[];
+extern const signed char exc_8_128_table[];
+extern const signed char exc_10_32_table[];
+extern const signed char exc_10_16_table[];
+extern const signed char exc_20_32_table[];
+extern const signed char hexc_10_32_table[];
+
+static const ltp_params *
+speex_ltp_params_new (const signed char * gain_cdbk, int gain_bits,
+                     int pitch_bits)
+{
+  ltp_params * params;
+
+  params = (ltp_params *) speex_alloc (sizeof (ltp_params));
+  if (params == NULL) return NULL;
+
+  params->gain_cdbk = gain_cdbk;
+  params->gain_bits = gain_bits;
+  params->pitch_bits = pitch_bits;
+
+  return params;
+}
+
+static void
+speex_ltp_params_free (const ltp_params * params)
+{
+  speex_free ((void *)params);
+}
+
+static const split_cb_params *
+speex_split_cb_params_new (int subvect_size, int nb_subvect,
+                          const signed char * shape_cb, int shape_bits,
+                          int have_sign)
+{
+  split_cb_params * params;
+
+  params = (split_cb_params *) speex_alloc (sizeof (split_cb_params));
+  if (params == NULL) return NULL;
+
+  params->subvect_size = subvect_size;
+  params->nb_subvect = nb_subvect;
+  params->shape_cb = shape_cb;
+  params->shape_bits = shape_bits;
+  params->have_sign = have_sign;
+
+  return params;
+}
+
+static void
+speex_split_cb_params_free (const split_cb_params * params)
+{
+  speex_free ((void *)params);
+}
+
+static SpeexSubmode *
+speex_submode_new (int lbr_pitch, int forced_pitch_gain,
+                  int have_subframe_gain, int double_codebook,
+
+                  lsp_quant_func lsp_quant, lsp_unquant_func lsp_unquant,
+                  ltp_quant_func ltp_quant, ltp_unquant_func ltp_unquant,
+                  const void * ltp_params,
+
+                  innovation_quant_func innovation_quant,
+                  innovation_unquant_func innovation_unquant,
+                  const void * innovation_params,
+
+                  /*Synthesis filter enhancement*/
+                  spx_word16_t      lpc_enh_k1, /**< Enhancer constant */
+                  spx_word16_t      lpc_enh_k2, /**< Enhancer constant */
+                  spx_word16_t      lpc_enh_k3, /**< Enhancer constant */
+                  spx_word16_t      comb_gain,  /**< Gain of enhancer comb filter */
+                  
+                  int               bits_per_frame /**< Number of bits per frame after encoding*/
+
+                  )
+{
+  SpeexSubmode * submode;
+
+  submode = (SpeexSubmode *) speex_alloc (sizeof (SpeexSubmode));
+  if (submode == NULL) return NULL;
+
+  submode->lbr_pitch = lbr_pitch;
+  submode->forced_pitch_gain = forced_pitch_gain;
+  submode->have_subframe_gain = have_subframe_gain;
+  submode->double_codebook = double_codebook;
+  submode->lsp_quant = lsp_quant;
+  submode->lsp_unquant = lsp_unquant;
+  submode->ltp_quant = ltp_quant;
+  submode->ltp_unquant = ltp_unquant;
+  submode->ltp_params = ltp_params;
+  submode->innovation_quant = innovation_quant;
+  submode->innovation_unquant = innovation_unquant;
+  submode->innovation_params = innovation_params;
+  submode->lpc_enh_k1 = lpc_enh_k1;
+  submode->lpc_enh_k2 = lpc_enh_k2;
+  submode->lpc_enh_k3 = lpc_enh_k3;
+  submode->comb_gain = comb_gain;
+  submode->bits_per_frame = bits_per_frame;
+
+  return submode;
+}
+
+static void
+speex_submode_free (const SpeexSubmode * submode)
+{
+  if (submode->ltp_params)
+    speex_ltp_params_free (submode->ltp_params);
+
+  if (submode->innovation_params)
+    speex_split_cb_params_free (submode->innovation_params);
+
+  speex_free ((void *)submode);
+}
+
+static SpeexNBMode *
+nb_mode_new (int frameSize, int subframeSize, int lpcSize, int bufSize,
+            int pitchStart, int pitchEnd, spx_word16_t gamma1,
+            spx_word16_t gamma2, float lag_factor, float lpc_floor,
+#ifdef EPIC_48K
+            int lbr48k,
+#endif
+            const SpeexSubmode * submodes[], int defaultSubmode,
+            int quality_map[])
+{
+  SpeexNBMode * nb_mode;
+
+  nb_mode = (SpeexNBMode *) speex_alloc (sizeof (SpeexNBMode));
+  if (nb_mode == NULL) return NULL;
+
+  nb_mode->frameSize = frameSize;
+  nb_mode->subframeSize = subframeSize;
+  nb_mode->lpcSize = lpcSize;
+  nb_mode->bufSize = bufSize;
+  nb_mode->pitchStart = pitchStart;
+  nb_mode->pitchEnd = pitchEnd;
+  nb_mode->gamma1 = gamma1;
+  nb_mode->gamma2 = gamma2;
+  nb_mode->lag_factor = lag_factor;
+  nb_mode->lpc_floor = lpc_floor;
+#ifdef EPIC_48K
+  nb_mode->lbr48k = lbr48k;
+#endif
+  memcpy (nb_mode->submodes, submodes, sizeof (nb_mode->submodes));
+  nb_mode->defaultSubmode = defaultSubmode;
+  memcpy (nb_mode->quality_map, quality_map, sizeof (nb_mode->quality_map));
+
+  return nb_mode;
+}
+
+static void
+nb_mode_free (const SpeexNBMode * nb_mode)
+{
+  speex_free ((void *)nb_mode);
+}
+
+static SpeexSBMode *
+sb_mode_new (
+   const SpeexMode *nb_mode,    /**< Embedded narrowband mode */
+   int     frameSize,     /**< Size of frames used for encoding */
+   int     subframeSize,  /**< Size of sub-frames used for encoding */
+   int     lpcSize,       /**< Order of LPC filter */
+   int     bufSize,       /**< Signal buffer size in encoder */
+   spx_word16_t gamma1,   /**< Perceptual filter parameter #1 */
+   spx_word16_t gamma2,   /**< Perceptual filter parameter #1 */
+   float   lag_factor,    /**< Lag-windowing parameter */
+   float   lpc_floor,     /**< Noise floor for LPC analysis */
+   float   folding_gain,
+
+   const SpeexSubmode *submodes[], /**< Sub-mode data for the mode */
+   int     defaultSubmode, /**< Default sub-mode to use when encoding */
+   int     low_quality_map[], /**< Mode corresponding to each quality setting */
+   int     quality_map[], /**< Mode corresponding to each quality setting */
+   const float (*vbr_thresh)[11],
+   int     nb_modes
+                  )
+{
+  SpeexSBMode * sb_mode;
+
+  sb_mode = (SpeexSBMode *) speex_alloc (sizeof (SpeexSBMode));
+  if (sb_mode == NULL) return NULL;
+
+  sb_mode->nb_mode = nb_mode;
+  sb_mode->frameSize = frameSize;
+  sb_mode->subframeSize = subframeSize;
+  sb_mode->lpcSize = lpcSize;
+  sb_mode->bufSize = bufSize;
+  sb_mode->gamma1 = gamma1;
+  sb_mode->gamma2 = gamma2;
+  sb_mode->lag_factor = lag_factor;
+  sb_mode->lpc_floor = lpc_floor;
+  sb_mode->folding_gain = folding_gain;
+
+  memcpy (sb_mode->submodes, submodes, sizeof (sb_mode->submodes));
+  sb_mode->defaultSubmode = defaultSubmode;
+  memcpy (sb_mode->low_quality_map, low_quality_map, sizeof (sb_mode->low_quality_map));
+  memcpy (sb_mode->quality_map, quality_map, sizeof (sb_mode->quality_map));
+  sb_mode->vbr_thresh = vbr_thresh;
+  sb_mode->nb_modes = nb_modes;
+
+  return sb_mode;
+}
+
+static void
+sb_mode_free (const SpeexSBMode * sb_mode)
+{
+  int i;
+
+  for (i = 0; i < SB_SUBMODES; i++)
+    if (sb_mode->submodes[i]) speex_submode_free (sb_mode->submodes[i]);
+
+  speex_free ((void *)sb_mode);
+}
+
+static SpeexMode *
+mode_new (const void * b_mode, mode_query_func query, char * modeName,
+         int modeID, int bitstream_version, encoder_init_func enc_init,
+         encoder_destroy_func enc_destroy, encode_func enc,
+         decoder_init_func dec_init, decoder_destroy_func dec_destroy,
+         decode_func dec, encoder_ctl_func enc_ctl,
+         decoder_ctl_func dec_ctl)
+{
+  SpeexMode * mode;
+
+  mode = (SpeexMode *) speex_alloc (sizeof (SpeexMode));
+  if (mode == NULL) return NULL;
+
+  mode->mode = b_mode;
+  mode->query = query;
+  mode->modeName = modeName;
+  mode->modeID = modeID;
+  mode->bitstream_version = bitstream_version;
+  mode->enc_init = enc_init;
+  mode->enc_destroy = enc_destroy;
+  mode->enc = enc;
+  mode->dec_init = dec_init;
+  mode->dec_destroy = dec_destroy;
+  mode->dec = dec;
+  mode->enc_ctl = enc_ctl;
+  mode->dec_ctl = dec_ctl;
+
+  return mode;
+}
+
+/* Freeing each kind of created (SpeexMode *) is done separately below */
+
+/* Parameters for Long-Term Prediction (LTP)*/
+static const ltp_params * ltp_params_nb (void)
+{
+  return speex_ltp_params_new (
+   gain_cdbk_nb,
+   7,
+   7
+   );
+}
+
+/* Parameters for Long-Term Prediction (LTP)*/
+static const ltp_params * ltp_params_vlbr (void)
+{
+  return speex_ltp_params_new (
+   gain_cdbk_lbr,
+   5,
+   0
+   );
+}
+
+/* Parameters for Long-Term Prediction (LTP)*/
+static const ltp_params * ltp_params_lbr (void)
+{
+  return speex_ltp_params_new (
+   gain_cdbk_lbr,
+   5,
+   7
+   );
+}
+
+/* Parameters for Long-Term Prediction (LTP)*/
+static const ltp_params * ltp_params_med (void)
+{
+  return speex_ltp_params_new (
+   gain_cdbk_lbr,
+   5,
+   7
+   );
+}
+
+/* Split-VQ innovation parameters for very low bit-rate narrowband */
+static const split_cb_params * split_cb_nb_vlbr (void)
+{
+  return speex_split_cb_params_new (
+   10,               /*subvect_size*/
+   4,               /*nb_subvect*/
+   exc_10_16_table, /*shape_cb*/
+   4,               /*shape_bits*/
+   0
+   );
+}
+
+/* Split-VQ innovation parameters for very low bit-rate narrowband */
+static const split_cb_params * split_cb_nb_ulbr (void)
+{
+  return speex_split_cb_params_new (
+   20,               /*subvect_size*/
+   2,               /*nb_subvect*/
+   exc_20_32_table, /*shape_cb*/
+   5,               /*shape_bits*/
+   0
+   );
+}
+
+/* Split-VQ innovation parameters for low bit-rate narrowband */
+static const split_cb_params * split_cb_nb_lbr (void)
+{
+  return speex_split_cb_params_new (
+   10,              /*subvect_size*/
+   4,               /*nb_subvect*/
+   exc_10_32_table, /*shape_cb*/
+   5,               /*shape_bits*/
+   0
+   );
+}
+
+
+/* Split-VQ innovation parameters narrowband */
+static const split_cb_params * split_cb_nb (void)
+{
+  return speex_split_cb_params_new (
+   5,               /*subvect_size*/
+   8,               /*nb_subvect*/
+   exc_5_64_table, /*shape_cb*/
+   6,               /*shape_bits*/
+   0
+   );
+}
+
+/* Split-VQ innovation parameters narrowband */
+static const split_cb_params * split_cb_nb_med (void)
+{
+  return speex_split_cb_params_new (
+   8,               /*subvect_size*/
+   5,               /*nb_subvect*/
+   exc_8_128_table, /*shape_cb*/
+   7,               /*shape_bits*/
+   0
+   );
+}
+
+/* Split-VQ innovation for low-band wideband */
+static const split_cb_params * split_cb_sb (void)
+{
+  return speex_split_cb_params_new (
+   5,               /*subvect_size*/
+   8,              /*nb_subvect*/
+   exc_5_256_table,    /*shape_cb*/
+   8,               /*shape_bits*/
+   0
+   );
+}
+
+/* Split-VQ innovation for high-band wideband */
+static const split_cb_params * split_cb_high (void)
+{
+  return speex_split_cb_params_new (
+   8,               /*subvect_size*/
+   5,               /*nb_subvect*/
+   hexc_table,       /*shape_cb*/
+   7,               /*shape_bits*/
+   1
+   );
+}
+
+
+/* Split-VQ innovation for high-band wideband */
+static const split_cb_params * split_cb_high_lbr (void)
+{
+  return speex_split_cb_params_new (
+   10,               /*subvect_size*/
+   4,               /*nb_subvect*/
+   hexc_10_32_table,       /*shape_cb*/
+   5,               /*shape_bits*/
+   0
+   );
+}
+
+/* 2150 bps "vocoder-like" mode for comfort noise */
+static const SpeexSubmode * nb_submode1 (void)
+{
+  return speex_submode_new (
+   0,
+   1,
+   0,
+   0,
+   /* LSP quantization */
+   lsp_quant_lbr,
+   lsp_unquant_lbr,
+   /* No pitch quantization */
+   forced_pitch_quant,
+   forced_pitch_unquant,
+   NULL,
+   /* No innovation quantization (noise only) */
+   noise_codebook_quant,
+   noise_codebook_unquant,
+   NULL,
+#ifdef FIXED_POINT
+   22938, 22938, 0, -1,
+#else
+   .7, .7, 0, -1,
+#endif
+   43
+   );
+}
+
+/* 3.95 kbps very low bit-rate mode */
+static const SpeexSubmode * nb_submode8 (void)
+{
+  const split_cb_params * params;
+
+  params = split_cb_nb_ulbr();
+  if (params == NULL) return NULL;
+
+  return speex_submode_new (
+   0,
+   1,
+   0,
+   0,
+   /*LSP quantization*/
+   lsp_quant_lbr,
+   lsp_unquant_lbr,
+   /*No pitch quantization*/
+   forced_pitch_quant,
+   forced_pitch_unquant,
+   NULL,
+   /*Innovation quantization*/
+   split_cb_search_shape_sign,
+   split_cb_shape_sign_unquant,
+   params,
+#ifdef FIXED_POINT
+   22938, 16384, 11796, 21299,
+#else
+   0.7, 0.5, .36, .65,
+#endif
+   79
+   );
+}
+
+/* 5.95 kbps very low bit-rate mode */
+static const SpeexSubmode * nb_submode2 (void)
+{
+  return speex_submode_new (
+   0,
+   0,
+   0,
+   0,
+   /*LSP quantization*/
+   lsp_quant_lbr,
+   lsp_unquant_lbr,
+   /*No pitch quantization*/
+   pitch_search_3tap,
+   pitch_unquant_3tap,
+   ltp_params_vlbr(),
+   /*Innovation quantization*/
+   split_cb_search_shape_sign,
+   split_cb_shape_sign_unquant,
+   split_cb_nb_vlbr(),
+#ifdef FIXED_POINT
+   22938, 16384, 11796, 18022,
+#else
+   0.7, 0.5, .36, .55,
+#endif
+   119
+   );
+}
+
+/* 8 kbps low bit-rate mode */
+static const SpeexSubmode * nb_submode3 (void)
+{
+  return speex_submode_new (
+   -1,
+   0,
+   1,
+   0,
+   /*LSP quantization*/
+   lsp_quant_lbr,
+   lsp_unquant_lbr,
+   /*Pitch quantization*/
+   pitch_search_3tap,
+   pitch_unquant_3tap,
+   ltp_params_lbr(),
+   /*Innovation quantization*/
+   split_cb_search_shape_sign,
+   split_cb_shape_sign_unquant,
+   split_cb_nb_lbr(),
+#ifdef FIXED_POINT
+   22938, 18022, 9830, 14746,
+#else
+   0.7, 0.55, .30, .45,
+#endif
+   160
+   );
+}
+
+/* 11 kbps medium bit-rate mode */
+static const SpeexSubmode * nb_submode4 (void)
+{
+  return speex_submode_new (
+   -1,
+   0,
+   1,
+   0,
+   /*LSP quantization*/
+   lsp_quant_lbr,
+   lsp_unquant_lbr,
+   /*Pitch quantization*/
+   pitch_search_3tap,
+   pitch_unquant_3tap,
+   ltp_params_med(),
+   /*Innovation quantization*/
+   split_cb_search_shape_sign,
+   split_cb_shape_sign_unquant,
+   split_cb_nb_med(),
+#ifdef FIXED_POINT
+   22938, 20644, 5243, 11469,
+#else
+   0.7, 0.63, .16, .35,
+#endif
+   220
+   );
+}
+
+/* 15 kbps high bit-rate mode */
+static const SpeexSubmode * nb_submode5 (void)
+{
+  return speex_submode_new (
+   -1,
+   0,
+   3,
+   0,
+   /*LSP quantization*/
+   lsp_quant_nb,
+   lsp_unquant_nb,
+   /*Pitch quantization*/
+   pitch_search_3tap,
+   pitch_unquant_3tap,
+   ltp_params_nb(),
+   /*Innovation quantization*/
+   split_cb_search_shape_sign,
+   split_cb_shape_sign_unquant,
+   split_cb_nb(),
+#ifdef FIXED_POINT
+   22938, 21299, 3932, 8192,
+#else
+   0.7, 0.65, .12, .25,
+#endif
+   300
+   );
+}
+
+/* 18.2 high bit-rate mode */
+static const SpeexSubmode * nb_submode6 (void)
+{
+  return speex_submode_new (
+   -1,
+   0,
+   3,
+   0,
+   /*LSP quantization*/
+   lsp_quant_nb,
+   lsp_unquant_nb,
+   /*Pitch quantization*/
+   pitch_search_3tap,
+   pitch_unquant_3tap,
+   ltp_params_nb(),
+   /*Innovation quantization*/
+   split_cb_search_shape_sign,
+   split_cb_shape_sign_unquant,
+   split_cb_sb(),
+#ifdef FIXED_POINT
+   22282, 21299, 2294, 3277,
+#else
+   0.68, 0.65, .07, .1,
+#endif
+   364
+   );
+}
+
+/* 24.6 kbps high bit-rate mode */
+static const SpeexSubmode * nb_submode7 (void)
+{
+  return speex_submode_new (
+   -1,
+   0,
+   3,
+   1,
+   /*LSP quantization*/
+   lsp_quant_nb,
+   lsp_unquant_nb,
+   /*Pitch quantization*/
+   pitch_search_3tap,
+   pitch_unquant_3tap,
+   ltp_params_nb(),
+   /*Innovation quantization*/
+   split_cb_search_shape_sign,
+   split_cb_shape_sign_unquant,
+   split_cb_nb(),
+#ifdef FIXED_POINT
+   21299, 21299, 0, -1,
+#else
+   0.65, 0.65, .0, -1,
+#endif
+   492
+   );
+}
+
+
+/* Default mode for narrowband */
+static const SpeexNBMode * nb_mode (void)
+{
+  const SpeexSubmode ** submodes;
+  int quality_map[11] = {1, 8, 2, 3, 3, 4, 4, 5, 5, 6, 7};
+  const SpeexNBMode * ret;
+
+  submodes = (const SpeexSubmode **)
+    speex_alloc (sizeof (SpeexSubmode *) * SB_SUBMODES);
+  if (submodes == NULL) return NULL;
+  memset (submodes, 0, sizeof (submodes));
+
+  if (!(submodes[1] = nb_submode1())) goto nb_1;
+  if (!(submodes[2] = nb_submode2())) goto nb_2;
+  if (!(submodes[3] = nb_submode3())) goto nb_3;
+  if (!(submodes[4] = nb_submode4())) goto nb_4;
+  if (!(submodes[5] = nb_submode5())) goto nb_5;
+  if (!(submodes[6] = nb_submode6())) goto nb_6;
+  if (!(submodes[7] = nb_submode7())) goto nb_7;
+  if (!(submodes[8] = nb_submode8())) goto nb_8;
+
+  ret = nb_mode_new (
+   160,    /*frameSize*/
+   40,     /*subframeSize*/
+   10,     /*lpcSize*/
+   640,    /*bufSize*/
+   17,     /*pitchStart*/
+   144,    /*pitchEnd*/
+#ifdef FIXED_POINT
+   29491, 19661, /* gamma1, gamma2 */
+#else
+   0.9, 0.6, /* gamma1, gamma2 */
+#endif
+   .012,   /*lag_factor*/
+   1.0002, /*lpc_floor*/
+#ifdef EPIC_48K
+   0,
+#endif
+   submodes,
+   5,
+   quality_map
+   );
+
+  if (ret == NULL) goto nb_8;
+  /* If nb_mode_new() was successful, the references to submodes have been
+   * copied into ret->submodes[], and it's safe to free submodes.
+   */
+  speex_free ((void *)submodes);
+
+  return ret;
+
+  /* Cleanup on memory allocation errors */
+ nb_8: speex_submode_free (submodes[8]);
+ nb_7: speex_submode_free (submodes[7]);
+ nb_6: speex_submode_free (submodes[6]);
+ nb_5: speex_submode_free (submodes[5]);
+ nb_4: speex_submode_free (submodes[4]);
+ nb_3: speex_submode_free (submodes[3]);
+ nb_2: speex_submode_free (submodes[2]);
+ nb_1: speex_submode_free (submodes[1]);
+
+  speex_free ((void *)submodes);
+
+  return NULL;
+}
+
+
+/* Default mode for narrowband */
+static const SpeexMode * speex_nb_mode_new (void)
+{
+  const SpeexNBMode * _nb_mode;
+
+  _nb_mode = nb_mode();
+  if (_nb_mode == NULL) return NULL;
+
+  return mode_new (
+   _nb_mode,
+   nb_mode_query,
+   "narrowband",
+   0,
+   4,
+   &nb_encoder_init,
+   &nb_encoder_destroy,
+   &nb_encode,
+   &nb_decoder_init,
+   &nb_decoder_destroy,
+   &nb_decode,
+   &nb_encoder_ctl,
+   &nb_decoder_ctl
+   );
+}
+
+static void speex_nb_mode_free (const SpeexMode * mode)
+{
+  nb_mode_free ((SpeexNBMode *)mode->mode);
+  speex_free ((void *)mode);
+}
+
+/* Wideband part */
+
+static const SpeexSubmode * wb_submode1 (void)
+{
+  return speex_submode_new (
+   0,
+   0,
+   1,
+   0,
+   /*LSP quantization*/
+   lsp_quant_high,
+   lsp_unquant_high,
+   /*Pitch quantization*/
+   NULL,
+   NULL,
+   NULL,
+   /*No innovation quantization*/
+   NULL,
+   NULL,
+   NULL,
+#ifdef FIXED_POINT
+   24576, 24576, 0, -1,
+#else
+   .75, .75, .0, -1,
+#endif
+   36
+   );
+}
+
+
+static const SpeexSubmode * wb_submode2 (void)
+{
+  return speex_submode_new (
+   0,
+   0,
+   1,
+   0,
+   /*LSP quantization*/
+   lsp_quant_high,
+   lsp_unquant_high,
+   /*Pitch quantization*/
+   NULL,
+   NULL,
+   NULL,
+   /*Innovation quantization*/
+   split_cb_search_shape_sign,
+   split_cb_shape_sign_unquant,
+   split_cb_high_lbr(),
+#ifdef FIXED_POINT
+   27853, 19661, 8192, -1,
+#else
+   .85, .6, .25, -1,
+#endif
+   112
+   );
+}
+
+
+static const SpeexSubmode * wb_submode3 (void)
+{
+  return speex_submode_new (
+   0,
+   0,
+   1,
+   0,
+   /*LSP quantization*/
+   lsp_quant_high,
+   lsp_unquant_high,
+   /*Pitch quantization*/
+   NULL,
+   NULL,
+   NULL,
+   /*Innovation quantization*/
+   split_cb_search_shape_sign,
+   split_cb_shape_sign_unquant,
+   split_cb_high(),
+
+#ifdef FIXED_POINT
+   24576, 22938, 1638, -1,
+#else
+   .75, .7, .05, -1,
+#endif
+   192
+   );
+}
+
+static const SpeexSubmode * wb_submode4 (void)
+{
+  return speex_submode_new (
+   0,
+   0,
+   1,
+   1,
+   /*LSP quantization*/
+   lsp_quant_high,
+   lsp_unquant_high,
+   /*Pitch quantization*/
+   NULL,
+   NULL,
+   NULL,
+   /*Innovation quantization*/
+   split_cb_search_shape_sign,
+   split_cb_shape_sign_unquant,
+   split_cb_high(),
+#ifdef FIXED_POINT
+   24576, 24576, 0, -1,
+#else
+   .75, .75, .0, -1,
+#endif
+   352
+   );
+}
+
+
+/* Split-band wideband CELP mode*/
+static const SpeexSBMode * sb_wb_mode (void)
+{
+  const SpeexMode * nb_mode;
+  const SpeexSubmode ** submodes;
+  int low_quality_map[11] = {1, 8, 2, 3, 4, 5, 5, 6, 6, 7, 7};
+  int quality_map[11] = {1, 1, 1, 1, 1, 1, 2, 2, 3, 3, 4};
+  SpeexSBMode * ret;
+
+  nb_mode = speex_nb_mode_new ();
+  if (nb_mode == NULL) return NULL;
+
+  submodes = (const SpeexSubmode **)
+    speex_alloc (sizeof (SpeexSubmode *) * SB_SUBMODES);
+  if (submodes == NULL) return NULL;
+  memset (submodes, 0, sizeof (submodes));
+
+  if (!(submodes[1] = wb_submode1())) goto sb_1;
+  if (!(submodes[2] = wb_submode2())) goto sb_2;
+  if (!(submodes[3] = wb_submode3())) goto sb_3;
+  if (!(submodes[4] = wb_submode4())) goto sb_4;
+
+  ret = sb_mode_new (
+   nb_mode,
+   160,    /*frameSize*/
+   40,     /*subframeSize*/
+   8,     /*lpcSize*/
+   640,    /*bufSize*/
+#ifdef FIXED_POINT
+   29491, 19661, /* gamma1, gamma2 */
+#else
+   0.9, 0.6, /* gamma1, gamma2 */
+#endif
+   .001,   /*lag_factor*/
+   1.0001, /*lpc_floor*/
+   0.9,
+   submodes,
+   3,
+   low_quality_map,
+   quality_map,
+   vbr_hb_thresh,
+   5
+   );
+
+  if (ret == NULL) goto sb_4;
+
+  /* If sb_mode_new() was successful, the references to submodes have been
+   * copied into ret->submodes[], and it's safe to free submodes.
+   */
+  speex_free ((void *)submodes);
+
+  return ret;
+
+  /* Cleanup on memory allocation errors */
+ sb_4: speex_submode_free (submodes[4]);
+ sb_3: speex_submode_free (submodes[3]);
+ sb_2: speex_submode_free (submodes[2]);
+ sb_1: speex_submode_free (submodes[1]);
+
+  speex_free ((void *)submodes);
+
+  return NULL;
+}
+
+static void
+sb_wb_mode_free (const SpeexSBMode * mode)
+{
+  speex_nb_mode_free (mode->nb_mode);
+}
+
+static const SpeexMode * speex_wb_mode_new (void)
+{
+  const SpeexSBMode * sb_mode;
+
+  sb_mode = sb_wb_mode ();
+  if (sb_mode == NULL) return NULL;
+
+  return mode_new (
+   (const SpeexNBMode *)sb_mode,
+   wb_mode_query,
+   "wideband (sub-band CELP)",
+   1,
+   4,
+   &sb_encoder_init,
+   &sb_encoder_destroy,
+   &sb_encode,
+   &sb_decoder_init,
+   &sb_decoder_destroy,
+   &sb_decode,
+   &sb_encoder_ctl,
+   &sb_decoder_ctl
+   );
+}
+
+static void speex_wb_mode_free (const SpeexMode * mode)
+{
+  sb_wb_mode_free (mode->mode);
+  speex_free ((void *)mode);
+}
+
+
+/* "Ultra-wideband" mode stuff */
+
+
+
+/* Split-band "ultra-wideband" (32 kbps) CELP mode*/
+static const SpeexSBMode * sb_uwb_mode (void)
+{
+  const SpeexSBMode * nb_mode;
+  const SpeexSubmode ** submodes;
+  int low_quality_map[11] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+  int quality_map[11] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
+  SpeexSBMode * ret;
+
+  nb_mode = sb_wb_mode ();
+  if (nb_mode == NULL) return NULL;
+
+  submodes = (const SpeexSubmode **)
+    speex_alloc (sizeof (SpeexSubmode *) * SB_SUBMODES);
+  if (submodes == NULL) return NULL;
+  memset (submodes, 0, sizeof (submodes));
+
+  if (!(submodes[1] = wb_submode1())) goto uwb_1;
+
+  ret = sb_mode_new (
+   (const SpeexMode *)nb_mode,
+   320,    /*frameSize*/
+   80,     /*subframeSize*/
+   8,     /*lpcSize*/
+   1280,    /*bufSize*/
+#ifdef FIXED_POINT
+   29491, 19661, /* gamma1, gamma2 */
+#else
+   0.9, 0.6, /* gamma1, gamma2 */
+#endif
+   .002,   /*lag_factor*/
+   1.0001, /*lpc_floor*/
+   0.7,
+   submodes,
+   1,
+   low_quality_map,
+   quality_map,
+   vbr_uhb_thresh,
+   2
+   );
+
+  if (ret == NULL) goto uwb_1;
+
+  /* If sb_mode_new() was successful, the references to submodes have been
+   * copied into ret->submodes[], and it's safe to free submodes.
+   */
+  speex_free ((void *)submodes);
+
+  return ret;
+
+ uwb_1: speex_submode_free (submodes[1]);
+
+  speex_free ((void *)submodes);
+
+  return NULL;
+}
+
+static void sb_uwb_mode_free (const SpeexSBMode * mode)
+{
+  sb_wb_mode_free ((const SpeexSBMode *)mode->nb_mode);
+  sb_mode_free (mode);
+}
+
+static const SpeexMode * speex_uwb_mode_new (void)
+{
+  const SpeexSBMode * sb_mode;
+
+  sb_mode = sb_uwb_mode();
+  if (sb_mode == NULL) return NULL;
+
+  return mode_new (
+   sb_mode,
+   wb_mode_query,
+   "ultra-wideband (sub-band CELP)",
+   2,
+   4,
+   &sb_encoder_init,
+   &sb_encoder_destroy,
+   &sb_encode,
+   &sb_decoder_init,
+   &sb_decoder_destroy,
+   &sb_decode,
+   &sb_encoder_ctl,
+   &sb_decoder_ctl
+   );
+}
+
+static void speex_uwb_mode_free (const SpeexMode * mode)
+{
+  sb_uwb_mode_free (mode->mode);
+  speex_free ((void *)mode);
+}
+
+const SpeexMode * speex_mode_new (int modeID)
+{
+  switch (modeID) {
+  case 0: return speex_nb_mode_new(); break;
+  case 1: return speex_wb_mode_new(); break;
+  case 2: return speex_uwb_mode_new(); break;
+  default: return NULL;
+  }
+}
+
+void speex_mode_destroy (const SpeexMode * mode)
+{
+  switch (mode->modeID) {
+  case 0: speex_nb_mode_free(mode); break;
+  case 1: speex_wb_mode_free(mode); break;
+  case 2:  speex_uwb_mode_free(mode); break;
+  default: break;
+  }
+}
+
+/** XXX: This is just a dummy global mode, as used by nb_celp.c */
+const SpeexMode speex_wb_mode = {
+   NULL,
+   NULL,
+   NULL,
+   0,
+   0,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL,
+   NULL
+};
+
+int speex_mode_query(const SpeexMode *mode, int request, void *ptr)
+{
+  if (mode == &speex_wb_mode && request == SPEEX_SUBMODE_BITS_PER_FRAME) {
+    int * p = (int*)ptr;
+
+    switch (*p) {
+    case 0: *p = SB_SUBMODE_BITS+1; break;
+    case 1: *p = 36; break;
+    case 2: *p = 112; break;
+    case 3: *p = 192; break;
+    case 4: *p = 352; break;
+    default: *p = -1; break;
+    }
+
+    return 0;
+  }
+  
+  return mode->query(mode->mode, request, ptr);
+}
diff --git a/utils/iaxclient/lib/libspeex/nb_celp.c b/utils/iaxclient/lib/libspeex/nb_celp.c
new file mode 100644 (file)
index 0000000..5298a65
--- /dev/null
@@ -0,0 +1,1940 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: nb_celp.c
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <math.h>
+#include "nb_celp.h"
+#include "lpc.h"
+#include "lsp.h"
+#include "ltp.h"
+#include "quant_lsp.h"
+#include "cb_search.h"
+#include "filters.h"
+#include "stack_alloc.h"
+#include "vq.h"
+#include <speex/speex_bits.h>
+#include "vbr.h"
+#include "misc.h"
+#include <speex/speex_callbacks.h>
+
+#ifndef M_PI
+#define M_PI           3.14159265358979323846  /* pi */
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define SUBMODE(x) st->submodes[st->submodeID]->x
+
+
+#ifdef FIXED_POINT
+const spx_word32_t ol_gain_table[32]={18900, 25150, 33468, 44536, 59265, 78865, 104946, 139653, 185838, 247297, 329081, 437913, 582736, 775454, 1031906, 1373169, 1827293, 2431601, 3235761, 4305867, 5729870, 7624808, 10146425, 13501971, 17967238, 23909222, 31816294, 42338330, 56340132, 74972501, 99766822, 132760927};
+const spx_word16_t exc_gain_quant_scal3_bound[7]={1841, 3883, 6051, 8062, 10444, 13580, 18560};
+const spx_word16_t exc_gain_quant_scal3[8]={1002, 2680, 5086, 7016, 9108, 11781, 15380, 21740};
+const spx_word16_t exc_gain_quant_scal1_bound[1]={14385};
+const spx_word16_t exc_gain_quant_scal1[2]={11546, 17224};
+
+#define LSP_MARGIN 16
+#define LSP_DELTA1 6553
+#define LSP_DELTA2 1638
+
+#else
+
+const float exc_gain_quant_scal3_bound[7]={0.112338, 0.236980, 0.369316, 0.492054, 0.637471, 0.828874, 1.132784};
+const float exc_gain_quant_scal3[8]={0.061130, 0.163546, 0.310413, 0.428220, 0.555887, 0.719055, 0.938694, 1.326874};
+const float exc_gain_quant_scal1_bound[1]={0.87798};
+const float exc_gain_quant_scal1[2]={0.70469, 1.05127};
+
+#define LSP_MARGIN .002
+#define LSP_DELTA1 .2
+#define LSP_DELTA2 .05
+
+#endif
+
+
+
+
+#define sqr(x) ((x)*(x))
+
+void *nb_encoder_init(const SpeexMode *m)
+{
+   EncState *st;
+   const SpeexNBMode *mode;
+   int i;
+
+   mode=(const SpeexNBMode *)m->mode;
+#if defined(VAR_ARRAYS) || defined (USE_ALLOCA)
+   st = (EncState*)speex_alloc(sizeof(EncState));
+   st->stack = NULL;
+#else
+   st = (EncState*)speex_alloc(sizeof(EncState)+8000*sizeof(spx_sig_t));
+   st->stack = ((char*)st) + sizeof(EncState);
+#endif
+   if (!st)
+      return NULL;
+   
+   st->mode=m;
+
+   st->frameSize = mode->frameSize;
+   st->windowSize = st->frameSize*3/2;
+   st->nbSubframes=mode->frameSize/mode->subframeSize;
+   st->subframeSize=mode->subframeSize;
+   st->lpcSize = mode->lpcSize;
+   st->gamma1=mode->gamma1;
+   st->gamma2=mode->gamma2;
+   st->min_pitch=mode->pitchStart;
+   st->max_pitch=mode->pitchEnd;
+   st->lag_factor=mode->lag_factor;
+   st->lpc_floor = mode->lpc_floor;
+  
+   st->submodes=mode->submodes;
+   st->submodeID=st->submodeSelect=mode->defaultSubmode;
+   st->bounded_pitch = 1;
+
+   st->encode_submode = 1;
+#ifdef EPIC_48K
+   st->lbr_48k=mode->lbr48k;
+#endif
+
+   /* Allocating input buffer */
+   st->inBuf = speex_alloc((st->windowSize)*sizeof(spx_sig_t));
+   st->frame = st->inBuf;
+   /* Allocating excitation buffer */
+   st->excBuf = speex_alloc((mode->frameSize+mode->pitchEnd+1)*sizeof(spx_sig_t));
+   st->exc = st->excBuf + mode->pitchEnd + 1;
+   st->swBuf = speex_alloc((mode->frameSize+mode->pitchEnd+1)*sizeof(spx_sig_t));
+   st->sw = st->swBuf + mode->pitchEnd + 1;
+
+   st->innov = speex_alloc((st->frameSize)*sizeof(spx_sig_t));
+
+   /* Asymmetric "pseudo-Hamming" window */
+   {
+      int part1, part2;
+      part1=st->frameSize - (st->subframeSize>>1);
+      part2=(st->frameSize>>1) + (st->subframeSize>>1);
+      st->window = speex_alloc((st->windowSize)*sizeof(spx_word16_t));
+      for (i=0;i<part1;i++)
+         st->window[i]=(spx_word16_t)(SIG_SCALING*(.54-.46*cos(M_PI*i/part1)));
+      for (i=0;i<part2;i++)
+         st->window[part1+i]=(spx_word16_t)(SIG_SCALING*(.54+.46*cos(M_PI*i/part2)));
+   }
+   /* Create the window for autocorrelation (lag-windowing) */
+   st->lagWindow = speex_alloc((st->lpcSize+1)*sizeof(spx_word16_t));
+   for (i=0;i<st->lpcSize+1;i++)
+      st->lagWindow[i]=16384*exp(-.5*sqr(2*M_PI*st->lag_factor*i));
+
+   st->autocorr = speex_alloc((st->lpcSize+1)*sizeof(spx_word16_t));
+
+   st->lpc = speex_alloc((st->lpcSize+1)*sizeof(spx_coef_t));
+   st->interp_lpc = speex_alloc((st->lpcSize+1)*sizeof(spx_coef_t));
+   st->interp_qlpc = speex_alloc((st->lpcSize+1)*sizeof(spx_coef_t));
+   st->bw_lpc1 = speex_alloc((st->lpcSize+1)*sizeof(spx_coef_t));
+   st->bw_lpc2 = speex_alloc((st->lpcSize+1)*sizeof(spx_coef_t));
+
+   st->lsp = speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
+   st->qlsp = speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
+   st->old_lsp = speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
+   st->old_qlsp = speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
+   st->interp_lsp = speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
+   st->interp_qlsp = speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
+
+   st->first = 1;
+   for (i=0;i<st->lpcSize;i++)
+   {
+      st->lsp[i]=LSP_SCALING*(M_PI*((float)(i+1)))/(st->lpcSize+1);
+   }
+
+   st->mem_sp = speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
+   st->mem_sw = speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
+   st->mem_sw_whole = speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
+   st->mem_exc = speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
+
+   st->pi_gain = speex_alloc((st->nbSubframes)*sizeof(spx_word32_t));
+
+   st->pitch = speex_alloc((st->nbSubframes)*sizeof(int));
+
+   st->vbr = speex_alloc(sizeof(VBRState));
+   vbr_init(st->vbr);
+   st->vbr_quality = 8;
+   st->vbr_enabled = 0;
+   st->vad_enabled = 0;
+   st->dtx_enabled = 0;
+   st->abr_enabled = 0;
+   st->abr_drift = 0;
+
+   st->plc_tuning = 2;
+   st->complexity=2;
+   st->sampling_rate=8000;
+   st->dtx_count=0;
+
+#ifdef ENABLE_VALGRIND
+   VALGRIND_MAKE_READABLE(st, (st->stack-(char*)st));
+#endif
+   return st;
+}
+
+void nb_encoder_destroy(void *state)
+{
+   EncState *st=(EncState *)state;
+   /* Free all allocated memory */
+
+   vbr_destroy(st->vbr);
+
+   /*Free state memory... should be last*/
+   speex_free(st);
+}
+
+int nb_encode(void *state, void *vin, SpeexBits *bits)
+{
+   EncState *st;
+   int i, sub, roots;
+   int ol_pitch;
+   spx_word16_t ol_pitch_coef;
+   spx_word32_t ol_gain;
+   VARDECL(spx_sig_t *res);
+   VARDECL(spx_sig_t *target);
+   VARDECL(spx_mem_t *mem);
+   char *stack;
+   VARDECL(spx_word16_t *syn_resp);
+   VARDECL(spx_sig_t *real_exc);
+#ifdef EPIC_48K
+   int pitch_half[2];
+   int ol_pitch_id=0;
+#endif
+   spx_word16_t *in = vin;
+
+   st=(EncState *)state;
+   stack=st->stack;
+
+   /* Copy new data in input buffer */
+   speex_move(st->inBuf, st->inBuf+st->frameSize, (st->windowSize-st->frameSize)*sizeof(spx_sig_t));
+   for (i=0;i<st->frameSize;i++)
+      st->inBuf[st->windowSize-st->frameSize+i] = SHL32(EXTEND32(in[i]), SIG_SHIFT);
+
+   /* Move signals 1 frame towards the past */
+   speex_move(st->excBuf, st->excBuf+st->frameSize, (st->max_pitch+1)*sizeof(spx_sig_t));
+   speex_move(st->swBuf, st->swBuf+st->frameSize, (st->max_pitch+1)*sizeof(spx_sig_t));
+
+   {
+      VARDECL(spx_word16_t *w_sig);
+      ALLOC(w_sig, st->windowSize, spx_word16_t);
+      /* Window for analysis */
+      for (i=0;i<st->windowSize;i++)
+         w_sig[i] = EXTRACT16(SHR32(MULT16_16(EXTRACT16(SHR32(st->frame[i],SIG_SHIFT)),st->window[i]),SIG_SHIFT));
+
+      /* Compute auto-correlation */
+      _spx_autocorr(w_sig, st->autocorr, st->lpcSize+1, st->windowSize);
+   }
+   st->autocorr[0] = (spx_word16_t) (st->autocorr[0]*st->lpc_floor); /* Noise floor in auto-correlation domain */
+
+   /* Lag windowing: equivalent to filtering in the power-spectrum domain */
+   for (i=0;i<st->lpcSize+1;i++)
+      st->autocorr[i] = MULT16_16_Q14(st->autocorr[i],st->lagWindow[i]);
+
+   /* Levinson-Durbin */
+   _spx_lpc(st->lpc+1, st->autocorr, st->lpcSize);
+   st->lpc[0]=(spx_coef_t)LPC_SCALING;
+
+   /* LPC to LSPs (x-domain) transform */
+   roots=lpc_to_lsp (st->lpc, st->lpcSize, st->lsp, 15, LSP_DELTA1, stack);
+   /* Check if we found all the roots */
+   if (roots!=st->lpcSize)
+   {
+      /* Search again if we can afford it */
+      if (st->complexity>1)
+         roots = lpc_to_lsp (st->lpc, st->lpcSize, st->lsp, 11, LSP_DELTA2, stack);
+      if (roots!=st->lpcSize) 
+      {
+         /*If we can't find all LSP's, do some damage control and use previous filter*/
+         for (i=0;i<st->lpcSize;i++)
+         {
+            st->lsp[i]=st->old_lsp[i];
+         }
+      }
+   }
+
+
+
+   /* Whole frame analysis (open-loop estimation of pitch and excitation gain) */
+   {
+      if (st->first)
+         for (i=0;i<st->lpcSize;i++)
+            st->interp_lsp[i] = st->lsp[i];
+      else
+         lsp_interpolate(st->old_lsp, st->lsp, st->interp_lsp, st->lpcSize, st->nbSubframes, st->nbSubframes<<1);
+
+      lsp_enforce_margin(st->interp_lsp, st->lpcSize, LSP_MARGIN);
+
+      /* Compute interpolated LPCs (unquantized) for whole frame*/
+      lsp_to_lpc(st->interp_lsp, st->interp_lpc, st->lpcSize,stack);
+
+
+      /*Open-loop pitch*/
+      if (!st->submodes[st->submodeID] || st->vbr_enabled || st->vad_enabled || SUBMODE(forced_pitch_gain) ||
+          SUBMODE(lbr_pitch) != -1)
+      {
+         int nol_pitch[6];
+         spx_word16_t nol_pitch_coef[6];
+         
+         bw_lpc(st->gamma1, st->interp_lpc, st->bw_lpc1, st->lpcSize);
+         bw_lpc(st->gamma2, st->interp_lpc, st->bw_lpc2, st->lpcSize);
+         
+         filter_mem2(st->frame, st->bw_lpc1, st->bw_lpc2, st->sw, st->frameSize, st->lpcSize, st->mem_sw_whole);
+
+         open_loop_nbest_pitch(st->sw, st->min_pitch, st->max_pitch, st->frameSize, 
+                               nol_pitch, nol_pitch_coef, 6, stack);
+         ol_pitch=nol_pitch[0];
+         ol_pitch_coef = nol_pitch_coef[0];
+         /*Try to remove pitch multiples*/
+         for (i=1;i<6;i++)
+         {
+#ifdef FIXED_POINT
+            if ((nol_pitch_coef[i]>MULT16_16_Q15(nol_pitch_coef[0],27853)) && 
+#else
+            if ((nol_pitch_coef[i]>.85*nol_pitch_coef[0]) && 
+#endif
+                (ABS(2*nol_pitch[i]-ol_pitch)<=2 || ABS(3*nol_pitch[i]-ol_pitch)<=3 || 
+                 ABS(4*nol_pitch[i]-ol_pitch)<=4 || ABS(5*nol_pitch[i]-ol_pitch)<=5))
+            {
+               /*ol_pitch_coef=nol_pitch_coef[i];*/
+               ol_pitch = nol_pitch[i];
+            }
+         }
+         /*if (ol_pitch>50)
+           ol_pitch/=2;*/
+         /*ol_pitch_coef = sqrt(ol_pitch_coef);*/
+
+#ifdef EPIC_48K
+         if (st->lbr_48k)
+         {
+            if (ol_pitch < st->min_pitch+2)
+               ol_pitch = st->min_pitch+2;
+            if (ol_pitch > st->max_pitch-2)
+               ol_pitch = st->max_pitch-2;
+            open_loop_nbest_pitch(st->sw, ol_pitch-2, ol_pitch+2, st->frameSize>>1, 
+                                  &pitch_half[0], nol_pitch_coef, 1, stack);
+            open_loop_nbest_pitch(st->sw+(st->frameSize>>1), pitch_half[0]-1, pitch_half[0]+2, st->frameSize>>1, 
+                                  &pitch_half[1], nol_pitch_coef, 1, stack);
+         }
+#endif
+      } else {
+         ol_pitch=0;
+         ol_pitch_coef=0;
+      }
+      /*Compute "real" excitation*/
+      fir_mem2(st->frame, st->interp_lpc, st->exc, st->frameSize, st->lpcSize, st->mem_exc);
+
+      /* Compute open-loop excitation gain */
+#ifdef EPIC_48K
+      if (st->lbr_48k)
+      {
+         float ol1=0,ol2=0;
+         float ol_gain2;
+         ol1 = compute_rms(st->exc, st->frameSize>>1);
+         ol2 = compute_rms(st->exc+(st->frameSize>>1), st->frameSize>>1);
+         ol1 *= ol1*(st->frameSize>>1);
+         ol2 *= ol2*(st->frameSize>>1);
+
+         ol_gain2=ol1;
+         if (ol2>ol1)
+            ol_gain2=ol2;
+         ol_gain2 = sqrt(2*ol_gain2*(ol1+ol2))*1.3*(1-.5*GAIN_SCALING_1*GAIN_SCALING_1*ol_pitch_coef*ol_pitch_coef);
+      
+         ol_gain=SHR(sqrt(1+ol_gain2/st->frameSize),SIG_SHIFT);
+
+      } else {
+#endif
+         ol_gain = SHL32(EXTEND32(compute_rms(st->exc, st->frameSize)),SIG_SHIFT);
+#ifdef EPIC_48K
+      }
+#endif
+   }
+
+   /*VBR stuff*/
+   if (st->vbr && (st->vbr_enabled||st->vad_enabled))
+   {
+      float lsp_dist=0;
+      for (i=0;i<st->lpcSize;i++)
+         lsp_dist += (st->old_lsp[i] - st->lsp[i])*(st->old_lsp[i] - st->lsp[i]);
+      lsp_dist /= LSP_SCALING*LSP_SCALING;
+      
+      if (st->abr_enabled)
+      {
+         float qual_change=0;
+         if (st->abr_drift2 * st->abr_drift > 0)
+         {
+            /* Only adapt if long-term and short-term drift are the same sign */
+            qual_change = -.00001*st->abr_drift/(1+st->abr_count);
+            if (qual_change>.05)
+               qual_change=.05;
+            if (qual_change<-.05)
+               qual_change=-.05;
+         }
+         st->vbr_quality += qual_change;
+         if (st->vbr_quality>10)
+            st->vbr_quality=10;
+         if (st->vbr_quality<0)
+            st->vbr_quality=0;
+      }
+
+      st->relative_quality = vbr_analysis(st->vbr, in, st->frameSize, ol_pitch, GAIN_SCALING_1*ol_pitch_coef);
+      /*if (delta_qual<0)*/
+      /*  delta_qual*=.1*(3+st->vbr_quality);*/
+      if (st->vbr_enabled) 
+      {
+         int mode;
+         int choice=0;
+         float min_diff=100;
+         mode = 8;
+         while (mode)
+         {
+            int v1;
+            float thresh;
+            v1=(int)floor(st->vbr_quality);
+            if (v1==10)
+               thresh = vbr_nb_thresh[mode][v1];
+            else
+               thresh = (st->vbr_quality-v1)*vbr_nb_thresh[mode][v1+1] + (1+v1-st->vbr_quality)*vbr_nb_thresh[mode][v1];
+            if (st->relative_quality > thresh && 
+                st->relative_quality-thresh<min_diff)
+            {
+               choice = mode;
+               min_diff = st->relative_quality-thresh;
+            }
+            mode--;
+         }
+         mode=choice;
+         if (mode==0)
+         {
+            if (st->dtx_count==0 || lsp_dist>.05 || !st->dtx_enabled || st->dtx_count>20)
+            {
+               mode=1;
+               st->dtx_count=1;
+            } else {
+               mode=0;
+               st->dtx_count++;
+            }
+         } else {
+            st->dtx_count=0;
+         }
+
+         speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);
+
+         if (st->abr_enabled)
+         {
+            int bitrate;
+            speex_encoder_ctl(state, SPEEX_GET_BITRATE, &bitrate);
+            st->abr_drift+=(bitrate-st->abr_enabled);
+            st->abr_drift2 = .95*st->abr_drift2 + .05*(bitrate-st->abr_enabled);
+            st->abr_count += 1.0;
+         }
+
+      } else {
+         /*VAD only case*/
+         int mode;
+         if (st->relative_quality<2)
+         {
+            if (st->dtx_count==0 || lsp_dist>.05 || !st->dtx_enabled || st->dtx_count>20)
+            {
+               st->dtx_count=1;
+               mode=1;
+            } else {
+               mode=0;
+               st->dtx_count++;
+            }
+         } else {
+            st->dtx_count = 0;
+            mode=st->submodeSelect;
+         }
+         /*speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);*/
+         st->submodeID=mode;
+      } 
+   } else {
+      st->relative_quality = -1;
+   }
+
+   if (st->encode_submode)
+   {
+#ifdef EPIC_48K
+   if (!st->lbr_48k) {
+#endif
+
+   /* First, transmit a zero for narrowband */
+   speex_bits_pack(bits, 0, 1);
+
+   /* Transmit the sub-mode we use for this frame */
+   speex_bits_pack(bits, st->submodeID, NB_SUBMODE_BITS);
+
+#ifdef EPIC_48K
+   }
+#endif
+   }
+
+   /* If null mode (no transmission), just set a couple things to zero*/
+   if (st->submodes[st->submodeID] == NULL)
+   {
+      for (i=0;i<st->frameSize;i++)
+         st->exc[i]=st->sw[i]=VERY_SMALL;
+
+      for (i=0;i<st->lpcSize;i++)
+         st->mem_sw[i]=0;
+      st->first=1;
+      st->bounded_pitch = 1;
+
+      /* Final signal synthesis from excitation */
+      iir_mem2(st->exc, st->interp_qlpc, st->frame, st->frameSize, st->lpcSize, st->mem_sp);
+
+#ifdef RESYNTH
+      for (i=0;i<st->frameSize;i++)
+         in[i]=st->frame[i];
+#endif
+      return 0;
+
+   }
+
+   /* LSP Quantization */
+   if (st->first)
+   {
+      for (i=0;i<st->lpcSize;i++)
+         st->old_lsp[i] = st->lsp[i];
+   }
+
+
+   /*Quantize LSPs*/
+#if 1 /*0 for unquantized*/
+   SUBMODE(lsp_quant)(st->lsp, st->qlsp, st->lpcSize, bits);
+#else
+   for (i=0;i<st->lpcSize;i++)
+     st->qlsp[i]=st->lsp[i];
+#endif
+
+#ifdef EPIC_48K
+   if (st->lbr_48k) {
+      speex_bits_pack(bits, pitch_half[0]-st->min_pitch, 7);
+      speex_bits_pack(bits, pitch_half[1]-pitch_half[0]+1, 2);
+      
+      {
+         int quant = (int)floor(.5+7.4*GAIN_SCALING_1*ol_pitch_coef);
+         if (quant>7)
+            quant=7;
+         if (quant<0)
+            quant=0;
+         ol_pitch_id=quant;
+         speex_bits_pack(bits, quant, 3);
+         ol_pitch_coef=GAIN_SCALING*0.13514*quant;
+         
+      }
+      {
+         int qe = (int)(floor(.5+2.1*log(ol_gain*1.0/SIG_SCALING)))-2;
+         if (qe<0)
+            qe=0;
+         if (qe>15)
+            qe=15;
+         ol_gain = exp((qe+2)/2.1)*SIG_SCALING;
+         speex_bits_pack(bits, qe, 4);
+      }
+
+   } else {
+#endif
+
+   /*If we use low bit-rate pitch mode, transmit open-loop pitch*/
+   if (SUBMODE(lbr_pitch)!=-1)
+   {
+      speex_bits_pack(bits, ol_pitch-st->min_pitch, 7);
+   } 
+
+   if (SUBMODE(forced_pitch_gain))
+   {
+      int quant;
+      quant = (int)floor(.5+15*ol_pitch_coef*GAIN_SCALING_1);
+      if (quant>15)
+         quant=15;
+      if (quant<0)
+         quant=0;
+      speex_bits_pack(bits, quant, 4);
+      ol_pitch_coef=GAIN_SCALING*0.066667*quant;
+   }
+   
+   
+   /*Quantize and transmit open-loop excitation gain*/
+#ifdef FIXED_POINT
+   {
+      int qe = scal_quant32(ol_gain, ol_gain_table, 32);
+      /*ol_gain = exp(qe/3.5)*SIG_SCALING;*/
+      ol_gain = MULT16_32_Q15(28406,ol_gain_table[qe]);
+      speex_bits_pack(bits, qe, 5);
+   }
+#else
+   {
+      int qe = (int)(floor(.5+3.5*log(ol_gain*1.0/SIG_SCALING)));
+      if (qe<0)
+         qe=0;
+      if (qe>31)
+         qe=31;
+      ol_gain = exp(qe/3.5)*SIG_SCALING;
+      speex_bits_pack(bits, qe, 5);
+   }
+#endif
+
+
+#ifdef EPIC_48K
+   }
+#endif
+
+
+   /* Special case for first frame */
+   if (st->first)
+   {
+      for (i=0;i<st->lpcSize;i++)
+         st->old_qlsp[i] = st->qlsp[i];
+   }
+
+   /* Filter response */
+   ALLOC(res, st->subframeSize, spx_sig_t);
+   /* Target signal */
+   ALLOC(target, st->subframeSize, spx_sig_t);
+   ALLOC(syn_resp, st->subframeSize, spx_word16_t);
+   ALLOC(real_exc, st->subframeSize, spx_sig_t);
+   ALLOC(mem, st->lpcSize, spx_mem_t);
+
+   /* Loop on sub-frames */
+   for (sub=0;sub<st->nbSubframes;sub++)
+   {
+      int   offset;
+      spx_sig_t *sp, *sw, *exc;
+      int pitch;
+      int response_bound = st->subframeSize;
+#ifdef EPIC_48K
+      if (st->lbr_48k)
+      {
+         if (sub*2 < st->nbSubframes)
+            ol_pitch = pitch_half[0];
+         else
+            ol_pitch = pitch_half[1];
+      }
+#endif
+
+      /* Offset relative to start of frame */
+      offset = st->subframeSize*sub;
+      /* Original signal */
+      sp=st->frame+offset;
+      /* Excitation */
+      exc=st->exc+offset;
+      /* Weighted signal */
+      sw=st->sw+offset;
+
+      /* LSP interpolation (quantized and unquantized) */
+      lsp_interpolate(st->old_lsp, st->lsp, st->interp_lsp, st->lpcSize, sub, st->nbSubframes);
+      lsp_interpolate(st->old_qlsp, st->qlsp, st->interp_qlsp, st->lpcSize, sub, st->nbSubframes);
+
+      /* Make sure the filters are stable */
+      lsp_enforce_margin(st->interp_lsp, st->lpcSize, LSP_MARGIN);
+      lsp_enforce_margin(st->interp_qlsp, st->lpcSize, LSP_MARGIN);
+
+      /* Compute interpolated LPCs (quantized and unquantized) */
+      lsp_to_lpc(st->interp_lsp, st->interp_lpc, st->lpcSize,stack);
+
+      lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack);
+
+      /* Compute analysis filter gain at w=pi (for use in SB-CELP) */
+      {
+         spx_word32_t pi_g=st->interp_qlpc[0];
+         for (i=1;i<=st->lpcSize;i+=2)
+         {
+            /*pi_g += -st->interp_qlpc[i] +  st->interp_qlpc[i+1];*/
+            pi_g = ADD32(pi_g, SUB32(st->interp_qlpc[i+1],st->interp_qlpc[i]));
+         }
+         st->pi_gain[sub] = pi_g;
+      }
+
+
+      /* Compute bandwidth-expanded (unquantized) LPCs for perceptual weighting */
+      bw_lpc(st->gamma1, st->interp_lpc, st->bw_lpc1, st->lpcSize);
+      if (st->gamma2>=0)
+         bw_lpc(st->gamma2, st->interp_lpc, st->bw_lpc2, st->lpcSize);
+      else
+      {
+         st->bw_lpc2[0]=1;
+         for (i=1;i<=st->lpcSize;i++)
+            st->bw_lpc2[i]=0;
+      }
+
+      for (i=0;i<st->subframeSize;i++)
+         real_exc[i] = exc[i];
+      
+      if (st->complexity==0)
+         response_bound >>= 1;
+      compute_impulse_response(st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, syn_resp, response_bound, st->lpcSize, stack);
+      for (i=response_bound;i<st->subframeSize;i++)
+         syn_resp[i]=VERY_SMALL;
+      
+      /* Reset excitation */
+      for (i=0;i<st->subframeSize;i++)
+         exc[i]=VERY_SMALL;
+
+      /* Compute zero response of A(z/g1) / ( A(z/g2) * A(z) ) */
+      for (i=0;i<st->lpcSize;i++)
+         mem[i]=st->mem_sp[i];
+#ifdef SHORTCUTS2
+      iir_mem2(exc, st->interp_qlpc, exc, response_bound, st->lpcSize, mem);
+      for (i=0;i<st->lpcSize;i++)
+         mem[i]=st->mem_sw[i];
+      filter_mem2(exc, st->bw_lpc1, st->bw_lpc2, res, response_bound, st->lpcSize, mem);
+      for (i=response_bound;i<st->subframeSize;i++)
+         res[i]=0;
+#else
+      iir_mem2(exc, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, mem);
+      for (i=0;i<st->lpcSize;i++)
+         mem[i]=st->mem_sw[i];
+      filter_mem2(exc, st->bw_lpc1, st->bw_lpc2, res, st->subframeSize, st->lpcSize, mem);
+#endif
+      
+      /* Compute weighted signal */
+      for (i=0;i<st->lpcSize;i++)
+         mem[i]=st->mem_sw[i];
+      filter_mem2(sp, st->bw_lpc1, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, mem);
+      
+      if (st->complexity==0)
+         for (i=0;i<st->lpcSize;i++)
+            st->mem_sw[i]=mem[i];
+      
+      /* Compute target signal */
+      for (i=0;i<st->subframeSize;i++)
+         target[i]=sw[i]-res[i];
+
+      for (i=0;i<st->subframeSize;i++)
+         exc[i]=0;
+
+      /* If we have a long-term predictor (otherwise, something's wrong) */
+      if (SUBMODE(ltp_quant))
+      {
+         int pit_min, pit_max;
+         /* Long-term prediction */
+         if (SUBMODE(lbr_pitch) != -1)
+         {
+            /* Low bit-rate pitch handling */
+            int margin;
+            margin = SUBMODE(lbr_pitch);
+            if (margin)
+            {
+               if (ol_pitch < st->min_pitch+margin-1)
+                  ol_pitch=st->min_pitch+margin-1;
+               if (ol_pitch > st->max_pitch-margin)
+                  ol_pitch=st->max_pitch-margin;
+               pit_min = ol_pitch-margin+1;
+               pit_max = ol_pitch+margin;
+            } else {
+               pit_min=pit_max=ol_pitch;
+            }
+         } else {
+            pit_min = st->min_pitch;
+            pit_max = st->max_pitch;
+         }
+         
+         /* Force pitch to use only the current frame if needed */
+         if (st->bounded_pitch && pit_max>offset)
+            pit_max=offset;
+
+#ifdef EPIC_48K
+         if (st->lbr_48k)
+         {
+            pitch = SUBMODE(ltp_quant)(target, sw, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2,
+                                       exc, SUBMODE(ltp_params), pit_min, pit_max, ol_pitch_coef,
+                                       st->lpcSize, st->subframeSize, bits, stack, 
+                                       exc, syn_resp, st->complexity, ol_pitch_id, st->plc_tuning);
+         } else {
+#endif
+
+         /* Perform pitch search */
+         pitch = SUBMODE(ltp_quant)(target, sw, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2,
+                                    exc, SUBMODE(ltp_params), pit_min, pit_max, ol_pitch_coef,
+                                    st->lpcSize, st->subframeSize, bits, stack, 
+                                    exc, syn_resp, st->complexity, 0, st->plc_tuning);
+#ifdef EPIC_48K
+         }
+#endif
+
+         st->pitch[sub]=pitch;
+      } else {
+         speex_error ("No pitch prediction, what's wrong");
+      }
+
+      /* Quantization of innovation */
+      {
+         spx_sig_t *innov;
+         spx_word32_t ener=0;
+         spx_word16_t fine_gain;
+
+         innov = st->innov+sub*st->subframeSize;
+         for (i=0;i<st->subframeSize;i++)
+            innov[i]=0;
+         
+         for (i=0;i<st->subframeSize;i++)
+            real_exc[i] = SUB32(real_exc[i], exc[i]);
+
+         ener = SHL32(EXTEND32(compute_rms(real_exc, st->subframeSize)),SIG_SHIFT);
+         
+         /*FIXME: Should use DIV32_16 and make sure result fits in 16 bits */
+#ifdef FIXED_POINT
+         {
+            spx_word32_t f = DIV32(ener,PSHR32(ol_gain,SIG_SHIFT));
+            if (f<32768)
+               fine_gain = f;
+            else
+               fine_gain = 32767;
+         }
+#else
+         fine_gain = DIV32_16(ener,PSHR32(ol_gain,SIG_SHIFT));
+#endif
+         /* Calculate gain correction for the sub-frame (if any) */
+         if (SUBMODE(have_subframe_gain)) 
+         {
+            int qe;
+            if (SUBMODE(have_subframe_gain)==3)
+            {
+               qe = scal_quant(fine_gain, exc_gain_quant_scal3_bound, 8);
+               speex_bits_pack(bits, qe, 3);
+               ener=MULT16_32_Q14(exc_gain_quant_scal3[qe],ol_gain);
+            } else {
+               qe = scal_quant(fine_gain, exc_gain_quant_scal1_bound, 2);
+               speex_bits_pack(bits, qe, 1);
+               ener=MULT16_32_Q14(exc_gain_quant_scal1[qe],ol_gain);               
+            }
+         } else {
+            ener=ol_gain;
+         }
+
+         /*printf ("%f %f\n", ener, ol_gain);*/
+
+         /* Normalize innovation */
+         signal_div(target, target, ener, st->subframeSize);
+
+         /* Quantize innovation */
+         if (SUBMODE(innovation_quant))
+         {
+            /* Codebook search */
+            SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, 
+                                      SUBMODE(innovation_params), st->lpcSize, st->subframeSize, 
+                                      innov, syn_resp, bits, stack, st->complexity, SUBMODE(double_codebook));
+            
+            /* De-normalize innovation and update excitation */
+            signal_mul(innov, innov, ener, st->subframeSize);
+
+            for (i=0;i<st->subframeSize;i++)
+               exc[i] = ADD32(exc[i],innov[i]);
+         } else {
+            speex_error("No fixed codebook");
+         }
+
+         /* In some (rare) modes, we do a second search (more bits) to reduce noise even more */
+         if (SUBMODE(double_codebook)) {
+            char *tmp_stack=stack;
+            VARDECL(spx_sig_t *innov2);
+            ALLOC(innov2, st->subframeSize, spx_sig_t);
+            for (i=0;i<st->subframeSize;i++)
+               innov2[i]=0;
+            for (i=0;i<st->subframeSize;i++)
+               target[i]*=2.2;
+            SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, 
+                                      SUBMODE(innovation_params), st->lpcSize, st->subframeSize, 
+                                      innov2, syn_resp, bits, stack, st->complexity, 0);
+            signal_mul(innov2, innov2, (spx_word32_t) (ener*(1/2.2)), st->subframeSize);
+            for (i=0;i<st->subframeSize;i++)
+               exc[i] = ADD32(exc[i],innov2[i]);
+            stack = tmp_stack;
+         }
+
+      }
+
+      /* Final signal synthesis from excitation */
+      iir_mem2(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp);
+
+      /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */
+      if (st->complexity!=0)
+         filter_mem2(sp, st->bw_lpc1, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw);
+      
+   }
+
+   /* Store the LSPs for interpolation in the next frame */
+   if (st->submodeID>=1)
+   {
+      for (i=0;i<st->lpcSize;i++)
+         st->old_lsp[i] = st->lsp[i];
+      for (i=0;i<st->lpcSize;i++)
+         st->old_qlsp[i] = st->qlsp[i];
+   }
+
+   if (st->submodeID==1)
+   {
+      if (st->dtx_count)
+         speex_bits_pack(bits, 15, 4);
+      else
+         speex_bits_pack(bits, 0, 4);
+   }
+
+   /* The next frame will not be the first (Duh!) */
+   st->first = 0;
+
+#ifdef RESYNTH
+   /* Replace input by synthesized speech */
+   for (i=0;i<st->frameSize;i++)
+   {
+      spx_word32_t sig = PSHR32(st->frame[i],SIG_SHIFT);
+      if (sig>32767)
+         sig = 32767;
+      if (sig<-32767)
+         sig = -32767;
+     in[i]=sig;
+   }
+#endif
+
+   if (SUBMODE(innovation_quant) == noise_codebook_quant || st->submodeID==0)
+      st->bounded_pitch = 1;
+   else
+      st->bounded_pitch = 0;
+
+   return 1;
+}
+
+
+void *nb_decoder_init(const SpeexMode *m)
+{
+   DecState *st;
+   const SpeexNBMode *mode;
+   int i;
+
+   mode=(const SpeexNBMode*)m->mode;
+#if defined(VAR_ARRAYS) || defined (USE_ALLOCA)
+   st = (DecState *)speex_alloc(sizeof(DecState));
+   st->stack = NULL;
+#else
+   st = (DecState *)speex_alloc(sizeof(DecState)+4000*sizeof(spx_sig_t));
+   st->stack = ((char*)st) + sizeof(DecState);
+#endif
+   if (!st)
+      return NULL;
+
+   st->mode=m;
+
+
+   st->encode_submode = 1;
+#ifdef EPIC_48K
+   st->lbr_48k=mode->lbr48k;
+#endif
+
+   st->first=1;
+   /* Codec parameters, should eventually have several "modes"*/
+   st->frameSize = mode->frameSize;
+   st->nbSubframes=mode->frameSize/mode->subframeSize;
+   st->subframeSize=mode->subframeSize;
+   st->lpcSize = mode->lpcSize;
+   st->min_pitch=mode->pitchStart;
+   st->max_pitch=mode->pitchEnd;
+
+   st->submodes=mode->submodes;
+   st->submodeID=mode->defaultSubmode;
+
+   st->lpc_enh_enabled=0;
+
+
+   st->inBuf = speex_alloc((st->frameSize)*sizeof(spx_sig_t));
+   st->frame = st->inBuf;
+   st->excBuf = speex_alloc((st->frameSize + st->max_pitch + 1)*sizeof(spx_sig_t));
+   st->exc = st->excBuf + st->max_pitch + 1;
+   for (i=0;i<st->frameSize;i++)
+      st->inBuf[i]=0;
+   for (i=0;i<st->frameSize + st->max_pitch + 1;i++)
+      st->excBuf[i]=0;
+   st->innov = speex_alloc((st->frameSize)*sizeof(spx_sig_t));
+
+   st->interp_qlpc = speex_alloc((st->lpcSize+1)*sizeof(spx_coef_t));
+   st->qlsp = speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
+   st->old_qlsp = speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
+   st->interp_qlsp = speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
+   st->mem_sp = speex_alloc((5*st->lpcSize)*sizeof(spx_mem_t));
+   st->comb_mem = speex_alloc(sizeof(CombFilterMem));
+   comb_filter_mem_init (st->comb_mem);
+
+   st->pi_gain = speex_alloc((st->nbSubframes)*sizeof(spx_word32_t));
+   st->last_pitch = 40;
+   st->count_lost=0;
+   st->pitch_gain_buf[0] = st->pitch_gain_buf[1] = st->pitch_gain_buf[2] = 0;
+   st->pitch_gain_buf_idx = 0;
+
+   st->sampling_rate=8000;
+   st->last_ol_gain = 0;
+
+   st->user_callback.func = &speex_default_user_handler;
+   st->user_callback.data = NULL;
+   for (i=0;i<16;i++)
+      st->speex_callbacks[i].func = NULL;
+
+   st->voc_m1=st->voc_m2=st->voc_mean=0;
+   st->voc_offset=0;
+   st->dtx_enabled=0;
+#ifdef ENABLE_VALGRIND
+   VALGRIND_MAKE_READABLE(st, (st->stack-(char*)st));
+#endif
+   return st;
+}
+
+void nb_decoder_destroy(void *state)
+{
+   //DecState *st;
+   //st=(DecState*)state;
+   
+   speex_free(state);
+}
+
+#define median3(a, b, c)       ((a) < (b) ? ((b) < (c) ? (b) : ((a) < (c) ? (c) : (a))) : ((c) < (b) ? (b) : ((c) < (a) ? (c) : (a))))
+
+static void nb_decode_lost(DecState *st, spx_word16_t *out, char *stack)
+{
+   int i, sub;
+   VARDECL(spx_coef_t *awk1);
+   VARDECL(spx_coef_t *awk2);
+   VARDECL(spx_coef_t *awk3);
+   float pitch_gain, fact;
+   spx_word16_t gain_med;
+
+   fact = exp(-.04*st->count_lost*st->count_lost);
+   gain_med = median3(st->pitch_gain_buf[0], st->pitch_gain_buf[1], st->pitch_gain_buf[2]);
+   if (gain_med < st->last_pitch_gain)
+      st->last_pitch_gain = gain_med;
+   
+   pitch_gain = GAIN_SCALING_1*st->last_pitch_gain;
+   if (pitch_gain>.95)
+      pitch_gain=.95;
+
+   pitch_gain = fact*pitch_gain + VERY_SMALL;
+
+   /* Shift all buffers by one frame */
+   /*speex_move(st->inBuf, st->inBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(spx_sig_t));*/
+   speex_move(st->excBuf, st->excBuf+st->frameSize, (st->max_pitch + 1)*sizeof(spx_sig_t));
+
+   ALLOC(awk1, (st->lpcSize+1), spx_coef_t);
+   ALLOC(awk2, (st->lpcSize+1), spx_coef_t);
+   ALLOC(awk3, (st->lpcSize+1), spx_coef_t);
+
+   for (sub=0;sub<st->nbSubframes;sub++)
+   {
+      int offset;
+      spx_sig_t *sp, *exc;
+      /* Offset relative to start of frame */
+      offset = st->subframeSize*sub;
+      /* Original signal */
+      sp=st->frame+offset;
+      /* Excitation */
+      exc=st->exc+offset;
+      /* Excitation after post-filter*/
+
+      /* Calculate perceptually enhanced LPC filter */
+      if (st->lpc_enh_enabled)
+      {
+         spx_word16_t k1,k2,k3;
+         if (st->submodes[st->submodeID] != NULL)
+         {
+            k1=SUBMODE(lpc_enh_k1);
+            k2=SUBMODE(lpc_enh_k2);
+            k3=SUBMODE(lpc_enh_k3);
+         } else {
+            k1=k2=.7*GAMMA_SCALING;
+            k3=.0;
+         }
+         bw_lpc(k1, st->interp_qlpc, awk1, st->lpcSize);
+         bw_lpc(k2, st->interp_qlpc, awk2, st->lpcSize);
+         bw_lpc(k3, st->interp_qlpc, awk3, st->lpcSize);
+      }
+        
+      /* Make up a plausible excitation */
+      /* FIXME: THIS CAN BE IMPROVED */
+      /*if (pitch_gain>.95)
+        pitch_gain=.95;*/
+      {
+      float innov_gain=0;
+      innov_gain = compute_rms(st->innov, st->frameSize);
+      for (i=0;i<st->subframeSize;i++)
+      {
+#if 0
+         exc[i] = pitch_gain * exc[i - st->last_pitch] + fact*sqrt(1-pitch_gain)*st->innov[i+offset];
+         /*Just so it give the same lost packets as with if 0*/
+         /*rand();*/
+#else
+         /*exc[i]=pitch_gain*exc[i-st->last_pitch] +  fact*st->innov[i+offset];*/
+         exc[i]=pitch_gain*(exc[i-st->last_pitch]+VERY_SMALL) + 
+         fact*sqrt(1-pitch_gain)*speex_rand(innov_gain);
+#endif
+      }
+      }
+      for (i=0;i<st->subframeSize;i++)
+         sp[i]=exc[i];
+      
+      /* Signal synthesis */
+      if (st->lpc_enh_enabled)
+      {
+         filter_mem2(sp, awk2, awk1, sp, st->subframeSize, st->lpcSize, 
+                     st->mem_sp+st->lpcSize);
+         filter_mem2(sp, awk3, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, 
+                     st->mem_sp);
+      } else {
+         for (i=0;i<st->lpcSize;i++)
+            st->mem_sp[st->lpcSize+i] = 0;
+         iir_mem2(sp, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, 
+                     st->mem_sp);
+      }      
+   }
+
+   for (i=0;i<st->frameSize;i++)
+   {
+      spx_word32_t sig = PSHR32(st->frame[i],SIG_SHIFT);
+      if (sig>32767)
+         sig = 32767;
+      if (sig<-32767)
+         sig = -32767;
+     out[i]=sig;
+   }
+   
+   st->first = 0;
+   st->count_lost++;
+   st->pitch_gain_buf[st->pitch_gain_buf_idx++] = GAIN_SCALING*pitch_gain;
+   if (st->pitch_gain_buf_idx > 2) /* rollover */
+      st->pitch_gain_buf_idx = 0;
+}
+
+int nb_decode(void *state, SpeexBits *bits, void *vout)
+{
+   DecState *st;
+   int i, sub;
+   int pitch;
+   spx_word16_t pitch_gain[3];
+   spx_word32_t ol_gain=0;
+   int ol_pitch=0;
+   spx_word16_t ol_pitch_coef=0;
+   int best_pitch=40;
+   spx_word16_t best_pitch_gain=0;
+   int wideband;
+   int m;
+   char *stack;
+   VARDECL(spx_coef_t *awk1);
+   VARDECL(spx_coef_t *awk2);
+   VARDECL(spx_coef_t *awk3);
+   spx_word16_t pitch_average=0;
+#ifdef EPIC_48K
+   int pitch_half[2];
+   int ol_pitch_id=0;
+#endif
+   spx_word16_t *out = vout;
+
+   st=(DecState*)state;
+   stack=st->stack;
+
+   if (st->encode_submode)
+   {
+#ifdef EPIC_48K
+   if (!st->lbr_48k) {
+#endif
+
+   /* Check if we're in DTX mode*/
+   if (!bits && st->dtx_enabled)
+   {
+      st->submodeID=0;
+   } else 
+   {
+      /* If bits is NULL, consider the packet to be lost (what could we do anyway) */
+      if (!bits)
+      {
+         nb_decode_lost(st, out, stack);
+         return 0;
+      }
+
+      /* Search for next narrowband block (handle requests, skip wideband blocks) */
+      do {
+         if (speex_bits_remaining(bits)<5)
+            return -1;
+         wideband = speex_bits_unpack_unsigned(bits, 1);
+         if (wideband) /* Skip wideband block (for compatibility) */
+         {
+            int submode;
+            int advance;
+            advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);
+            speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);
+            if (advance < 0)
+            {
+               speex_warning ("Invalid wideband mode encountered. Corrupted stream?");
+               return -2;
+            } 
+            advance -= (SB_SUBMODE_BITS+1);
+            speex_bits_advance(bits, advance);
+            
+            if (speex_bits_remaining(bits)<5)
+               return -1;
+            wideband = speex_bits_unpack_unsigned(bits, 1);
+            if (wideband)
+            {
+               advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);
+               speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance);
+               if (advance < 0)
+               {
+                  speex_warning ("Invalid wideband mode encountered: corrupted stream?");
+                  return -2;
+               } 
+               advance -= (SB_SUBMODE_BITS+1);
+               speex_bits_advance(bits, advance);
+               wideband = speex_bits_unpack_unsigned(bits, 1);
+               if (wideband)
+               {
+                  speex_warning ("More than two wideband layers found: corrupted stream?");
+                  return -2;
+               }
+
+            }
+         }
+         if (speex_bits_remaining(bits)<4)
+            return -1;
+         /* FIXME: Check for overflow */
+         m = speex_bits_unpack_unsigned(bits, 4);
+         if (m==15) /* We found a terminator */
+         {
+            return -1;
+         } else if (m==14) /* Speex in-band request */
+         {
+            int ret = speex_inband_handler(bits, st->speex_callbacks, state);
+            if (ret)
+               return ret;
+         } else if (m==13) /* User in-band request */
+         {
+            int ret = st->user_callback.func(bits, state, st->user_callback.data);
+            if (ret)
+               return ret;
+         } else if (m>8) /* Invalid mode */
+         {
+            speex_warning("Invalid mode encountered: corrupted stream?");
+            return -2;
+         }
+      
+      } while (m>8);
+
+      /* Get the sub-mode that was used */
+      st->submodeID = m;
+
+   }
+#ifdef EPIC_48K
+   }
+#endif
+   }
+
+   /* Shift all buffers by one frame */
+   speex_move(st->excBuf, st->excBuf+st->frameSize, (st->max_pitch + 1)*sizeof(spx_sig_t));
+
+   /* If null mode (no transmission), just set a couple things to zero*/
+   if (st->submodes[st->submodeID] == NULL)
+   {
+      VARDECL(spx_coef_t *lpc);
+      ALLOC(lpc, 11, spx_coef_t);
+      bw_lpc(GAMMA_SCALING*.93, st->interp_qlpc, lpc, 10);
+      {
+         float innov_gain=0;
+         float pgain=GAIN_SCALING_1*st->last_pitch_gain;
+         if (pgain>.6)
+            pgain=.6;
+        innov_gain = compute_rms(st->innov, st->frameSize);
+         for (i=0;i<st->frameSize;i++)
+            st->exc[i]=VERY_SMALL;
+         speex_rand_vec(innov_gain, st->exc, st->frameSize);
+      }
+
+
+      st->first=1;
+
+      /* Final signal synthesis from excitation */
+      iir_mem2(st->exc, lpc, st->frame, st->frameSize, st->lpcSize, st->mem_sp);
+
+      for (i=0;i<st->frameSize;i++)
+      {
+         spx_word32_t sig = PSHR32(st->frame[i],SIG_SHIFT);
+         if (sig>32767)
+            sig = 32767;
+         if (sig<-32767)
+            sig = -32767;
+         out[i]=sig;
+      }
+
+      st->count_lost=0;
+      return 0;
+   }
+
+   /* Unquantize LSPs */
+   SUBMODE(lsp_unquant)(st->qlsp, st->lpcSize, bits);
+
+   /*Damp memory if a frame was lost and the LSP changed too much*/
+   if (st->count_lost)
+   {
+      float lsp_dist=0, fact;
+      for (i=0;i<st->lpcSize;i++)
+         lsp_dist += fabs(st->old_qlsp[i] - st->qlsp[i]);
+      lsp_dist /= LSP_SCALING;
+      fact = .6*exp(-.2*lsp_dist);
+      for (i=0;i<2*st->lpcSize;i++)
+         st->mem_sp[i] = (spx_mem_t)(st->mem_sp[i]*fact);
+   }
+
+
+   /* Handle first frame and lost-packet case */
+   if (st->first || st->count_lost)
+   {
+      for (i=0;i<st->lpcSize;i++)
+         st->old_qlsp[i] = st->qlsp[i];
+   }
+
+#ifdef EPIC_48K
+   if (st->lbr_48k) {
+      pitch_half[0] = st->min_pitch+speex_bits_unpack_unsigned(bits, 7);
+      pitch_half[1] = pitch_half[0]+speex_bits_unpack_unsigned(bits, 2)-1;
+
+      ol_pitch_id = speex_bits_unpack_unsigned(bits, 3);
+      ol_pitch_coef=GAIN_SCALING*0.13514*ol_pitch_id;
+
+      {
+         int qe;
+         qe = speex_bits_unpack_unsigned(bits, 4);
+         ol_gain = SIG_SCALING*exp((qe+2)/2.1),SIG_SHIFT;
+      }
+
+   } else {
+#endif
+
+   /* Get open-loop pitch estimation for low bit-rate pitch coding */
+   if (SUBMODE(lbr_pitch)!=-1)
+   {
+      ol_pitch = st->min_pitch+speex_bits_unpack_unsigned(bits, 7);
+   } 
+   
+   if (SUBMODE(forced_pitch_gain))
+   {
+      int quant;
+      quant = speex_bits_unpack_unsigned(bits, 4);
+      ol_pitch_coef=GAIN_SCALING*0.066667*quant;
+   }
+   
+   /* Get global excitation gain */
+   {
+      int qe;
+      qe = speex_bits_unpack_unsigned(bits, 5);
+#ifdef FIXED_POINT
+      ol_gain = MULT16_32_Q15(28406,ol_gain_table[qe]);
+#else
+      ol_gain = SIG_SCALING*exp(qe/3.5);
+#endif
+   }
+#ifdef EPIC_48K
+   }
+#endif
+
+   ALLOC(awk1, st->lpcSize+1, spx_coef_t);
+   ALLOC(awk2, st->lpcSize+1, spx_coef_t);
+   ALLOC(awk3, st->lpcSize+1, spx_coef_t);
+
+   if (st->submodeID==1)
+   {
+      int extra;
+      extra = speex_bits_unpack_unsigned(bits, 4);
+
+      if (extra==15)
+         st->dtx_enabled=1;
+      else
+         st->dtx_enabled=0;
+   }
+   if (st->submodeID>1)
+      st->dtx_enabled=0;
+
+   /*Loop on subframes */
+   for (sub=0;sub<st->nbSubframes;sub++)
+   {
+      int offset;
+      spx_sig_t *sp, *exc;
+      spx_word16_t tmp;
+
+#ifdef EPIC_48K
+      if (st->lbr_48k)
+      {
+         if (sub*2 < st->nbSubframes)
+            ol_pitch = pitch_half[0];
+         else
+            ol_pitch = pitch_half[1];
+      }
+#endif
+
+      /* Offset relative to start of frame */
+      offset = st->subframeSize*sub;
+      /* Original signal */
+      sp=st->frame+offset;
+      /* Excitation */
+      exc=st->exc+offset;
+      /* Excitation after post-filter*/
+
+      /* LSP interpolation (quantized and unquantized) */
+      lsp_interpolate(st->old_qlsp, st->qlsp, st->interp_qlsp, st->lpcSize, sub, st->nbSubframes);
+
+      /* Make sure the LSP's are stable */
+      lsp_enforce_margin(st->interp_qlsp, st->lpcSize, LSP_MARGIN);
+
+
+      /* Compute interpolated LPCs (unquantized) */
+      lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack);
+
+      /* Compute enhanced synthesis filter */
+      if (st->lpc_enh_enabled)
+      {
+         bw_lpc(SUBMODE(lpc_enh_k1), st->interp_qlpc, awk1, st->lpcSize);
+         bw_lpc(SUBMODE(lpc_enh_k2), st->interp_qlpc, awk2, st->lpcSize);
+         bw_lpc(SUBMODE(lpc_enh_k3), st->interp_qlpc, awk3, st->lpcSize);
+      }
+
+      /* Compute analysis filter at w=pi */
+      {
+         spx_word32_t pi_g=st->interp_qlpc[0];
+         for (i=1;i<=st->lpcSize;i+=2)
+         {
+            /*pi_g += -st->interp_qlpc[i] +  st->interp_qlpc[i+1];*/
+            pi_g = ADD32(pi_g, SUB32(st->interp_qlpc[i+1],st->interp_qlpc[i]));
+         }
+         st->pi_gain[sub] = pi_g;
+      }
+
+      /* Reset excitation */
+      for (i=0;i<st->subframeSize;i++)
+         exc[i]=0;
+
+      /*Adaptive codebook contribution*/
+      if (SUBMODE(ltp_unquant))
+      {
+         int pit_min, pit_max;
+         /* Handle pitch constraints if any */
+         if (SUBMODE(lbr_pitch) != -1)
+         {
+            int margin;
+            margin = SUBMODE(lbr_pitch);
+            if (margin)
+            {
+/* GT - need optimization?
+               if (ol_pitch < st->min_pitch+margin-1)
+                  ol_pitch=st->min_pitch+margin-1;
+               if (ol_pitch > st->max_pitch-margin)
+                  ol_pitch=st->max_pitch-margin;
+               pit_min = ol_pitch-margin+1;
+               pit_max = ol_pitch+margin;
+*/
+               pit_min = ol_pitch-margin+1;
+               if (pit_min < st->min_pitch)
+                 pit_min = st->min_pitch;
+               pit_max = ol_pitch+margin;
+               if (pit_max > st->max_pitch)
+                 pit_max = st->max_pitch;
+            } else {
+               pit_min = pit_max = ol_pitch;
+            }
+         } else {
+            pit_min = st->min_pitch;
+            pit_max = st->max_pitch;
+         }
+
+
+#ifdef EPIC_48K
+         if (st->lbr_48k)
+         {
+             SUBMODE(ltp_unquant)(exc, pit_min, pit_max, ol_pitch_coef, SUBMODE(ltp_params), 
+                                  st->subframeSize, &pitch, &pitch_gain[0], bits, stack, 
+                                  st->count_lost, offset, st->last_pitch_gain, ol_pitch_id);
+         } else {
+#endif
+
+             SUBMODE(ltp_unquant)(exc, pit_min, pit_max, ol_pitch_coef, SUBMODE(ltp_params), 
+                                  st->subframeSize, &pitch, &pitch_gain[0], bits, stack, 
+                                  st->count_lost, offset, st->last_pitch_gain, 0);
+
+#ifdef EPIC_48K
+         }
+#endif
+
+         
+         /* If we had lost frames, check energy of last received frame */
+         if (st->count_lost && ol_gain < st->last_ol_gain)
+         {
+            float fact = (float)ol_gain/(st->last_ol_gain+1);
+            for (i=0;i<st->subframeSize;i++)
+               exc[i]*=fact;
+         }
+
+         tmp = gain_3tap_to_1tap(pitch_gain);
+
+         pitch_average += tmp;
+         if (tmp>best_pitch_gain)
+         {
+            best_pitch = pitch;
+           best_pitch_gain = tmp;
+         }
+      } else {
+         speex_error("No pitch prediction, what's wrong");
+      }
+      
+      /* Unquantize the innovation */
+      {
+         int q_energy;
+         spx_word32_t ener;
+         spx_sig_t *innov;
+         
+         innov = st->innov+sub*st->subframeSize;
+         for (i=0;i<st->subframeSize;i++)
+            innov[i]=0;
+
+         /* Decode sub-frame gain correction */
+         if (SUBMODE(have_subframe_gain)==3)
+         {
+            q_energy = speex_bits_unpack_unsigned(bits, 3);
+            ener = MULT16_32_Q14(exc_gain_quant_scal3[q_energy],ol_gain);
+         } else if (SUBMODE(have_subframe_gain)==1)
+         {
+            q_energy = speex_bits_unpack_unsigned(bits, 1);
+            ener = MULT16_32_Q14(exc_gain_quant_scal1[q_energy],ol_gain);
+         } else {
+            ener = ol_gain;
+         }
+                  
+         if (SUBMODE(innovation_unquant))
+         {
+            /*Fixed codebook contribution*/
+            SUBMODE(innovation_unquant)(innov, SUBMODE(innovation_params), st->subframeSize, bits, stack);
+         } else {
+            speex_error("No fixed codebook");
+         }
+
+         /* De-normalize innovation and update excitation */
+#ifdef FIXED_POINT
+         signal_mul(innov, innov, ener, st->subframeSize);
+#else
+         signal_mul(innov, innov, ener, st->subframeSize);
+#endif
+         /*Vocoder mode*/
+         if (st->submodeID==1) 
+         {
+            float g=ol_pitch_coef*GAIN_SCALING_1;
+
+            
+            for (i=0;i<st->subframeSize;i++)
+               exc[i]=0;
+            while (st->voc_offset<st->subframeSize)
+            {
+               if (st->voc_offset>=0)
+                  exc[st->voc_offset]=SIG_SCALING*sqrt(1.0*ol_pitch);
+               st->voc_offset+=ol_pitch;
+            }
+            st->voc_offset -= st->subframeSize;
+
+            g=.5+2*(g-.6);
+            if (g<0)
+               g=0;
+            if (g>1)
+               g=1;
+            for (i=0;i<st->subframeSize;i++)
+            {
+               float exci=exc[i];
+               exc[i]=.8*g*exc[i]*ol_gain/SIG_SCALING + .6*g*st->voc_m1*ol_gain/SIG_SCALING + .5*g*innov[i] - .5*g*st->voc_m2 + (1-g)*innov[i];
+               st->voc_m1 = exci;
+               st->voc_m2=innov[i];
+               st->voc_mean = .95*st->voc_mean + .05*exc[i];
+               exc[i]-=st->voc_mean;
+            }
+         } else {
+            for (i=0;i<st->subframeSize;i++)
+               exc[i]=ADD32(exc[i],innov[i]);
+            /*print_vec(exc, 40, "innov");*/
+         }
+         /* Decode second codebook (only for some modes) */
+         if (SUBMODE(double_codebook))
+         {
+            char *tmp_stack=stack;
+            VARDECL(spx_sig_t *innov2);
+            ALLOC(innov2, st->subframeSize, spx_sig_t);
+            for (i=0;i<st->subframeSize;i++)
+               innov2[i]=0;
+            SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize, bits, stack);
+            signal_mul(innov2, innov2, (spx_word32_t) (ener*(1/2.2)), st->subframeSize);
+            for (i=0;i<st->subframeSize;i++)
+               exc[i] = ADD32(exc[i],innov2[i]);
+            stack = tmp_stack;
+         }
+
+      }
+
+      for (i=0;i<st->subframeSize;i++)
+         sp[i]=exc[i];
+
+      /* Signal synthesis */
+      if (st->lpc_enh_enabled && SUBMODE(comb_gain)>0)
+         comb_filter(exc, sp, st->interp_qlpc, st->lpcSize, st->subframeSize,
+                              pitch, pitch_gain, SUBMODE(comb_gain), st->comb_mem);
+
+      if (st->lpc_enh_enabled)
+      {
+         /* Use enhanced LPC filter */
+         filter_mem2(sp, awk2, awk1, sp, st->subframeSize, st->lpcSize, 
+                     st->mem_sp+st->lpcSize);
+         filter_mem2(sp, awk3, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, 
+                     st->mem_sp);
+      } else {
+         /* Use regular filter */
+         for (i=0;i<st->lpcSize;i++)
+            st->mem_sp[st->lpcSize+i] = 0;
+         iir_mem2(sp, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, 
+                     st->mem_sp);
+      }
+   }
+   
+   /*Copy output signal*/   
+   for (i=0;i<st->frameSize;i++)
+   {
+      spx_word32_t sig = PSHR32(st->frame[i],SIG_SHIFT);
+      if (sig>32767)
+         sig = 32767;
+      if (sig<-32767)
+         sig = -32767;
+     out[i]=sig;
+   }
+
+   /*for (i=0;i<st->frameSize;i++)
+     printf ("%d\n", (int)st->frame[i]);*/
+
+   /* Store the LSPs for interpolation in the next frame */
+   for (i=0;i<st->lpcSize;i++)
+      st->old_qlsp[i] = st->qlsp[i];
+
+   /* The next frame will not be the first (Duh!) */
+   st->first = 0;
+   st->count_lost=0;
+   st->last_pitch = best_pitch;
+#ifdef FIXED_POINT
+   st->last_pitch_gain = PSHR16(pitch_average,2);
+#else
+   st->last_pitch_gain = .25*pitch_average;   
+#endif
+   st->pitch_gain_buf[st->pitch_gain_buf_idx++] = st->last_pitch_gain;
+   if (st->pitch_gain_buf_idx > 2) /* rollover */
+      st->pitch_gain_buf_idx = 0;
+
+   st->last_ol_gain = ol_gain;
+
+   return 0;
+}
+
+int nb_encoder_ctl(void *state, int request, void *ptr)
+{
+   EncState *st;
+   st=(EncState*)state;     
+   switch(request)
+   {
+   case SPEEX_GET_FRAME_SIZE:
+      (*(int*)ptr) = st->frameSize;
+      break;
+   case SPEEX_SET_LOW_MODE:
+   case SPEEX_SET_MODE:
+      st->submodeSelect = st->submodeID = (*(int*)ptr);
+      break;
+   case SPEEX_GET_LOW_MODE:
+   case SPEEX_GET_MODE:
+      (*(int*)ptr) = st->submodeID;
+      break;
+   case SPEEX_SET_VBR:
+      st->vbr_enabled = (*(int*)ptr);
+      break;
+   case SPEEX_GET_VBR:
+      (*(int*)ptr) = st->vbr_enabled;
+      break;
+   case SPEEX_SET_VAD:
+      st->vad_enabled = (*(int*)ptr);
+      break;
+   case SPEEX_GET_VAD:
+      (*(int*)ptr) = st->vad_enabled;
+      break;
+   case SPEEX_SET_DTX:
+      st->dtx_enabled = (*(int*)ptr);
+      break;
+   case SPEEX_GET_DTX:
+      (*(int*)ptr) = st->dtx_enabled;
+      break;
+   case SPEEX_SET_ABR:
+      st->abr_enabled = (*(int*)ptr);
+      st->vbr_enabled = 1;
+      {
+         int i=10, rate, target;
+         float vbr_qual;
+         target = (*(int*)ptr);
+         while (i>=0)
+         {
+            speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i);
+            speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate);
+            if (rate <= target)
+               break;
+            i--;
+         }
+         vbr_qual=i;
+         if (vbr_qual<0)
+            vbr_qual=0;
+         speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_qual);
+         st->abr_count=0;
+         st->abr_drift=0;
+         st->abr_drift2=0;
+      }
+      
+      break;
+   case SPEEX_GET_ABR:
+      (*(int*)ptr) = st->abr_enabled;
+      break;
+   case SPEEX_SET_VBR_QUALITY:
+      st->vbr_quality = (*(float*)ptr);
+      break;
+   case SPEEX_GET_VBR_QUALITY:
+      (*(float*)ptr) = st->vbr_quality;
+      break;
+   case SPEEX_SET_QUALITY:
+      {
+         int quality = (*(int*)ptr);
+         if (quality < 0)
+            quality = 0;
+         if (quality > 10)
+            quality = 10;
+         st->submodeSelect = st->submodeID = ((const SpeexNBMode*)(st->mode->mode))->quality_map[quality];
+      }
+      break;
+   case SPEEX_SET_COMPLEXITY:
+      st->complexity = (*(int*)ptr);
+      if (st->complexity<0)
+         st->complexity=0;
+      break;
+   case SPEEX_GET_COMPLEXITY:
+      (*(int*)ptr) = st->complexity;
+      break;
+   case SPEEX_SET_BITRATE:
+      {
+         int i=10, rate, target;
+         target = (*(int*)ptr);
+         while (i>=0)
+         {
+            speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i);
+            speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate);
+            if (rate <= target)
+               break;
+            i--;
+         }
+      }
+      break;
+   case SPEEX_GET_BITRATE:
+      if (st->submodes[st->submodeID])
+         (*(int*)ptr) = st->sampling_rate*SUBMODE(bits_per_frame)/st->frameSize;
+      else
+         (*(int*)ptr) = st->sampling_rate*(NB_SUBMODE_BITS+1)/st->frameSize;
+      break;
+   case SPEEX_SET_SAMPLING_RATE:
+      st->sampling_rate = (*(int*)ptr);
+      break;
+   case SPEEX_GET_SAMPLING_RATE:
+      (*(int*)ptr)=st->sampling_rate;
+      break;
+   case SPEEX_RESET_STATE:
+      {
+         int i;
+         st->bounded_pitch = 1;
+         st->first = 1;
+         for (i=0;i<st->lpcSize;i++)
+            st->lsp[i]=(M_PI*((float)(i+1)))/(st->lpcSize+1);
+         for (i=0;i<st->lpcSize;i++)
+            st->mem_sw[i]=st->mem_sw_whole[i]=st->mem_sp[i]=st->mem_exc[i]=0;
+         for (i=0;i<st->frameSize+st->max_pitch+1;i++)
+            st->excBuf[i]=st->swBuf[i]=0;
+         for (i=0;i<st->windowSize;i++)
+            st->inBuf[i]=0;
+      }
+      break;
+   case SPEEX_SET_SUBMODE_ENCODING:
+      st->encode_submode = (*(int*)ptr);
+      break;
+   case SPEEX_GET_SUBMODE_ENCODING:
+      (*(int*)ptr) = st->encode_submode;
+      break;
+   case SPEEX_GET_LOOKAHEAD:
+      (*(int*)ptr)=(st->windowSize-st->frameSize);
+      break;
+   case SPEEX_SET_PLC_TUNING:
+      st->plc_tuning = (*(int*)ptr);
+      if (st->plc_tuning>100)
+         st->plc_tuning=100;
+      break;
+   case SPEEX_GET_PLC_TUNING:
+      (*(int*)ptr)=(st->plc_tuning);
+      break;
+   case SPEEX_GET_PI_GAIN:
+      {
+         int i;
+         spx_word32_t *g = (spx_word32_t*)ptr;
+         for (i=0;i<st->nbSubframes;i++)
+            g[i]=st->pi_gain[i];
+      }
+      break;
+   case SPEEX_GET_EXC:
+      {
+         int i;
+         spx_sig_t *e = (spx_sig_t*)ptr;
+         for (i=0;i<st->frameSize;i++)
+            e[i]=st->exc[i];
+      }
+      break;
+   case SPEEX_GET_INNOV:
+      {
+         int i;
+         spx_sig_t *e = (spx_sig_t*)ptr;
+         for (i=0;i<st->frameSize;i++)
+            e[i]=st->innov[i];
+      }
+      break;
+   case SPEEX_GET_RELATIVE_QUALITY:
+      (*(float*)ptr)=st->relative_quality;
+      break;
+   default:
+      speex_warning_int("Unknown nb_ctl request: ", request);
+      return -1;
+   }
+   return 0;
+}
+
+int nb_decoder_ctl(void *state, int request, void *ptr)
+{
+   DecState *st;
+   st=(DecState*)state;
+   switch(request)
+   {
+   case SPEEX_SET_LOW_MODE:
+   case SPEEX_SET_MODE:
+      st->submodeID = (*(int*)ptr);
+      break;
+   case SPEEX_GET_LOW_MODE:
+   case SPEEX_GET_MODE:
+      (*(int*)ptr) = st->submodeID;
+      break;
+   case SPEEX_SET_ENH:
+      st->lpc_enh_enabled = *((int*)ptr);
+      break;
+   case SPEEX_GET_ENH:
+      *((int*)ptr) = st->lpc_enh_enabled;
+      break;
+   case SPEEX_GET_FRAME_SIZE:
+      (*(int*)ptr) = st->frameSize;
+      break;
+   case SPEEX_GET_BITRATE:
+      if (st->submodes[st->submodeID])
+         (*(int*)ptr) = st->sampling_rate*SUBMODE(bits_per_frame)/st->frameSize;
+      else
+         (*(int*)ptr) = st->sampling_rate*(NB_SUBMODE_BITS+1)/st->frameSize;
+      break;
+   case SPEEX_SET_SAMPLING_RATE:
+      st->sampling_rate = (*(int*)ptr);
+      break;
+   case SPEEX_GET_SAMPLING_RATE:
+      (*(int*)ptr)=st->sampling_rate;
+      break;
+   case SPEEX_SET_HANDLER:
+      {
+         SpeexCallback *c = (SpeexCallback*)ptr;
+         st->speex_callbacks[c->callback_id].func=c->func;
+         st->speex_callbacks[c->callback_id].data=c->data;
+         st->speex_callbacks[c->callback_id].callback_id=c->callback_id;
+      }
+      break;
+   case SPEEX_SET_USER_HANDLER:
+      {
+         SpeexCallback *c = (SpeexCallback*)ptr;
+         st->user_callback.func=c->func;
+         st->user_callback.data=c->data;
+         st->user_callback.callback_id=c->callback_id;
+      }
+      break;
+   case SPEEX_RESET_STATE:
+      {
+         int i;
+         for (i=0;i<2*st->lpcSize;i++)
+            st->mem_sp[i]=0;
+         for (i=0;i<st->frameSize + st->max_pitch + 1;i++)
+            st->excBuf[i]=0;
+         for (i=0;i<st->frameSize;i++)
+            st->inBuf[i] = 0;
+      }
+      break;
+   case SPEEX_SET_SUBMODE_ENCODING:
+      st->encode_submode = (*(int*)ptr);
+      break;
+   case SPEEX_GET_SUBMODE_ENCODING:
+      (*(int*)ptr) = st->encode_submode;
+      break;
+   case SPEEX_GET_PI_GAIN:
+      {
+         int i;
+         spx_word32_t *g = (spx_word32_t*)ptr;
+         for (i=0;i<st->nbSubframes;i++)
+            g[i]=st->pi_gain[i];
+      }
+      break;
+   case SPEEX_GET_EXC:
+      {
+         int i;
+         spx_sig_t *e = (spx_sig_t*)ptr;
+         for (i=0;i<st->frameSize;i++)
+            e[i]=st->exc[i];
+      }
+      break;
+   case SPEEX_GET_INNOV:
+      {
+         int i;
+         spx_sig_t *e = (spx_sig_t*)ptr;
+         for (i=0;i<st->frameSize;i++)
+            e[i]=st->innov[i];
+      }
+      break;
+   case SPEEX_GET_DTX_STATUS:
+      *((int*)ptr) = st->dtx_enabled;
+      break;
+   default:
+      speex_warning_int("Unknown nb_ctl request: ", request);
+      return -1;
+   }
+   return 0;
+}
diff --git a/utils/iaxclient/lib/libspeex/nb_celp.h b/utils/iaxclient/lib/libspeex/nb_celp.h
new file mode 100644 (file)
index 0000000..5f2675f
--- /dev/null
@@ -0,0 +1,199 @@
+/* Copyright (C) 2002 Jean-Marc Valin */
+/**
+    @file nb_celp.h
+    @brief Narrowband CELP encoder/decoder
+*/
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+
+*/
+
+#ifndef NB_CELP_H
+#define NB_CELP_H
+
+#include "modes.h"
+#include <speex/speex_bits.h>
+#include <speex/speex_callbacks.h>
+#include "vbr.h"
+#include "filters.h"
+
+/**Structure representing the full state of the narrowband encoder*/
+typedef struct EncState {
+   const SpeexMode *mode;       /**< Mode corresponding to the state */
+   int    first;          /**< Is this the first frame? */
+   int    frameSize;      /**< Size of frames */
+   int    subframeSize;   /**< Size of sub-frames */
+   int    nbSubframes;    /**< Number of sub-frames */
+   int    windowSize;     /**< Analysis (LPC) window length */
+   int    lpcSize;        /**< LPC order */
+   int    min_pitch;      /**< Minimum pitch value allowed */
+   int    max_pitch;      /**< Maximum pitch value allowed */
+
+   int    safe_pitch;     /**< Don't use too large values for pitch (in case we lose a packet) */
+   int    bounded_pitch;  /**< Next frame should not rely on previous frames for pitch */
+   int    ol_pitch;       /**< Open-loop pitch */
+   int    ol_voiced;      /**< Open-loop voiced/non-voiced decision */
+   int   *pitch;
+
+#ifdef EPIC_48K
+   int    lbr_48k;
+#endif
+
+   spx_word16_t  gamma1;         /**< Perceptual filter: A(z/gamma1) */
+   spx_word16_t  gamma2;         /**< Perceptual filter: A(z/gamma2) */
+   float  lag_factor;     /**< Lag windowing Gaussian width */
+   float  lpc_floor;      /**< Noise floor multiplier for A[0] in LPC analysis*/
+   char  *stack;          /**< Pseudo-stack allocation for temporary memory */
+   spx_sig_t *inBuf;          /**< Input buffer (original signal) */
+   spx_sig_t *frame;          /**< Start of original frame */
+   spx_sig_t *excBuf;         /**< Excitation buffer */
+   spx_sig_t *exc;            /**< Start of excitation frame */
+   spx_sig_t *swBuf;          /**< Weighted signal buffer */
+   spx_sig_t *sw;             /**< Start of weighted signal frame */
+   spx_sig_t *innov;          /**< Innovation for the frame */
+   spx_word16_t *window;         /**< Temporary (Hanning) window */
+   spx_word16_t *autocorr;       /**< auto-correlation */
+   spx_word16_t *lagWindow;      /**< Window applied to auto-correlation */
+   spx_coef_t *lpc;            /**< LPCs for current frame */
+   spx_lsp_t *lsp;            /**< LSPs for current frame */
+   spx_lsp_t *qlsp;           /**< Quantized LSPs for current frame */
+   spx_lsp_t *old_lsp;        /**< LSPs for previous frame */
+   spx_lsp_t *old_qlsp;       /**< Quantized LSPs for previous frame */
+   spx_lsp_t *interp_lsp;     /**< Interpolated LSPs */
+   spx_lsp_t *interp_qlsp;    /**< Interpolated quantized LSPs */
+   spx_coef_t *interp_lpc;     /**< Interpolated LPCs */
+   spx_coef_t *interp_qlpc;    /**< Interpolated quantized LPCs */
+   spx_coef_t *bw_lpc1;        /**< LPCs after bandwidth expansion by gamma1 for perceptual weighting*/
+   spx_coef_t *bw_lpc2;        /**< LPCs after bandwidth expansion by gamma2 for perceptual weighting*/
+   spx_mem_t *mem_sp;         /**< Filter memory for signal synthesis */
+   spx_mem_t *mem_sw;         /**< Filter memory for perceptually-weighted signal */
+   spx_mem_t *mem_sw_whole;   /**< Filter memory for perceptually-weighted signal (whole frame)*/
+   spx_mem_t *mem_exc;        /**< Filter memory for excitation (whole frame) */
+   spx_word32_t *pi_gain;        /**< Gain of LPC filter at theta=pi (fe/2) */
+
+   VBRState *vbr;         /**< State of the VBR data */
+   float  vbr_quality;    /**< Quality setting for VBR encoding */
+   float  relative_quality; /**< Relative quality that will be needed by VBR */
+   int    vbr_enabled;    /**< 1 for enabling VBR, 0 otherwise */
+   int    vad_enabled;    /**< 1 for enabling VAD, 0 otherwise */
+   int    dtx_enabled;    /**< 1 for enabling DTX, 0 otherwise */
+   int    dtx_count;      /**< Number of consecutive DTX frames */
+   int    abr_enabled;    /**< ABR setting (in bps), 0 if off */
+   float  abr_drift;
+   float  abr_drift2;
+   float  abr_count;
+   int    complexity;     /**< Complexity setting (0-10 from least complex to most complex) */
+   int    sampling_rate;
+   int    plc_tuning;
+   int    encode_submode;
+   const SpeexSubmode * const *submodes; /**< Sub-mode data */
+   int    submodeID;      /**< Activated sub-mode */
+   int    submodeSelect;  /**< Mode chosen by the user (may differ from submodeID if VAD is on) */
+} EncState;
+
+/**Structure representing the full state of the narrowband decoder*/
+typedef struct DecState {
+   const SpeexMode *mode;       /**< Mode corresponding to the state */
+   int    first;          /**< Is this the first frame? */
+   int    count_lost;     /**< Was the last frame lost? */
+   int    frameSize;      /**< Size of frames */
+   int    subframeSize;   /**< Size of sub-frames */
+   int    nbSubframes;    /**< Number of sub-frames */
+   int    lpcSize;        /**< LPC order */
+   int    min_pitch;      /**< Minimum pitch value allowed */
+   int    max_pitch;      /**< Maximum pitch value allowed */
+   int    sampling_rate;
+
+#ifdef EPIC_48K
+   int    lbr_48k;
+#endif
+
+   spx_word16_t  last_ol_gain;   /**< Open-loop gain for previous frame */
+
+   char  *stack;          /**< Pseudo-stack allocation for temporary memory */
+   spx_sig_t *inBuf;          /**< Input buffer (original signal) */
+   spx_sig_t *frame;          /**< Start of original frame */
+   spx_sig_t *excBuf;         /**< Excitation buffer */
+   spx_sig_t *exc;            /**< Start of excitation frame */
+   spx_sig_t *innov;          /**< Innovation for the frame */
+   spx_lsp_t *qlsp;           /**< Quantized LSPs for current frame */
+   spx_lsp_t *old_qlsp;       /**< Quantized LSPs for previous frame */
+   spx_lsp_t *interp_qlsp;    /**< Interpolated quantized LSPs */
+   spx_coef_t *interp_qlpc;    /**< Interpolated quantized LPCs */
+   spx_mem_t *mem_sp;         /**< Filter memory for synthesis signal */
+   spx_word32_t *pi_gain;        /**< Gain of LPC filter at theta=pi (fe/2) */
+   int    last_pitch;     /**< Pitch of last correctly decoded frame */
+   spx_word16_t  last_pitch_gain; /**< Pitch gain of last correctly decoded frame */
+   spx_word16_t  pitch_gain_buf[3];  /**< Pitch gain of last decoded frames */
+   int    pitch_gain_buf_idx; /**< Tail of the buffer */
+
+   int    encode_submode;
+   const SpeexSubmode * const *submodes; /**< Sub-mode data */
+   int    submodeID;      /**< Activated sub-mode */
+   int    lpc_enh_enabled; /**< 1 when LPC enhancer is on, 0 otherwise */
+   CombFilterMem *comb_mem;
+   SpeexCallback speex_callbacks[SPEEX_MAX_CALLBACKS];
+
+   SpeexCallback user_callback;
+
+   /*Vocoder data*/
+   float  voc_m1;
+   float  voc_m2;
+   float  voc_mean;
+   int    voc_offset;
+
+   int    dtx_enabled;
+} DecState;
+
+/** Initializes encoder state*/
+void *nb_encoder_init(const SpeexMode *m);
+
+/** De-allocates encoder state resources*/
+void nb_encoder_destroy(void *state);
+
+/** Encodes one frame*/
+int nb_encode(void *state, void *in, SpeexBits *bits);
+
+
+/** Initializes decoder state*/
+void *nb_decoder_init(const SpeexMode *m);
+
+/** De-allocates decoder state resources*/
+void nb_decoder_destroy(void *state);
+
+/** Decodes one frame*/
+int nb_decode(void *state, SpeexBits *bits, void *out);
+
+/** ioctl-like function for controlling a narrowband encoder */
+int nb_encoder_ctl(void *state, int request, void *ptr);
+
+/** ioctl-like function for controlling a narrowband decoder */
+int nb_decoder_ctl(void *state, int request, void *ptr);
+
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/preprocess.c b/utils/iaxclient/lib/libspeex/preprocess.c
new file mode 100644 (file)
index 0000000..f643895
--- /dev/null
@@ -0,0 +1,1074 @@
+/* Copyright (C) 2003 Epic Games 
+   Written by Jean-Marc Valin
+
+   File: preprocess.c
+   Preprocessor with denoising based on the algorithm by Ephraim and Malah
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are
+   met:
+
+   1. Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+
+   2. 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.
+
+   3. The name of the author may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <math.h>
+#include "speex/speex_preprocess.h"
+#include "misc.h"
+#include "smallft.h"
+
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#define min(a,b) ((a) < (b) ? (a) : (b))
+
+#ifndef M_PI
+#define M_PI 3.14159263
+#endif
+
+#define SQRT_M_PI_2 0.88623
+#define LOUDNESS_EXP 2.5
+
+#define SPEEX_PROB_START_DEFAULT    0.35f
+#define SPEEX_PROB_CONTINUE_DEFAULT 0.20f
+
+#define NB_BANDS 8
+
+#define ZMIN .1
+#define ZMAX .316
+#define ZMIN_1 10
+#define LOG_MIN_MAX_1 0.86859
+
+static void conj_window(float *w, int len)
+{
+   int i;
+   for (i=0;i<len;i++)
+   {
+      float x=4*((float)i)/len;
+      int inv=0;
+      if (x<1)
+      {
+      } else if (x<2)
+      {
+         x=2-x;
+         inv=1;
+      } else if (x<3)
+      {
+         x=x-2;
+         inv=1;
+      } else {
+         x=4-x;
+      }
+      x*=1.9979;
+      w[i]=(.5-.5*cos(x))*(.5-.5*cos(x));
+      if (inv)
+         w[i]=1-w[i];
+      w[i]=sqrt(w[i]);
+   }
+}
+
+/* This function approximates the gain function 
+   y = gamma(1.25)^2 * M(-.25;1;-x) / sqrt(x)  
+   which multiplied by xi/(1+xi) is the optimal gain
+   in the loudness domain ( sqrt[amplitude] )
+*/
+static float hypergeom_gain(float x)
+{
+   int ind;
+   float integer, frac;
+   static const float table[21] = {
+      0.82157f, 1.02017f, 1.20461f, 1.37534f, 1.53363f, 1.68092f, 1.81865f, 
+      1.94811f, 2.07038f, 2.18638f, 2.29688f, 2.40255f, 2.50391f, 2.60144f, 
+      2.69551f, 2.78647f, 2.87458f, 2.96015f, 3.04333f, 3.12431f, 3.20326f};
+   
+   if (x>9.5)
+      return 1+.12/x;
+
+   integer = floor(2*x);
+   frac = 2*x-integer;
+   ind = (int)integer;
+   /*if (ind > 20 || ind < 0)
+   fprintf (stderr, "error: %d %f\n", ind, x);*/
+   return ((1-frac)*table[ind] + frac*table[ind+1])/sqrt(x+.0001f);
+}
+
+SpeexPreprocessState *speex_preprocess_state_init(int frame_size, int sampling_rate)
+{
+   int i;
+   int N, N3, N4;
+
+   SpeexPreprocessState *st = (SpeexPreprocessState *)speex_alloc(sizeof(SpeexPreprocessState));
+   st->frame_size = frame_size;
+
+   /* Round ps_size down to the nearest power of two */
+#if 0
+   i=1;
+   st->ps_size = st->frame_size;
+   while(1)
+   {
+      if (st->ps_size & ~i)
+      {
+         st->ps_size &= ~i;
+         i<<=1;
+      } else {
+         break;
+      }
+   }
+   
+   
+   if (st->ps_size < 3*st->frame_size/4)
+      st->ps_size = st->ps_size * 3 / 2;
+#else
+   st->ps_size = st->frame_size;
+#endif
+
+   N = st->ps_size;
+   N3 = 2*N - st->frame_size;
+   N4 = st->frame_size - N3;
+   
+   st->sampling_rate = sampling_rate;
+   st->denoise_enabled = 1;
+   st->agc_enabled = 0;
+   st->agc_level = 8000;
+   st->vad_enabled = 0;
+   st->dereverb_enabled = 0;
+   st->reverb_decay = .5;
+   st->reverb_level = .2;
+
+   st->speech_prob_start = SPEEX_PROB_START_DEFAULT;
+   st->speech_prob_continue = SPEEX_PROB_CONTINUE_DEFAULT;
+
+   st->frame = (float*)speex_alloc(2*N*sizeof(float));
+   st->ps = (float*)speex_alloc(N*sizeof(float));
+   st->gain2 = (float*)speex_alloc(N*sizeof(float));
+   st->window = (float*)speex_alloc(2*N*sizeof(float));
+   st->noise = (float*)speex_alloc(N*sizeof(float));
+   st->reverb_estimate = (float*)speex_alloc(N*sizeof(float));
+   st->old_ps = (float*)speex_alloc(N*sizeof(float));
+   st->gain = (float*)speex_alloc(N*sizeof(float));
+   st->prior = (float*)speex_alloc(N*sizeof(float));
+   st->post = (float*)speex_alloc(N*sizeof(float));
+   st->loudness_weight = (float*)speex_alloc(N*sizeof(float));
+   st->inbuf = (float*)speex_alloc(N3*sizeof(float));
+   st->outbuf = (float*)speex_alloc(N3*sizeof(float));
+   st->echo_noise = (float*)speex_alloc(N*sizeof(float));
+
+   st->S = (float*)speex_alloc(N*sizeof(float));
+   st->Smin = (float*)speex_alloc(N*sizeof(float));
+   st->Stmp = (float*)speex_alloc(N*sizeof(float));
+   st->update_prob = (float*)speex_alloc(N*sizeof(float));
+
+   st->zeta = (float*)speex_alloc(N*sizeof(float));
+   st->Zpeak = 0;
+   st->Zlast = 0;
+
+   st->noise_bands = (float*)speex_alloc(NB_BANDS*sizeof(float));
+   st->noise_bands2 = (float*)speex_alloc(NB_BANDS*sizeof(float));
+   st->speech_bands = (float*)speex_alloc(NB_BANDS*sizeof(float));
+   st->speech_bands2 = (float*)speex_alloc(NB_BANDS*sizeof(float));
+   st->noise_bandsN = st->speech_bandsN = 1;
+
+   conj_window(st->window, 2*N3);
+   for (i=2*N3;i<2*st->ps_size;i++)
+      st->window[i]=1;
+   
+   if (N4>0)
+   {
+      for (i=N3-1;i>=0;i--)
+      {
+         st->window[i+N3+N4]=st->window[i+N3];
+         st->window[i+N3]=1;
+      }
+   }
+   for (i=0;i<N;i++)
+   {
+      st->noise[i]=1e4;
+      st->reverb_estimate[i]=0.;
+      st->old_ps[i]=1e4;
+      st->gain[i]=1;
+      st->post[i]=1;
+      st->prior[i]=1;
+   }
+
+   for (i=0;i<N3;i++)
+   {
+      st->inbuf[i]=0;
+      st->outbuf[i]=0;
+   }
+
+   for (i=0;i<N;i++)
+   {
+      float ff=((float)i)*.5*sampling_rate/((float)N);
+      st->loudness_weight[i] = .35f-.35f*ff/16000.f+.73f*exp(-.5f*(ff-3800)*(ff-3800)/9e5f);
+      if (st->loudness_weight[i]<.01f)
+         st->loudness_weight[i]=.01f;
+      st->loudness_weight[i] *= st->loudness_weight[i];
+   }
+
+   st->speech_prob = 0;
+   st->last_speech = 1000;
+   st->loudness = pow(6000,LOUDNESS_EXP);
+   st->loudness2 = 6000;
+   st->nb_loudness_adapt = 0;
+
+   st->fft_lookup = (struct drft_lookup*)speex_alloc(sizeof(struct drft_lookup));
+   spx_drft_init(st->fft_lookup,2*N);
+
+   st->nb_adapt=0;
+   st->consec_noise=0;
+   st->nb_preprocess=0;
+   return st;
+}
+
+void speex_preprocess_state_destroy(SpeexPreprocessState *st)
+{
+   speex_free(st->frame);
+   speex_free(st->ps);
+   speex_free(st->gain2);
+   speex_free(st->window);
+   speex_free(st->noise);
+   speex_free(st->reverb_estimate);
+   speex_free(st->old_ps);
+   speex_free(st->gain);
+   speex_free(st->prior);
+   speex_free(st->post);
+   speex_free(st->loudness_weight);
+   speex_free(st->echo_noise);
+
+   speex_free(st->S);
+   speex_free(st->Smin);
+   speex_free(st->Stmp);
+   speex_free(st->update_prob);
+   speex_free(st->zeta);
+
+   speex_free(st->noise_bands);
+   speex_free(st->noise_bands2);
+   speex_free(st->speech_bands);
+   speex_free(st->speech_bands2);
+
+   speex_free(st->inbuf);
+   speex_free(st->outbuf);
+
+   spx_drft_clear(st->fft_lookup);
+   speex_free(st->fft_lookup);
+
+   speex_free(st);
+}
+
+static void update_noise(SpeexPreprocessState *st, float *ps, float *echo)
+{
+   int i;
+   float beta;
+   st->nb_adapt++;
+   beta=1.0f/st->nb_adapt;
+   if (beta < .05f)
+      beta=.05f;
+   
+   if (!echo)
+   {
+      for (i=0;i<st->ps_size;i++)
+         st->noise[i] = (1.f-beta)*st->noise[i] + beta*ps[i];
+   } else {
+      for (i=0;i<st->ps_size;i++)
+         st->noise[i] = (1.f-beta)*st->noise[i] + beta*max(1.f,ps[i]-echo[i]); 
+#if 0
+      for (i=0;i<st->ps_size;i++)
+         st->noise[i] = 0;
+#endif
+   }
+}
+
+static int speex_compute_vad(SpeexPreprocessState *st, float *ps, float mean_prior, float mean_post)
+{
+   int i, is_speech=0;
+   int N = st->ps_size;
+   float scale=.5f/N;
+
+   /* FIXME: Clean this up a bit */
+   {
+      float bands[NB_BANDS];
+      int j;
+      float p0, p1;
+      float tot_loudness=0;
+      float x = sqrt(mean_post);
+
+      for (i=5;i<N-10;i++)
+      {
+         tot_loudness += scale*st->ps[i] * st->loudness_weight[i];
+      }
+
+      for (i=0;i<NB_BANDS;i++)
+      {
+         bands[i]=1e4f;
+         for (j=i*N/NB_BANDS;j<(i+1)*N/NB_BANDS;j++)
+         {
+            bands[i] += ps[j];
+         }
+         bands[i]=log(bands[i]);
+      }
+      
+      /*p1 = .0005+.6*exp(-.5*(x-.4)*(x-.4)*11)+.1*exp(-1.2*x);
+      if (x<1.5)
+         p0=.1*exp(2*(x-1.5));
+      else
+         p0=.02+.1*exp(-.2*(x-1.5));
+      */
+
+      p0=1.f/(1.f+exp(3.f*(1.5f-x)));
+      p1=1.f-p0;
+
+      /*fprintf (stderr, "%f %f ", p0, p1);*/
+      /*p0 *= .99*st->speech_prob + .01*(1-st->speech_prob);
+      p1 *= .01*st->speech_prob + .99*(1-st->speech_prob);
+      
+      st->speech_prob = p0/(p1+p0);
+      */
+
+      if (st->noise_bandsN < 50 || st->speech_bandsN < 50)
+      {
+         if (mean_post > 5.f)
+         {
+            float adapt = 1./st->speech_bandsN++;
+            if (adapt<.005f)
+               adapt = .005f;
+            for (i=0;i<NB_BANDS;i++)
+            {
+               st->speech_bands[i] = (1.f-adapt)*st->speech_bands[i] + adapt*bands[i];
+               /*st->speech_bands2[i] = (1-adapt)*st->speech_bands2[i] + adapt*bands[i]*bands[i];*/
+               st->speech_bands2[i] = (1.f-adapt)*st->speech_bands2[i] + adapt*(bands[i]-st->speech_bands[i])*(bands[i]-st->speech_bands[i]);
+            }
+         } else {
+            float adapt = 1./st->noise_bandsN++;
+            if (adapt<.005f)
+               adapt = .005f;
+            for (i=0;i<NB_BANDS;i++)
+            {
+               st->noise_bands[i] = (1.f-adapt)*st->noise_bands[i] + adapt*bands[i];
+               /*st->noise_bands2[i] = (1-adapt)*st->noise_bands2[i] + adapt*bands[i]*bands[i];*/
+               st->noise_bands2[i] = (1.f-adapt)*st->noise_bands2[i] + adapt*(bands[i]-st->noise_bands[i])*(bands[i]-st->noise_bands[i]);
+            }
+         }
+      }
+      p0=p1=1;
+      for (i=0;i<NB_BANDS;i++)
+      {
+         float noise_var, speech_var;
+         float noise_mean, speech_mean;
+         float tmp1, tmp2, pr;
+
+         /*noise_var = 1.01*st->noise_bands2[i] - st->noise_bands[i]*st->noise_bands[i];
+           speech_var = 1.01*st->speech_bands2[i] - st->speech_bands[i]*st->speech_bands[i];*/
+         noise_var = st->noise_bands2[i];
+         speech_var = st->speech_bands2[i];
+         if (noise_var < .1f)
+            noise_var = .1f;
+         if (speech_var < .1f)
+            speech_var = .1f;
+         
+         /*speech_var = sqrt(speech_var*noise_var);
+           noise_var = speech_var;*/
+         if (speech_var < .05f*speech_var)
+            noise_var = .05f*speech_var; 
+         if (speech_var < .05f*noise_var)
+            speech_var = .05f*noise_var;
+         
+         if (bands[i] < st->noise_bands[i])
+            speech_var = noise_var;
+         if (bands[i] > st->speech_bands[i])
+            noise_var = speech_var;
+
+         speech_mean = st->speech_bands[i];
+         noise_mean = st->noise_bands[i];
+         if (noise_mean < speech_mean - 5.f)
+            noise_mean = speech_mean - 5.f;
+
+         tmp1 = exp(-.5f*(bands[i]-speech_mean)*(bands[i]-speech_mean)/speech_var)/sqrt(2.f*M_PI*speech_var);
+         tmp2 = exp(-.5f*(bands[i]-noise_mean)*(bands[i]-noise_mean)/noise_var)/sqrt(2.f*M_PI*noise_var);
+         /*fprintf (stderr, "%f ", (float)(p0/(.01+p0+p1)));*/
+         /*fprintf (stderr, "%f ", (float)(bands[i]));*/
+         pr = tmp1/(1e-25+tmp1+tmp2);
+         /*if (bands[i] < st->noise_bands[i])
+            pr=.01;
+         if (bands[i] > st->speech_bands[i] && pr < .995)
+         pr=.995;*/
+         if (pr>.999f)
+            pr=.999f;
+         if (pr<.001f)
+            pr=.001f;
+         /*fprintf (stderr, "%f ", pr);*/
+         p0 *= pr;
+         p1 *= (1-pr);
+      }
+
+      p0 = pow(p0,.2);
+      p1 = pow(p1,.2);      
+      
+#if 1
+      p0 *= 2.f;
+      p0=p0/(p1+p0);
+      if (st->last_speech>20) 
+      {
+         float tmp = sqrt(tot_loudness)/st->loudness2;
+         tmp = 1.f-exp(-10.f*tmp);
+         if (p0>tmp)
+            p0=tmp;
+      }
+      p1=1-p0;
+#else
+      if (sqrt(tot_loudness) < .6f*st->loudness2 && p0>15.f*p1)
+         p0=15.f*p1;
+      if (sqrt(tot_loudness) < .45f*st->loudness2 && p0>7.f*p1)
+         p0=7.f*p1;
+      if (sqrt(tot_loudness) < .3f*st->loudness2 && p0>3.f*p1)
+         p0=3.f*p1;
+      if (sqrt(tot_loudness) < .15f*st->loudness2 && p0>p1)
+         p0=p1;
+      /*fprintf (stderr, "%f %f ", (float)(sqrt(tot_loudness) /( .25*st->loudness2)), p0/(p1+p0));*/
+#endif
+
+      p0 *= .99f*st->speech_prob + .01f*(1-st->speech_prob);
+      p1 *= .01f*st->speech_prob + .99f*(1-st->speech_prob);
+      
+      st->speech_prob = p0/(1e-25f+p1+p0);
+      /*fprintf (stderr, "%f %f %f ", tot_loudness, st->loudness2, st->speech_prob);*/
+
+      if (st->speech_prob > st->speech_prob_start 
+         || (st->last_speech < 20 && st->speech_prob > st->speech_prob_continue))
+      {
+         is_speech = 1;
+         st->last_speech = 0;
+      } else {
+         st->last_speech++;
+         if (st->last_speech<20)
+           is_speech = 1;
+      }
+
+      if (st->noise_bandsN > 50 && st->speech_bandsN > 50)
+      {
+         if (mean_post > 5)
+         {
+            float adapt = 1./st->speech_bandsN++;
+            if (adapt<.005f)
+               adapt = .005f;
+            for (i=0;i<NB_BANDS;i++)
+            {
+               st->speech_bands[i] = (1-adapt)*st->speech_bands[i] + adapt*bands[i];
+               /*st->speech_bands2[i] = (1-adapt)*st->speech_bands2[i] + adapt*bands[i]*bands[i];*/
+               st->speech_bands2[i] = (1-adapt)*st->speech_bands2[i] + adapt*(bands[i]-st->speech_bands[i])*(bands[i]-st->speech_bands[i]);
+            }
+         } else {
+            float adapt = 1./st->noise_bandsN++;
+            if (adapt<.005f)
+               adapt = .005f;
+            for (i=0;i<NB_BANDS;i++)
+            {
+               st->noise_bands[i] = (1-adapt)*st->noise_bands[i] + adapt*bands[i];
+               /*st->noise_bands2[i] = (1-adapt)*st->noise_bands2[i] + adapt*bands[i]*bands[i];*/
+               st->noise_bands2[i] = (1-adapt)*st->noise_bands2[i] + adapt*(bands[i]-st->noise_bands[i])*(bands[i]-st->noise_bands[i]);
+            }
+         }
+      }
+
+
+   }
+
+   return is_speech;
+}
+
+static void speex_compute_agc(SpeexPreprocessState *st, float mean_prior)
+{
+   int i;
+   int N = st->ps_size;
+   float scale=.5f/N;
+   float agc_gain;
+   int freq_start, freq_end;
+   float active_bands = 0;
+
+   freq_start = (int)(300.0f*2*N/st->sampling_rate);
+   freq_end   = (int)(2000.0f*2*N/st->sampling_rate);
+   for (i=freq_start;i<freq_end;i++)
+   {
+      if (st->S[i] > 20.f*st->Smin[i]+1000.f)
+         active_bands+=1;
+   }
+   active_bands /= (freq_end-freq_start+1);
+
+   if (active_bands > .2f)
+   {
+      float loudness=0.f;
+      float rate, rate2=.2f;
+      st->nb_loudness_adapt++;
+      rate=2.0f/(1+st->nb_loudness_adapt);
+      if (rate < .05f)
+         rate = .05f;
+      if (rate < .1f && pow(loudness, LOUDNESS_EXP) > st->loudness)
+         rate = .1f;
+      if (rate < .2f && pow(loudness, LOUDNESS_EXP) > 3.f*st->loudness)
+         rate = .2f;
+      if (rate < .4f && pow(loudness, LOUDNESS_EXP) > 10.f*st->loudness)
+         rate = .4f;
+
+      for (i=2;i<N;i++)
+      {
+         loudness += scale*st->ps[i] * st->gain2[i] * st->gain2[i] * st->loudness_weight[i];
+      }
+      loudness=sqrt(loudness);
+      /*if (loudness < 2*pow(st->loudness, 1.0/LOUDNESS_EXP) &&
+        loudness*2 > pow(st->loudness, 1.0/LOUDNESS_EXP))*/
+      st->loudness = (1-rate)*st->loudness + (rate)*pow(loudness, LOUDNESS_EXP);
+      
+      st->loudness2 = (1-rate2)*st->loudness2 + rate2*pow(st->loudness, 1.0f/LOUDNESS_EXP);
+
+      loudness = pow(st->loudness, 1.0f/LOUDNESS_EXP);
+
+      /*fprintf (stderr, "%f %f %f\n", loudness, st->loudness2, rate);*/
+   }
+   
+   agc_gain = st->agc_level/st->loudness2;
+   /*fprintf (stderr, "%f %f %f %f\n", active_bands, st->loudness, st->loudness2, agc_gain);*/
+   if (agc_gain>200)
+      agc_gain = 200;
+
+   for (i=0;i<N;i++)
+      st->gain2[i] *= agc_gain;
+   
+}
+
+static void preprocess_analysis(SpeexPreprocessState *st, spx_int16_t *x)
+{
+   int i;
+   int N = st->ps_size;
+   int N3 = 2*N - st->frame_size;
+   int N4 = st->frame_size - N3;
+   float *ps=st->ps;
+
+   /* 'Build' input frame */
+   for (i=0;i<N3;i++)
+      st->frame[i]=st->inbuf[i];
+   for (i=0;i<st->frame_size;i++)
+      st->frame[N3+i]=x[i];
+   
+   /* Update inbuf */
+   for (i=0;i<N3;i++)
+      st->inbuf[i]=x[N4+i];
+
+   /* Windowing */
+   for (i=0;i<2*N;i++)
+      st->frame[i] *= st->window[i];
+
+   /* Perform FFT */
+   spx_drft_forward(st->fft_lookup, st->frame);
+
+   /* Power spectrum */
+   ps[0]=1;
+   for (i=1;i<N;i++)
+      ps[i]=1+st->frame[2*i-1]*st->frame[2*i-1] + st->frame[2*i]*st->frame[2*i];
+
+}
+
+static void update_noise_prob(SpeexPreprocessState *st)
+{
+   int i;
+   int N = st->ps_size;
+
+   for (i=1;i<N-1;i++)
+      st->S[i] = 100.f+ .8f*st->S[i] + .05f*st->ps[i-1]+.1f*st->ps[i]+.05f*st->ps[i+1];
+   
+   if (st->nb_preprocess<1)
+   {
+      for (i=1;i<N-1;i++)
+         st->Smin[i] = st->Stmp[i] = st->S[i]+100.f;
+   }
+
+   if (st->nb_preprocess%200==0)
+   {
+      for (i=1;i<N-1;i++)
+      {
+         st->Smin[i] = min(st->Stmp[i], st->S[i]);
+         st->Stmp[i] = st->S[i];
+      }
+   } else {
+      for (i=1;i<N-1;i++)
+      {
+         st->Smin[i] = min(st->Smin[i], st->S[i]);
+         st->Stmp[i] = min(st->Stmp[i], st->S[i]);      
+      }
+   }
+   for (i=1;i<N-1;i++)
+   {
+      st->update_prob[i] *= .2f;
+      if (st->S[i] > 2.5*st->Smin[i])
+         st->update_prob[i] += .8f;
+      /*fprintf (stderr, "%f ", st->S[i]/st->Smin[i]);*/
+      /*fprintf (stderr, "%f ", st->update_prob[i]);*/
+   }
+
+}
+
+#define NOISE_OVERCOMPENS 1.4
+
+int speex_preprocess(SpeexPreprocessState *st, spx_int16_t *x, float *echo)
+{
+   int i;
+   int is_speech=1;
+   float mean_post=0;
+   float mean_prior=0;
+   int N = st->ps_size;
+   int N3 = 2*N - st->frame_size;
+   int N4 = st->frame_size - N3;
+   float scale=.5f/N;
+   float *ps=st->ps;
+   float Zframe=0, Pframe;
+
+   preprocess_analysis(st, x);
+
+   update_noise_prob(st);
+
+   st->nb_preprocess++;
+
+   /* Noise estimation always updated for the 20 first times */
+   if (st->nb_adapt<10)
+   {
+      update_noise(st, ps, echo);
+   }
+
+   /* Deal with residual echo if provided */
+   if (echo)
+      for (i=1;i<N;i++)
+         st->echo_noise[i] = (.3f*st->echo_noise[i] + echo[i]);
+
+   /* Compute a posteriori SNR */
+   for (i=1;i<N;i++)
+   {
+      st->post[i] = ps[i]/(1.f+NOISE_OVERCOMPENS*st->noise[i]+st->echo_noise[i]+st->reverb_estimate[i]) - 1.f;
+      if (st->post[i]>100.f)
+         st->post[i]=100.f;
+      /*if (st->post[i]<0)
+        st->post[i]=0;*/
+      mean_post+=st->post[i];
+   }
+   mean_post /= N;
+   if (mean_post<0.f)
+      mean_post=0.f;
+
+   /* Special case for first frame */
+   if (st->nb_adapt==1)
+      for (i=1;i<N;i++)
+         st->old_ps[i] = ps[i];
+
+   /* Compute a priori SNR */
+   {
+      /* A priori update rate */
+      float gamma;
+      float min_gamma=0.12f;
+      gamma = 1.0f/st->nb_preprocess;
+
+      /*Make update rate smaller when there's no speech*/
+#if 0
+      if (mean_post<3.5 && mean_prior < 1)
+         min_gamma *= (mean_post+.5);
+      else
+         min_gamma *= 4.;
+#else
+      min_gamma = .1f*fabs(mean_prior - mean_post)*fabs(mean_prior - mean_post);
+      if (min_gamma>.15f)
+         min_gamma = .15f;
+      if (min_gamma<.02f)
+         min_gamma = .02f;
+#endif
+      /*min_gamma = .08;*/
+
+      /*if (gamma<min_gamma)*/
+         gamma=min_gamma;
+      gamma = .1;
+      for (i=1;i<N;i++)
+      {
+         
+         /* A priori SNR update */
+         st->prior[i] = gamma*max(0.0f,st->post[i]) +
+         (1.f-gamma)*st->gain[i]*st->gain[i]*st->old_ps[i]/(1.f+NOISE_OVERCOMPENS*st->noise[i]+st->echo_noise[i]+st->reverb_estimate[i]);
+         
+         if (st->prior[i]>100.f)
+            st->prior[i]=100.f;
+         
+         mean_prior+=st->prior[i];
+      }
+   }
+   mean_prior /= N;
+
+#if 0
+   for (i=0;i<N;i++)
+   {
+      fprintf (stderr, "%f ", st->prior[i]);
+   }
+   fprintf (stderr, "\n");
+#endif
+   /*fprintf (stderr, "%f %f\n", mean_prior,mean_post);*/
+
+   if (st->nb_preprocess>=20)
+   {
+      int do_update = 0;
+      float noise_ener=0, sig_ener=0;
+      /* If SNR is low (both a priori and a posteriori), update the noise estimate*/
+      /*if (mean_prior<.23 && mean_post < .5)*/
+      if (mean_prior<.23f && mean_post < .5f)
+         do_update = 1;
+      for (i=1;i<N;i++)
+      {
+         noise_ener += st->noise[i];
+         sig_ener += ps[i];
+      }
+      if (noise_ener > 3.f*sig_ener)
+         do_update = 1;
+      /*do_update = 0;*/
+      if (do_update)
+      {
+         st->consec_noise++;
+      } else {
+         st->consec_noise=0;
+      }
+   }
+
+   if (st->vad_enabled)
+      is_speech = speex_compute_vad(st, ps, mean_prior, mean_post);
+
+
+   if (st->consec_noise>=3)
+   {
+      update_noise(st, st->old_ps, echo);
+   } else {
+      for (i=1;i<N-1;i++)
+      {
+         if (st->update_prob[i]<.5f || st->ps[i] < st->noise[i])
+         {
+            if (echo)
+               st->noise[i] = .90f*st->noise[i] + .1f*max(1.0f,st->ps[i]-echo[i]);
+            else
+               st->noise[i] = .90f*st->noise[i] + .1f*st->ps[i];
+         }
+      }
+   }
+
+   for (i=1;i<N;i++)
+   {
+      st->zeta[i] = .7f*st->zeta[i] + .3f*st->prior[i];
+   }
+
+   {
+      int freq_start = (int)(300.0f*2.f*N/st->sampling_rate);
+      int freq_end   = (int)(2000.0f*2.f*N/st->sampling_rate);
+      for (i=freq_start;i<freq_end;i++)
+      {
+         Zframe += st->zeta[i];         
+      }
+   }
+
+   Zframe /= N;
+   if (Zframe<ZMIN)
+   {
+      Pframe = 0;
+   } else {
+      if (Zframe > 1.5f*st->Zlast)
+      {
+         Pframe = 1.f;
+         st->Zpeak = Zframe;
+         if (st->Zpeak > 10.f)
+            st->Zpeak = 10.f;
+         if (st->Zpeak < 1.f)
+            st->Zpeak = 1.f;
+      } else {
+         if (Zframe < st->Zpeak*ZMIN)
+         {
+            Pframe = 0;
+         } else if (Zframe > st->Zpeak*ZMAX)
+         {
+            Pframe = 1;
+         } else {
+            Pframe = log(Zframe/(st->Zpeak*ZMIN)) / log(ZMAX/ZMIN);
+         }
+      }
+   }
+   st->Zlast = Zframe;
+
+   /*fprintf (stderr, "%f\n", Pframe);*/
+   /* Compute gain according to the Ephraim-Malah algorithm */
+   for (i=1;i<N;i++)
+   {
+      float MM;
+      float theta;
+      float prior_ratio;
+      float p, q;
+      float zeta1;
+      float P1;
+
+      prior_ratio = st->prior[i]/(1.0001f+st->prior[i]);
+      theta = (1.f+st->post[i])*prior_ratio;
+
+      if (i==1 || i==N-1)
+         zeta1 = st->zeta[i];
+      else
+         zeta1 = .25f*st->zeta[i-1] + .5f*st->zeta[i] + .25f*st->zeta[i+1];
+      if (zeta1<ZMIN)
+         P1 = 0.f;
+      else if (zeta1>ZMAX)
+         P1 = 1.f;
+      else
+         P1 = LOG_MIN_MAX_1 * log(ZMIN_1*zeta1);
+  
+      /*P1 = log(zeta1/ZMIN)/log(ZMAX/ZMIN);*/
+      
+      /* FIXME: add global prob (P2) */
+      q = 1-Pframe*P1;
+      q = 1-P1;
+      if (q>.95f)
+         q=.95f;
+      p=1.f/(1.f + (q/(1.f-q))*(1.f+st->prior[i])*exp(-theta));
+      /*p=1;*/
+
+#if 0
+      /* log-spectral magnitude estimator */
+      if (theta<6)
+         MM = 0.74082*pow(theta+1,.61)/sqrt(.0001+theta);
+      else
+         MM=1;
+#else
+      /* Optimal estimator for loudness domain */
+      MM = hypergeom_gain(theta);
+#endif
+
+      st->gain[i] = prior_ratio * MM;
+      /*Put some (very arbitraty) limit on the gain*/
+      if (st->gain[i]>2.f)
+      {
+         st->gain[i]=2.f;
+      }
+      
+      st->reverb_estimate[i] = st->reverb_decay*st->reverb_estimate[i] + st->reverb_decay*st->reverb_level*st->gain[i]*st->gain[i]*st->ps[i];
+      if (st->denoise_enabled)
+      {
+         st->gain2[i]=p*p*st->gain[i];
+      } else {
+         st->gain2[i]=1.f;
+      }
+   }
+   st->gain2[0]=st->gain[0]=0.f;
+   st->gain2[N-1]=st->gain[N-1]=0.f;
+
+   if (st->agc_enabled)
+      speex_compute_agc(st, mean_prior);
+
+#if 0
+   if (!is_speech)
+   {
+      for (i=0;i<N;i++)
+         st->gain2[i] = 0;
+   }
+#if 0
+ else {
+      for (i=0;i<N;i++)
+         st->gain2[i] = 1;
+   }
+#endif
+#endif
+
+   /* Apply computed gain */
+   for (i=1;i<N;i++)
+   {
+      st->frame[2*i-1] *= st->gain2[i];
+      st->frame[2*i] *= st->gain2[i];
+   }
+
+   /* Get rid of the DC and very low frequencies */
+   st->frame[0]=0;
+   st->frame[1]=0;
+   st->frame[2]=0;
+   /* Nyquist frequency is mostly useless too */
+   st->frame[2*N-1]=0;
+
+   /* Inverse FFT with 1/N scaling */
+   spx_drft_backward(st->fft_lookup, st->frame);
+
+   for (i=0;i<2*N;i++)
+      st->frame[i] *= scale;
+
+   {
+      float max_sample=0;
+      for (i=0;i<2*N;i++)
+         if (fabs(st->frame[i])>max_sample)
+            max_sample = fabs(st->frame[i]);
+      if (max_sample>28000.f)
+      {
+         float damp = 28000.f/max_sample;
+         for (i=0;i<2*N;i++)
+            st->frame[i] *= damp;
+      }
+   }
+
+   for (i=0;i<2*N;i++)
+      st->frame[i] *= st->window[i];
+
+   /* Perform overlap and add */
+   for (i=0;i<N3;i++)
+      x[i] = st->outbuf[i] + st->frame[i];
+   for (i=0;i<N4;i++)
+      x[N3+i] = st->frame[N3+i];
+   
+   /* Update outbuf */
+   for (i=0;i<N3;i++)
+      st->outbuf[i] = st->frame[st->frame_size+i];
+
+   /* Save old power spectrum */
+   for (i=1;i<N;i++)
+      st->old_ps[i] = ps[i];
+
+   return is_speech;
+}
+
+void speex_preprocess_estimate_update(SpeexPreprocessState *st, spx_int16_t *x, float *echo)
+{
+   int i;
+   int N = st->ps_size;
+   int N3 = 2*N - st->frame_size;
+
+   float *ps=st->ps;
+
+   preprocess_analysis(st, x);
+
+   update_noise_prob(st);
+
+   st->nb_preprocess++;
+   
+   for (i=1;i<N-1;i++)
+   {
+      if (st->update_prob[i]<.5f || st->ps[i] < st->noise[i])
+      {
+         if (echo)
+            st->noise[i] = .90f*st->noise[i] + .1f*max(1.0f,st->ps[i]-echo[i]);
+         else
+            st->noise[i] = .90f*st->noise[i] + .1f*st->ps[i];
+      }
+   }
+
+   for (i=0;i<N3;i++)
+      st->outbuf[i] = x[st->frame_size-N3+i]*st->window[st->frame_size+i];
+
+   /* Save old power spectrum */
+   for (i=1;i<N;i++)
+      st->old_ps[i] = ps[i];
+
+   for (i=1;i<N;i++)
+      st->reverb_estimate[i] *= st->reverb_decay;
+}
+
+
+int speex_preprocess_ctl(SpeexPreprocessState *state, int request, void *ptr)
+{
+   int i;
+   SpeexPreprocessState *st;
+   st=(SpeexPreprocessState*)state;
+   switch(request)
+   {
+   case SPEEX_PREPROCESS_SET_DENOISE:
+      st->denoise_enabled = (*(int*)ptr);
+      break;
+   case SPEEX_PREPROCESS_GET_DENOISE:
+      (*(int*)ptr) = st->denoise_enabled;
+      break;
+
+   case SPEEX_PREPROCESS_SET_AGC:
+      st->agc_enabled = (*(int*)ptr);
+      break;
+   case SPEEX_PREPROCESS_GET_AGC:
+      (*(int*)ptr) = st->agc_enabled;
+      break;
+
+   case SPEEX_PREPROCESS_SET_AGC_LEVEL:
+      st->agc_level = (*(float*)ptr);
+      if (st->agc_level<1)
+         st->agc_level=1;
+      if (st->agc_level>32768)
+         st->agc_level=32768;
+      break;
+   case SPEEX_PREPROCESS_GET_AGC_LEVEL:
+      (*(float*)ptr) = st->agc_level;
+      break;
+
+   case SPEEX_PREPROCESS_SET_VAD:
+      st->vad_enabled = (*(int*)ptr);
+      break;
+   case SPEEX_PREPROCESS_GET_VAD:
+      (*(int*)ptr) = st->vad_enabled;
+      break;
+   
+   case SPEEX_PREPROCESS_SET_DEREVERB:
+      st->dereverb_enabled = (*(int*)ptr);
+      for (i=0;i<st->ps_size;i++)
+         st->reverb_estimate[i]=0;
+      break;
+   case SPEEX_PREPROCESS_GET_DEREVERB:
+      (*(int*)ptr) = st->dereverb_enabled;
+      break;
+
+   case SPEEX_PREPROCESS_SET_DEREVERB_LEVEL:
+      st->reverb_level = (*(float*)ptr);
+      break;
+   case SPEEX_PREPROCESS_GET_DEREVERB_LEVEL:
+      (*(float*)ptr) = st->reverb_level;
+      break;
+   
+   case SPEEX_PREPROCESS_SET_DEREVERB_DECAY:
+      st->reverb_decay = (*(float*)ptr);
+      break;
+   case SPEEX_PREPROCESS_GET_DEREVERB_DECAY:
+      (*(float*)ptr) = st->reverb_decay;
+      break;
+
+   case SPEEX_PREPROCESS_SET_PROB_START:
+      st->speech_prob_start = (*(float*)ptr);
+      if ( st->speech_prob_start > 1 )
+         st->speech_prob_start = st->speech_prob_start / 100;
+      if ( st->speech_prob_start > 1 || st->speech_prob_start < 0 )
+         st->speech_prob_start = SPEEX_PROB_START_DEFAULT;
+      break;
+   case SPEEX_PREPROCESS_GET_PROB_START:
+      (*(float*)ptr) = st->speech_prob_start ;
+      break;
+
+   case SPEEX_PREPROCESS_SET_PROB_CONTINUE:
+      st->speech_prob_continue = (*(float*)ptr);
+      if ( st->speech_prob_continue > 1 )
+         st->speech_prob_continue = st->speech_prob_continue / 100;
+      if ( st->speech_prob_continue > 1 || st->speech_prob_continue < 0 )
+         st->speech_prob_continue = SPEEX_PROB_CONTINUE_DEFAULT;
+      break;
+   case SPEEX_PREPROCESS_GET_PROB_CONTINUE:
+      (*(float*)ptr) = st->speech_prob_continue;
+      break;
+
+   default:
+      speex_warning_int("Unknown speex_preprocess_ctl request: ", request);
+      return -1;
+   }
+   return 0;
+}
diff --git a/utils/iaxclient/lib/libspeex/quant_lsp.c b/utils/iaxclient/lib/libspeex/quant_lsp.c
new file mode 100644 (file)
index 0000000..7bd0b91
--- /dev/null
@@ -0,0 +1,441 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: quant_lsp.c
+   LSP vector quantization
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "quant_lsp.h"
+#include <math.h>
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+
+#include "misc.h"
+
+#ifdef FIXED_POINT
+
+#define LSP_LINEAR(i) (SHL16(i+1,11))
+#define LSP_LINEAR_HIGH(i) (ADD16(MULT16_16_16(i,2560),6144))
+#define LSP_DIV_256(x) (SHL16((spx_word16_t)x, 5))
+#define LSP_DIV_512(x) (SHL16((spx_word16_t)x, 4))
+#define LSP_DIV_1024(x) (SHL16((spx_word16_t)x, 3))
+#define LSP_PI 25736
+
+#else
+
+#define LSP_LINEAR(i) (.25*(i)+.25)
+#define LSP_LINEAR_HIGH(i) (.3125*(i)+.75)
+#define LSP_SCALE 256.
+#define LSP_DIV_256(x) (0.0039062*(x))
+#define LSP_DIV_512(x) (0.0019531*(x))
+#define LSP_DIV_1024(x) (0.00097656*(x))
+#define LSP_PI M_PI
+
+#endif
+
+static void compute_quant_weights(spx_lsp_t *qlsp, spx_word16_t *quant_weight, int order)
+{
+   int i;
+   spx_word16_t tmp1, tmp2;
+   for (i=0;i<order;i++)
+   {
+      if (i==0)
+         tmp1 = qlsp[i];
+      else
+         tmp1 = qlsp[i]-qlsp[i-1];
+      if (i==order-1)
+         tmp2 = LSP_PI-qlsp[i];
+      else
+         tmp2 = qlsp[i+1]-qlsp[i];
+      if (tmp2<tmp1)
+         tmp1 = tmp2;
+#ifdef FIXED_POINT
+      quant_weight[i] = DIV32_16(81920,ADD16(300,tmp1));
+#else
+      quant_weight[i] = 10/(.04+tmp1);
+#endif
+   }
+
+}
+
+/* Note: x is modified*/
+static int lsp_quant(spx_word16_t *x, const signed char *cdbk, int nbVec, int nbDim)
+{
+   int i,j;
+   spx_word32_t dist;
+   spx_word16_t tmp;
+   spx_word32_t best_dist=0;
+   int best_id=0;
+   const signed char *ptr=cdbk;
+   for (i=0;i<nbVec;i++)
+   {
+      dist=0;
+      for (j=0;j<nbDim;j++)
+      {
+         tmp=SUB16(x[j],SHL16((spx_word16_t)*ptr++,5));
+         dist=MAC16_16(dist,tmp,tmp);
+      }
+      if (dist<best_dist || i==0)
+      {
+         best_dist=dist;
+         best_id=i;
+      }
+   }
+
+   for (j=0;j<nbDim;j++)
+      x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5));
+    
+   return best_id;
+}
+
+/* Note: x is modified*/
+static int lsp_weight_quant(spx_word16_t *x, spx_word16_t *weight, const signed char *cdbk, int nbVec, int nbDim)
+{
+   int i,j;
+   spx_word32_t dist;
+   spx_word16_t tmp;
+   spx_word32_t best_dist=0;
+   int best_id=0;
+   const signed char *ptr=cdbk;
+   for (i=0;i<nbVec;i++)
+   {
+      dist=0;
+      for (j=0;j<nbDim;j++)
+      {
+         tmp=SUB16(x[j],SHL16((spx_word16_t)*ptr++,5));
+         dist=MAC16_32_Q15(dist,weight[j],MULT16_16(tmp,tmp));
+      }
+      if (dist<best_dist || i==0)
+      {
+         best_dist=dist;
+         best_id=i;
+      }
+   }
+   
+   for (j=0;j<nbDim;j++)
+      x[j] = SUB16(x[j],SHL16((spx_word16_t)cdbk[best_id*nbDim+j],5));
+   return best_id;
+}
+
+
+void lsp_quant_nb(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
+{
+   int i;
+   int id;
+   spx_word16_t quant_weight[10];
+   
+   for (i=0;i<order;i++)
+      qlsp[i]=lsp[i];
+
+   compute_quant_weights(qlsp, quant_weight, order);
+
+   for (i=0;i<order;i++)
+      qlsp[i]=SUB16(qlsp[i],LSP_LINEAR(i));
+
+#ifndef FIXED_POINT
+   for (i=0;i<order;i++)
+      qlsp[i] = LSP_SCALE*qlsp[i];
+#endif
+   id = lsp_quant(qlsp, cdbk_nb, NB_CDBK_SIZE, order);
+   speex_bits_pack(bits, id, 6);
+
+   for (i=0;i<order;i++)
+      qlsp[i]*=2;
+   id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low1, NB_CDBK_SIZE_LOW1, 5);
+   speex_bits_pack(bits, id, 6);
+
+   for (i=0;i<5;i++)
+      qlsp[i]*=2;
+
+   id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low2, NB_CDBK_SIZE_LOW2, 5);
+   speex_bits_pack(bits, id, 6);
+
+   id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high1, NB_CDBK_SIZE_HIGH1, 5);
+   speex_bits_pack(bits, id, 6);
+
+   for (i=5;i<10;i++)
+      qlsp[i]*=2;
+
+   id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high2, NB_CDBK_SIZE_HIGH2, 5);
+   speex_bits_pack(bits, id, 6);
+
+#ifdef FIXED_POINT
+   for (i=0;i<order;i++)
+      qlsp[i]=PSHR16(qlsp[i],2);
+#else
+   for (i=0;i<order;i++)
+      qlsp[i]=qlsp[i] * .00097656;
+#endif
+
+   for (i=0;i<order;i++)
+      qlsp[i]=lsp[i]-qlsp[i];
+}
+
+void lsp_unquant_nb(spx_lsp_t *lsp, int order, SpeexBits *bits)
+{
+   int i, id;
+   for (i=0;i<order;i++)
+      lsp[i]=LSP_LINEAR(i);
+
+
+   id=speex_bits_unpack_unsigned(bits, 6);
+   for (i=0;i<10;i++)
+      lsp[i] = ADD32(lsp[i], LSP_DIV_256(cdbk_nb[id*10+i]));
+
+   id=speex_bits_unpack_unsigned(bits, 6);
+   for (i=0;i<5;i++)
+      lsp[i] = ADD16(lsp[i], LSP_DIV_512(cdbk_nb_low1[id*5+i]));
+
+   id=speex_bits_unpack_unsigned(bits, 6);
+   for (i=0;i<5;i++)
+      lsp[i] = ADD32(lsp[i], LSP_DIV_1024(cdbk_nb_low2[id*5+i]));
+
+   id=speex_bits_unpack_unsigned(bits, 6);
+   for (i=0;i<5;i++)
+      lsp[i+5] = ADD32(lsp[i+5], LSP_DIV_512(cdbk_nb_high1[id*5+i]));
+   
+   id=speex_bits_unpack_unsigned(bits, 6);
+   for (i=0;i<5;i++)
+      lsp[i+5] = ADD32(lsp[i+5], LSP_DIV_1024(cdbk_nb_high2[id*5+i]));
+}
+
+
+void lsp_quant_lbr(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
+{
+   int i;
+   int id;
+   spx_word16_t quant_weight[10];
+
+   for (i=0;i<order;i++)
+      qlsp[i]=lsp[i];
+
+   compute_quant_weights(qlsp, quant_weight, order);
+
+   for (i=0;i<order;i++)
+      qlsp[i]=SUB16(qlsp[i],LSP_LINEAR(i));
+#ifndef FIXED_POINT
+   for (i=0;i<order;i++)
+      qlsp[i]=qlsp[i]*LSP_SCALE;
+#endif
+   id = lsp_quant(qlsp, cdbk_nb, NB_CDBK_SIZE, order);
+   speex_bits_pack(bits, id, 6);
+   
+   for (i=0;i<order;i++)
+      qlsp[i]*=2;
+   
+   id = lsp_weight_quant(qlsp, quant_weight, cdbk_nb_low1, NB_CDBK_SIZE_LOW1, 5);
+   speex_bits_pack(bits, id, 6);
+
+   id = lsp_weight_quant(qlsp+5, quant_weight+5, cdbk_nb_high1, NB_CDBK_SIZE_HIGH1, 5);
+   speex_bits_pack(bits, id, 6);
+
+#ifdef FIXED_POINT
+   for (i=0;i<order;i++)
+      qlsp[i] = PSHR16(qlsp[i],1);
+#else
+   for (i=0;i<order;i++)
+      qlsp[i] = qlsp[i]*0.0019531;
+#endif
+
+   for (i=0;i<order;i++)
+      qlsp[i]=lsp[i]-qlsp[i];
+}
+
+void lsp_unquant_lbr(spx_lsp_t *lsp, int order, SpeexBits *bits)
+{
+   int i, id;
+   for (i=0;i<order;i++)
+      lsp[i]=LSP_LINEAR(i);
+
+
+   id=speex_bits_unpack_unsigned(bits, 6);
+   for (i=0;i<10;i++)
+      lsp[i] += LSP_DIV_256(cdbk_nb[id*10+i]);
+
+   id=speex_bits_unpack_unsigned(bits, 6);
+   for (i=0;i<5;i++)
+      lsp[i] += LSP_DIV_512(cdbk_nb_low1[id*5+i]);
+
+   id=speex_bits_unpack_unsigned(bits, 6);
+   for (i=0;i<5;i++)
+      lsp[i+5] += LSP_DIV_512(cdbk_nb_high1[id*5+i]);
+   
+}
+
+
+#ifdef DISABLE_WIDEBAND
+void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
+{
+   speex_error("Wideband and Ultra-wideband are disabled");
+}
+void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits)
+{
+   speex_error("Wideband and Ultra-wideband are disabled");
+}
+#else
+extern const signed char high_lsp_cdbk[];
+extern const signed char high_lsp_cdbk2[];
+
+
+void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
+{
+   int i;
+   int id;
+   spx_word16_t quant_weight[10];
+
+   for (i=0;i<order;i++)
+      qlsp[i]=lsp[i];
+
+   compute_quant_weights(qlsp, quant_weight, order);
+
+   /*   quant_weight[0] = 10/(qlsp[1]-qlsp[0]);
+   quant_weight[order-1] = 10/(qlsp[order-1]-qlsp[order-2]);
+   for (i=1;i<order-1;i++)
+   {
+      tmp1 = 10/(qlsp[i]-qlsp[i-1]);
+      tmp2 = 10/(qlsp[i+1]-qlsp[i]);
+      quant_weight[i] = tmp1 > tmp2 ? tmp1 : tmp2;
+      }*/
+
+   for (i=0;i<order;i++)
+      qlsp[i]=SUB16(qlsp[i],LSP_LINEAR_HIGH(i));
+#ifndef FIXED_POINT
+   for (i=0;i<order;i++)
+      qlsp[i] = qlsp[i]*LSP_SCALE;
+#endif
+   id = lsp_quant(qlsp, high_lsp_cdbk, 64, order);
+   speex_bits_pack(bits, id, 6);
+
+   for (i=0;i<order;i++)
+      qlsp[i]*=2;
+
+   id = lsp_weight_quant(qlsp, quant_weight, high_lsp_cdbk2, 64, order);
+   speex_bits_pack(bits, id, 6);
+
+#ifdef FIXED_POINT
+   for (i=0;i<order;i++)
+      qlsp[i] = PSHR16(qlsp[i],1);
+#else
+   for (i=0;i<order;i++)
+      qlsp[i] = qlsp[i]*0.0019531;
+#endif
+
+   for (i=0;i<order;i++)
+      qlsp[i]=lsp[i]-qlsp[i];
+}
+
+void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits)
+{
+
+   int i, id;
+   for (i=0;i<order;i++)
+      lsp[i]=LSP_LINEAR_HIGH(i);
+
+
+   id=speex_bits_unpack_unsigned(bits, 6);
+   for (i=0;i<order;i++)
+      lsp[i] += LSP_DIV_256(high_lsp_cdbk[id*order+i]);
+
+
+   id=speex_bits_unpack_unsigned(bits, 6);
+   for (i=0;i<order;i++)
+      lsp[i] += LSP_DIV_512(high_lsp_cdbk2[id*order+i]);
+}
+
+#endif
+
+
+#ifdef EPIC_48K
+
+extern const signed char cdbk_lsp_vlbr[5120];
+extern const signed char cdbk_lsp2_vlbr[160];
+
+void lsp_quant_48k(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits)
+{
+   int i;
+   int id;
+   spx_word16_t quant_weight[10];
+
+   for (i=0;i<order;i++)
+      qlsp[i]=lsp[i];
+
+   compute_quant_weights(qlsp, quant_weight, order);
+
+   for (i=0;i<order;i++)
+      qlsp[i]=SUB16(qlsp[i],LSP_SCALING*(.25*i+.3125));
+#ifndef FIXED_POINT
+   for (i=0;i<order;i++)
+      qlsp[i] = qlsp[i]*LSP_SCALE;
+#endif
+   
+   id = lsp_quant(qlsp, cdbk_lsp_vlbr, 512, order);
+   speex_bits_pack(bits, id, 9);
+
+   for (i=0;i<order;i++)
+      qlsp[i]*=4;
+   
+   id = lsp_weight_quant(qlsp, quant_weight, cdbk_lsp2_vlbr, 16, 10);
+   speex_bits_pack(bits, id, 4);
+
+#ifdef FIXED_POINT
+   for (i=0;i<order;i++)
+      qlsp[i]=PSHR(qlsp[i],2);
+#else
+   for (i=0;i<order;i++)
+      qlsp[i]=qlsp[i]*0.00097655;
+#endif
+
+   for (i=0;i<order;i++)
+      qlsp[i]=lsp[i]-qlsp[i];
+}
+
+void lsp_unquant_48k(spx_lsp_t *lsp, int order, SpeexBits *bits)
+{
+   int i, id;
+   for (i=0;i<order;i++)
+      lsp[i]=LSP_SCALING*(.25*i+.3125);
+
+
+   id=speex_bits_unpack_unsigned(bits, 9);
+   for (i=0;i<10;i++)
+      lsp[i] += LSP_SCALING*0.0039062*cdbk_lsp_vlbr[id*10+i];
+
+   id=speex_bits_unpack_unsigned(bits, 4);
+   for (i=0;i<10;i++)
+      lsp[i] += LSP_SCALING*0.00097655*cdbk_lsp2_vlbr[id*10+i];
+   
+}
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/quant_lsp.h b/utils/iaxclient/lib/libspeex/quant_lsp.h
new file mode 100644 (file)
index 0000000..dc2828e
--- /dev/null
@@ -0,0 +1,81 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: quant_lsp.h
+   LSP vector quantization
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifndef QUANT_LSP_H
+#define QUANT_LSP_H
+
+#include <speex/speex_bits.h>
+#include "misc.h"
+
+#define MAX_LSP_SIZE 20
+
+#define NB_CDBK_SIZE 64
+#define NB_CDBK_SIZE_LOW1 64
+#define NB_CDBK_SIZE_LOW2 64
+#define NB_CDBK_SIZE_HIGH1 64
+#define NB_CDBK_SIZE_HIGH2 64
+
+/*Narrowband codebooks*/
+extern const signed char cdbk_nb[];
+extern const signed char cdbk_nb_low1[];
+extern const signed char cdbk_nb_low2[];
+extern const signed char cdbk_nb_high1[];
+extern const signed char cdbk_nb_high2[];
+
+/* Quantizes narrowband LSPs with 30 bits */
+void lsp_quant_nb(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits);
+
+/* Decodes quantized narrowband LSPs */
+void lsp_unquant_nb(spx_lsp_t *lsp, int order, SpeexBits *bits);
+
+/* Quantizes low bit-rate narrowband LSPs with 18 bits */
+void lsp_quant_lbr(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits);
+
+/* Decodes quantized low bit-rate narrowband LSPs */
+void lsp_unquant_lbr(spx_lsp_t *lsp, int order, SpeexBits *bits);
+
+/* Quantizes high-band LSPs with 12 bits */
+void lsp_quant_high(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits);
+
+/* Decodes high-band LSPs */
+void lsp_unquant_high(spx_lsp_t *lsp, int order, SpeexBits *bits);
+
+#ifdef EPIC_48K
+/* Quantizes narrowband LSPs with 14 bits */
+void lsp_quant_48k(spx_lsp_t *lsp, spx_lsp_t *qlsp, int order, SpeexBits *bits);
+
+/* Decodes quantized narrowband LSPs (14 bits) */
+void lsp_unquant_48k(spx_lsp_t *lsp, int order, SpeexBits *bits);
+#endif
+
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/sb_celp.c b/utils/iaxclient/lib/libspeex/sb_celp.c
new file mode 100644 (file)
index 0000000..337c09c
--- /dev/null
@@ -0,0 +1,1519 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: sb_celp.c
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <math.h>
+#include "sb_celp.h"
+#include "stdlib.h"
+#include "filters.h"
+#include "lpc.h"
+#include "lsp.h"
+#include "stack_alloc.h"
+#include "cb_search.h"
+#include "quant_lsp.h"
+#include "vq.h"
+#include "ltp.h"
+#include "misc.h"
+
+#ifdef DISABLE_WIDEBAND
+void *sb_encoder_init(const SpeexMode *m)
+{
+   speex_error("Wideband and Ultra-wideband are disabled");
+   return NULL;
+}
+void sb_encoder_destroy(void *state)
+{
+   speex_error("Wideband and Ultra-wideband are disabled");
+}
+int sb_encode(void *state, void *vin, SpeexBits *bits)
+{
+   speex_error("Wideband and Ultra-wideband are disabled");
+   return -2;
+}
+void *sb_decoder_init(const SpeexMode *m)
+{
+   speex_error("Wideband and Ultra-wideband are disabled");
+   return NULL;
+}
+void sb_decoder_destroy(void *state)
+{
+   speex_error("Wideband and Ultra-wideband are disabled");
+}
+int sb_decode(void *state, SpeexBits *bits, void *vout)
+{
+   speex_error("Wideband and Ultra-wideband are disabled");
+   return -2;
+}
+int sb_encoder_ctl(void *state, int request, void *ptr)
+{
+   speex_error("Wideband and Ultra-wideband are disabled");
+   return -2;
+}
+int sb_decoder_ctl(void *state, int request, void *ptr)
+{
+   speex_error("Wideband and Ultra-wideband are disabled");
+   return -2;
+}
+#else
+
+
+#ifndef M_PI
+#define M_PI           3.14159265358979323846  /* pi */
+#endif
+
+#define sqr(x) ((x)*(x))
+
+#define SUBMODE(x) st->submodes[st->submodeID]->x
+
+#ifdef FIXED_POINT
+static const spx_word16_t gc_quant_bound[16] = {125, 164, 215, 282, 370, 484, 635, 832, 1090, 1428, 1871, 2452, 3213, 4210, 5516, 7228};
+#define LSP_MARGIN 410
+#define LSP_DELTA1 6553
+#define LSP_DELTA2 1638
+
+#else
+
+#define LSP_MARGIN .05
+#define LSP_DELTA1 .2
+#define LSP_DELTA2 .05
+
+#endif
+
+#define QMF_ORDER 64
+
+#ifdef FIXED_POINT
+static const spx_word16_t h0[64] = {2, -7, -7, 18, 15, -39, -25, 75, 35, -130, -41, 212, 38, -327, -17, 483, -32, -689, 124, 956, -283, -1307, 543, 1780, -973, -2467, 1733, 3633, -3339, -6409, 9059, 30153, 30153, 9059, -6409, -3339, 3633, 1733, -2467, -973, 1780, 543, -1307, -283, 956, 124, -689, -32, 483, -17, -327, 38, 212, -41, -130, 35, 75, -25, -39, 15, 18, -7, -7, 2};
+
+static const spx_word16_t h1[64] = {2, 7, -7, -18, 15, 39, -25, -75, 35, 130, -41, -212, 38, 327, -17, -483, -32, 689, 124, -956, -283, 1307, 543, -1780, -973, 2467, 1733, -3633, -3339, 6409, 9059, -30153, 30153, -9059, -6409, 3339, 3633, -1733, -2467, 973, 1780, -543, -1307, 283, 956, -124, -689, 32, 483, 17, -327, -38, 212, 41, -130, -35, 75, 25, -39, -15, 18, 7, -7, -2};
+
+
+#else
+static const float h0[64] = {
+   3.596189e-05, -0.0001123515,
+   -0.0001104587, 0.0002790277,
+   0.0002298438, -0.0005953563,
+   -0.0003823631, 0.00113826,
+   0.0005308539, -0.001986177,
+   -0.0006243724, 0.003235877,
+   0.0005743159, -0.004989147,
+   -0.0002584767, 0.007367171,
+   -0.0004857935, -0.01050689,
+   0.001894714, 0.01459396,
+   -0.004313674, -0.01994365,
+   0.00828756, 0.02716055,
+   -0.01485397, -0.03764973,
+   0.026447, 0.05543245,
+   -0.05095487, -0.09779096,
+   0.1382363, 0.4600981,
+   0.4600981, 0.1382363,
+   -0.09779096, -0.05095487,
+   0.05543245, 0.026447,
+   -0.03764973, -0.01485397,
+   0.02716055, 0.00828756,
+   -0.01994365, -0.004313674,
+   0.01459396, 0.001894714,
+   -0.01050689, -0.0004857935,
+   0.007367171, -0.0002584767,
+   -0.004989147, 0.0005743159,
+   0.003235877, -0.0006243724,
+   -0.001986177, 0.0005308539,
+   0.00113826, -0.0003823631,
+   -0.0005953563, 0.0002298438,
+   0.0002790277, -0.0001104587,
+   -0.0001123515, 3.596189e-05
+};
+
+static const float h1[64] = {
+   3.596189e-05, 0.0001123515,
+   -0.0001104587, -0.0002790277,
+   0.0002298438, 0.0005953563,
+   -0.0003823631, -0.00113826,
+   0.0005308539, 0.001986177,
+   -0.0006243724, -0.003235877,
+   0.0005743159, 0.004989147,
+   -0.0002584767, -0.007367171,
+   -0.0004857935, 0.01050689,
+   0.001894714, -0.01459396,
+   -0.004313674, 0.01994365,
+   0.00828756, -0.02716055,
+   -0.01485397, 0.03764973,
+   0.026447, -0.05543245,
+   -0.05095487, 0.09779096,
+   0.1382363, -0.4600981,
+   0.4600981, -0.1382363,
+   -0.09779096, 0.05095487,
+   0.05543245, -0.026447,
+   -0.03764973, 0.01485397,
+   0.02716055, -0.00828756,
+   -0.01994365, 0.004313674,
+   0.01459396, -0.001894714,
+   -0.01050689, 0.0004857935,
+   0.007367171, 0.0002584767,
+   -0.004989147, -0.0005743159,
+   0.003235877, 0.0006243724,
+   -0.001986177, -0.0005308539,
+   0.00113826, 0.0003823631,
+   -0.0005953563, -0.0002298438,
+   0.0002790277, 0.0001104587,
+   -0.0001123515, -3.596189e-05
+};
+#endif
+
+static void mix_and_saturate(spx_word32_t *x0, spx_word32_t *x1, spx_word16_t *out, int len)
+{
+   int i;
+   for (i=0;i<len;i++)
+   {
+      spx_word32_t tmp;
+#ifdef FIXED_POINT
+      tmp=PSHR(x0[i]-x1[i],SIG_SHIFT-1);
+#else
+      tmp=2*(x0[i]-x1[i]);
+#endif
+      if (tmp>32767)
+         out[i] = 32767;
+      else if (tmp<-32767)
+         out[i] = -32767;
+      else
+         out[i] = tmp;
+   }
+}
+
+void *sb_encoder_init(const SpeexMode *m)
+{
+   int i;
+   SBEncState *st;
+   const SpeexSBMode *mode;
+
+#if defined(VAR_ARRAYS) || defined (USE_ALLOCA)
+   st = (SBEncState*)speex_alloc(sizeof(SBEncState));
+   st->stack = NULL;
+#else
+   st = (SBEncState*)speex_alloc(sizeof(SBEncState)+10000*sizeof(spx_sig_t));
+   st->stack = ((char*)st) + sizeof(SBEncState);
+#endif
+   if (!st)
+      return NULL;
+   st->mode = m;
+   mode = (const SpeexSBMode*)m->mode;
+
+
+   st->st_low = speex_encoder_init(mode->nb_mode);
+   st->full_frame_size = 2*mode->frameSize;
+   st->frame_size = mode->frameSize;
+   st->subframeSize = mode->subframeSize;
+   st->nbSubframes = mode->frameSize/mode->subframeSize;
+   st->windowSize = st->frame_size*3/2;
+   st->lpcSize=mode->lpcSize;
+   st->bufSize=mode->bufSize;
+
+   st->encode_submode = 1;
+   st->submodes=mode->submodes;
+   st->submodeSelect = st->submodeID=mode->defaultSubmode;
+   
+   i=9;
+   speex_encoder_ctl(st->st_low, SPEEX_SET_QUALITY, &i);
+
+   st->lag_factor = mode->lag_factor;
+   st->lpc_floor = mode->lpc_floor;
+   st->gamma1=mode->gamma1;
+   st->gamma2=mode->gamma2;
+   st->first=1;
+
+   st->x0d=speex_alloc((st->frame_size)*sizeof(spx_sig_t));
+   st->x1d=speex_alloc((st->frame_size)*sizeof(spx_sig_t));
+   st->high=speex_alloc((st->full_frame_size)*sizeof(spx_sig_t));
+   st->y0=speex_alloc((st->full_frame_size)*sizeof(spx_sig_t));
+   st->y1=speex_alloc((st->full_frame_size)*sizeof(spx_sig_t));
+
+   st->h0_mem=speex_alloc((QMF_ORDER)*sizeof(spx_word16_t));
+   st->h1_mem=speex_alloc((QMF_ORDER)*sizeof(spx_word16_t));
+   st->g0_mem=speex_alloc((QMF_ORDER)*sizeof(spx_word32_t));
+   st->g1_mem=speex_alloc((QMF_ORDER)*sizeof(spx_word32_t));
+
+   st->buf=speex_alloc((st->windowSize)*sizeof(spx_sig_t));
+   st->excBuf=speex_alloc((st->bufSize)*sizeof(spx_sig_t));
+   st->exc = st->excBuf + st->bufSize - st->windowSize;
+
+   st->res=speex_alloc((st->frame_size)*sizeof(spx_sig_t));
+   st->sw=speex_alloc((st->frame_size)*sizeof(spx_sig_t));
+   st->target=speex_alloc((st->frame_size)*sizeof(spx_sig_t));
+   /*Asymmetric "pseudo-Hamming" window*/
+   {
+      int part1, part2;
+      part1 = st->subframeSize*7/2;
+      part2 = st->subframeSize*5/2;
+      st->window = speex_alloc((st->windowSize)*sizeof(spx_word16_t));
+      for (i=0;i<part1;i++)
+         st->window[i]=(spx_word16_t)(SIG_SCALING*(.54-.46*cos(M_PI*i/part1)));
+      for (i=0;i<part2;i++)
+         st->window[part1+i]=(spx_word16_t)(SIG_SCALING*(.54+.46*cos(M_PI*i/part2)));
+   }
+
+   st->lagWindow = speex_alloc((st->lpcSize+1)*sizeof(spx_word16_t));
+   for (i=0;i<st->lpcSize+1;i++)
+      st->lagWindow[i]=16384*exp(-.5*sqr(2*M_PI*st->lag_factor*i));
+
+   st->autocorr = speex_alloc((st->lpcSize+1)*sizeof(spx_word16_t));
+   st->lpc = speex_alloc((st->lpcSize+1)*sizeof(spx_coef_t));
+   st->bw_lpc1 = speex_alloc((st->lpcSize+1)*sizeof(spx_coef_t));
+   st->bw_lpc2 = speex_alloc((st->lpcSize+1)*sizeof(spx_coef_t));
+   st->lsp = speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
+   st->qlsp = speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
+   st->old_lsp = speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
+   st->old_qlsp = speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
+   st->interp_lsp = speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
+   st->interp_qlsp = speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
+   st->interp_lpc = speex_alloc((st->lpcSize+1)*sizeof(spx_coef_t));
+   st->interp_qlpc = speex_alloc((st->lpcSize+1)*sizeof(spx_coef_t));
+   st->pi_gain = speex_alloc((st->nbSubframes)*sizeof(spx_word32_t));
+
+   st->mem_sp = speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
+   st->mem_sp2 = speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
+   st->mem_sw = speex_alloc((st->lpcSize)*sizeof(spx_mem_t));
+
+   st->vbr_quality = 8;
+   st->vbr_enabled = 0;
+   st->vad_enabled = 0;
+   st->abr_enabled = 0;
+   st->relative_quality=0;
+
+   st->complexity=2;
+   speex_encoder_ctl(st->st_low, SPEEX_GET_SAMPLING_RATE, &st->sampling_rate);
+   st->sampling_rate*=2;
+
+#ifdef ENABLE_VALGRIND
+   VALGRIND_MAKE_READABLE(st, (st->stack-(char*)st));
+#endif
+   return st;
+}
+
+void sb_encoder_destroy(void *state)
+{
+   SBEncState *st=(SBEncState*)state;
+
+   speex_encoder_destroy(st->st_low);
+
+   speex_free(st);
+}
+
+
+int sb_encode(void *state, void *vin, SpeexBits *bits)
+{
+   SBEncState *st;
+   int i, roots, sub;
+   char *stack;
+   VARDECL(spx_mem_t *mem);
+   VARDECL(spx_sig_t *innov);
+   VARDECL(spx_word16_t *syn_resp);
+   VARDECL(spx_word32_t *low_pi_gain);
+   VARDECL(spx_sig_t *low_exc);
+   VARDECL(spx_sig_t *low_innov);
+   const SpeexSBMode *mode;
+   int dtx;
+   spx_word16_t *in = vin;
+
+   st = (SBEncState*)state;
+   stack=st->stack;
+   mode = (const SpeexSBMode*)(st->mode->mode);
+
+   {
+      VARDECL(spx_word16_t *low);
+      ALLOC(low, st->frame_size, spx_word16_t);
+
+      /* Compute the two sub-bands by filtering with h0 and h1*/
+      qmf_decomp(in, h0, st->x0d, st->x1d, st->full_frame_size, QMF_ORDER, st->h0_mem, stack);
+      
+      for (i=0;i<st->frame_size;i++)
+         low[i] = SATURATE(PSHR(st->x0d[i],SIG_SHIFT),32767);
+      
+      /* Encode the narrowband part*/
+      speex_encode_native(st->st_low, low, bits);
+
+      for (i=0;i<st->frame_size;i++)
+         st->x0d[i] = SHL(low[i],SIG_SHIFT);
+   }
+   /* High-band buffering / sync with low band */
+   for (i=0;i<st->windowSize-st->frame_size;i++)
+      st->high[i] = st->high[st->frame_size+i];
+   for (i=0;i<st->frame_size;i++)
+      st->high[st->windowSize-st->frame_size+i]=SATURATE(st->x1d[i],536854528);
+
+   speex_move(st->excBuf, st->excBuf+st->frame_size, (st->bufSize-st->frame_size)*sizeof(spx_sig_t));
+
+
+   ALLOC(low_pi_gain, st->nbSubframes, spx_word32_t);
+   ALLOC(low_exc, st->frame_size, spx_sig_t);
+   ALLOC(low_innov, st->frame_size, spx_sig_t);
+   speex_encoder_ctl(st->st_low, SPEEX_GET_PI_GAIN, low_pi_gain);
+   speex_encoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc);
+   speex_encoder_ctl(st->st_low, SPEEX_GET_INNOV, low_innov);
+   
+   speex_encoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, &dtx);
+
+   if (dtx==0)
+      dtx=1;
+   else
+      dtx=0;
+
+   {
+      VARDECL(spx_word16_t *w_sig);
+      ALLOC(w_sig, st->windowSize, spx_word16_t);
+      /* Window for analysis */
+      for (i=0;i<st->windowSize;i++)
+         w_sig[i] = SHR(MULT16_16(SHR((spx_word32_t)(st->high[i]),SIG_SHIFT),st->window[i]),SIG_SHIFT);
+
+      /* Compute auto-correlation */
+      _spx_autocorr(w_sig, st->autocorr, st->lpcSize+1, st->windowSize);
+   }
+
+   st->autocorr[0] = (spx_word16_t)(st->autocorr[0]*st->lpc_floor); /* Noise floor in auto-correlation domain */
+
+   /* Lag windowing: equivalent to filtering in the power-spectrum domain */
+   for (i=0;i<st->lpcSize+1;i++)
+      st->autocorr[i] = MULT16_16_Q14(st->autocorr[i],st->lagWindow[i]);
+
+   /* Levinson-Durbin */
+   _spx_lpc(st->lpc+1, st->autocorr, st->lpcSize);
+   st->lpc[0] = (spx_coef_t)LPC_SCALING;
+
+   /* LPC to LSPs (x-domain) transform */
+   roots=lpc_to_lsp (st->lpc, st->lpcSize, st->lsp, 15, LSP_DELTA1, stack);
+   if (roots!=st->lpcSize)
+   {
+      roots = lpc_to_lsp (st->lpc, st->lpcSize, st->lsp, 11, LSP_DELTA2, stack);
+      if (roots!=st->lpcSize) {
+         /*If we can't find all LSP's, do some damage control and use a flat filter*/
+         for (i=0;i<st->lpcSize;i++)
+         {
+            st->lsp[i]=M_PI*((float)(i+1))/(st->lpcSize+1);
+         }
+      }
+   }
+
+   /* VBR code */
+   if ((st->vbr_enabled || st->vad_enabled) && !dtx)
+   {
+      float e_low=0, e_high=0;
+      float ratio;
+      if (st->abr_enabled)
+      {
+         float qual_change=0;
+         if (st->abr_drift2 * st->abr_drift > 0)
+         {
+            /* Only adapt if long-term and short-term drift are the same sign */
+            qual_change = -.00001*st->abr_drift/(1+st->abr_count);
+            if (qual_change>.1)
+               qual_change=.1;
+            if (qual_change<-.1)
+               qual_change=-.1;
+         }
+         st->vbr_quality += qual_change;
+         if (st->vbr_quality>10)
+            st->vbr_quality=10;
+         if (st->vbr_quality<0)
+            st->vbr_quality=0;
+      }
+
+
+      /*FIXME: Are the two signals (low, high) in sync? */
+      e_low = compute_rms(st->x0d, st->frame_size);
+      e_high = compute_rms(st->high, st->frame_size);
+      ratio = 2*log((1+e_high)/(1+e_low));
+      
+      speex_encoder_ctl(st->st_low, SPEEX_GET_RELATIVE_QUALITY, &st->relative_quality);
+      if (ratio<-4)
+         ratio=-4;
+      if (ratio>2)
+         ratio=2;
+      /*if (ratio>-2)*/
+      if (st->vbr_enabled) 
+      {
+         int modeid;
+         modeid = mode->nb_modes-1;
+         st->relative_quality+=1.0*(ratio+2);
+        if (st->relative_quality<-1)
+            st->relative_quality=-1;
+         while (modeid)
+         {
+            int v1;
+            float thresh;
+            v1=(int)floor(st->vbr_quality);
+            if (v1==10)
+               thresh = mode->vbr_thresh[modeid][v1];
+            else
+               thresh = (st->vbr_quality-v1)   * mode->vbr_thresh[modeid][v1+1] + 
+                        (1+v1-st->vbr_quality) * mode->vbr_thresh[modeid][v1];
+            if (st->relative_quality >= thresh)
+               break;
+            modeid--;
+         }
+         speex_encoder_ctl(state, SPEEX_SET_HIGH_MODE, &modeid);
+         if (st->abr_enabled)
+         {
+            int bitrate;
+            speex_encoder_ctl(state, SPEEX_GET_BITRATE, &bitrate);
+            st->abr_drift+=(bitrate-st->abr_enabled);
+            st->abr_drift2 = .95*st->abr_drift2 + .05*(bitrate-st->abr_enabled);
+            st->abr_count += 1.0;
+         }
+
+      } else {
+         /* VAD only */
+         int modeid;
+         if (st->relative_quality<2.0)
+            modeid=1;
+         else
+            modeid=st->submodeSelect;
+         /*speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);*/
+         st->submodeID=modeid;
+
+      }
+      /*fprintf (stderr, "%f %f\n", ratio, low_qual);*/
+   }
+
+   if (st->encode_submode)
+   {
+      speex_bits_pack(bits, 1, 1);
+      if (dtx)
+         speex_bits_pack(bits, 0, SB_SUBMODE_BITS);
+      else
+         speex_bits_pack(bits, st->submodeID, SB_SUBMODE_BITS);
+   }
+
+   /* If null mode (no transmission), just set a couple things to zero*/
+   if (dtx || st->submodes[st->submodeID] == NULL)
+   {
+      for (i=0;i<st->frame_size;i++)
+         st->exc[i]=st->sw[i]=VERY_SMALL;
+
+      for (i=0;i<st->lpcSize;i++)
+         st->mem_sw[i]=0;
+      st->first=1;
+
+      /* Final signal synthesis from excitation */
+      iir_mem2(st->exc, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, st->mem_sp);
+
+#ifdef RESYNTH
+      /* Reconstruct the original */
+      fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack);
+      fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack);
+
+      for (i=0;i<st->full_frame_size;i++)
+         in[i]=SHR(st->y0[i]-st->y1[i], SIG_SHIFT-1);
+#endif
+
+      if (dtx)
+         return 0;
+      else
+         return 1;
+   }
+
+
+   /* LSP quantization */
+   SUBMODE(lsp_quant)(st->lsp, st->qlsp, st->lpcSize, bits);   
+
+   if (st->first)
+   {
+      for (i=0;i<st->lpcSize;i++)
+         st->old_lsp[i] = st->lsp[i];
+      for (i=0;i<st->lpcSize;i++)
+         st->old_qlsp[i] = st->qlsp[i];
+   }
+   
+   ALLOC(mem, st->lpcSize, spx_mem_t);
+   ALLOC(syn_resp, st->subframeSize, spx_word16_t);
+   ALLOC(innov, st->subframeSize, spx_sig_t);
+
+   for (sub=0;sub<st->nbSubframes;sub++)
+   {
+      spx_sig_t *exc, *sp, *res, *target, *sw;
+      spx_word16_t filter_ratio;
+      int offset;
+      spx_word32_t rl, rh;
+      spx_word16_t eh=0;
+
+      offset = st->subframeSize*sub;
+      sp=st->high+offset;
+      exc=st->exc+offset;
+      res=st->res+offset;
+      target=st->target+offset;
+      sw=st->sw+offset;
+      
+      /* LSP interpolation (quantized and unquantized) */
+      lsp_interpolate(st->old_lsp, st->lsp, st->interp_lsp, st->lpcSize, sub, st->nbSubframes);
+      lsp_interpolate(st->old_qlsp, st->qlsp, st->interp_qlsp, st->lpcSize, sub, st->nbSubframes);
+
+      lsp_enforce_margin(st->interp_lsp, st->lpcSize, LSP_MARGIN);
+      lsp_enforce_margin(st->interp_qlsp, st->lpcSize, LSP_MARGIN);
+
+      lsp_to_lpc(st->interp_lsp, st->interp_lpc, st->lpcSize,stack);
+      lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack);
+
+      bw_lpc(st->gamma1, st->interp_lpc, st->bw_lpc1, st->lpcSize);
+      bw_lpc(st->gamma2, st->interp_lpc, st->bw_lpc2, st->lpcSize);
+
+      /* Compute mid-band (4000 Hz for wideband) response of low-band and high-band
+         filters */
+      st->pi_gain[sub]=LPC_SCALING;
+      rh = LPC_SCALING;
+      for (i=1;i<=st->lpcSize;i+=2)
+      {
+         rh += st->interp_qlpc[i+1] - st->interp_qlpc[i];
+         st->pi_gain[sub] += st->interp_qlpc[i] + st->interp_qlpc[i+1];
+      }
+      
+      rl = low_pi_gain[sub];
+#ifdef FIXED_POINT
+      filter_ratio=DIV32_16(SHL(rl+82,2),SHR(82+rh,5));
+#else
+      filter_ratio=(rl+.01)/(rh+.01);
+#endif
+      
+      /* Compute "real excitation" */
+      fir_mem2(sp, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, st->mem_sp2);
+      /* Compute energy of low-band and high-band excitation */
+
+      eh = compute_rms(exc, st->subframeSize);
+
+      if (!SUBMODE(innovation_quant)) {/* 1 for spectral folding excitation, 0 for stochastic */
+         float g;
+         spx_word16_t el;
+         el = compute_rms(low_innov+offset, st->subframeSize);
+
+         /* Gain to use if we want to use the low-band excitation for high-band */
+         g=eh/(.01+el);
+         
+#if 0
+         {
+            char *tmp_stack=stack;
+            float *tmp_sig;
+            float g2;
+            ALLOC(tmp_sig, st->subframeSize, spx_sig_t);
+            for (i=0;i<st->lpcSize;i++)
+               mem[i]=st->mem_sp[i];
+            iir_mem2(low_innov+offset, st->interp_qlpc, tmp_sig, st->subframeSize, st->lpcSize, mem);
+            g2 = compute_rms(sp, st->subframeSize)/(.01+compute_rms(tmp_sig, st->subframeSize));
+            /*fprintf (stderr, "gains: %f %f\n", g, g2);*/
+            g = g2;
+            stack = tmp_stack;
+         }
+#endif
+
+#ifdef FIXED_POINT
+         g *= filter_ratio/128.;
+#else
+         g *= filter_ratio;
+#endif
+         /*print_vec(&g, 1, "gain factor");*/
+         /* Gain quantization */
+         {
+            int quant = (int) floor(.5 + 10 + 8.0 * log((g+.0001)));
+            /*speex_warning_int("tata", quant);*/
+            if (quant<0)
+               quant=0;
+            if (quant>31)
+               quant=31;
+            speex_bits_pack(bits, quant, 5);
+         }
+
+      } else {
+         spx_word16_t gc;
+         spx_word32_t scale;
+         spx_word16_t el;
+         el = compute_rms(low_exc+offset, st->subframeSize);
+
+         gc = DIV32_16(MULT16_16(filter_ratio,1+eh),1+el);
+
+         /* This is a kludge that cleans up a historical bug */
+         if (st->subframeSize==80)
+            gc *= 0.70711;
+         /*printf ("%f %f %f %f\n", el, eh, filter_ratio, gc);*/
+#ifdef FIXED_POINT
+         {
+            int qgc = scal_quant(gc, gc_quant_bound, 16);
+            speex_bits_pack(bits, qgc, 4);
+            gc = MULT16_32_Q15(28626,gc_quant_bound[qgc]);
+         }
+#else
+         {
+            int qgc = (int)floor(.5+3.7*(log(gc)+0.15556));
+            if (qgc<0)
+               qgc=0;
+            if (qgc>15)
+               qgc=15;
+            speex_bits_pack(bits, qgc, 4);
+            gc = exp((1/3.7)*qgc-0.15556);
+         }         
+#endif
+         if (st->subframeSize==80)
+            gc *= 1.4142;
+
+         scale = SHL(MULT16_16(DIV32_16(SHL(gc,SIG_SHIFT-4),filter_ratio),(1+el)),4);
+
+         compute_impulse_response(st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, syn_resp, st->subframeSize, st->lpcSize, stack);
+
+         
+         /* Reset excitation */
+         for (i=0;i<st->subframeSize;i++)
+            exc[i]=VERY_SMALL;
+         
+         /* Compute zero response (ringing) of A(z/g1) / ( A(z/g2) * Aq(z) ) */
+         for (i=0;i<st->lpcSize;i++)
+            mem[i]=st->mem_sp[i];
+         iir_mem2(exc, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, mem);
+
+         for (i=0;i<st->lpcSize;i++)
+            mem[i]=st->mem_sw[i];
+         filter_mem2(exc, st->bw_lpc1, st->bw_lpc2, res, st->subframeSize, st->lpcSize, mem);
+
+         /* Compute weighted signal */
+         for (i=0;i<st->lpcSize;i++)
+            mem[i]=st->mem_sw[i];
+         filter_mem2(sp, st->bw_lpc1, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, mem);
+
+         /* Compute target signal */
+         for (i=0;i<st->subframeSize;i++)
+            target[i]=sw[i]-res[i];
+
+         for (i=0;i<st->subframeSize;i++)
+           exc[i]=0;
+
+         signal_div(target, target, scale, st->subframeSize);
+
+         /* Reset excitation */
+         for (i=0;i<st->subframeSize;i++)
+            innov[i]=0;
+
+         /*print_vec(target, st->subframeSize, "\ntarget");*/
+         SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, 
+                                   SUBMODE(innovation_params), st->lpcSize, st->subframeSize, 
+                                   innov, syn_resp, bits, stack, (st->complexity+1)>>1, SUBMODE(double_codebook));
+         /*print_vec(target, st->subframeSize, "after");*/
+
+         signal_mul(innov, innov, scale, st->subframeSize);
+
+         for (i=0;i<st->subframeSize;i++)
+            exc[i] = ADD32(exc[i], innov[i]);
+
+         if (SUBMODE(double_codebook)) {
+            char *tmp_stack=stack;
+            VARDECL(spx_sig_t *innov2);
+            ALLOC(innov2, st->subframeSize, spx_sig_t);
+            for (i=0;i<st->subframeSize;i++)
+               innov2[i]=0;
+            for (i=0;i<st->subframeSize;i++)
+               target[i]*=2.5;
+            SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, 
+                                      SUBMODE(innovation_params), st->lpcSize, st->subframeSize, 
+                                      innov2, syn_resp, bits, stack, (st->complexity+1)>>1, 0);
+            for (i=0;i<st->subframeSize;i++)
+               innov2[i]*=scale*(1/2.5)/SIG_SCALING;
+            for (i=0;i<st->subframeSize;i++)
+               exc[i] = ADD32(exc[i],innov2[i]);
+            stack = tmp_stack;
+         }
+
+      }
+
+      /*Keep the previous memory*/
+      for (i=0;i<st->lpcSize;i++)
+         mem[i]=st->mem_sp[i];
+      /* Final signal synthesis from excitation */
+      iir_mem2(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp);
+      
+      /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */
+      filter_mem2(sp, st->bw_lpc1, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw);
+   }
+
+
+#ifdef RESYNTH
+   /* Reconstruct the original */
+   fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack);
+   fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack);
+
+   for (i=0;i<st->full_frame_size;i++)
+      in[i]=SHR(st->y0[i]-st->y1[i], SIG_SHIFT-1);
+#endif
+   for (i=0;i<st->lpcSize;i++)
+      st->old_lsp[i] = st->lsp[i];
+   for (i=0;i<st->lpcSize;i++)
+      st->old_qlsp[i] = st->qlsp[i];
+
+   st->first=0;
+
+   return 1;
+}
+
+
+
+
+
+void *sb_decoder_init(const SpeexMode *m)
+{
+   SBDecState *st;
+   const SpeexSBMode *mode;
+#if defined(VAR_ARRAYS) || defined (USE_ALLOCA)
+   st = (SBDecState*)speex_alloc(sizeof(SBDecState));
+   st->stack = NULL;
+#else   
+   st = (SBDecState*)speex_alloc(sizeof(SBDecState)+6000*sizeof(spx_sig_t));
+   st->stack = ((char*)st) + sizeof(SBDecState);
+#endif
+   if (!st)
+      return NULL;
+   st->mode = m;
+   mode=(const SpeexSBMode*)m->mode;
+
+   st->encode_submode = 1;
+
+
+
+
+   st->st_low = speex_decoder_init(mode->nb_mode);
+   st->full_frame_size = 2*mode->frameSize;
+   st->frame_size = mode->frameSize;
+   st->subframeSize = mode->subframeSize;
+   st->nbSubframes = mode->frameSize/mode->subframeSize;
+   st->lpcSize=mode->lpcSize;
+   speex_decoder_ctl(st->st_low, SPEEX_GET_SAMPLING_RATE, &st->sampling_rate);
+   st->sampling_rate*=2;
+
+   st->submodes=mode->submodes;
+   st->submodeID=mode->defaultSubmode;
+
+   st->first=1;
+
+
+   st->x0d=speex_alloc((st->frame_size)*sizeof(spx_sig_t));
+   st->x1d=speex_alloc((st->frame_size)*sizeof(spx_sig_t));
+   st->high=speex_alloc((st->full_frame_size)*sizeof(spx_sig_t));
+   st->y0=speex_alloc((st->full_frame_size)*sizeof(spx_sig_t));
+   st->y1=speex_alloc((st->full_frame_size)*sizeof(spx_sig_t));
+
+   st->g0_mem=speex_alloc((QMF_ORDER)*sizeof(spx_word32_t));
+   st->g1_mem=speex_alloc((QMF_ORDER)*sizeof(spx_word32_t));
+
+   st->exc=speex_alloc((st->frame_size)*sizeof(spx_sig_t));
+
+   st->qlsp = speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
+   st->old_qlsp = speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
+   st->interp_qlsp = speex_alloc((st->lpcSize)*sizeof(spx_lsp_t));
+   st->interp_qlpc = speex_alloc((st->lpcSize+1)*sizeof(spx_coef_t));
+
+   st->pi_gain = speex_alloc((st->nbSubframes)*sizeof(spx_word32_t));
+   st->mem_sp = speex_alloc((2*st->lpcSize)*sizeof(spx_mem_t));
+   
+   st->lpc_enh_enabled=0;
+
+#ifdef ENABLE_VALGRIND
+   VALGRIND_MAKE_READABLE(st, (st->stack-(char*)st));
+#endif
+   return st;
+}
+
+void sb_decoder_destroy(void *state)
+{
+   SBDecState *st;
+   st = (SBDecState*)state;
+   speex_decoder_destroy(st->st_low);
+
+   speex_free(state);
+}
+
+static void sb_decode_lost(SBDecState *st, spx_word16_t *out, int dtx, char *stack)
+{
+   int i;
+   VARDECL(spx_coef_t *awk1);
+   VARDECL(spx_coef_t *awk2);
+   VARDECL(spx_coef_t *awk3);
+   int saved_modeid=0;
+
+   if (dtx)
+   {
+      saved_modeid=st->submodeID;
+      st->submodeID=1;
+   } else {
+      bw_lpc(GAMMA_SCALING*0.99, st->interp_qlpc, st->interp_qlpc, st->lpcSize);
+   }
+
+   st->first=1;
+   
+   ALLOC(awk1, st->lpcSize+1, spx_coef_t);
+   ALLOC(awk2, st->lpcSize+1, spx_coef_t);
+   ALLOC(awk3, st->lpcSize+1, spx_coef_t);
+   
+   if (st->lpc_enh_enabled)
+   {
+      spx_word16_t k1,k2,k3;
+      if (st->submodes[st->submodeID] != NULL)
+      {
+         k1=SUBMODE(lpc_enh_k1);
+         k2=SUBMODE(lpc_enh_k2);
+         k3=SUBMODE(lpc_enh_k3);
+      } else {
+         k1=k2=.7*GAMMA_SCALING;
+         k3 = 0;
+      }
+      bw_lpc(k1, st->interp_qlpc, awk1, st->lpcSize);
+      bw_lpc(k2, st->interp_qlpc, awk2, st->lpcSize);
+      bw_lpc(k3, st->interp_qlpc, awk3, st->lpcSize);
+      /*fprintf (stderr, "%f %f %f\n", k1, k2, k3);*/
+   }
+   
+   
+   /* Final signal synthesis from excitation */
+   if (!dtx)
+   {
+      for (i=0;i<st->frame_size;i++)
+         st->exc[i] *= .9;
+   }
+
+   for (i=0;i<st->frame_size;i++)
+      st->high[i]=st->exc[i];
+
+   if (st->lpc_enh_enabled)
+   {
+      /* Use enhanced LPC filter */
+      filter_mem2(st->high, awk2, awk1, st->high, st->frame_size, st->lpcSize, 
+                  st->mem_sp+st->lpcSize);
+      filter_mem2(st->high, awk3, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, 
+                  st->mem_sp);
+   } else {
+      /* Use regular filter */
+      for (i=0;i<st->lpcSize;i++)
+         st->mem_sp[st->lpcSize+i] = 0;
+      iir_mem2(st->high, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, 
+               st->mem_sp);
+   }
+   
+   /*iir_mem2(st->exc, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, st->mem_sp);*/
+   
+   /* Reconstruct the original */
+   fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack);
+   fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack);
+
+   mix_and_saturate(st->y0, st->y1, out, st->full_frame_size);
+
+   if (dtx)
+   {
+      st->submodeID=saved_modeid;
+   }
+
+   return;
+}
+
+int sb_decode(void *state, SpeexBits *bits, void *vout)
+{
+   int i, sub;
+   SBDecState *st;
+   int wideband;
+   int ret;
+   char *stack;
+   VARDECL(spx_word32_t *low_pi_gain);
+   VARDECL(spx_sig_t *low_exc);
+   VARDECL(spx_sig_t *low_innov);
+   VARDECL(spx_coef_t *awk1);
+   VARDECL(spx_coef_t *awk2);
+   VARDECL(spx_coef_t *awk3);
+   int dtx;
+   const SpeexSBMode *mode;
+   spx_word16_t *out = vout;
+   
+   st = (SBDecState*)state;
+   stack=st->stack;
+   mode = (const SpeexSBMode*)(st->mode->mode);
+
+   {
+      VARDECL(spx_word16_t *low);
+      ALLOC(low, st->frame_size, spx_word16_t);
+      
+      /* Decode the low-band */
+      ret = speex_decode_native(st->st_low, bits, low);
+      
+      for (i=0;i<st->frame_size;i++)
+         st->x0d[i] = SHL((spx_sig_t)low[i], SIG_SHIFT);
+   }
+
+   speex_decoder_ctl(st->st_low, SPEEX_GET_DTX_STATUS, &dtx);
+
+   /* If error decoding the narrowband part, propagate error */
+   if (ret!=0)
+   {
+      return ret;
+   }
+
+   if (!bits)
+   {
+      sb_decode_lost(st, out, dtx, stack);
+      return 0;
+   }
+
+   if (st->encode_submode)
+   {
+
+      /*Check "wideband bit"*/
+      if (speex_bits_remaining(bits)>0)
+         wideband = speex_bits_peek(bits);
+      else
+         wideband = 0;
+      if (wideband)
+      {
+         /*Regular wideband frame, read the submode*/
+         wideband = speex_bits_unpack_unsigned(bits, 1);
+         st->submodeID = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS);
+      } else
+      {
+         /*Was a narrowband frame, set "null submode"*/
+         st->submodeID = 0;
+      }
+      if (st->submodeID != 0 && st->submodes[st->submodeID] == NULL)
+      {
+         speex_warning("Invalid mode encountered: corrupted stream?");
+         return -2;
+      }
+   }
+
+   /* If null mode (no transmission), just set a couple things to zero*/
+   if (st->submodes[st->submodeID] == NULL)
+   {
+      if (dtx)
+      {
+         sb_decode_lost(st, out, 1, stack);
+         return 0;
+      }
+
+      for (i=0;i<st->frame_size;i++)
+         st->exc[i]=VERY_SMALL;
+
+      st->first=1;
+
+      /* Final signal synthesis from excitation */
+      iir_mem2(st->exc, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, st->mem_sp);
+
+      fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack);
+      fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack);
+
+      mix_and_saturate(st->y0, st->y1, out, st->full_frame_size);
+
+      return 0;
+
+   }
+
+   for (i=0;i<st->frame_size;i++)
+      st->exc[i]=0;
+
+   ALLOC(low_pi_gain, st->nbSubframes, spx_word32_t);
+   ALLOC(low_exc, st->frame_size, spx_sig_t);
+   ALLOC(low_innov, st->frame_size, spx_sig_t);
+   speex_decoder_ctl(st->st_low, SPEEX_GET_PI_GAIN, low_pi_gain);
+   speex_decoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc);
+   speex_decoder_ctl(st->st_low, SPEEX_GET_INNOV, low_innov);
+
+   SUBMODE(lsp_unquant)(st->qlsp, st->lpcSize, bits);
+   
+   if (st->first)
+   {
+      for (i=0;i<st->lpcSize;i++)
+         st->old_qlsp[i] = st->qlsp[i];
+   }
+   
+   ALLOC(awk1, st->lpcSize+1, spx_coef_t);
+   ALLOC(awk2, st->lpcSize+1, spx_coef_t);
+   ALLOC(awk3, st->lpcSize+1, spx_coef_t);
+
+   for (sub=0;sub<st->nbSubframes;sub++)
+   {
+      spx_sig_t *exc, *sp;
+      spx_word16_t filter_ratio;
+      spx_word16_t el=0;
+      int offset;
+      spx_word32_t rl=0,rh=0;
+      
+      offset = st->subframeSize*sub;
+      sp=st->high+offset;
+      exc=st->exc+offset;
+      
+      /* LSP interpolation */
+      lsp_interpolate(st->old_qlsp, st->qlsp, st->interp_qlsp, st->lpcSize, sub, st->nbSubframes);
+
+      lsp_enforce_margin(st->interp_qlsp, st->lpcSize, LSP_MARGIN);
+
+      /* LSP to LPC */
+      lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack);
+
+
+      if (st->lpc_enh_enabled)
+      {
+         spx_word16_t k1,k2,k3;
+         k1=SUBMODE(lpc_enh_k1);
+         k2=SUBMODE(lpc_enh_k2);
+         k3=SUBMODE(lpc_enh_k3);
+         bw_lpc(k1, st->interp_qlpc, awk1, st->lpcSize);
+         bw_lpc(k2, st->interp_qlpc, awk2, st->lpcSize);
+         bw_lpc(k3, st->interp_qlpc, awk3, st->lpcSize);
+         /*fprintf (stderr, "%f %f %f\n", k1, k2, k3);*/
+      }
+
+
+      /* Calculate reponse ratio between the low and high filter in the middle
+         of the band (4000 Hz) */
+      
+         st->pi_gain[sub]=LPC_SCALING;
+         rh = LPC_SCALING;
+         for (i=1;i<=st->lpcSize;i+=2)
+         {
+            rh += st->interp_qlpc[i+1] - st->interp_qlpc[i];
+            st->pi_gain[sub] += st->interp_qlpc[i] + st->interp_qlpc[i+1];
+         }
+
+         rl = low_pi_gain[sub];
+#ifdef FIXED_POINT
+         filter_ratio=DIV32_16(SHL(rl+82,2),SHR(82+rh,5));
+#else
+         filter_ratio=(rl+.01)/(rh+.01);
+#endif
+      
+      for (i=0;i<st->subframeSize;i++)
+         exc[i]=0;
+      if (!SUBMODE(innovation_unquant))
+      {
+         float g;
+         int quant;
+
+         quant = speex_bits_unpack_unsigned(bits, 5);
+         g= exp(((float)quant-10)/8.0);
+         
+#ifdef FIXED_POINT
+         g /= filter_ratio/128.;
+#else
+         g /= filter_ratio;
+#endif
+         /* High-band excitation using the low-band excitation and a gain */
+         for (i=0;i<st->subframeSize;i++)
+            exc[i]=mode->folding_gain*g*low_innov[offset+i];
+         /*speex_rand_vec(mode->folding_gain*g*sqrt(el/st->subframeSize), exc, st->subframeSize);*/
+      } else {
+         spx_word16_t gc;
+         spx_word32_t scale;
+         int qgc = speex_bits_unpack_unsigned(bits, 4);
+
+         el = compute_rms(low_exc+offset, st->subframeSize);
+
+#ifdef FIXED_POINT
+         gc = MULT16_32_Q15(28626,gc_quant_bound[qgc]);
+#else
+         gc = exp((1/3.7)*qgc-0.15556);
+#endif
+
+         if (st->subframeSize==80)
+            gc *= 1.4142;
+
+         scale = SHL(MULT16_16(DIV32_16(SHL(gc,SIG_SHIFT-4),filter_ratio),(1+el)),4);
+
+         SUBMODE(innovation_unquant)(exc, SUBMODE(innovation_params), st->subframeSize, 
+                                bits, stack);
+
+         signal_mul(exc,exc,scale,st->subframeSize);
+
+         if (SUBMODE(double_codebook)) {
+            char *tmp_stack=stack;
+            VARDECL(spx_sig_t *innov2);
+            ALLOC(innov2, st->subframeSize, spx_sig_t);
+            for (i=0;i<st->subframeSize;i++)
+               innov2[i]=0;
+            SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize, 
+                                bits, stack);
+            for (i=0;i<st->subframeSize;i++)
+               innov2[i]*=scale/(float)SIG_SCALING*(1/2.5);
+            for (i=0;i<st->subframeSize;i++)
+               exc[i] = ADD32(exc[i],innov2[i]);
+            stack = tmp_stack;
+         }
+
+      }
+
+      for (i=0;i<st->subframeSize;i++)
+         sp[i]=exc[i];
+      if (st->lpc_enh_enabled)
+      {
+         /* Use enhanced LPC filter */
+         filter_mem2(sp, awk2, awk1, sp, st->subframeSize, st->lpcSize, 
+                     st->mem_sp+st->lpcSize);
+         filter_mem2(sp, awk3, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, 
+                     st->mem_sp);
+      } else {
+         /* Use regular filter */
+         for (i=0;i<st->lpcSize;i++)
+            st->mem_sp[st->lpcSize+i] = 0;
+         iir_mem2(sp, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, 
+                     st->mem_sp);
+      }
+      /*iir_mem2(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp);*/
+
+   }
+
+   fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack);
+   fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack);
+
+   mix_and_saturate(st->y0, st->y1, out, st->full_frame_size);
+
+   for (i=0;i<st->lpcSize;i++)
+      st->old_qlsp[i] = st->qlsp[i];
+
+   st->first=0;
+
+   return 0;
+}
+
+
+int sb_encoder_ctl(void *state, int request, void *ptr)
+{
+   SBEncState *st;
+   st=(SBEncState*)state;
+   switch(request)
+   {
+   case SPEEX_GET_FRAME_SIZE:
+      (*(int*)ptr) = st->full_frame_size;
+      break;
+   case SPEEX_SET_HIGH_MODE:
+      st->submodeSelect = st->submodeID = (*(int*)ptr);
+      break;
+   case SPEEX_SET_LOW_MODE:
+      speex_encoder_ctl(st->st_low, SPEEX_SET_LOW_MODE, ptr);
+      break;
+   case SPEEX_SET_DTX:
+      speex_encoder_ctl(st->st_low, SPEEX_SET_DTX, ptr);
+      break;
+   case SPEEX_GET_DTX:
+      speex_encoder_ctl(st->st_low, SPEEX_GET_DTX, ptr);
+      break;
+   case SPEEX_GET_LOW_MODE:
+      speex_encoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, ptr);
+      break;
+   case SPEEX_SET_MODE:
+      speex_encoder_ctl(st, SPEEX_SET_QUALITY, ptr);
+      break;
+   case SPEEX_SET_VBR:
+      st->vbr_enabled = (*(int*)ptr);
+      speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, ptr);
+      break;
+   case SPEEX_GET_VBR:
+      (*(int*)ptr) = st->vbr_enabled;
+      break;
+   case SPEEX_SET_VAD:
+      st->vad_enabled = (*(int*)ptr);
+      speex_encoder_ctl(st->st_low, SPEEX_SET_VAD, ptr);
+      break;
+   case SPEEX_GET_VAD:
+      (*(int*)ptr) = st->vad_enabled;
+      break;
+   case SPEEX_SET_VBR_QUALITY:
+      {
+         int q;
+         float qual = (*(float*)ptr)+.6;
+         st->vbr_quality = (*(float*)ptr);
+         if (qual>10)
+            qual=10;
+         q=(int)floor(.5+*(float*)ptr);
+         if (q>10)
+            q=10;
+         speex_encoder_ctl(st->st_low, SPEEX_SET_VBR_QUALITY, &qual);
+         speex_encoder_ctl(state, SPEEX_SET_QUALITY, &q);
+         break;
+      }
+   case SPEEX_SET_ABR:
+      st->abr_enabled = (*(int*)ptr);
+      st->vbr_enabled = 1;
+      speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, &st->vbr_enabled);
+      {
+         int i=10, rate, target;
+         float vbr_qual;
+         target = (*(int*)ptr);
+         while (i>=0)
+         {
+            speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i);
+            speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate);
+            if (rate <= target)
+               break;
+            i--;
+         }
+         vbr_qual=i;
+         if (vbr_qual<0)
+            vbr_qual=0;
+         speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_qual);
+         st->abr_count=0;
+         st->abr_drift=0;
+         st->abr_drift2=0;
+      }
+      
+      break;
+   case SPEEX_GET_ABR:
+      (*(int*)ptr) = st->abr_enabled;
+      break;
+   case SPEEX_SET_QUALITY:
+      {
+         int nb_qual;
+         int quality = (*(int*)ptr);
+         if (quality < 0)
+            quality = 0;
+         if (quality > 10)
+            quality = 10;
+         st->submodeSelect = st->submodeID = ((const SpeexSBMode*)(st->mode->mode))->quality_map[quality];
+         nb_qual = ((const SpeexSBMode*)(st->mode->mode))->low_quality_map[quality];
+         speex_encoder_ctl(st->st_low, SPEEX_SET_MODE, &nb_qual);
+      }
+      break;
+   case SPEEX_SET_COMPLEXITY:
+      speex_encoder_ctl(st->st_low, SPEEX_SET_COMPLEXITY, ptr);
+      st->complexity = (*(int*)ptr);
+      if (st->complexity<1)
+         st->complexity=1;
+      break;
+   case SPEEX_GET_COMPLEXITY:
+      (*(int*)ptr) = st->complexity;
+      break;
+   case SPEEX_SET_BITRATE:
+      {
+         int i=10, rate, target;
+         target = (*(int*)ptr);
+         while (i>=0)
+         {
+            speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i);
+            speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate);
+            if (rate <= target)
+               break;
+            i--;
+         }
+      }
+      break;
+   case SPEEX_GET_BITRATE:
+      speex_encoder_ctl(st->st_low, request, ptr);
+      /*fprintf (stderr, "before: %d\n", (*(int*)ptr));*/
+      if (st->submodes[st->submodeID])
+         (*(int*)ptr) += st->sampling_rate*SUBMODE(bits_per_frame)/st->full_frame_size;
+      else
+         (*(int*)ptr) += st->sampling_rate*(SB_SUBMODE_BITS+1)/st->full_frame_size;
+      /*fprintf (stderr, "after: %d\n", (*(int*)ptr));*/
+      break;
+   case SPEEX_SET_SAMPLING_RATE:
+      {
+         int tmp=(*(int*)ptr);
+         st->sampling_rate = tmp;
+         tmp>>=1;
+         speex_encoder_ctl(st->st_low, SPEEX_SET_SAMPLING_RATE, &tmp);
+      }
+      break;
+   case SPEEX_GET_SAMPLING_RATE:
+      (*(int*)ptr)=st->sampling_rate;
+      break;
+   case SPEEX_RESET_STATE:
+      {
+         int i;
+         st->first = 1;
+         for (i=0;i<st->lpcSize;i++)
+            st->lsp[i]=(M_PI*((float)(i+1)))/(st->lpcSize+1);
+         for (i=0;i<st->lpcSize;i++)
+            st->mem_sw[i]=st->mem_sp[i]=st->mem_sp2[i]=0;
+         for (i=0;i<st->bufSize;i++)
+            st->excBuf[i]=0;
+         for (i=0;i<QMF_ORDER;i++)
+            st->h0_mem[i]=st->h1_mem[i]=st->g0_mem[i]=st->g1_mem[i]=0;
+      }
+      break;
+   case SPEEX_SET_SUBMODE_ENCODING:
+      st->encode_submode = (*(int*)ptr);
+      speex_encoder_ctl(st->st_low, SPEEX_SET_SUBMODE_ENCODING, &ptr);
+      break;
+   case SPEEX_GET_SUBMODE_ENCODING:
+      (*(int*)ptr) = st->encode_submode;
+      break;
+   case SPEEX_GET_LOOKAHEAD:
+      speex_encoder_ctl(st->st_low, SPEEX_GET_LOOKAHEAD, ptr);
+      (*(int*)ptr) = 2*(*(int*)ptr) + QMF_ORDER - 1;
+      break;
+   case SPEEX_GET_PI_GAIN:
+      {
+         int i;
+         spx_word32_t *g = (spx_word32_t*)ptr;
+         for (i=0;i<st->nbSubframes;i++)
+            g[i]=st->pi_gain[i];
+      }
+      break;
+   case SPEEX_GET_EXC:
+      {
+         int i;
+         spx_sig_t *e = (spx_sig_t*)ptr;
+         for (i=0;i<st->full_frame_size;i++)
+            e[i]=0;
+         for (i=0;i<st->frame_size;i++)
+            e[2*i]=2*st->exc[i];
+      }
+      break;
+   case SPEEX_GET_INNOV:
+      {
+         int i;
+         spx_sig_t *e = (spx_sig_t*)ptr;
+         for (i=0;i<st->full_frame_size;i++)
+            e[i]=0;
+         for (i=0;i<st->frame_size;i++)
+            e[2*i]=2*st->exc[i];
+      }
+      break;
+   case SPEEX_GET_RELATIVE_QUALITY:
+      (*(float*)ptr)=st->relative_quality;
+      break;
+   default:
+      speex_warning_int("Unknown nb_ctl request: ", request);
+      return -1;
+   }
+   return 0;
+}
+
+int sb_decoder_ctl(void *state, int request, void *ptr)
+{
+   SBDecState *st;
+   st=(SBDecState*)state;
+   switch(request)
+   {
+   case SPEEX_SET_HIGH_MODE:
+      st->submodeID = (*(int*)ptr);
+      break;
+   case SPEEX_SET_LOW_MODE:
+      speex_decoder_ctl(st->st_low, SPEEX_SET_LOW_MODE, ptr);
+      break;
+   case SPEEX_GET_LOW_MODE:
+      speex_decoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, ptr);
+      break;
+   case SPEEX_GET_FRAME_SIZE:
+      (*(int*)ptr) = st->full_frame_size;
+      break;
+   case SPEEX_SET_ENH:
+      speex_decoder_ctl(st->st_low, request, ptr);
+      st->lpc_enh_enabled = *((int*)ptr);
+      break;
+   case SPEEX_SET_MODE:
+   case SPEEX_SET_QUALITY:
+      {
+         int nb_qual;
+         int quality = (*(int*)ptr);
+         if (quality < 0)
+            quality = 0;
+         if (quality > 10)
+            quality = 10;
+         st->submodeID = ((const SpeexSBMode*)(st->mode->mode))->quality_map[quality];
+         nb_qual = ((const SpeexSBMode*)(st->mode->mode))->low_quality_map[quality];
+         speex_decoder_ctl(st->st_low, SPEEX_SET_MODE, &nb_qual);
+      }
+      break;
+   case SPEEX_GET_BITRATE:
+      speex_decoder_ctl(st->st_low, request, ptr);
+      if (st->submodes[st->submodeID])
+         (*(int*)ptr) += st->sampling_rate*SUBMODE(bits_per_frame)/st->full_frame_size;
+      else
+         (*(int*)ptr) += st->sampling_rate*(SB_SUBMODE_BITS+1)/st->full_frame_size;
+      break;
+   case SPEEX_SET_SAMPLING_RATE:
+      {
+         int tmp=(*(int*)ptr);
+         st->sampling_rate = tmp;
+         tmp>>=1;
+         speex_decoder_ctl(st->st_low, SPEEX_SET_SAMPLING_RATE, &tmp);
+      }
+      break;
+   case SPEEX_GET_SAMPLING_RATE:
+      (*(int*)ptr)=st->sampling_rate;
+      break;
+   case SPEEX_SET_HANDLER:
+      speex_decoder_ctl(st->st_low, SPEEX_SET_HANDLER, ptr);
+      break;
+   case SPEEX_SET_USER_HANDLER:
+      speex_decoder_ctl(st->st_low, SPEEX_SET_USER_HANDLER, ptr);
+      break;
+   case SPEEX_RESET_STATE:
+      {
+         int i;
+         for (i=0;i<2*st->lpcSize;i++)
+            st->mem_sp[i]=0;
+         for (i=0;i<QMF_ORDER;i++)
+            st->g0_mem[i]=st->g1_mem[i]=0;
+      }
+      break;
+   case SPEEX_SET_SUBMODE_ENCODING:
+      st->encode_submode = (*(int*)ptr);
+      speex_decoder_ctl(st->st_low, SPEEX_SET_SUBMODE_ENCODING, &ptr);
+      break;
+   case SPEEX_GET_SUBMODE_ENCODING:
+      (*(int*)ptr) = st->encode_submode;
+      break;
+   case SPEEX_GET_PI_GAIN:
+      {
+         int i;
+         spx_word32_t *g = (spx_word32_t*)ptr;
+         for (i=0;i<st->nbSubframes;i++)
+            g[i]=st->pi_gain[i];
+      }
+      break;
+   case SPEEX_GET_EXC:
+      {
+         int i;
+         spx_sig_t *e = (spx_sig_t*)ptr;
+         for (i=0;i<st->full_frame_size;i++)
+            e[i]=0;
+         for (i=0;i<st->frame_size;i++)
+            e[2*i]=2*st->exc[i];
+      }
+      break;
+   case SPEEX_GET_INNOV:
+      {
+         int i;
+         spx_sig_t *e = (spx_sig_t*)ptr;
+         for (i=0;i<st->full_frame_size;i++)
+            e[i]=0;
+         for (i=0;i<st->frame_size;i++)
+            e[2*i]=2*st->exc[i];
+      }
+      break;
+   case SPEEX_GET_DTX_STATUS:
+      speex_decoder_ctl(st->st_low, SPEEX_GET_DTX_STATUS, ptr);
+      break;
+   default:
+      speex_warning_int("Unknown nb_ctl request: ", request);
+      return -1;
+   }
+   return 0;
+}
+
+#endif
+
diff --git a/utils/iaxclient/lib/libspeex/sb_celp.h b/utils/iaxclient/lib/libspeex/sb_celp.h
new file mode 100644 (file)
index 0000000..b812a2e
--- /dev/null
@@ -0,0 +1,169 @@
+/* Copyright (C) 2002 Jean-Marc Valin */
+/**
+   @file sb_celp.h
+   @brief Sub-band CELP mode used for wideband encoding
+*/
+/*
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+
+*/
+
+#ifndef SB_CELP_H
+#define SB_CELP_H
+
+#include "modes.h"
+#include <speex/speex_bits.h>
+#include "nb_celp.h"
+
+/**Structure representing the full state of the sub-band encoder*/
+typedef struct SBEncState {
+   const SpeexMode *mode;            /**< Pointer to the mode (containing for vtable info) */
+   void *st_low;               /**< State of the low-band (narrowband) encoder */
+   int    full_frame_size;     /**< Length of full-band frames*/
+   int    frame_size;          /**< Length of high-band frames*/
+   int    subframeSize;        /**< Length of high-band sub-frames*/
+   int    nbSubframes;         /**< Number of high-band sub-frames*/
+   int    windowSize;          /**< Length of high-band LPC window*/
+   int    lpcSize;             /**< Order of high-band LPC analysis */
+   int    bufSize;             /**< Buffer size */
+   int    first;               /**< First frame? */
+   float  lag_factor;          /**< Lag-windowing control parameter */
+   float  lpc_floor;           /**< Controls LPC analysis noise floor */
+   spx_word16_t  gamma1;              /**< Perceptual weighting coef 1 */
+   spx_word16_t  gamma2;              /**< Perceptual weighting coef 2 */
+
+   char  *stack;               /**< Temporary allocation stack */
+   spx_sig_t *x0d, *x1d; /**< QMF filter signals*/
+   spx_sig_t *high;                /**< High-band signal (buffer) */
+   spx_sig_t *y0, *y1;             /**< QMF synthesis signals */
+   spx_word16_t *h0_mem, *h1_mem;
+   spx_word32_t *g0_mem, *g1_mem; /**< QMF memories */
+
+   spx_sig_t *excBuf;              /**< High-band excitation */
+   spx_sig_t *exc;                 /**< High-band excitation (for QMF only)*/
+   spx_sig_t *buf;                 /**< Temporary buffer */
+   spx_sig_t *res;                 /**< Zero-input response (ringing) */
+   spx_sig_t *sw;                  /**< Perceptually weighted signal */
+   spx_sig_t *target;              /**< Weighted target signal (analysis by synthesis) */
+   spx_word16_t *window;              /**< LPC analysis window */
+   spx_word16_t *lagWindow;           /**< Auto-correlation window */
+   spx_word16_t *autocorr;            /**< Auto-correlation (for LPC analysis) */
+   spx_coef_t *lpc;                 /**< LPC coefficients */
+   spx_lsp_t *lsp;                 /**< LSP coefficients */
+   spx_lsp_t *qlsp;                /**< Quantized LSPs */
+   spx_lsp_t *old_lsp;             /**< LSPs of previous frame */
+   spx_lsp_t *old_qlsp;            /**< Quantized LSPs of previous frame */
+   spx_lsp_t *interp_lsp;          /**< Interpolated LSPs for current sub-frame */
+   spx_lsp_t *interp_qlsp;         /**< Interpolated quantized LSPs for current sub-frame */
+   spx_coef_t *interp_lpc;          /**< Interpolated LPCs for current sub-frame */
+   spx_coef_t *interp_qlpc;         /**< Interpolated quantized LPCs for current sub-frame */
+   spx_coef_t *bw_lpc1;             /**< Bandwidth-expanded version of LPCs (#1) */
+   spx_coef_t *bw_lpc2;             /**< Bandwidth-expanded version of LPCs (#2) */
+
+   spx_mem_t *mem_sp;              /**< Synthesis signal memory */
+   spx_mem_t *mem_sp2;
+   spx_mem_t *mem_sw;              /**< Perceptual signal memory */
+   spx_word32_t *pi_gain;
+
+   float  vbr_quality;         /**< Quality setting for VBR encoding */
+   int    vbr_enabled;         /**< 1 for enabling VBR, 0 otherwise */
+   int    abr_enabled;         /**< ABR setting (in bps), 0 if off */
+   float  abr_drift;
+   float  abr_drift2;
+   float  abr_count;
+   int    vad_enabled;         /**< 1 for enabling VAD, 0 otherwise */
+   float  relative_quality;
+
+   int    encode_submode;
+   const SpeexSubmode * const *submodes;
+   int    submodeID;
+   int    submodeSelect;
+   int    complexity;
+   int    sampling_rate;
+
+} SBEncState;
+
+
+/**Structure representing the full state of the sub-band decoder*/
+typedef struct SBDecState {
+   const SpeexMode *mode;            /**< Pointer to the mode (containing for vtable info) */
+   void *st_low;               /**< State of the low-band (narrowband) encoder */
+   int    full_frame_size;
+   int    frame_size;
+   int    subframeSize;
+   int    nbSubframes;
+   int    lpcSize;
+   int    first;
+   int    sampling_rate;
+   int    lpc_enh_enabled;
+
+   char  *stack;
+   spx_sig_t *x0d, *x1d;
+   spx_sig_t *high;
+   spx_sig_t *y0, *y1;
+   spx_word32_t *g0_mem, *g1_mem;
+
+   spx_sig_t *exc;
+   spx_lsp_t *qlsp;
+   spx_lsp_t *old_qlsp;
+   spx_lsp_t *interp_qlsp;
+   spx_coef_t *interp_qlpc;
+
+   spx_mem_t *mem_sp;
+   spx_word32_t *pi_gain;
+
+   int    encode_submode;
+   const SpeexSubmode * const *submodes;
+   int    submodeID;
+} SBDecState;
+
+
+/**Initializes encoder state*/
+void *sb_encoder_init(const SpeexMode *m);
+
+/**De-allocates encoder state resources*/
+void sb_encoder_destroy(void *state);
+
+/**Encodes one frame*/
+int sb_encode(void *state, void *in, SpeexBits *bits);
+
+
+/**Initializes decoder state*/
+void *sb_decoder_init(const SpeexMode *m);
+
+/**De-allocates decoder state resources*/
+void sb_decoder_destroy(void *state);
+
+/**Decodes one frame*/
+int sb_decode(void *state, SpeexBits *bits, void *out);
+
+int sb_encoder_ctl(void *state, int request, void *ptr);
+
+int sb_decoder_ctl(void *state, int request, void *ptr);
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/smallft.c b/utils/iaxclient/lib/libspeex/smallft.c
new file mode 100644 (file)
index 0000000..197587d
--- /dev/null
@@ -0,0 +1,1260 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
+ * by the XIPHOPHORUS Company http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: *unnormalized* fft transform
+ last mod: $Id: smallft.c 465 2005-05-13 19:19:47Z stevek $
+
+ ********************************************************************/
+
+/* FFT implementation from OggSquish, minus cosine transforms,
+ * minus all but radix 2/4 case.  In Vorbis we only need this
+ * cut-down version.
+ *
+ * To do more than just power-of-two sized vectors, see the full
+ * version I wrote for NetLib.
+ *
+ * Note that the packing is a little strange; rather than the FFT r/i
+ * packing following R_0, I_n, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1,
+ * it follows R_0, R_1, I_1, R_2, I_2 ... R_n-1, I_n-1, I_n like the
+ * FORTRAN version
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <math.h>
+#include "smallft.h"
+#include "misc.h"
+
+static void drfti1(int n, float *wa, int *ifac){
+  static int ntryh[4] = { 4,2,3,5 };
+  static float tpi = 6.28318530717958648f;
+  float arg,argh,argld,fi;
+  int ntry=0,i,j=-1;
+  int k1, l1, l2, ib;
+  int ld, ii, ip, is, nq, nr;
+  int ido, ipm, nfm1;
+  int nl=n;
+  int nf=0;
+
+ L101:
+  j++;
+  if (j < 4)
+    ntry=ntryh[j];
+  else
+    ntry+=2;
+
+ L104:
+  nq=nl/ntry;
+  nr=nl-ntry*nq;
+  if (nr!=0) goto L101;
+
+  nf++;
+  ifac[nf+1]=ntry;
+  nl=nq;
+  if(ntry!=2)goto L107;
+  if(nf==1)goto L107;
+
+  for (i=1;i<nf;i++){
+    ib=nf-i+1;
+    ifac[ib+1]=ifac[ib];
+  }
+  ifac[2] = 2;
+
+ L107:
+  if(nl!=1)goto L104;
+  ifac[0]=n;
+  ifac[1]=nf;
+  argh=tpi/n;
+  is=0;
+  nfm1=nf-1;
+  l1=1;
+
+  if(nfm1==0)return;
+
+  for (k1=0;k1<nfm1;k1++){
+    ip=ifac[k1+2];
+    ld=0;
+    l2=l1*ip;
+    ido=n/l2;
+    ipm=ip-1;
+
+    for (j=0;j<ipm;j++){
+      ld+=l1;
+      i=is;
+      argld=(float)ld*argh;
+      fi=0.f;
+      for (ii=2;ii<ido;ii+=2){
+       fi+=1.f;
+       arg=fi*argld;
+       wa[i++]=cos(arg);
+       wa[i++]=sin(arg);
+      }
+      is+=ido;
+    }
+    l1=l2;
+  }
+}
+
+static void fdrffti(int n, float *wsave, int *ifac){
+
+  if (n == 1) return;
+  drfti1(n, wsave+n, ifac);
+}
+
+static void dradf2(int ido,int l1,float *cc,float *ch,float *wa1){
+  int i,k;
+  float ti2,tr2;
+  int t0,t1,t2,t3,t4,t5,t6;
+
+  t1=0;
+  t0=(t2=l1*ido);
+  t3=ido<<1;
+  for(k=0;k<l1;k++){
+    ch[t1<<1]=cc[t1]+cc[t2];
+    ch[(t1<<1)+t3-1]=cc[t1]-cc[t2];
+    t1+=ido;
+    t2+=ido;
+  }
+    
+  if(ido<2)return;
+  if(ido==2)goto L105;
+
+  t1=0;
+  t2=t0;
+  for(k=0;k<l1;k++){
+    t3=t2;
+    t4=(t1<<1)+(ido<<1);
+    t5=t1;
+    t6=t1+t1;
+    for(i=2;i<ido;i+=2){
+      t3+=2;
+      t4-=2;
+      t5+=2;
+      t6+=2;
+      tr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3];
+      ti2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1];
+      ch[t6]=cc[t5]+ti2;
+      ch[t4]=ti2-cc[t5];
+      ch[t6-1]=cc[t5-1]+tr2;
+      ch[t4-1]=cc[t5-1]-tr2;
+    }
+    t1+=ido;
+    t2+=ido;
+  }
+
+  if(ido%2==1)return;
+
+ L105:
+  t3=(t2=(t1=ido)-1);
+  t2+=t0;
+  for(k=0;k<l1;k++){
+    ch[t1]=-cc[t2];
+    ch[t1-1]=cc[t3];
+    t1+=ido<<1;
+    t2+=ido;
+    t3+=ido;
+  }
+}
+
+static void dradf4(int ido,int l1,float *cc,float *ch,float *wa1,
+           float *wa2,float *wa3){
+  static float hsqt2 = .70710678118654752f;
+  int i,k,t0,t1,t2,t3,t4,t5,t6;
+  float ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4;
+  t0=l1*ido;
+  
+  t1=t0;
+  t4=t1<<1;
+  t2=t1+(t1<<1);
+  t3=0;
+
+  for(k=0;k<l1;k++){
+    tr1=cc[t1]+cc[t2];
+    tr2=cc[t3]+cc[t4];
+
+    ch[t5=t3<<2]=tr1+tr2;
+    ch[(ido<<2)+t5-1]=tr2-tr1;
+    ch[(t5+=(ido<<1))-1]=cc[t3]-cc[t4];
+    ch[t5]=cc[t2]-cc[t1];
+
+    t1+=ido;
+    t2+=ido;
+    t3+=ido;
+    t4+=ido;
+  }
+
+  if(ido<2)return;
+  if(ido==2)goto L105;
+
+
+  t1=0;
+  for(k=0;k<l1;k++){
+    t2=t1;
+    t4=t1<<2;
+    t5=(t6=ido<<1)+t4;
+    for(i=2;i<ido;i+=2){
+      t3=(t2+=2);
+      t4+=2;
+      t5-=2;
+
+      t3+=t0;
+      cr2=wa1[i-2]*cc[t3-1]+wa1[i-1]*cc[t3];
+      ci2=wa1[i-2]*cc[t3]-wa1[i-1]*cc[t3-1];
+      t3+=t0;
+      cr3=wa2[i-2]*cc[t3-1]+wa2[i-1]*cc[t3];
+      ci3=wa2[i-2]*cc[t3]-wa2[i-1]*cc[t3-1];
+      t3+=t0;
+      cr4=wa3[i-2]*cc[t3-1]+wa3[i-1]*cc[t3];
+      ci4=wa3[i-2]*cc[t3]-wa3[i-1]*cc[t3-1];
+
+      tr1=cr2+cr4;
+      tr4=cr4-cr2;
+      ti1=ci2+ci4;
+      ti4=ci2-ci4;
+
+      ti2=cc[t2]+ci3;
+      ti3=cc[t2]-ci3;
+      tr2=cc[t2-1]+cr3;
+      tr3=cc[t2-1]-cr3;
+
+      ch[t4-1]=tr1+tr2;
+      ch[t4]=ti1+ti2;
+
+      ch[t5-1]=tr3-ti4;
+      ch[t5]=tr4-ti3;
+
+      ch[t4+t6-1]=ti4+tr3;
+      ch[t4+t6]=tr4+ti3;
+
+      ch[t5+t6-1]=tr2-tr1;
+      ch[t5+t6]=ti1-ti2;
+    }
+    t1+=ido;
+  }
+  if(ido&1)return;
+
+ L105:
+  
+  t2=(t1=t0+ido-1)+(t0<<1);
+  t3=ido<<2;
+  t4=ido;
+  t5=ido<<1;
+  t6=ido;
+
+  for(k=0;k<l1;k++){
+    ti1=-hsqt2*(cc[t1]+cc[t2]);
+    tr1=hsqt2*(cc[t1]-cc[t2]);
+
+    ch[t4-1]=tr1+cc[t6-1];
+    ch[t4+t5-1]=cc[t6-1]-tr1;
+
+    ch[t4]=ti1-cc[t1+t0];
+    ch[t4+t5]=ti1+cc[t1+t0];
+
+    t1+=ido;
+    t2+=ido;
+    t4+=t3;
+    t6+=ido;
+  }
+}
+
+static void dradfg(int ido,int ip,int l1,int idl1,float *cc,float *c1,
+                          float *c2,float *ch,float *ch2,float *wa){
+
+  static float tpi=6.283185307179586f;
+  int idij,ipph,i,j,k,l,ic,ik,is;
+  int t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
+  float dc2,ai1,ai2,ar1,ar2,ds2;
+  int nbd;
+  float dcp,arg,dsp,ar1h,ar2h;
+  int idp2,ipp2;
+  
+  arg=tpi/(float)ip;
+  dcp=cos(arg);
+  dsp=sin(arg);
+  ipph=(ip+1)>>1;
+  ipp2=ip;
+  idp2=ido;
+  nbd=(ido-1)>>1;
+  t0=l1*ido;
+  t10=ip*ido;
+
+  if(ido==1)goto L119;
+  for(ik=0;ik<idl1;ik++)ch2[ik]=c2[ik];
+
+  t1=0;
+  for(j=1;j<ip;j++){
+    t1+=t0;
+    t2=t1;
+    for(k=0;k<l1;k++){
+      ch[t2]=c1[t2];
+      t2+=ido;
+    }
+  }
+
+  is=-ido;
+  t1=0;
+  if(nbd>l1){
+    for(j=1;j<ip;j++){
+      t1+=t0;
+      is+=ido;
+      t2= -ido+t1;
+      for(k=0;k<l1;k++){
+        idij=is-1;
+        t2+=ido;
+        t3=t2;
+        for(i=2;i<ido;i+=2){
+          idij+=2;
+          t3+=2;
+          ch[t3-1]=wa[idij-1]*c1[t3-1]+wa[idij]*c1[t3];
+          ch[t3]=wa[idij-1]*c1[t3]-wa[idij]*c1[t3-1];
+        }
+      }
+    }
+  }else{
+
+    for(j=1;j<ip;j++){
+      is+=ido;
+      idij=is-1;
+      t1+=t0;
+      t2=t1;
+      for(i=2;i<ido;i+=2){
+        idij+=2;
+        t2+=2;
+        t3=t2;
+        for(k=0;k<l1;k++){
+          ch[t3-1]=wa[idij-1]*c1[t3-1]+wa[idij]*c1[t3];
+          ch[t3]=wa[idij-1]*c1[t3]-wa[idij]*c1[t3-1];
+          t3+=ido;
+        }
+      }
+    }
+  }
+
+  t1=0;
+  t2=ipp2*t0;
+  if(nbd<l1){
+    for(j=1;j<ipph;j++){
+      t1+=t0;
+      t2-=t0;
+      t3=t1;
+      t4=t2;
+      for(i=2;i<ido;i+=2){
+        t3+=2;
+        t4+=2;
+        t5=t3-ido;
+        t6=t4-ido;
+        for(k=0;k<l1;k++){
+          t5+=ido;
+          t6+=ido;
+          c1[t5-1]=ch[t5-1]+ch[t6-1];
+          c1[t6-1]=ch[t5]-ch[t6];
+          c1[t5]=ch[t5]+ch[t6];
+          c1[t6]=ch[t6-1]-ch[t5-1];
+        }
+      }
+    }
+  }else{
+    for(j=1;j<ipph;j++){
+      t1+=t0;
+      t2-=t0;
+      t3=t1;
+      t4=t2;
+      for(k=0;k<l1;k++){
+        t5=t3;
+        t6=t4;
+        for(i=2;i<ido;i+=2){
+          t5+=2;
+          t6+=2;
+          c1[t5-1]=ch[t5-1]+ch[t6-1];
+          c1[t6-1]=ch[t5]-ch[t6];
+          c1[t5]=ch[t5]+ch[t6];
+          c1[t6]=ch[t6-1]-ch[t5-1];
+        }
+        t3+=ido;
+        t4+=ido;
+      }
+    }
+  }
+
+L119:
+  for(ik=0;ik<idl1;ik++)c2[ik]=ch2[ik];
+
+  t1=0;
+  t2=ipp2*idl1;
+  for(j=1;j<ipph;j++){
+    t1+=t0;
+    t2-=t0;
+    t3=t1-ido;
+    t4=t2-ido;
+    for(k=0;k<l1;k++){
+      t3+=ido;
+      t4+=ido;
+      c1[t3]=ch[t3]+ch[t4];
+      c1[t4]=ch[t4]-ch[t3];
+    }
+  }
+
+  ar1=1.f;
+  ai1=0.f;
+  t1=0;
+  t2=ipp2*idl1;
+  t3=(ip-1)*idl1;
+  for(l=1;l<ipph;l++){
+    t1+=idl1;
+    t2-=idl1;
+    ar1h=dcp*ar1-dsp*ai1;
+    ai1=dcp*ai1+dsp*ar1;
+    ar1=ar1h;
+    t4=t1;
+    t5=t2;
+    t6=t3;
+    t7=idl1;
+
+    for(ik=0;ik<idl1;ik++){
+      ch2[t4++]=c2[ik]+ar1*c2[t7++];
+      ch2[t5++]=ai1*c2[t6++];
+    }
+
+    dc2=ar1;
+    ds2=ai1;
+    ar2=ar1;
+    ai2=ai1;
+
+    t4=idl1;
+    t5=(ipp2-1)*idl1;
+    for(j=2;j<ipph;j++){
+      t4+=idl1;
+      t5-=idl1;
+
+      ar2h=dc2*ar2-ds2*ai2;
+      ai2=dc2*ai2+ds2*ar2;
+      ar2=ar2h;
+
+      t6=t1;
+      t7=t2;
+      t8=t4;
+      t9=t5;
+      for(ik=0;ik<idl1;ik++){
+        ch2[t6++]+=ar2*c2[t8++];
+        ch2[t7++]+=ai2*c2[t9++];
+      }
+    }
+  }
+
+  t1=0;
+  for(j=1;j<ipph;j++){
+    t1+=idl1;
+    t2=t1;
+    for(ik=0;ik<idl1;ik++)ch2[ik]+=c2[t2++];
+  }
+
+  if(ido<l1)goto L132;
+
+  t1=0;
+  t2=0;
+  for(k=0;k<l1;k++){
+    t3=t1;
+    t4=t2;
+    for(i=0;i<ido;i++)cc[t4++]=ch[t3++];
+    t1+=ido;
+    t2+=t10;
+  }
+
+  goto L135;
+
+ L132:
+  for(i=0;i<ido;i++){
+    t1=i;
+    t2=i;
+    for(k=0;k<l1;k++){
+      cc[t2]=ch[t1];
+      t1+=ido;
+      t2+=t10;
+    }
+  }
+
+ L135:
+  t1=0;
+  t2=ido<<1;
+  t3=0;
+  t4=ipp2*t0;
+  for(j=1;j<ipph;j++){
+
+    t1+=t2;
+    t3+=t0;
+    t4-=t0;
+
+    t5=t1;
+    t6=t3;
+    t7=t4;
+
+    for(k=0;k<l1;k++){
+      cc[t5-1]=ch[t6];
+      cc[t5]=ch[t7];
+      t5+=t10;
+      t6+=ido;
+      t7+=ido;
+    }
+  }
+
+  if(ido==1)return;
+  if(nbd<l1)goto L141;
+
+  t1=-ido;
+  t3=0;
+  t4=0;
+  t5=ipp2*t0;
+  for(j=1;j<ipph;j++){
+    t1+=t2;
+    t3+=t2;
+    t4+=t0;
+    t5-=t0;
+    t6=t1;
+    t7=t3;
+    t8=t4;
+    t9=t5;
+    for(k=0;k<l1;k++){
+      for(i=2;i<ido;i+=2){
+        ic=idp2-i;
+        cc[i+t7-1]=ch[i+t8-1]+ch[i+t9-1];
+        cc[ic+t6-1]=ch[i+t8-1]-ch[i+t9-1];
+        cc[i+t7]=ch[i+t8]+ch[i+t9];
+        cc[ic+t6]=ch[i+t9]-ch[i+t8];
+      }
+      t6+=t10;
+      t7+=t10;
+      t8+=ido;
+      t9+=ido;
+    }
+  }
+  return;
+
+ L141:
+
+  t1=-ido;
+  t3=0;
+  t4=0;
+  t5=ipp2*t0;
+  for(j=1;j<ipph;j++){
+    t1+=t2;
+    t3+=t2;
+    t4+=t0;
+    t5-=t0;
+    for(i=2;i<ido;i+=2){
+      t6=idp2+t1-i;
+      t7=i+t3;
+      t8=i+t4;
+      t9=i+t5;
+      for(k=0;k<l1;k++){
+        cc[t7-1]=ch[t8-1]+ch[t9-1];
+        cc[t6-1]=ch[t8-1]-ch[t9-1];
+        cc[t7]=ch[t8]+ch[t9];
+        cc[t6]=ch[t9]-ch[t8];
+        t6+=t10;
+        t7+=t10;
+        t8+=ido;
+        t9+=ido;
+      }
+    }
+  }
+}
+
+static void drftf1(int n,float *c,float *ch,float *wa,int *ifac){
+  int i,k1,l1,l2;
+  int na,kh,nf;
+  int ip,iw,ido,idl1,ix2,ix3;
+
+  nf=ifac[1];
+  na=1;
+  l2=n;
+  iw=n;
+
+  for(k1=0;k1<nf;k1++){
+    kh=nf-k1;
+    ip=ifac[kh+1];
+    l1=l2/ip;
+    ido=n/l2;
+    idl1=ido*l1;
+    iw-=(ip-1)*ido;
+    na=1-na;
+
+    if(ip!=4)goto L102;
+
+    ix2=iw+ido;
+    ix3=ix2+ido;
+    if(na!=0)
+      dradf4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1);
+    else
+      dradf4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1);
+    goto L110;
+
+ L102:
+    if(ip!=2)goto L104;
+    if(na!=0)goto L103;
+
+    dradf2(ido,l1,c,ch,wa+iw-1);
+    goto L110;
+
+  L103:
+    dradf2(ido,l1,ch,c,wa+iw-1);
+    goto L110;
+
+  L104:
+    if(ido==1)na=1-na;
+    if(na!=0)goto L109;
+
+    dradfg(ido,ip,l1,idl1,c,c,c,ch,ch,wa+iw-1);
+    na=1;
+    goto L110;
+
+  L109:
+    dradfg(ido,ip,l1,idl1,ch,ch,ch,c,c,wa+iw-1);
+    na=0;
+
+  L110:
+    l2=l1;
+  }
+
+  if(na==1)return;
+
+  for(i=0;i<n;i++)c[i]=ch[i];
+}
+
+static void dradb2(int ido,int l1,float *cc,float *ch,float *wa1){
+  int i,k,t0,t1,t2,t3,t4,t5,t6;
+  float ti2,tr2;
+
+  t0=l1*ido;
+  
+  t1=0;
+  t2=0;
+  t3=(ido<<1)-1;
+  for(k=0;k<l1;k++){
+    ch[t1]=cc[t2]+cc[t3+t2];
+    ch[t1+t0]=cc[t2]-cc[t3+t2];
+    t2=(t1+=ido)<<1;
+  }
+
+  if(ido<2)return;
+  if(ido==2)goto L105;
+
+  t1=0;
+  t2=0;
+  for(k=0;k<l1;k++){
+    t3=t1;
+    t5=(t4=t2)+(ido<<1);
+    t6=t0+t1;
+    for(i=2;i<ido;i+=2){
+      t3+=2;
+      t4+=2;
+      t5-=2;
+      t6+=2;
+      ch[t3-1]=cc[t4-1]+cc[t5-1];
+      tr2=cc[t4-1]-cc[t5-1];
+      ch[t3]=cc[t4]-cc[t5];
+      ti2=cc[t4]+cc[t5];
+      ch[t6-1]=wa1[i-2]*tr2-wa1[i-1]*ti2;
+      ch[t6]=wa1[i-2]*ti2+wa1[i-1]*tr2;
+    }
+    t2=(t1+=ido)<<1;
+  }
+
+  if(ido%2==1)return;
+
+L105:
+  t1=ido-1;
+  t2=ido-1;
+  for(k=0;k<l1;k++){
+    ch[t1]=cc[t2]+cc[t2];
+    ch[t1+t0]=-(cc[t2+1]+cc[t2+1]);
+    t1+=ido;
+    t2+=ido<<1;
+  }
+}
+
+static void dradb3(int ido,int l1,float *cc,float *ch,float *wa1,
+                          float *wa2){
+  static float taur = -.5f;
+  static float taui = .8660254037844386f;
+  int i,k,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
+  float ci2,ci3,di2,di3,cr2,cr3,dr2,dr3,ti2,tr2;
+  t0=l1*ido;
+
+  t1=0;
+  t2=t0<<1;
+  t3=ido<<1;
+  t4=ido+(ido<<1);
+  t5=0;
+  for(k=0;k<l1;k++){
+    tr2=cc[t3-1]+cc[t3-1];
+    cr2=cc[t5]+(taur*tr2);
+    ch[t1]=cc[t5]+tr2;
+    ci3=taui*(cc[t3]+cc[t3]);
+    ch[t1+t0]=cr2-ci3;
+    ch[t1+t2]=cr2+ci3;
+    t1+=ido;
+    t3+=t4;
+    t5+=t4;
+  }
+
+  if(ido==1)return;
+
+  t1=0;
+  t3=ido<<1;
+  for(k=0;k<l1;k++){
+    t7=t1+(t1<<1);
+    t6=(t5=t7+t3);
+    t8=t1;
+    t10=(t9=t1+t0)+t0;
+
+    for(i=2;i<ido;i+=2){
+      t5+=2;
+      t6-=2;
+      t7+=2;
+      t8+=2;
+      t9+=2;
+      t10+=2;
+      tr2=cc[t5-1]+cc[t6-1];
+      cr2=cc[t7-1]+(taur*tr2);
+      ch[t8-1]=cc[t7-1]+tr2;
+      ti2=cc[t5]-cc[t6];
+      ci2=cc[t7]+(taur*ti2);
+      ch[t8]=cc[t7]+ti2;
+      cr3=taui*(cc[t5-1]-cc[t6-1]);
+      ci3=taui*(cc[t5]+cc[t6]);
+      dr2=cr2-ci3;
+      dr3=cr2+ci3;
+      di2=ci2+cr3;
+      di3=ci2-cr3;
+      ch[t9-1]=wa1[i-2]*dr2-wa1[i-1]*di2;
+      ch[t9]=wa1[i-2]*di2+wa1[i-1]*dr2;
+      ch[t10-1]=wa2[i-2]*dr3-wa2[i-1]*di3;
+      ch[t10]=wa2[i-2]*di3+wa2[i-1]*dr3;
+    }
+    t1+=ido;
+  }
+}
+
+static void dradb4(int ido,int l1,float *cc,float *ch,float *wa1,
+                         float *wa2,float *wa3){
+  static float sqrt2=1.414213562373095f;
+  int i,k,t0,t1,t2,t3,t4,t5,t6,t7,t8;
+  float ci2,ci3,ci4,cr2,cr3,cr4,ti1,ti2,ti3,ti4,tr1,tr2,tr3,tr4;
+  t0=l1*ido;
+  
+  t1=0;
+  t2=ido<<2;
+  t3=0;
+  t6=ido<<1;
+  for(k=0;k<l1;k++){
+    t4=t3+t6;
+    t5=t1;
+    tr3=cc[t4-1]+cc[t4-1];
+    tr4=cc[t4]+cc[t4]; 
+    tr1=cc[t3]-cc[(t4+=t6)-1];
+    tr2=cc[t3]+cc[t4-1];
+    ch[t5]=tr2+tr3;
+    ch[t5+=t0]=tr1-tr4;
+    ch[t5+=t0]=tr2-tr3;
+    ch[t5+=t0]=tr1+tr4;
+    t1+=ido;
+    t3+=t2;
+  }
+
+  if(ido<2)return;
+  if(ido==2)goto L105;
+
+  t1=0;
+  for(k=0;k<l1;k++){
+    t5=(t4=(t3=(t2=t1<<2)+t6))+t6;
+    t7=t1;
+    for(i=2;i<ido;i+=2){
+      t2+=2;
+      t3+=2;
+      t4-=2;
+      t5-=2;
+      t7+=2;
+      ti1=cc[t2]+cc[t5];
+      ti2=cc[t2]-cc[t5];
+      ti3=cc[t3]-cc[t4];
+      tr4=cc[t3]+cc[t4];
+      tr1=cc[t2-1]-cc[t5-1];
+      tr2=cc[t2-1]+cc[t5-1];
+      ti4=cc[t3-1]-cc[t4-1];
+      tr3=cc[t3-1]+cc[t4-1];
+      ch[t7-1]=tr2+tr3;
+      cr3=tr2-tr3;
+      ch[t7]=ti2+ti3;
+      ci3=ti2-ti3;
+      cr2=tr1-tr4;
+      cr4=tr1+tr4;
+      ci2=ti1+ti4;
+      ci4=ti1-ti4;
+
+      ch[(t8=t7+t0)-1]=wa1[i-2]*cr2-wa1[i-1]*ci2;
+      ch[t8]=wa1[i-2]*ci2+wa1[i-1]*cr2;
+      ch[(t8+=t0)-1]=wa2[i-2]*cr3-wa2[i-1]*ci3;
+      ch[t8]=wa2[i-2]*ci3+wa2[i-1]*cr3;
+      ch[(t8+=t0)-1]=wa3[i-2]*cr4-wa3[i-1]*ci4;
+      ch[t8]=wa3[i-2]*ci4+wa3[i-1]*cr4;
+    }
+    t1+=ido;
+  }
+
+  if(ido%2 == 1)return;
+
+ L105:
+
+  t1=ido;
+  t2=ido<<2;
+  t3=ido-1;
+  t4=ido+(ido<<1);
+  for(k=0;k<l1;k++){
+    t5=t3;
+    ti1=cc[t1]+cc[t4];
+    ti2=cc[t4]-cc[t1];
+    tr1=cc[t1-1]-cc[t4-1];
+    tr2=cc[t1-1]+cc[t4-1];
+    ch[t5]=tr2+tr2;
+    ch[t5+=t0]=sqrt2*(tr1-ti1);
+    ch[t5+=t0]=ti2+ti2;
+    ch[t5+=t0]=-sqrt2*(tr1+ti1);
+
+    t3+=ido;
+    t1+=t2;
+    t4+=t2;
+  }
+}
+
+static void dradbg(int ido,int ip,int l1,int idl1,float *cc,float *c1,
+            float *c2,float *ch,float *ch2,float *wa){
+  static float tpi=6.283185307179586f;
+  int idij,ipph,i,j,k,l,ik,is,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,
+      t11,t12;
+  float dc2,ai1,ai2,ar1,ar2,ds2;
+  int nbd;
+  float dcp,arg,dsp,ar1h,ar2h;
+  int ipp2;
+
+  t10=ip*ido;
+  t0=l1*ido;
+  arg=tpi/(float)ip;
+  dcp=cos(arg);
+  dsp=sin(arg);
+  nbd=(ido-1)>>1;
+  ipp2=ip;
+  ipph=(ip+1)>>1;
+  if(ido<l1)goto L103;
+  
+  t1=0;
+  t2=0;
+  for(k=0;k<l1;k++){
+    t3=t1;
+    t4=t2;
+    for(i=0;i<ido;i++){
+      ch[t3]=cc[t4];
+      t3++;
+      t4++;
+    }
+    t1+=ido;
+    t2+=t10;
+  }
+  goto L106;
+
+ L103:
+  t1=0;
+  for(i=0;i<ido;i++){
+    t2=t1;
+    t3=t1;
+    for(k=0;k<l1;k++){
+      ch[t2]=cc[t3];
+      t2+=ido;
+      t3+=t10;
+    }
+    t1++;
+  }
+
+ L106:
+  t1=0;
+  t2=ipp2*t0;
+  t7=(t5=ido<<1);
+  for(j=1;j<ipph;j++){
+    t1+=t0;
+    t2-=t0;
+    t3=t1;
+    t4=t2;
+    t6=t5;
+    for(k=0;k<l1;k++){
+      ch[t3]=cc[t6-1]+cc[t6-1];
+      ch[t4]=cc[t6]+cc[t6];
+      t3+=ido;
+      t4+=ido;
+      t6+=t10;
+    }
+    t5+=t7;
+  }
+
+  if (ido == 1)goto L116;
+  if(nbd<l1)goto L112;
+
+  t1=0;
+  t2=ipp2*t0;
+  t7=0;
+  for(j=1;j<ipph;j++){
+    t1+=t0;
+    t2-=t0;
+    t3=t1;
+    t4=t2;
+
+    t7+=(ido<<1);
+    t8=t7;
+    for(k=0;k<l1;k++){
+      t5=t3;
+      t6=t4;
+      t9=t8;
+      t11=t8;
+      for(i=2;i<ido;i+=2){
+        t5+=2;
+        t6+=2;
+        t9+=2;
+        t11-=2;
+        ch[t5-1]=cc[t9-1]+cc[t11-1];
+        ch[t6-1]=cc[t9-1]-cc[t11-1];
+        ch[t5]=cc[t9]-cc[t11];
+        ch[t6]=cc[t9]+cc[t11];
+      }
+      t3+=ido;
+      t4+=ido;
+      t8+=t10;
+    }
+  }
+  goto L116;
+
+ L112:
+  t1=0;
+  t2=ipp2*t0;
+  t7=0;
+  for(j=1;j<ipph;j++){
+    t1+=t0;
+    t2-=t0;
+    t3=t1;
+    t4=t2;
+    t7+=(ido<<1);
+    t8=t7;
+    t9=t7;
+    for(i=2;i<ido;i+=2){
+      t3+=2;
+      t4+=2;
+      t8+=2;
+      t9-=2;
+      t5=t3;
+      t6=t4;
+      t11=t8;
+      t12=t9;
+      for(k=0;k<l1;k++){
+        ch[t5-1]=cc[t11-1]+cc[t12-1];
+        ch[t6-1]=cc[t11-1]-cc[t12-1];
+        ch[t5]=cc[t11]-cc[t12];
+        ch[t6]=cc[t11]+cc[t12];
+        t5+=ido;
+        t6+=ido;
+        t11+=t10;
+        t12+=t10;
+      }
+    }
+  }
+
+L116:
+  ar1=1.f;
+  ai1=0.f;
+  t1=0;
+  t9=(t2=ipp2*idl1);
+  t3=(ip-1)*idl1;
+  for(l=1;l<ipph;l++){
+    t1+=idl1;
+    t2-=idl1;
+
+    ar1h=dcp*ar1-dsp*ai1;
+    ai1=dcp*ai1+dsp*ar1;
+    ar1=ar1h;
+    t4=t1;
+    t5=t2;
+    t6=0;
+    t7=idl1;
+    t8=t3;
+    for(ik=0;ik<idl1;ik++){
+      c2[t4++]=ch2[t6++]+ar1*ch2[t7++];
+      c2[t5++]=ai1*ch2[t8++];
+    }
+    dc2=ar1;
+    ds2=ai1;
+    ar2=ar1;
+    ai2=ai1;
+
+    t6=idl1;
+    t7=t9-idl1;
+    for(j=2;j<ipph;j++){
+      t6+=idl1;
+      t7-=idl1;
+      ar2h=dc2*ar2-ds2*ai2;
+      ai2=dc2*ai2+ds2*ar2;
+      ar2=ar2h;
+      t4=t1;
+      t5=t2;
+      t11=t6;
+      t12=t7;
+      for(ik=0;ik<idl1;ik++){
+        c2[t4++]+=ar2*ch2[t11++];
+        c2[t5++]+=ai2*ch2[t12++];
+      }
+    }
+  }
+
+  t1=0;
+  for(j=1;j<ipph;j++){
+    t1+=idl1;
+    t2=t1;
+    for(ik=0;ik<idl1;ik++)ch2[ik]+=ch2[t2++];
+  }
+
+  t1=0;
+  t2=ipp2*t0;
+  for(j=1;j<ipph;j++){
+    t1+=t0;
+    t2-=t0;
+    t3=t1;
+    t4=t2;
+    for(k=0;k<l1;k++){
+      ch[t3]=c1[t3]-c1[t4];
+      ch[t4]=c1[t3]+c1[t4];
+      t3+=ido;
+      t4+=ido;
+    }
+  }
+
+  if(ido==1)goto L132;
+  if(nbd<l1)goto L128;
+
+  t1=0;
+  t2=ipp2*t0;
+  for(j=1;j<ipph;j++){
+    t1+=t0;
+    t2-=t0;
+    t3=t1;
+    t4=t2;
+    for(k=0;k<l1;k++){
+      t5=t3;
+      t6=t4;
+      for(i=2;i<ido;i+=2){
+        t5+=2;
+        t6+=2;
+        ch[t5-1]=c1[t5-1]-c1[t6];
+        ch[t6-1]=c1[t5-1]+c1[t6];
+        ch[t5]=c1[t5]+c1[t6-1];
+        ch[t6]=c1[t5]-c1[t6-1];
+      }
+      t3+=ido;
+      t4+=ido;
+    }
+  }
+  goto L132;
+
+ L128:
+  t1=0;
+  t2=ipp2*t0;
+  for(j=1;j<ipph;j++){
+    t1+=t0;
+    t2-=t0;
+    t3=t1;
+    t4=t2;
+    for(i=2;i<ido;i+=2){
+      t3+=2;
+      t4+=2;
+      t5=t3;
+      t6=t4;
+      for(k=0;k<l1;k++){
+        ch[t5-1]=c1[t5-1]-c1[t6];
+        ch[t6-1]=c1[t5-1]+c1[t6];
+        ch[t5]=c1[t5]+c1[t6-1];
+        ch[t6]=c1[t5]-c1[t6-1];
+        t5+=ido;
+        t6+=ido;
+      }
+    }
+  }
+
+L132:
+  if(ido==1)return;
+
+  for(ik=0;ik<idl1;ik++)c2[ik]=ch2[ik];
+
+  t1=0;
+  for(j=1;j<ip;j++){
+    t2=(t1+=t0);
+    for(k=0;k<l1;k++){
+      c1[t2]=ch[t2];
+      t2+=ido;
+    }
+  }
+
+  if(nbd>l1)goto L139;
+
+  is= -ido-1;
+  t1=0;
+  for(j=1;j<ip;j++){
+    is+=ido;
+    t1+=t0;
+    idij=is;
+    t2=t1;
+    for(i=2;i<ido;i+=2){
+      t2+=2;
+      idij+=2;
+      t3=t2;
+      for(k=0;k<l1;k++){
+        c1[t3-1]=wa[idij-1]*ch[t3-1]-wa[idij]*ch[t3];
+        c1[t3]=wa[idij-1]*ch[t3]+wa[idij]*ch[t3-1];
+        t3+=ido;
+      }
+    }
+  }
+  return;
+
+ L139:
+  is= -ido-1;
+  t1=0;
+  for(j=1;j<ip;j++){
+    is+=ido;
+    t1+=t0;
+    t2=t1;
+    for(k=0;k<l1;k++){
+      idij=is;
+      t3=t2;
+      for(i=2;i<ido;i+=2){
+        idij+=2;
+        t3+=2;
+        c1[t3-1]=wa[idij-1]*ch[t3-1]-wa[idij]*ch[t3];
+        c1[t3]=wa[idij-1]*ch[t3]+wa[idij]*ch[t3-1];
+      }
+      t2+=ido;
+    }
+  }
+}
+
+static void drftb1(int n, float *c, float *ch, float *wa, int *ifac){
+  int i,k1,l1,l2;
+  int na;
+  int nf,ip,iw,ix2,ix3,ido,idl1;
+
+  nf=ifac[1];
+  na=0;
+  l1=1;
+  iw=1;
+
+  for(k1=0;k1<nf;k1++){
+    ip=ifac[k1 + 2];
+    l2=ip*l1;
+    ido=n/l2;
+    idl1=ido*l1;
+    if(ip!=4)goto L103;
+    ix2=iw+ido;
+    ix3=ix2+ido;
+
+    if(na!=0)
+      dradb4(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1);
+    else
+      dradb4(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1);
+    na=1-na;
+    goto L115;
+
+  L103:
+    if(ip!=2)goto L106;
+
+    if(na!=0)
+      dradb2(ido,l1,ch,c,wa+iw-1);
+    else
+      dradb2(ido,l1,c,ch,wa+iw-1);
+    na=1-na;
+    goto L115;
+
+  L106:
+    if(ip!=3)goto L109;
+
+    ix2=iw+ido;
+    if(na!=0)
+      dradb3(ido,l1,ch,c,wa+iw-1,wa+ix2-1);
+    else
+      dradb3(ido,l1,c,ch,wa+iw-1,wa+ix2-1);
+    na=1-na;
+    goto L115;
+
+  L109:
+/*    The radix five case can be translated later..... */
+/*    if(ip!=5)goto L112;
+
+    ix2=iw+ido;
+    ix3=ix2+ido;
+    ix4=ix3+ido;
+    if(na!=0)
+      dradb5(ido,l1,ch,c,wa+iw-1,wa+ix2-1,wa+ix3-1,wa+ix4-1);
+    else
+      dradb5(ido,l1,c,ch,wa+iw-1,wa+ix2-1,wa+ix3-1,wa+ix4-1);
+    na=1-na;
+    goto L115;
+
+  L112:*/
+    if(na!=0)
+      dradbg(ido,ip,l1,idl1,ch,ch,ch,c,c,wa+iw-1);
+    else
+      dradbg(ido,ip,l1,idl1,c,c,c,ch,ch,wa+iw-1);
+    if(ido==1)na=1-na;
+
+  L115:
+    l1=l2;
+    iw+=(ip-1)*ido;
+  }
+
+  if(na==0)return;
+
+  for(i=0;i<n;i++)c[i]=ch[i];
+}
+
+void spx_drft_forward(struct drft_lookup *l,float *data){
+  if(l->n==1)return;
+  drftf1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache);
+}
+
+void spx_drft_backward(struct drft_lookup *l,float *data){
+  if (l->n==1)return;
+  drftb1(l->n,data,l->trigcache,l->trigcache+l->n,l->splitcache);
+}
+
+void spx_drft_init(struct drft_lookup *l,int n)
+{
+  l->n=n;
+  l->trigcache=(float*)speex_alloc(3*n*sizeof(*l->trigcache));
+  l->splitcache=(int*)speex_alloc(32*sizeof(*l->splitcache));
+  fdrffti(n, l->trigcache, l->splitcache);
+}
+
+void spx_drft_clear(struct drft_lookup *l)
+{
+  if(l)
+  {
+    if(l->trigcache)
+      speex_free(l->trigcache);
+    if(l->splitcache)
+      speex_free(l->splitcache);
+  }
+}
diff --git a/utils/iaxclient/lib/libspeex/smallft.h b/utils/iaxclient/lib/libspeex/smallft.h
new file mode 100644 (file)
index 0000000..303bc87
--- /dev/null
@@ -0,0 +1,42 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
+ * by the XIPHOPHORUS Company http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+ function: fft transform
+ last mod: $Id: smallft.h 465 2005-05-13 19:19:47Z stevek $
+
+ ********************************************************************/
+
+#ifndef _V_SMFT_H_
+#define _V_SMFT_H_
+
+/*#include "vorbis/codec.h"*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct drft_lookup{
+  int n;
+  float *trigcache;
+  int *splitcache;
+};
+
+extern void spx_drft_forward(struct drft_lookup *l,float *data);
+extern void spx_drft_backward(struct drft_lookup *l,float *data);
+extern void spx_drft_init(struct drft_lookup *l,int n);
+extern void spx_drft_clear(struct drft_lookup *l);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/speex.c b/utils/iaxclient/lib/libspeex/speex.c
new file mode 100644 (file)
index 0000000..94829e6
--- /dev/null
@@ -0,0 +1,268 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: speex.c
+
+   Basic Speex functions
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "modes.h"
+#include <math.h>
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define MAX_IN_SAMPLES 640
+
+
+
+void *speex_encoder_init(const SpeexMode *mode)
+{
+   return mode->enc_init(mode);
+}
+
+void *speex_decoder_init(const SpeexMode *mode)
+{
+   return mode->dec_init(mode);
+}
+
+void speex_encoder_destroy(void *state)
+{
+   (*((SpeexMode**)state))->enc_destroy(state);
+}
+
+void speex_decoder_destroy(void *state)
+{
+   (*((SpeexMode**)state))->dec_destroy(state);
+}
+
+
+
+int speex_encode_native(void *state, spx_word16_t *in, SpeexBits *bits)
+{
+   return (*((SpeexMode**)state))->enc(state, in, bits);
+}
+
+int speex_decode_native(void *state, SpeexBits *bits, spx_word16_t *out)
+{
+   return (*((SpeexMode**)state))->dec(state, bits, out);
+}
+
+
+
+#ifdef FIXED_POINT
+
+int speex_encode(void *state, float *in, SpeexBits *bits)
+{
+   int i;
+   int N;
+   spx_int16_t short_in[MAX_IN_SAMPLES];
+   speex_encoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
+   for (i=0;i<N;i++)
+   {
+      if (in[i]>32767.f)
+         short_in[i] = 32767;
+      else if (in[i]<-32768.f)
+         short_in[i] = -32768;
+      else
+         short_in[i] = (spx_int16_t)floor(.5+in[i]);
+   }
+   return (*((SpeexMode**)state))->enc(state, short_in, bits);
+}
+
+int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits)
+{
+   SpeexMode *mode;
+   mode = *(SpeexMode**)state;
+   return (mode)->enc(state, in, bits);
+}
+
+int speex_decode(void *state, SpeexBits *bits, float *out)
+{
+   int i, ret;
+   int N;
+   spx_int16_t short_out[MAX_IN_SAMPLES];
+   speex_decoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
+   ret = (*((SpeexMode**)state))->dec(state, bits, short_out);
+   for (i=0;i<N;i++)
+      out[i] = short_out[i];
+   return ret;
+}
+
+int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out)
+{
+   SpeexMode *mode = *(SpeexMode**)state;
+   return (mode)->dec(state, bits, out);
+}
+
+#else
+
+int speex_encode(void *state, float *in, SpeexBits *bits)
+{
+   return (*((SpeexMode**)state))->enc(state, in, bits);
+}
+
+int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits)
+{
+   int i;
+   int N;
+   float float_in[MAX_IN_SAMPLES];
+   speex_encoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
+   for (i=0;i<N;i++)
+      float_in[i] = in[i];
+   return (*((SpeexMode**)state))->enc(state, float_in, bits);
+}
+
+int speex_decode(void *state, SpeexBits *bits, float *out)
+{
+   return (*((SpeexMode**)state))->dec(state, bits, out);
+}
+
+int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out)
+{
+   int i;
+   int N;
+   float float_out[MAX_IN_SAMPLES];
+   int ret;
+   speex_decoder_ctl(state, SPEEX_GET_FRAME_SIZE, &N);
+   ret = (*((SpeexMode**)state))->dec(state, bits, float_out);
+   for (i=0;i<N;i++)
+   {
+      if (float_out[i]>32767.f)
+         out[i] = 32767;
+      else if (float_out[i]<-32768.f)
+         out[i] = -32768;
+      else
+         out[i] = (spx_int16_t)floor(.5+float_out[i]);
+   }
+   return ret;
+}
+#endif
+
+
+
+int speex_encoder_ctl(void *state, int request, void *ptr)
+{
+   return (*((SpeexMode**)state))->enc_ctl(state, request, ptr);
+}
+
+int speex_decoder_ctl(void *state, int request, void *ptr)
+{
+   return (*((SpeexMode**)state))->dec_ctl(state, request, ptr);
+}
+
+
+
+int nb_mode_query(const void *mode, int request, void *ptr)
+{
+   const SpeexNBMode *m = (const SpeexNBMode*)mode;
+   
+   switch (request)
+   {
+   case SPEEX_MODE_FRAME_SIZE:
+      *((int*)ptr)=m->frameSize;
+      break;
+   case SPEEX_SUBMODE_BITS_PER_FRAME:
+      if (*((int*)ptr)==0)
+         *((int*)ptr) = NB_SUBMODE_BITS+1;
+      else if (m->submodes[*((int*)ptr)]==NULL)
+         *((int*)ptr) = -1;
+      else
+         *((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame;
+      break;
+   default:
+      speex_warning_int("Unknown nb_mode_query request: ", request);
+      return -1;
+   }
+   return 0;
+}
+
+int wb_mode_query(const void *mode, int request, void *ptr)
+{
+   const SpeexSBMode *m = (const SpeexSBMode*)mode;
+
+   switch (request)
+   {
+   case SPEEX_MODE_FRAME_SIZE:
+      *((int*)ptr)=2*m->frameSize;
+      break;
+   case SPEEX_SUBMODE_BITS_PER_FRAME:
+      if (*((int*)ptr)==0)
+         *((int*)ptr) = SB_SUBMODE_BITS+1;
+      else if (m->submodes[*((int*)ptr)]==NULL)
+         *((int*)ptr) = -1;
+      else
+         *((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame;
+      break;
+   default:
+      speex_warning_int("Unknown wb_mode_query request: ", request);
+      return -1;
+   }
+   return 0;
+}
+
+
+int speex_lib_ctl(int request, void *ptr)
+{
+   switch (request)
+   {
+      case SPEEX_LIB_GET_MAJOR_VERSION:
+         *((int*)ptr) = SPEEX_MAJOR_VERSION;
+         break;
+      case SPEEX_LIB_GET_MINOR_VERSION:
+         *((int*)ptr) = SPEEX_MINOR_VERSION;
+         break;
+      case SPEEX_LIB_GET_MICRO_VERSION:
+         *((int*)ptr) = SPEEX_MICRO_VERSION;
+         break;
+      case SPEEX_LIB_GET_EXTRA_VERSION:
+         *((const char**)ptr) = SPEEX_EXTRA_VERSION;
+         break;
+      case SPEEX_LIB_GET_VERSION_STRING:
+         *((const char**)ptr) = SPEEX_VERSION;
+         break;
+      /*case SPEEX_LIB_SET_ALLOC_FUNC:
+         break;
+      case SPEEX_LIB_GET_ALLOC_FUNC:
+         break;
+      case SPEEX_LIB_SET_FREE_FUNC:
+         break;
+      case SPEEX_LIB_GET_FREE_FUNC:
+         break;*/
+      default:
+         speex_warning_int("Unknown wb_mode_query request: ", request);
+         return -1;
+   }
+   return 0;
+}
diff --git a/utils/iaxclient/lib/libspeex/speex_callbacks.c b/utils/iaxclient/lib/libspeex/speex_callbacks.c
new file mode 100644 (file)
index 0000000..0b99188
--- /dev/null
@@ -0,0 +1,140 @@
+/* Copyright (C) 2002 Jean-Marc Valin
+   File speex_callbacks.c
+   Callback handling and in-band signalling
+
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <speex/speex_callbacks.h>
+#include "misc.h"
+
+int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state)
+{
+   int id;
+   SpeexCallback *callback;
+   /*speex_bits_advance(bits, 5);*/
+   id=speex_bits_unpack_unsigned(bits, 4);
+   callback = callback_list+id;
+
+   if (callback->func)
+   {
+      return callback->func(bits, state, callback->data);
+   } else
+      /*If callback is not registered, skip the right number of bits*/
+   {
+      int adv;
+      if (id<2)
+         adv = 1;
+      else if (id<8)
+         adv = 4;
+      else if (id<10)
+         adv = 8;
+      else if (id<12)
+         adv = 16;
+      else if (id<14)
+         adv = 32;
+      else 
+         adv = 64;
+      speex_bits_advance(bits, adv);
+   }
+   return 0;
+}
+
+int speex_std_mode_request_handler(SpeexBits *bits, void *state, void *data)
+{
+   int m;
+   m = speex_bits_unpack_unsigned(bits, 4);
+   speex_encoder_ctl(data, SPEEX_SET_MODE, &m);
+   return 0;
+}
+
+int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data)
+{
+   int m;
+   m = speex_bits_unpack_unsigned(bits, 4);
+   speex_encoder_ctl(data, SPEEX_SET_LOW_MODE, &m);
+   return 0;
+}
+
+int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data)
+{
+   int m;
+   m = speex_bits_unpack_unsigned(bits, 4);
+   speex_encoder_ctl(data, SPEEX_SET_HIGH_MODE, &m);
+   return 0;
+}
+
+int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data)
+{
+   int vbr;
+   vbr = speex_bits_unpack_unsigned(bits, 1);
+   speex_encoder_ctl(data, SPEEX_SET_VBR, &vbr);
+   return 0;
+}
+
+int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data)
+{
+   int enh;
+   enh = speex_bits_unpack_unsigned(bits, 1);
+   speex_decoder_ctl(data, SPEEX_SET_ENH, &enh);
+   return 0;
+}
+
+int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data)
+{
+   int qual;
+   qual = speex_bits_unpack_unsigned(bits, 4);
+   speex_encoder_ctl(data, SPEEX_SET_VBR_QUALITY, &qual);
+   return 0;
+}
+
+
+int speex_std_char_handler(SpeexBits *bits, void *state, void *data)
+{
+   unsigned char ch;
+   ch = speex_bits_unpack_unsigned(bits, 8);
+   _speex_putc(ch, data);
+   /*printf("speex_std_char_handler ch=%x\n", ch);*/
+   return 0;
+}
+
+
+
+/* Default handler for user callbacks: skip it */
+int speex_default_user_handler(SpeexBits *bits, void *state, void *data)
+{
+   int req_size = speex_bits_unpack_unsigned(bits, 4);
+   speex_bits_advance(bits, 5+8*req_size);
+   return 0;
+}
diff --git a/utils/iaxclient/lib/libspeex/speex_header.c b/utils/iaxclient/lib/libspeex/speex_header.c
new file mode 100644 (file)
index 0000000..93e2423
--- /dev/null
@@ -0,0 +1,166 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: speex_header.c
+   Describes the Speex header
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "misc.h"
+#include <speex/speex_header.h>
+#include <speex/speex.h>
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define ENDIAN_SWITCH(x) {x=le_int(x);}
+
+
+/*
+typedef struct SpeexHeader {
+   char speex_string[8];
+   char speex_version[SPEEX_HEADER_VERSION_LENGTH];
+   int speex_version_id;
+   int header_size;
+   int rate;
+   int mode;
+   int mode_bitstream_version;
+   int nb_channels;
+   int bitrate;
+   int frame_size;
+   int vbr;
+   int frames_per_packet;
+   int extra_headers;
+   int reserved1;
+   int reserved2;
+} SpeexHeader;
+*/
+
+void speex_init_header(SpeexHeader *header, int rate, int nb_channels, const SpeexMode *m)
+{
+   int i;
+   const char *h="Speex   ";
+   /*
+   strncpy(header->speex_string, "Speex   ", 8);
+   strncpy(header->speex_version, SPEEX_VERSION, SPEEX_HEADER_VERSION_LENGTH-1);
+   header->speex_version[SPEEX_HEADER_VERSION_LENGTH-1]=0;
+   */
+   for (i=0;i<8;i++)
+      header->speex_string[i]=h[i];
+   for (i=0;i<SPEEX_HEADER_VERSION_LENGTH-1 && SPEEX_VERSION[i];i++)
+      header->speex_version[i]=SPEEX_VERSION[i];
+   for (;i<SPEEX_HEADER_VERSION_LENGTH;i++)
+      header->speex_version[i]=0;
+   
+   header->speex_version_id = 1;
+   header->header_size = sizeof(SpeexHeader);
+   
+   header->rate = rate;
+   header->mode = m->modeID;
+   header->mode_bitstream_version = m->bitstream_version;
+   if (m->modeID<0)
+      speex_warning("This mode is meant to be used alone");
+   header->nb_channels = nb_channels;
+   header->bitrate = -1;
+   speex_mode_query(m, SPEEX_MODE_FRAME_SIZE, &header->frame_size);
+   header->vbr = 0;
+   
+   header->frames_per_packet = 0;
+   header->extra_headers = 0;
+   header->reserved1 = 0;
+   header->reserved2 = 0;
+}
+
+char *speex_header_to_packet(SpeexHeader *header, int *size)
+{
+   SpeexHeader *le_header;
+   le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader));
+   
+   speex_move(le_header, header, sizeof(SpeexHeader));
+   
+   /*Make sure everything is now little-endian*/
+   ENDIAN_SWITCH(le_header->speex_version_id);
+   ENDIAN_SWITCH(le_header->header_size);
+   ENDIAN_SWITCH(le_header->rate);
+   ENDIAN_SWITCH(le_header->mode);
+   ENDIAN_SWITCH(le_header->mode_bitstream_version);
+   ENDIAN_SWITCH(le_header->nb_channels);
+   ENDIAN_SWITCH(le_header->bitrate);
+   ENDIAN_SWITCH(le_header->frame_size);
+   ENDIAN_SWITCH(le_header->vbr);
+   ENDIAN_SWITCH(le_header->frames_per_packet);
+   ENDIAN_SWITCH(le_header->extra_headers);
+
+   *size = sizeof(SpeexHeader);
+   return (char *)le_header;
+}
+
+SpeexHeader *speex_packet_to_header(char *packet, int size)
+{
+   int i;
+   SpeexHeader *le_header;
+   const char *h = "Speex   ";
+   for (i=0;i<8;i++)
+      if (packet[i]!=h[i])
+      {
+         speex_warning ("This doesn't look like a Speex file");
+         return NULL;
+      }
+   
+   /*FIXME: Do we allow larger headers?*/
+   if (size < sizeof(SpeexHeader))
+   {
+      speex_warning("Speex header too small");
+      return NULL;
+   }
+   
+   le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader));
+   
+   speex_move(le_header, packet, sizeof(SpeexHeader));
+   
+   /*Make sure everything is converted correctly from little-endian*/
+   ENDIAN_SWITCH(le_header->speex_version_id);
+   ENDIAN_SWITCH(le_header->header_size);
+   ENDIAN_SWITCH(le_header->rate);
+   ENDIAN_SWITCH(le_header->mode);
+   ENDIAN_SWITCH(le_header->mode_bitstream_version);
+   ENDIAN_SWITCH(le_header->nb_channels);
+   ENDIAN_SWITCH(le_header->bitrate);
+   ENDIAN_SWITCH(le_header->frame_size);
+   ENDIAN_SWITCH(le_header->vbr);
+   ENDIAN_SWITCH(le_header->frames_per_packet);
+   ENDIAN_SWITCH(le_header->extra_headers);
+
+   return le_header;
+
+}
diff --git a/utils/iaxclient/lib/libspeex/stack_alloc.h b/utils/iaxclient/lib/libspeex/stack_alloc.h
new file mode 100644 (file)
index 0000000..9d18468
--- /dev/null
@@ -0,0 +1,79 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: stack_alloc.h
+   
+   Temporary memory allocation on stack
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifndef STACK_ALLOC_H
+#define STACK_ALLOC_H
+
+#ifdef USE_ALLOCA
+#include <alloca.h>
+#endif
+
+#ifdef ENABLE_VALGRIND
+
+#include <valgrind/memcheck.h>
+/*Aligns the stack to a 'size' boundary */
+#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1))
+
+/* Allocates 'size' elements of type 'type' on the stack */
+#define PUSH(stack, size, type) (VALGRIND_MAKE_NOACCESS(stack, 1000),ALIGN((stack),sizeof(type)),VALGRIND_MAKE_WRITABLE(stack, ((size)*sizeof(type))),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type))))
+
+/* Allocates a struct stack */
+#define PUSHS(stack, type) (VALGRIND_MAKE_NOACCESS(stack, 1000),ALIGN((stack),sizeof(long)),VALGRIND_MAKE_WRITABLE(stack, (sizeof(type))),(stack)+=(sizeof(type)),(type*)((stack)-(sizeof(type))))
+
+#else
+
+
+/*Aligns the stack to a 'size' boundary */
+#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1))
+
+/* Allocates 'size' elements of type 'type' on the stack */
+#define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type))))
+
+/* Allocates a struct stack */
+#define PUSHS(stack, type) (ALIGN((stack),sizeof(long)),(stack)+=(sizeof(type)),(type*)((stack)-(sizeof(type))))
+
+#endif
+
+#if defined(VAR_ARRAYS)
+#define VARDECL(var) 
+#define ALLOC(var, size, type) type var[size]
+#elif defined(USE_ALLOCA)
+#define VARDECL(var) var
+#define ALLOC(var, size, type) var = alloca(sizeof(type)*size)
+#else
+#define VARDECL(var) var
+#define ALLOC(var, size, type) var = PUSH(stack, size, type)
+#endif
+
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/stereo.c b/utils/iaxclient/lib/libspeex/stereo.c
new file mode 100644 (file)
index 0000000..f18387e
--- /dev/null
@@ -0,0 +1,192 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: stereo.c
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <speex/speex_stereo.h>
+#include <speex/speex_callbacks.h>
+#include "vq.h"
+#include <math.h>
+
+/*float e_ratio_quant[4] = {1, 1.26, 1.587, 2};*/
+static const float e_ratio_quant[4] = {.25f, .315f, .397f, .5f};
+
+void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits)
+{
+   int i, tmp;
+   float e_left=0, e_right=0, e_tot=0;
+   float balance, e_ratio;
+   for (i=0;i<frame_size;i++)
+   {
+      e_left  += ((float)data[2*i])*data[2*i];
+      e_right += ((float)data[2*i+1])*data[2*i+1];
+      data[i] =  .5*(((float)data[2*i])+data[2*i+1]);
+      e_tot   += ((float)data[i])*data[i];
+   }
+   balance=(e_left+1)/(e_right+1);
+   e_ratio = e_tot/(1+e_left+e_right);
+
+   /*Quantization*/
+   speex_bits_pack(bits, 14, 5);
+   speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4);
+   
+   balance=4*log(balance);
+
+   /*Pack sign*/
+   if (balance>0)
+      speex_bits_pack(bits, 0, 1);
+   else
+      speex_bits_pack(bits, 1, 1);
+   balance=floor(.5+fabs(balance));
+   if (balance>30)
+      balance=31;
+   
+   speex_bits_pack(bits, (int)balance, 5);
+   
+   /*Quantize energy ratio*/
+   tmp=vq_index(&e_ratio, e_ratio_quant, 1, 4);
+   speex_bits_pack(bits, tmp, 2);
+}
+
+void speex_encode_stereo_int(spx_int16_t *data, int frame_size, SpeexBits *bits)
+{
+   int i, tmp;
+   float e_left=0, e_right=0, e_tot=0;
+   float balance, e_ratio;
+   for (i=0;i<frame_size;i++)
+   {
+      e_left  += ((float)data[2*i])*data[2*i];
+      e_right += ((float)data[2*i+1])*data[2*i+1];
+      data[i] =  .5*(((float)data[2*i])+data[2*i+1]);
+      e_tot   += ((float)data[i])*data[i];
+   }
+   balance=(e_left+1)/(e_right+1);
+   e_ratio = e_tot/(1+e_left+e_right);
+
+   /*Quantization*/
+   speex_bits_pack(bits, 14, 5);
+   speex_bits_pack(bits, SPEEX_INBAND_STEREO, 4);
+   
+   balance=4*log(balance);
+
+   /*Pack sign*/
+   if (balance>0)
+      speex_bits_pack(bits, 0, 1);
+   else
+      speex_bits_pack(bits, 1, 1);
+   balance=floor(.5+fabs(balance));
+   if (balance>30)
+      balance=31;
+   
+   speex_bits_pack(bits, (int)balance, 5);
+   
+   /*Quantize energy ratio*/
+   tmp=vq_index(&e_ratio, e_ratio_quant, 1, 4);
+   speex_bits_pack(bits, tmp, 2);
+}
+
+void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *stereo)
+{
+   float balance, e_ratio;
+   int i;
+   float e_tot=0, e_left, e_right, e_sum;
+
+   balance=stereo->balance;
+   e_ratio=stereo->e_ratio;
+   for (i=frame_size-1;i>=0;i--)
+   {
+      e_tot += ((float)data[i])*data[i];
+   }
+   e_sum=e_tot/e_ratio;
+   e_left  = e_sum*balance / (1+balance);
+   e_right = e_sum-e_left;
+
+   e_left  = sqrt(e_left/(e_tot+.01));
+   e_right = sqrt(e_right/(e_tot+.01));
+
+   for (i=frame_size-1;i>=0;i--)
+   {
+      float ftmp=data[i];
+      stereo->smooth_left  = .98*stereo->smooth_left  + .02*e_left;
+      stereo->smooth_right = .98*stereo->smooth_right + .02*e_right;
+      data[2*i] = stereo->smooth_left*ftmp;
+      data[2*i+1] = stereo->smooth_right*ftmp;
+   }
+}
+
+void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *stereo)
+{
+   float balance, e_ratio;
+   int i;
+   float e_tot=0, e_left, e_right, e_sum;
+
+   balance=stereo->balance;
+   e_ratio=stereo->e_ratio;
+   for (i=frame_size-1;i>=0;i--)
+   {
+      e_tot += ((float)data[i])*data[i];
+   }
+   e_sum=e_tot/e_ratio;
+   e_left  = e_sum*balance / (1+balance);
+   e_right = e_sum-e_left;
+
+   e_left  = sqrt(e_left/(e_tot+.01));
+   e_right = sqrt(e_right/(e_tot+.01));
+
+   for (i=frame_size-1;i>=0;i--)
+   {
+      float ftmp=data[i];
+      stereo->smooth_left  = .98*stereo->smooth_left  + .02*e_left;
+      stereo->smooth_right = .98*stereo->smooth_right + .02*e_right;
+      data[2*i] = stereo->smooth_left*ftmp;
+      data[2*i+1] = stereo->smooth_right*ftmp;
+   }
+}
+
+int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data)
+{
+   SpeexStereoState *stereo;
+   float sign=1;
+   int tmp;
+
+   stereo = (SpeexStereoState*)data;
+   if (speex_bits_unpack_unsigned(bits, 1))
+      sign=-1;
+   tmp = speex_bits_unpack_unsigned(bits, 5);
+   stereo->balance = exp(sign*.25*tmp);
+
+   tmp = speex_bits_unpack_unsigned(bits, 2);
+   stereo->e_ratio = e_ratio_quant[tmp];
+
+   return 0;
+}
diff --git a/utils/iaxclient/lib/libspeex/testdenoise.c b/utils/iaxclient/lib/libspeex/testdenoise.c
new file mode 100644 (file)
index 0000000..177227d
--- /dev/null
@@ -0,0 +1,44 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <speex/speex_preprocess.h>
+#include <stdio.h>
+
+#define NN 160
+
+int main()
+{
+   short in[NN];
+   int i;
+   SpeexPreprocessState *st;
+   int count=0;
+   float f;
+
+   st = speex_preprocess_state_init(NN, 8000);
+   i=1;
+   speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DENOISE, &i);
+   i=0;
+   speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC, &i);
+   f=8000;
+   speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_AGC_LEVEL, &f);
+   i=0;
+   speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB, &i);
+   f=.4;
+   speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f);
+   f=.3;
+   speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f);
+   while (1)
+   {
+      int vad;
+      fread(in, sizeof(short), NN, stdin);
+      if (feof(stdin))
+         break;
+      vad = speex_preprocess(st, in, NULL);
+      /*fprintf (stderr, "%d\n", vad);*/
+      fwrite(in, sizeof(short), NN, stdout);
+      count++;
+   }
+   speex_preprocess_state_destroy(st);
+   return 0;
+}
diff --git a/utils/iaxclient/lib/libspeex/testecho.c b/utils/iaxclient/lib/libspeex/testecho.c
new file mode 100644 (file)
index 0000000..dd2aea8
--- /dev/null
@@ -0,0 +1,45 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "speex/speex_echo.h"
+#include "speex/speex_preprocess.h"
+
+
+#define NN 160
+
+int main()
+{
+   int echo_fd, ref_fd, e_fd;
+   float noise[NN+1];
+   short echo_buf[NN], ref_buf[NN], e_buf[NN];
+   SpeexEchoState *st;
+   SpeexPreprocessState *den;
+
+   echo_fd = open ("play.sw", O_RDONLY);
+   ref_fd  = open ("rec.sw",  O_RDONLY);
+   e_fd    = open ("echo.sw", O_WRONLY | O_CREAT | O_TRUNC, 0644);
+
+   st = speex_echo_state_init(NN, 8*NN);
+   den = speex_preprocess_state_init(NN, 8000);
+
+   while (read(ref_fd, ref_buf, NN*2))
+   {
+      read(echo_fd, echo_buf, NN*2);
+      speex_echo_cancel(st, ref_buf, echo_buf, e_buf, noise);
+      speex_preprocess(den, e_buf, noise);
+      write(e_fd, e_buf, NN*2);
+   }
+   speex_echo_state_destroy(st);
+   speex_preprocess_state_destroy(den);
+   close(e_fd);
+   close(echo_fd);
+   close(ref_fd);
+   return 0;
+}
diff --git a/utils/iaxclient/lib/libspeex/testenc.c b/utils/iaxclient/lib/libspeex/testenc.c
new file mode 100644 (file)
index 0000000..2d8c785
--- /dev/null
@@ -0,0 +1,136 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <speex/speex.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <speex/speex_callbacks.h>
+
+#ifdef FIXED_DEBUG
+extern long long spx_mips;
+#endif
+
+#define FRAME_SIZE 160
+#include <math.h>
+int main(int argc, char **argv)
+{
+   char *inFile, *outFile, *bitsFile;
+   FILE *fin, *fout, *fbits=NULL;
+   short in_short[FRAME_SIZE];
+   short out_short[FRAME_SIZE];
+   float in_float[FRAME_SIZE];
+   float sigpow,errpow,snr, seg_snr=0;
+   int snr_frames = 0;
+   char cbits[200];
+   int nbBits;
+   int i;
+   void *st;
+   void *dec;
+   SpeexBits bits;
+   int tmp;
+   int bitCount=0;
+   int skip_group_delay;
+   SpeexCallback callback;
+
+   sigpow = 0;
+   errpow = 0;
+
+   st = speex_encoder_init(&speex_nb_mode);
+   dec = speex_decoder_init(&speex_nb_mode);
+
+   callback.callback_id = SPEEX_INBAND_CHAR;
+   callback.func = speex_std_char_handler;
+   callback.data = stderr;
+   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);
+
+   callback.callback_id = SPEEX_INBAND_MODE_REQUEST;
+   callback.func = speex_std_mode_request_handler;
+   callback.data = st;
+   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);
+
+   tmp=0;
+   speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp);
+   tmp=0;
+   speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp);
+   tmp=4;
+   speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp);
+   tmp=1;
+   speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp);
+
+   speex_mode_query(&speex_nb_mode, SPEEX_MODE_FRAME_SIZE, &tmp);
+   fprintf (stderr, "frame size: %d\n", tmp);
+   skip_group_delay = tmp / 2;
+
+   if (argc != 4 && argc != 3)
+   {
+      fprintf (stderr, "Usage: encode [in file] [out file] [bits file]\nargc = %d", argc);
+      exit(1);
+   }
+   inFile = argv[1];
+   fin = fopen(inFile, "r");
+   outFile = argv[2];
+   fout = fopen(outFile, "w+");
+   if (argc==4)
+   {
+      bitsFile = argv[3];
+      fbits = fopen(bitsFile, "w");
+   }
+   speex_bits_init(&bits);
+   while (!feof(fin))
+   {
+      fread(in_short, sizeof(short), FRAME_SIZE, fin);
+      if (feof(fin))
+         break;
+      for (i=0;i<FRAME_SIZE;i++)
+         in_float[i]=in_short[i];
+      speex_bits_reset(&bits);
+
+      speex_encode_int(st, in_short, &bits);
+      nbBits = speex_bits_write(&bits, cbits, 200);
+      bitCount+=bits.nbBits;
+
+      if (argc==4)
+         fwrite(cbits, 1, nbBits, fbits);
+      speex_bits_rewind(&bits);
+
+      speex_decode_int(dec, &bits, out_short);
+      speex_bits_reset(&bits);
+
+      fwrite(&out_short[skip_group_delay], sizeof(short), FRAME_SIZE-skip_group_delay, fout);
+      skip_group_delay = 0;
+   }
+   fprintf (stderr, "Total encoded size: %d bits\n", bitCount);
+   speex_encoder_destroy(st);
+   speex_decoder_destroy(dec);
+
+   rewind(fin);
+   rewind(fout);
+
+   while ( FRAME_SIZE == fread(in_short, sizeof(short), FRAME_SIZE, fin) 
+           &&
+           FRAME_SIZE ==  fread(out_short, sizeof(short), FRAME_SIZE,fout) )
+   {
+       float s=0, e=0;
+        for (i=0;i<FRAME_SIZE;++i) {
+            s += (float)in_short[i] * in_short[i];
+            e += ((float)in_short[i]-out_short[i]) * ((float)in_short[i]-out_short[i]);
+        }
+       seg_snr += 10*log10((s+160)/(e+160));
+       sigpow += s;
+       errpow += e;
+       snr_frames++;
+   }
+   fclose(fin);
+   fclose(fout);
+
+   snr = 10 * log10( sigpow / errpow );
+   seg_snr /= snr_frames;
+   fprintf(stderr,"SNR = %f\nsegmental SNR = %f\n",snr, seg_snr);
+
+#ifdef FIXED_DEBUG
+   printf ("Total: %f MIPS\n", (float)(1e-6*50*spx_mips/snr_frames));
+#endif
+   
+   return 1;
+}
diff --git a/utils/iaxclient/lib/libspeex/testenc_uwb.c b/utils/iaxclient/lib/libspeex/testenc_uwb.c
new file mode 100644 (file)
index 0000000..bb2081d
--- /dev/null
@@ -0,0 +1,136 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <speex/speex.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <speex/speex_callbacks.h>
+
+#ifdef FIXED_DEBUG
+extern long long spx_mips;
+#endif
+
+#define FRAME_SIZE 640
+#include <math.h>
+int main(int argc, char **argv)
+{
+   char *inFile, *outFile, *bitsFile;
+   FILE *fin, *fout, *fbits=NULL;
+   short in_short[FRAME_SIZE];
+   short out_short[FRAME_SIZE];
+   float in_float[FRAME_SIZE];
+   float sigpow,errpow,snr, seg_snr=0;
+   int snr_frames = 0;
+   char cbits[200];
+   int nbBits;
+   int i;
+   void *st;
+   void *dec;
+   SpeexBits bits;
+   int tmp;
+   int bitCount=0;
+   int skip_group_delay;
+   SpeexCallback callback;
+
+   sigpow = 0;
+   errpow = 0;
+
+   st = speex_encoder_init(&speex_uwb_mode);
+   dec = speex_decoder_init(&speex_uwb_mode);
+
+   callback.callback_id = SPEEX_INBAND_CHAR;
+   callback.func = speex_std_char_handler;
+   callback.data = stderr;
+   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);
+
+   callback.callback_id = SPEEX_INBAND_MODE_REQUEST;
+   callback.func = speex_std_mode_request_handler;
+   callback.data = st;
+   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);
+
+   tmp=0;
+   speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp);
+   tmp=0;
+   speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp);
+   tmp=7;
+   speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp);
+   tmp=1;
+   speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp);
+
+   speex_mode_query(&speex_nb_mode, SPEEX_MODE_FRAME_SIZE, &tmp);
+   fprintf (stderr, "frame size: %d\n", tmp);
+   skip_group_delay = 509;
+
+   if (argc != 4 && argc != 3)
+   {
+      fprintf (stderr, "Usage: encode [in file] [out file] [bits file]\nargc = %d", argc);
+      exit(1);
+   }
+   inFile = argv[1];
+   fin = fopen(inFile, "r");
+   outFile = argv[2];
+   fout = fopen(outFile, "w+");
+   if (argc==4)
+   {
+      bitsFile = argv[3];
+      fbits = fopen(bitsFile, "w");
+   }
+   speex_bits_init(&bits);
+   while (!feof(fin))
+   {
+      fread(in_short, sizeof(short), FRAME_SIZE, fin);
+      if (feof(fin))
+         break;
+      for (i=0;i<FRAME_SIZE;i++)
+         in_float[i]=in_short[i];
+      speex_bits_reset(&bits);
+
+      speex_encode_int(st, in_short, &bits);
+      nbBits = speex_bits_write(&bits, cbits, 200);
+      bitCount+=bits.nbBits;
+
+      if (argc==4)
+         fwrite(cbits, 1, nbBits, fbits);
+      speex_bits_rewind(&bits);
+
+      speex_decode_int(dec, &bits, out_short);
+      speex_bits_reset(&bits);
+
+      fwrite(&out_short[skip_group_delay], sizeof(short), FRAME_SIZE-skip_group_delay, fout);
+      skip_group_delay = 0;
+   }
+   fprintf (stderr, "Total encoded size: %d bits\n", bitCount);
+   speex_encoder_destroy(st);
+   speex_decoder_destroy(dec);
+
+   rewind(fin);
+   rewind(fout);
+
+   while ( FRAME_SIZE == fread(in_short, sizeof(short), FRAME_SIZE, fin) 
+           &&
+           FRAME_SIZE ==  fread(out_short, sizeof(short), FRAME_SIZE,fout) )
+   {
+       float s=0, e=0;
+        for (i=0;i<FRAME_SIZE;++i) {
+            s += (float)in_short[i] * in_short[i];
+            e += ((float)in_short[i]-out_short[i]) * ((float)in_short[i]-out_short[i]);
+        }
+       seg_snr += 10*log10((s+1)/(e+1));
+       sigpow += s;
+       errpow += e;
+       snr_frames++;
+   }
+   fclose(fin);
+   fclose(fout);
+
+   snr = 10 * log10( sigpow / errpow );
+   seg_snr /= snr_frames;
+   fprintf(stderr,"SNR = %f\nsegmental SNR = %f\n",snr, seg_snr);
+
+#ifdef FIXED_DEBUG
+   printf ("Total: %f MIPS\n", (float)(1e-6*50*spx_mips/snr_frames));
+#endif
+   
+   return 1;
+}
diff --git a/utils/iaxclient/lib/libspeex/testenc_wb.c b/utils/iaxclient/lib/libspeex/testenc_wb.c
new file mode 100644 (file)
index 0000000..74984b4
--- /dev/null
@@ -0,0 +1,141 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <speex/speex.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <speex/speex_callbacks.h>
+
+#ifdef FIXED_DEBUG
+extern long long spx_mips;
+#endif
+
+#define FRAME_SIZE 320
+#include <math.h>
+int main(int argc, char **argv)
+{
+   char *inFile, *outFile, *bitsFile;
+   FILE *fin, *fout, *fbits=NULL;
+   short in_short[FRAME_SIZE];
+   short out_short[FRAME_SIZE];
+   float in_float[FRAME_SIZE];
+   float sigpow,errpow,snr, seg_snr=0;
+   int snr_frames = 0;
+   char cbits[200];
+   int nbBits;
+   int i;
+   void *st;
+   void *dec;
+   SpeexBits bits;
+   int tmp;
+   int bitCount=0;
+   int skip_group_delay;
+   SpeexCallback callback;
+
+   sigpow = 0;
+   errpow = 0;
+
+   st = speex_encoder_init(&speex_wb_mode);
+   dec = speex_decoder_init(&speex_wb_mode);
+
+   callback.callback_id = SPEEX_INBAND_CHAR;
+   callback.func = speex_std_char_handler;
+   callback.data = stderr;
+   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);
+
+   callback.callback_id = SPEEX_INBAND_MODE_REQUEST;
+   callback.func = speex_std_mode_request_handler;
+   callback.data = st;
+   speex_decoder_ctl(dec, SPEEX_SET_HANDLER, &callback);
+
+   tmp=0;
+   speex_decoder_ctl(dec, SPEEX_SET_ENH, &tmp);
+   tmp=0;
+   speex_encoder_ctl(st, SPEEX_SET_VBR, &tmp);
+   tmp=8;
+   speex_encoder_ctl(st, SPEEX_SET_QUALITY, &tmp);
+   tmp=2;
+   speex_encoder_ctl(st, SPEEX_SET_COMPLEXITY, &tmp);
+   tmp=3;
+   speex_encoder_ctl(st, SPEEX_SET_HIGH_MODE, &tmp);
+   tmp=6;
+   speex_encoder_ctl(st, SPEEX_SET_LOW_MODE, &tmp);
+
+
+   speex_mode_query(&speex_wb_mode, SPEEX_MODE_FRAME_SIZE, &tmp);
+   fprintf (stderr, "frame size: %d\n", tmp);
+   skip_group_delay = 223;
+
+   if (argc != 4 && argc != 3)
+   {
+      fprintf (stderr, "Usage: encode [in file] [out file] [bits file]\nargc = %d", argc);
+      exit(1);
+   }
+   inFile = argv[1];
+   fin = fopen(inFile, "r");
+   outFile = argv[2];
+   fout = fopen(outFile, "w+");
+   if (argc==4)
+   {
+      bitsFile = argv[3];
+      fbits = fopen(bitsFile, "w");
+   }
+   speex_bits_init(&bits);
+   while (!feof(fin))
+   {
+      fread(in_short, sizeof(short), FRAME_SIZE, fin);
+      if (feof(fin))
+         break;
+      for (i=0;i<FRAME_SIZE;i++)
+         in_float[i]=in_short[i];
+      speex_bits_reset(&bits);
+
+      speex_encode_int(st, in_short, &bits);
+      nbBits = speex_bits_write(&bits, cbits, 200);
+      bitCount+=bits.nbBits;
+
+      if (argc==4)
+         fwrite(cbits, 1, nbBits, fbits);
+      speex_bits_rewind(&bits);
+
+      speex_decode_int(dec, &bits, out_short);
+      speex_bits_reset(&bits);
+
+      fwrite(&out_short[skip_group_delay], sizeof(short), FRAME_SIZE-skip_group_delay, fout);
+      skip_group_delay = 0;
+   }
+   fprintf (stderr, "Total encoded size: %d bits\n", bitCount);
+   speex_encoder_destroy(st);
+   speex_decoder_destroy(dec);
+
+   rewind(fin);
+   rewind(fout);
+
+   while ( FRAME_SIZE == fread(in_short, sizeof(short), FRAME_SIZE, fin) 
+           &&
+           FRAME_SIZE ==  fread(out_short, sizeof(short), FRAME_SIZE,fout) )
+   {
+       float s=0, e=0;
+        for (i=0;i<FRAME_SIZE;++i) {
+            s += (float)in_short[i] * in_short[i];
+            e += ((float)in_short[i]-out_short[i]) * ((float)in_short[i]-out_short[i]);
+        }
+       seg_snr += 10*log10((s+160)/(e+160));
+       sigpow += s;
+       errpow += e;
+       snr_frames++;
+   }
+   fclose(fin);
+   fclose(fout);
+
+   snr = 10 * log10( sigpow / errpow );
+   seg_snr /= snr_frames;
+   fprintf(stderr,"SNR = %f\nsegmental SNR = %f\n",snr, seg_snr);
+
+#ifdef FIXED_DEBUG
+   printf ("Total: %f MIPS\n", (float)(1e-6*50*spx_mips/snr_frames));
+#endif
+   
+   return 1;
+}
diff --git a/utils/iaxclient/lib/libspeex/vbr.c b/utils/iaxclient/lib/libspeex/vbr.c
new file mode 100644 (file)
index 0000000..819d125
--- /dev/null
@@ -0,0 +1,272 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: vbr.c
+
+   VBR-related routines
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vbr.h"
+#include <math.h>
+
+
+#define sqr(x) ((x)*(x))
+
+#define MIN_ENERGY 6000
+#define NOISE_POW .3
+
+
+const float vbr_nb_thresh[9][11]={
+   {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /*   CNG   */
+   { 3.5,  2.5,  2.0,  1.2,  0.5,  0.0, -0.5, -0.7, -0.8, -0.9, -1.0}, /*  2 kbps */
+   {10.0,  6.5,  5.2,  4.5,  3.9,  3.5,  3.0,  2.5,  2.3,  1.8,  1.0}, /*  6 kbps */
+   {11.0,  8.8,  7.5,  6.5,  5.0,  3.9,  3.9,  3.9,  3.5,  3.0,  1.0}, /*  8 kbps */
+   {11.0, 11.0,  9.9,  9.0,  8.0,  7.0,  6.5,  6.0,  5.0,  4.0,  2.0}, /* 11 kbps */
+   {11.0, 11.0, 11.0, 11.0,  9.5,  9.0,  8.0,  7.0,  6.5,  5.0,  3.0}, /* 15 kbps */
+   {11.0, 11.0, 11.0, 11.0, 11.0, 11.0,  9.5,  8.5,  8.0,  6.5,  4.0}, /* 18 kbps */
+   {11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0,  9.8,  7.5,  5.5}, /* 24 kbps */ 
+   { 8.0,  5.0,  3.7,  3.0,  2.5,  2.0,  1.8,  1.5,  1.0,  0.0,  0.0}  /*  4 kbps */
+};
+
+
+const float vbr_hb_thresh[5][11]={
+   {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* silence */
+   {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /*  2 kbps */
+   {11.0, 11.0,  9.5,  8.5,  7.5,  6.0,  5.0,  3.9,  3.0,  2.0,  1.0}, /*  6 kbps */
+   {11.0, 11.0, 11.0, 11.0, 11.0,  9.5,  8.7,  7.8,  7.0,  6.5,  4.0}, /* 10 kbps */
+   {11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0,  9.8,  7.5,  5.5}  /* 18 kbps */ 
+};
+
+const float vbr_uhb_thresh[2][11]={
+   {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* silence */
+   { 3.9,  2.5,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0,  0.0, -1.0}  /*  2 kbps */
+};
+
+void vbr_init(VBRState *vbr)
+{
+   int i;
+
+   vbr->average_energy=0;
+   vbr->last_energy=1;
+   vbr->accum_sum=0;
+   vbr->energy_alpha=.1;
+   vbr->soft_pitch=0;
+   vbr->last_pitch_coef=0;
+   vbr->last_quality=0;
+
+   vbr->noise_accum = .05*pow(MIN_ENERGY, NOISE_POW);
+   vbr->noise_accum_count=.05;
+   vbr->noise_level=vbr->noise_accum/vbr->noise_accum_count;
+   vbr->consec_noise=0;
+
+
+   for (i=0;i<VBR_MEMORY_SIZE;i++)
+      vbr->last_log_energy[i] = log(MIN_ENERGY);
+}
+
+
+/*
+  This function should analyse the signal and decide how critical the
+  coding error will be perceptually. The following factors should be
+  taken into account:
+
+  -Attacks (positive energy derivative) should be coded with more bits
+
+  -Stationary voiced segments should receive more bits
+
+  -Segments with (very) low absolute energy should receive less bits (maybe
+  only shaped noise?)
+
+  -DTX for near-zero energy?
+
+  -Stationary fricative segments should have less bits
+
+  -Temporal masking: when energy slope is decreasing, decrease the bit-rate
+
+  -Decrease bit-rate for males (low pitch)?
+
+  -(wideband only) less bits in the high-band when signal is very 
+  non-stationary (harder to notice high-frequency noise)???
+
+*/
+
+float vbr_analysis(VBRState *vbr, spx_word16_t *sig, int len, int pitch, float pitch_coef)
+{
+   int i;
+   float ener=0, ener1=0, ener2=0;
+   float qual=7;
+   //int va;
+   float log_energy;
+   float non_st=0;
+   float voicing;
+   float pow_ener;
+
+   for (i=0;i<len>>1;i++)
+      ener1 += ((float)sig[i])*sig[i];
+
+   for (i=len>>1;i<len;i++)
+      ener2 += ((float)sig[i])*sig[i];
+   ener=ener1+ener2;
+
+   log_energy = log(ener+MIN_ENERGY);
+   for (i=0;i<VBR_MEMORY_SIZE;i++)
+      non_st += sqr(log_energy-vbr->last_log_energy[i]);
+   non_st =  non_st/(30*VBR_MEMORY_SIZE);
+   if (non_st>1)
+      non_st=1;
+
+   voicing = 3*(pitch_coef-.4)*fabs(pitch_coef-.4);
+   vbr->average_energy = (1-vbr->energy_alpha)*vbr->average_energy + vbr->energy_alpha*ener;
+   vbr->noise_level=vbr->noise_accum/vbr->noise_accum_count;
+   pow_ener = pow(ener,NOISE_POW);
+   if (vbr->noise_accum_count<.06 && ener>MIN_ENERGY)
+      vbr->noise_accum = .05*pow_ener;
+
+   if ((voicing<.3 && non_st < .2 && pow_ener < 1.2*vbr->noise_level)
+       || (voicing<.3 && non_st < .05 && pow_ener < 1.5*vbr->noise_level)
+       || (voicing<.4 && non_st < .05 && pow_ener < 1.2*vbr->noise_level)
+       || (voicing<0 && non_st < .05))
+   {
+      float tmp;
+      //va = 0;
+      vbr->consec_noise++;
+      if (pow_ener > 3*vbr->noise_level)
+         tmp = 3*vbr->noise_level;
+      else 
+         tmp = pow_ener;
+      if (vbr->consec_noise>=4)
+      {
+         vbr->noise_accum = .95*vbr->noise_accum + .05*tmp;
+         vbr->noise_accum_count = .95*vbr->noise_accum_count + .05;
+      }
+   } else {
+      //va = 1;
+      vbr->consec_noise=0;
+   }
+
+   if (pow_ener < vbr->noise_level && ener>MIN_ENERGY)
+   {
+      vbr->noise_accum = .95*vbr->noise_accum + .05*pow_ener;
+      vbr->noise_accum_count = .95*vbr->noise_accum_count + .05;      
+   }
+
+   /* Checking for very low absolute energy */
+   if (ener < 30000)
+   {
+      qual -= .7;
+      if (ener < 10000)
+         qual-=.7;
+      if (ener < 3000)
+         qual-=.7;
+   } else {
+      float short_diff, long_diff;
+      short_diff = log((ener+1)/(1+vbr->last_energy));
+      long_diff = log((ener+1)/(1+vbr->average_energy));
+      /*fprintf (stderr, "%f %f\n", short_diff, long_diff);*/
+
+      if (long_diff<-5)
+         long_diff=-5;
+      if (long_diff>2)
+         long_diff=2;
+
+      if (long_diff>0)
+         qual += .6*long_diff;
+      if (long_diff<0)
+         qual += .5*long_diff;
+      if (short_diff>0)
+      {
+         if (short_diff>5)
+            short_diff=5;
+         qual += .5*short_diff;
+      }
+      /* Checking for energy increases */
+      if (ener2 > 1.6*ener1)
+         qual += .5;
+   }
+   vbr->last_energy = ener;
+   vbr->soft_pitch = .6*vbr->soft_pitch + .4*pitch_coef;
+   qual += 2.2*((pitch_coef-.4) + (vbr->soft_pitch-.4));
+
+   if (qual < vbr->last_quality)
+      qual = .5*qual + .5*vbr->last_quality;
+   if (qual<4)
+      qual=4;
+   if (qual>10)
+      qual=10;
+   
+   /*
+   if (vbr->consec_noise>=2)
+      qual-=1.3;
+   if (vbr->consec_noise>=5)
+      qual-=1.3;
+   if (vbr->consec_noise>=12)
+      qual-=1.3;
+   */
+   if (vbr->consec_noise>=3)
+      qual=4;
+
+   if (vbr->consec_noise)
+      qual -= 1.0 * (log(3.0 + vbr->consec_noise)-log(3));
+   if (qual<0)
+      qual=0;
+   
+   if (ener<60000)
+   {
+      if (vbr->consec_noise>2)
+         qual-=0.5*(log(3.0 + vbr->consec_noise)-log(3));
+      if (ener<10000&&vbr->consec_noise>2)
+         qual-=0.5*(log(3.0 + vbr->consec_noise)-log(3));
+      if (qual<0)
+         qual=0;
+      qual += .3*log(ener/60000.0);
+   }
+   if (qual<-1)
+      qual=-1;
+
+   /*printf ("%f %f %f %f %d\n", qual, voicing, non_st, pow_ener/(.01+vbr->noise_level), va);*/
+
+   vbr->last_pitch_coef = pitch_coef;
+   vbr->last_quality = qual;
+
+   for (i=VBR_MEMORY_SIZE-1;i>0;i--)
+      vbr->last_log_energy[i] = vbr->last_log_energy[i-1];
+   vbr->last_log_energy[0] = log_energy;
+
+   /*printf ("VBR: %f %f %f %d %f\n", (float)(log_energy-log(vbr->average_energy+MIN_ENERGY)), non_st, voicing, va, vbr->noise_level);*/
+
+   return qual;
+}
+
+void vbr_destroy(VBRState *vbr)
+{
+}
diff --git a/utils/iaxclient/lib/libspeex/vbr.h b/utils/iaxclient/lib/libspeex/vbr.h
new file mode 100644 (file)
index 0000000..7a6abef
--- /dev/null
@@ -0,0 +1,68 @@
+/* Copyright (C) 2002 Jean-Marc Valin 
+   File: vbr.h
+
+   VBR-related routines
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+
+*/
+
+
+#ifndef VBR_H
+#define VBR_H
+
+#include "misc.h"
+
+#define VBR_MEMORY_SIZE 5
+
+extern const float vbr_nb_thresh[9][11];
+extern const float vbr_hb_thresh[5][11];
+extern const float vbr_uhb_thresh[2][11];
+
+typedef struct VBRState {
+   float energy_alpha;
+   float average_energy;
+   float last_energy;
+   float last_log_energy[VBR_MEMORY_SIZE];
+   float accum_sum;
+   float last_pitch_coef;
+   float soft_pitch;
+   float last_quality;
+   float noise_level;
+   float noise_accum;
+   float noise_accum_count;
+   int   consec_noise;
+} VBRState;
+
+void vbr_init(VBRState *vbr);
+
+float vbr_analysis(VBRState *vbr, spx_word16_t *sig, int len, int pitch, float pitch_coef);
+
+void vbr_destroy(VBRState *vbr);
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/vq.c b/utils/iaxclient/lib/libspeex/vq.c
new file mode 100644 (file)
index 0000000..c89c741
--- /dev/null
@@ -0,0 +1,253 @@
+/* Copyright (C) 2002 Jean-Marc Valin
+   File: vq.c
+   Vector quantization
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "vq.h"
+#include "stack_alloc.h"
+
+int scal_quant(spx_word16_t in, const spx_word16_t *boundary, int entries)
+{
+   int i=0;
+   while (i<entries-1 && in>boundary[0])
+   {
+      boundary++;
+      i++;
+   }
+   return i;
+}
+
+int scal_quant32(spx_word32_t in, const spx_word32_t *boundary, int entries)
+{
+   int i=0;
+   while (i<entries-1 && in>boundary[0])
+   {
+      boundary++;
+      i++;
+   }
+   return i;
+}
+
+/*Finds the index of the entry in a codebook that best matches the input*/
+int vq_index(float *in, const float *codebook, int len, int entries)
+{
+   int i,j;
+   float min_dist=0;
+   int best_index=0;
+   for (i=0;i<entries;i++)
+   {
+      float dist=0;
+      for (j=0;j<len;j++)
+      {
+         float tmp = in[j]-*codebook++;
+         dist += tmp*tmp;
+      }
+      if (i==0 || dist<min_dist)
+      {
+         min_dist=dist;
+         best_index=i;
+      }
+   }
+   return best_index;
+}
+
+#ifdef _USE_SSE
+#include <xmmintrin.h>
+#include "misc.h"
+void vq_nbest(spx_word16_t *_in, const __m128 *codebook, int len, int entries, __m128 *E, int N, int *nbest, spx_word32_t *best_dist, char *stack)
+{
+   int i,j,k,used;
+   VARDECL(float *dist);
+   VARDECL(__m128 *in);
+   __m128 half;
+   used = 0;
+   ALLOC(dist, entries, float);
+   half = _mm_set_ps1(.5f);
+   ALLOC(in, len, __m128);
+   for (i=0;i<len;i++)
+      in[i] = _mm_set_ps1(_in[i]);
+   for (i=0;i<entries>>2;i++)
+   {
+      __m128 d = _mm_mul_ps(E[i], half);
+      for (j=0;j<len;j++)
+         d = _mm_sub_ps(d, _mm_mul_ps(in[j], *codebook++));
+      _mm_storeu_ps(dist+4*i, d);
+   }
+   for (i=0;i<entries;i++)
+   {
+      if (i<N || dist[i]<best_dist[N-1])
+      {
+         for (k=N-1; (k >= 1) && (k > used || dist[i] < best_dist[k-1]); k--)
+         {
+            best_dist[k]=best_dist[k-1];
+            nbest[k] = nbest[k-1];
+         }
+         best_dist[k]=dist[i];
+         nbest[k]=i;
+         used++;
+      }
+   }
+}
+
+
+#else
+
+#if defined(SHORTCUTS) && (defined(ARM4_ASM) || defined(ARM5E_ASM))
+#include "vq_arm4.h"
+#else
+
+/*Finds the indices of the n-best entries in a codebook*/
+void vq_nbest(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack)
+{
+   int i,j,k,used;
+   used = 0;
+   for (i=0;i<entries;i++)
+   {
+      spx_word32_t dist=0;
+      for (j=0;j<len;j++)
+         dist = MAC16_16(dist,in[j],*codebook++);
+#ifdef FIXED_POINT
+      dist=SUB32(SHR32(E[i],1),dist);
+#else
+      dist=.5f*E[i]-dist;
+#endif
+      if (i<N || dist<best_dist[N-1])
+      {
+         for (k=N-1; (k >= 1) && (k > used || dist < best_dist[k-1]); k--)
+         {
+            best_dist[k]=best_dist[k-1];
+            nbest[k] = nbest[k-1];
+         }
+         best_dist[k]=dist;
+         nbest[k]=i;
+         used++;
+      }
+   }
+}
+#endif
+
+#endif
+
+
+
+#ifdef _USE_SSE
+
+void vq_nbest_sign(spx_word16_t *_in, const __m128 *codebook, int len, int entries, __m128 *E, int N, int *nbest, spx_word32_t *best_dist, char *stack)
+{
+   int i,j,k,used;
+   VARDECL(float *dist);
+   VARDECL(__m128 *in);
+   __m128 half;
+   used = 0;
+   ALLOC(dist, entries, float);
+   half = _mm_set_ps1(.5f);
+   ALLOC(in, len, __m128);
+   for (i=0;i<len;i++)
+      in[i] = _mm_set_ps1(_in[i]);
+   for (i=0;i<entries>>2;i++)
+   {
+      __m128 d = _mm_setzero_ps();
+      for (j=0;j<len;j++)
+         d = _mm_add_ps(d, _mm_mul_ps(in[j], *codebook++));
+      _mm_storeu_ps(dist+4*i, d);
+   }
+   for (i=0;i<entries;i++)
+   {
+      int sign;
+      if (dist[i]>0)
+      {
+         sign=0;
+         dist[i]=-dist[i];
+      } else
+      {
+         sign=1;
+      }
+      dist[i] += .5f*((float*)E)[i];
+      if (i<N || dist[i]<best_dist[N-1])
+      {
+         for (k=N-1; (k >= 1) && (k > used || dist[i] < best_dist[k-1]); k--)
+         {
+            best_dist[k]=best_dist[k-1];
+            nbest[k] = nbest[k-1];
+         }
+         best_dist[k]=dist[i];
+         nbest[k]=i;
+         used++;
+         if (sign)
+            nbest[k]+=entries;
+      }
+   }
+}
+
+#else
+
+/*Finds the indices of the n-best entries in a codebook with sign*/
+void vq_nbest_sign(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack)
+{
+   int i,j,k, sign, used;
+   used=0;
+   for (i=0;i<entries;i++)
+   {
+      spx_word32_t dist=0;
+      for (j=0;j<len;j++)
+         dist = MAC16_16(dist,in[j],*codebook++);
+      if (dist>0)
+      {
+         sign=0;
+         dist=-dist;
+      } else
+      {
+         sign=1;
+      }
+#ifdef FIXED_POINT
+      dist = ADD32(dist,SHR32(E[i],1));
+#else
+      dist = ADD32(dist,.5f*E[i]);
+#endif
+      if (i<N || dist<best_dist[N-1])
+      {
+         for (k=N-1; (k >= 1) && (k > used || dist < best_dist[k-1]); k--)
+         {
+            best_dist[k]=best_dist[k-1];
+            nbest[k] = nbest[k-1];
+         }
+         best_dist[k]=dist;
+         nbest[k]=i;
+         used++;
+         if (sign)
+            nbest[k]+=entries;
+      }
+   }
+}
+#endif
diff --git a/utils/iaxclient/lib/libspeex/vq.h b/utils/iaxclient/lib/libspeex/vq.h
new file mode 100644 (file)
index 0000000..79bd9e9
--- /dev/null
@@ -0,0 +1,53 @@
+/* Copyright (C) 2002 Jean-Marc Valin
+   File: vq.h
+   Vector quantization
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+#ifndef VQ_H
+#define VQ_H
+
+#include "misc.h"
+
+int scal_quant(spx_word16_t in, const spx_word16_t *boundary, int entries);
+int scal_quant32(spx_word32_t in, const spx_word32_t *boundary, int entries);
+
+int vq_index(float *in, const float *codebook, int len, int entries);
+#ifdef _USE_SSE
+#include <xmmintrin.h>
+void vq_nbest(spx_word16_t *in, const __m128 *codebook, int len, int entries, __m128 *E, int N, int *nbest, spx_word32_t *best_dist, char *stack);
+
+void vq_nbest_sign(spx_word16_t *in, const __m128 *codebook, int len, int entries, __m128 *E, int N, int *nbest, spx_word32_t *best_dist, char *stack);
+#else
+void vq_nbest(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack);
+
+void vq_nbest_sign(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack);
+#endif
+
+#endif
diff --git a/utils/iaxclient/lib/libspeex/vq_arm4.h b/utils/iaxclient/lib/libspeex/vq_arm4.h
new file mode 100644 (file)
index 0000000..cae3d06
--- /dev/null
@@ -0,0 +1,112 @@
+/* Copyright (C) 2004 Jean-Marc Valin 
+   File: vq_arm4.h
+   ARM4-optimized vq routine
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+   
+   - Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+   
+   - Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+   
+   - Neither the name of the Xiph.org Foundation nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+   
+   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION 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.
+*/
+
+void vq_nbest(spx_word16_t *in, const spx_word16_t *codebook, int len, int entries, spx_word32_t *E, int N, int *nbest, spx_word32_t *best_dist, char *stack)
+{
+   int i,j;
+   for (i=0;i<entries;i+=4)
+   {
+#if 1
+      spx_word32_t dist1, dist2, dist3, dist4;
+      int dead1, dead2, dead3, dead4, dead5, dead6, dead7, dead8;
+      __asm__ __volatile__ (
+            "mov %0, #0 \n\t"
+            "mov %1, #0 \n\t"
+            "mov %2, #0 \n\t"
+            "mov %3, #0 \n\t"
+            "mov %10, %4 \n\t"
+            "add %4, %4, %4\n\t"
+            ".vqloop%=:\n\t"
+            "ldrsh %7, [%5], #2 \n\t"
+            "ldrsh %8, [%6] \n\t"
+            "mov %9, %6 \n\t"
+            "mla %0, %7, %8, %0 \n\t"
+            "ldrsh %8, [%9, %4]! \n\t"
+            "mla %1, %7, %8, %1 \n\t"
+            "ldrsh %8, [%9, %4]!\n\t"
+            "mla %2, %7, %8, %2 \n\t"
+            "ldrsh %8, [%9, %4]! \n\t"
+            "mla %3, %7, %8, %3 \n\t"
+            "subs %10, %10, #1 \n\t"
+            "add %6, %6, #2 \n\t"
+            "bne .vqloop%="
+         : "=r" (dist1), "=r" (dist2), "=r" (dist3), "=r" (dist4),
+      "=r" (dead1), "=r" (dead2), "=r" (codebook), "=r" (dead4),
+      "=r" (dead5), "=r" (dead6), "=r" (dead7)
+         : "4" (len), "5" (in), "6" (codebook)
+         : "cc");
+#else
+dist1=dist2=dist3=dist4=0;
+   /*   spx_word32_t dist1=0;
+      spx_word32_t dist2=0;
+      spx_word32_t dist3=0;
+      spx_word32_t dist4=0;*/
+      for (j=0;j<2;j++)
+      {
+         const spx_word16_t *code = codebook;
+         dist1 = MAC16_16(dist1,in[j],*code);
+         code += len;
+         dist2 = MAC16_16(dist2,in[j],*code);
+         code += len;
+         dist3 = MAC16_16(dist3,in[j],*code);
+         code += len;
+         dist4 = MAC16_16(dist4,in[j],*code);
+         codebook++;
+      }
+#endif
+      dist1=SUB32(SHR(*E++,1),dist1);
+      if (dist1<*best_dist || i==0)
+      {
+         *best_dist=dist1;
+         *nbest=i;
+      }
+      dist2=SUB32(SHR(*E++,1),dist2);
+      if (dist2<*best_dist)
+      {
+         *best_dist=dist2;
+         *nbest=i+1;
+      }
+      dist3=SUB32(SHR(*E++,1),dist3);
+      if (dist3<*best_dist)
+      {
+         *best_dist=dist3;
+         *nbest=i+2;
+      }
+      dist4=SUB32(SHR(*E++,1),dist4);
+      if (dist4<*best_dist)
+      {
+         *best_dist=dist4;
+         *nbest=i+3;
+      }
+      codebook += 3*len;
+   }
+}
\ No newline at end of file
diff --git a/utils/iaxclient/lib/macosx/Prefixes.h b/utils/iaxclient/lib/macosx/Prefixes.h
new file mode 100644 (file)
index 0000000..88eec72
--- /dev/null
@@ -0,0 +1,48 @@
+
+#define MACOSX 
+#define LIBIAX 
+//#define IAXC_VIDEO
+
+
+//#define CODEC_ILBC 0
+#define SPEEX_PREPROCESS 1
+//#define SPAN_EC 0
+#define SPEEX_EC 1
+//#define MEC2_EC 0
+#define USE_NEWJB 1
+//#define USE_VIDEO 0
+
+
+
+// ***************************************************************************
+//             BEGIN CONFIGURABLE VARIABLES SECTION
+// ***************************************************************************
+
+// Choose wheter to compile iaxclient with ffmpeg library support or not
+#define USE_FFMPEG 0
+// Please fill in the path to ffmpeg's libavcodec source dir
+//FFMPEG_SRCDIR=
+
+// Warning: The use of AMR codec can change iaxclient library licensing 
+//
+// Please fill in the path to 3GPP TS26.104 source code ONLY IF you 
+// don't wants to use ffmpeg library. If you wants to use AMR narrow
+// band and wide band please instal it under the same subdirectory
+//AMR_CODEC_SRCDIR=
+#define USE_AMR 0
+#define USE_AMR_WB 0
+
+// Warning: The use of AMR codec included in ffmpeg library can change ffmpeg 
+// library licensing and iaxclient library licensing. Use only if you know 
+// what are you doing
+//
+// Use this only if you have installed 3GPP TS26.104 source codes following
+// ffmpeg inscrutions
+#define USE_FF_AMR 0
+#define USE_FF_AMR_WB 0
+
+
+// Mats hack for MacOSX 10.2.8; see jitterbuf.c
+#define HAVE_NOT_VA_ARGS
+#define HAVE_NOT_RESTRICT_KEYWORD
+
diff --git a/utils/iaxclient/lib/macosx/README b/utils/iaxclient/lib/macosx/README
new file mode 100644 (file)
index 0000000..af402ca
--- /dev/null
@@ -0,0 +1,2 @@
+ProjectBuilder project by 
+       Mats Bengtsson - https://sourceforge.net/users/matben/
diff --git a/utils/iaxclient/lib/macosx/iaxclientlib.pbproj/project.pbxproj b/utils/iaxclient/lib/macosx/iaxclientlib.pbproj/project.pbxproj
new file mode 100644 (file)
index 0000000..84b9345
--- /dev/null
@@ -0,0 +1,2924 @@
+// !$*UTF8*$!
+{
+       archiveVersion = 1;
+       classes = {
+       };
+       objectVersion = 38;
+       objects = {
+               9A0E1C200951AA7600D94F7B = {
+                       isa = PBXFrameworkReference;
+                       name = CoreAudio.framework;
+                       path = /System/Library/Frameworks/CoreAudio.framework;
+                       refType = 0;
+               };
+               9A0E1C210951AA7600D94F7B = {
+                       fileRef = 9A0E1C200951AA7600D94F7B;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A0E1C280951AAFE00D94F7B = {
+                       isa = PBXFrameworkReference;
+                       name = AudioToolbox.framework;
+                       path = /System/Library/Frameworks/AudioToolbox.framework;
+                       refType = 0;
+               };
+               9A0E1C290951AAFE00D94F7B = {
+                       fileRef = 9A0E1C280951AAFE00D94F7B;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A5373BC0955727B00A80065 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = "iax-client.h";
+                       path = "../libiax2/src/iax-client.h";
+                       refType = 2;
+               };
+               9A5373BD0955727B00A80065 = {
+                       fileRef = 9A5373BC0955727B00A80065;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A5373BE0955727B00A80065 = {
+                       fileRef = 9A5373BC0955727B00A80065;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A7D78530953FDFD002BD72F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = gsm_option.c;
+                       path = ../gsm/src/gsm_option.c;
+                       refType = 2;
+               };
+               9A7D78540953FDFD002BD72F = {
+                       fileRef = 9A7D78530953FDFD002BD72F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A7D78550953FDFD002BD72F = {
+                       fileRef = 9A7D78530953FDFD002BD72F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A7D78560953FEBE002BD72F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = config.h;
+                       path = ../gsm/inc/config.h;
+                       refType = 2;
+               };
+               9A7D78570953FEBE002BD72F = {
+                       fileRef = 9A7D78560953FEBE002BD72F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A7D78580953FEBE002BD72F = {
+                       fileRef = 9A7D78560953FEBE002BD72F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A31109499BB400B1561F = {
+                       children = (
+                               9AD8E43A0949CC2F0044FD2F,
+                               9A83A32809499C9600B1561F,
+                               9A0E1C200951AA7600D94F7B,
+                               9A0E1C280951AAFE00D94F7B,
+                       );
+                       isa = PBXGroup;
+                       refType = 4;
+               };
+               9A83A31309499BB400B1561F = {
+                       buildRules = (
+                       );
+                       buildSettings = {
+                               COPY_PHASE_STRIP = NO;
+                       };
+                       isa = PBXBuildStyle;
+                       name = Development;
+               };
+               9A83A31409499BB400B1561F = {
+                       buildRules = (
+                       );
+                       buildSettings = {
+                               COPY_PHASE_STRIP = YES;
+                       };
+                       isa = PBXBuildStyle;
+                       name = Deployment;
+               };
+               9A83A31509499BB400B1561F = {
+                       buildStyles = (
+                               9A83A31309499BB400B1561F,
+                               9A83A31409499BB400B1561F,
+                       );
+                       hasScannedForEncodings = 1;
+                       isa = PBXProject;
+                       mainGroup = 9A83A31109499BB400B1561F;
+                       productRefGroup = 9A83A32809499C9600B1561F;
+                       projectDirPath = "";
+                       targets = (
+                               9A83A32609499C9600B1561F,
+                               9AA950FA0951BDDB00895947,
+                       );
+               };
+               9A83A31609499BE300B1561F = {
+                       children = (
+                               9A83A31809499C6B00B1561F,
+                               9A83A31909499C6B00B1561F,
+                               9A83A31A09499C6B00B1561F,
+                               9A83A31B09499C6B00B1561F,
+                               9A83A31C09499C6B00B1561F,
+                               9A83A31D09499C6B00B1561F,
+                               9A83A31E09499C6B00B1561F,
+                               9A83A31F09499C6B00B1561F,
+                               9A83A32009499C6B00B1561F,
+                               9A83A32109499C6B00B1561F,
+                               9A7D78530953FDFD002BD72F,
+                               9A83A33309499CD200B1561F,
+                               9A83A33509499D0800B1561F,
+                               9A83A33609499D0800B1561F,
+                               9A83A33709499D0800B1561F,
+                               9A83A33809499D0800B1561F,
+                               9A83A33909499D0800B1561F,
+                               9A83A33A09499D0800B1561F,
+                               9A7D78560953FEBE002BD72F,
+                               9AD8E4F40949D5600044FD2F,
+                               9AD8E4F50949D5600044FD2F,
+                               9AD8E4F60949D5600044FD2F,
+                               9AD8E4F70949D5600044FD2F,
+                       );
+                       isa = PBXGroup;
+                       name = gsm;
+                       path = "";
+                       refType = 4;
+               };
+               9A83A31809499C6B00B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = add.c;
+                       path = ../gsm/src/add.c;
+                       refType = 2;
+               };
+               9A83A31909499C6B00B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = code.c;
+                       path = ../gsm/src/code.c;
+                       refType = 2;
+               };
+               9A83A31A09499C6B00B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = debug.c;
+                       path = ../gsm/src/debug.c;
+                       refType = 2;
+               };
+               9A83A31B09499C6B00B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = decode.c;
+                       path = ../gsm/src/decode.c;
+                       refType = 2;
+               };
+               9A83A31C09499C6B00B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = gsm_create.c;
+                       path = ../gsm/src/gsm_create.c;
+                       refType = 2;
+               };
+               9A83A31D09499C6B00B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = gsm_decode.c;
+                       path = ../gsm/src/gsm_decode.c;
+                       refType = 2;
+               };
+               9A83A31E09499C6B00B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = gsm_destroy.c;
+                       path = ../gsm/src/gsm_destroy.c;
+                       refType = 2;
+               };
+               9A83A31F09499C6B00B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = gsm_encode.c;
+                       path = ../gsm/src/gsm_encode.c;
+                       refType = 2;
+               };
+               9A83A32009499C6B00B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = gsm_explode.c;
+                       path = ../gsm/src/gsm_explode.c;
+                       refType = 2;
+               };
+               9A83A32109499C6B00B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = gsm_implode.c;
+                       path = ../gsm/src/gsm_implode.c;
+                       refType = 2;
+               };
+               9A83A32209499C9600B1561F = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               9A83A34B09499D9200B1561F,
+                               9A83A34D09499D9200B1561F,
+                               9A83A34F09499D9200B1561F,
+                               9A83A35109499D9200B1561F,
+                               9A83A35B09499E1800B1561F,
+                               9A83A35C09499E1800B1561F,
+                               9A83A35E09499E1800B1561F,
+                               9AD8E4380949CBBA0044FD2F,
+                               9AD8E4430949CD690044FD2F,
+                               9AD8E4450949CD690044FD2F,
+                               9AD8E4670949CED00044FD2F,
+                               9AD8E4680949CED00044FD2F,
+                               9AD8E46A0949CED00044FD2F,
+                               9AD8E46B0949CED00044FD2F,
+                               9AD8E46D0949CED00044FD2F,
+                               9AD8E4710949CED00044FD2F,
+                               9AD8E4740949CED00044FD2F,
+                               9AD8E4750949CED00044FD2F,
+                               9AD8E4760949CED00044FD2F,
+                               9AD8E4780949CED00044FD2F,
+                               9AD8E47A0949CED00044FD2F,
+                               9AD8E47C0949CED00044FD2F,
+                               9AD8E47E0949CED00044FD2F,
+                               9AD8E4800949CED00044FD2F,
+                               9AD8E4820949CED00044FD2F,
+                               9AD8E4840949CED00044FD2F,
+                               9AD8E4A70949CF6C0044FD2F,
+                               9AD8E4AA0949CF6C0044FD2F,
+                               9AD8E4AD0949CF6C0044FD2F,
+                               9AD8E4B20949CF6C0044FD2F,
+                               9AD8E4BC0949D0FC0044FD2F,
+                               9AD8E4D90949D1350044FD2F,
+                               9AD8E4DB0949D1350044FD2F,
+                               9AD8E4DD0949D1350044FD2F,
+                               9AD8E4E10949D1E40044FD2F,
+                               9AD8E4F10949D4B10044FD2F,
+                               9AD8E4F20949D4B10044FD2F,
+                               9AD8E4F90949D5600044FD2F,
+                               9AD8E4FA0949D5600044FD2F,
+                               9AD8E4FB0949D5600044FD2F,
+                               9AD8E4FC0949D5600044FD2F,
+                               9AA950E20951BA3000895947,
+                               9A7D78570953FEBE002BD72F,
+                               9A5373BD0955727B00A80065,
+                       );
+                       isa = PBXHeadersBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               9A83A32309499C9600B1561F = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               9A83A32909499CA000B1561F,
+                               9A83A32A09499CA100B1561F,
+                               9A83A32B09499CA300B1561F,
+                               9A83A32C09499CA400B1561F,
+                               9A83A32D09499CA400B1561F,
+                               9A83A32E09499CA500B1561F,
+                               9A83A32F09499CA600B1561F,
+                               9A83A33009499CA700B1561F,
+                               9A83A33109499CA800B1561F,
+                               9A83A33209499CA900B1561F,
+                               9A83A33409499CD200B1561F,
+                               9A83A33B09499D0800B1561F,
+                               9A83A33C09499D0800B1561F,
+                               9A83A33D09499D0800B1561F,
+                               9A83A33E09499D0800B1561F,
+                               9A83A33F09499D0800B1561F,
+                               9A83A34009499D0800B1561F,
+                               9A83A34A09499D9200B1561F,
+                               9A83A34C09499D9200B1561F,
+                               9A83A34E09499D9200B1561F,
+                               9A83A35009499D9200B1561F,
+                               9A83A35909499E1800B1561F,
+                               9A83A35A09499E1800B1561F,
+                               9A83A35D09499E1800B1561F,
+                               9AD8E4330949CB9A0044FD2F,
+                               9AD8E4370949CBBA0044FD2F,
+                               9AD8E4390949CBBA0044FD2F,
+                               9AD8E43D0949CD3B0044FD2F,
+                               9AD8E4420949CD690044FD2F,
+                               9AD8E4440949CD690044FD2F,
+                               9AD8E4660949CED00044FD2F,
+                               9AD8E4690949CED00044FD2F,
+                               9AD8E46C0949CED00044FD2F,
+                               9AD8E46E0949CED00044FD2F,
+                               9AD8E46F0949CED00044FD2F,
+                               9AD8E4700949CED00044FD2F,
+                               9AD8E4720949CED00044FD2F,
+                               9AD8E4730949CED00044FD2F,
+                               9AD8E4770949CED00044FD2F,
+                               9AD8E4790949CED00044FD2F,
+                               9AD8E47B0949CED00044FD2F,
+                               9AD8E47D0949CED00044FD2F,
+                               9AD8E47F0949CED00044FD2F,
+                               9AD8E4810949CED00044FD2F,
+                               9AD8E4830949CED00044FD2F,
+                               9AD8E49C0949CF6C0044FD2F,
+                               9AD8E49D0949CF6C0044FD2F,
+                               9AD8E49E0949CF6C0044FD2F,
+                               9AD8E49F0949CF6C0044FD2F,
+                               9AD8E4A00949CF6C0044FD2F,
+                               9AD8E4A10949CF6C0044FD2F,
+                               9AD8E4A20949CF6C0044FD2F,
+                               9AD8E4A30949CF6C0044FD2F,
+                               9AD8E4A40949CF6C0044FD2F,
+                               9AD8E4A50949CF6C0044FD2F,
+                               9AD8E4A60949CF6C0044FD2F,
+                               9AD8E4A80949CF6C0044FD2F,
+                               9AD8E4A90949CF6C0044FD2F,
+                               9AD8E4AB0949CF6C0044FD2F,
+                               9AD8E4AC0949CF6C0044FD2F,
+                               9AD8E4AE0949CF6C0044FD2F,
+                               9AD8E4AF0949CF6C0044FD2F,
+                               9AD8E4B00949CF6C0044FD2F,
+                               9AD8E4B10949CF6C0044FD2F,
+                               9AD8E4B50949CFE00044FD2F,
+                               9AD8E4B70949D0080044FD2F,
+                               9AD8E4BB0949D0FC0044FD2F,
+                               9AD8E4D80949D1350044FD2F,
+                               9AD8E4DA0949D1350044FD2F,
+                               9AD8E4DC0949D1350044FD2F,
+                               9AD8E4E00949D1E40044FD2F,
+                               9AD8E4F00949D4B10044FD2F,
+                               9AA950E00951B9F500895947,
+                               9AA950E40951BC7C00895947,
+                               9A7D78540953FDFD002BD72F,
+                       );
+                       isa = PBXSourcesBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               9A83A32409499C9600B1561F = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               9A0E1C210951AA7600D94F7B,
+                               9A0E1C290951AAFE00D94F7B,
+                       );
+                       isa = PBXFrameworksBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               9A83A32509499C9600B1561F = {
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       isa = PBXRezBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               9A83A32609499C9600B1561F = {
+                       buildPhases = (
+                               9A83A32209499C9600B1561F,
+                               9A83A32309499C9600B1561F,
+                               9A83A32409499C9600B1561F,
+                               9A83A32509499C9600B1561F,
+                       );
+                       buildSettings = {
+                               DYLIB_COMPATIBILITY_VERSION = 1;
+                               DYLIB_CURRENT_VERSION = 1;
+                               HEADER_SEARCH_PATHS = "../portaudio/pa_common ../gsm/inc ../libspeex/include";
+                               LIBRARY_STYLE = DYNAMIC;
+                               OPTIMIZATION_CFLAGS = "-O0";
+                               OTHER_CFLAGS = "--std=c99 -DLIBVER='\"CVS-$(shell date +%Y/%m/%d-%H:%M)\"'";
+                               OTHER_LIBTOOL_FLAGS = "";
+                               OTHER_REZFLAGS = "";
+                               PREFIX_HEADER = ./Prefixes.h;
+                               PRODUCT_NAME = libiaxclient.dylib;
+                               REZ_EXECUTABLE = YES;
+                               SECTORDER_FLAGS = "";
+                               WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+                       };
+                       dependencies = (
+                       );
+                       isa = PBXLibraryTarget;
+                       name = "iaxclientlib dylib";
+                       productInstallPath = /usr/local/lib;
+                       productName = iaxclientlib;
+                       productReference = 9A83A32709499C9600B1561F;
+               };
+               9A83A32709499C9600B1561F = {
+                       isa = PBXLibraryReference;
+                       path = libiaxclient.dylib;
+                       refType = 3;
+               };
+               9A83A32809499C9600B1561F = {
+                       children = (
+                               9A83A32709499C9600B1561F,
+                               9AA951770951BDDB00895947,
+                       );
+                       isa = PBXGroup;
+                       name = Products;
+                       refType = 4;
+               };
+               9A83A32909499CA000B1561F = {
+                       fileRef = 9A83A31809499C6B00B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A32A09499CA100B1561F = {
+                       fileRef = 9A83A31909499C6B00B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A32B09499CA300B1561F = {
+                       fileRef = 9A83A31A09499C6B00B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A32C09499CA400B1561F = {
+                       fileRef = 9A83A31B09499C6B00B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A32D09499CA400B1561F = {
+                       fileRef = 9A83A31C09499C6B00B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A32E09499CA500B1561F = {
+                       fileRef = 9A83A31D09499C6B00B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A32F09499CA600B1561F = {
+                       fileRef = 9A83A31E09499C6B00B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A33009499CA700B1561F = {
+                       fileRef = 9A83A31F09499C6B00B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A33109499CA800B1561F = {
+                       fileRef = 9A83A32009499C6B00B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A33209499CA900B1561F = {
+                       fileRef = 9A83A32109499C6B00B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A33309499CD200B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = gsm_print.c;
+                       path = ../gsm/src/gsm_print.c;
+                       refType = 2;
+               };
+               9A83A33409499CD200B1561F = {
+                       fileRef = 9A83A33309499CD200B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A33509499D0800B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = long_term.c;
+                       path = ../gsm/src/long_term.c;
+                       refType = 2;
+               };
+               9A83A33609499D0800B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = lpc.c;
+                       path = ../gsm/src/lpc.c;
+                       refType = 2;
+               };
+               9A83A33709499D0800B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = preprocess.c;
+                       path = ../gsm/src/preprocess.c;
+                       refType = 2;
+               };
+               9A83A33809499D0800B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = rpe.c;
+                       path = ../gsm/src/rpe.c;
+                       refType = 2;
+               };
+               9A83A33909499D0800B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = short_term.c;
+                       path = ../gsm/src/short_term.c;
+                       refType = 2;
+               };
+               9A83A33A09499D0800B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = table.c;
+                       path = ../gsm/src/table.c;
+                       refType = 2;
+               };
+               9A83A33B09499D0800B1561F = {
+                       fileRef = 9A83A33509499D0800B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A33C09499D0800B1561F = {
+                       fileRef = 9A83A33609499D0800B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A33D09499D0800B1561F = {
+                       fileRef = 9A83A33709499D0800B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A33E09499D0800B1561F = {
+                       fileRef = 9A83A33809499D0800B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A33F09499D0800B1561F = {
+                       fileRef = 9A83A33909499D0800B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A34009499D0800B1561F = {
+                       fileRef = 9A83A33A09499D0800B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A34109499D4C00B1561F = {
+                       children = (
+                               9A83A34209499D9200B1561F,
+                               9A83A34309499D9200B1561F,
+                               9A83A34409499D9200B1561F,
+                               9A83A34509499D9200B1561F,
+                               9A83A34609499D9200B1561F,
+                               9A83A34709499D9200B1561F,
+                               9A83A34809499D9200B1561F,
+                               9A83A34909499D9200B1561F,
+                       );
+                       isa = PBXGroup;
+                       name = codecs;
+                       path = "";
+                       refType = 4;
+               };
+               9A83A34209499D9200B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = codec_alaw.c;
+                       path = ../codec_alaw.c;
+                       refType = 2;
+               };
+               9A83A34309499D9200B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = codec_alaw.h;
+                       path = ../codec_alaw.h;
+                       refType = 2;
+               };
+               9A83A34409499D9200B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = codec_gsm.c;
+                       path = ../codec_gsm.c;
+                       refType = 2;
+               };
+               9A83A34509499D9200B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = codec_gsm.h;
+                       path = ../codec_gsm.h;
+                       refType = 2;
+               };
+               9A83A34609499D9200B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = codec_speex.c;
+                       path = ../codec_speex.c;
+                       refType = 2;
+               };
+               9A83A34709499D9200B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = codec_speex.h;
+                       path = ../codec_speex.h;
+                       refType = 2;
+               };
+               9A83A34809499D9200B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = codec_ulaw.c;
+                       path = ../codec_ulaw.c;
+                       refType = 2;
+               };
+               9A83A34909499D9200B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = codec_ulaw.h;
+                       path = ../codec_ulaw.h;
+                       refType = 2;
+               };
+               9A83A34A09499D9200B1561F = {
+                       fileRef = 9A83A34209499D9200B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A34B09499D9200B1561F = {
+                       fileRef = 9A83A34309499D9200B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A34C09499D9200B1561F = {
+                       fileRef = 9A83A34409499D9200B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A34D09499D9200B1561F = {
+                       fileRef = 9A83A34509499D9200B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A34E09499D9200B1561F = {
+                       fileRef = 9A83A34609499D9200B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A34F09499D9200B1561F = {
+                       fileRef = 9A83A34709499D9200B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A35009499D9200B1561F = {
+                       fileRef = 9A83A34809499D9200B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A35109499D9200B1561F = {
+                       fileRef = 9A83A34909499D9200B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A35209499DC500B1561F = {
+                       children = (
+                               9A83A35309499E1800B1561F,
+                               9A83A35409499E1800B1561F,
+                               9A83A35509499E1800B1561F,
+                               9A83A35609499E1800B1561F,
+                               9A83A35709499E1800B1561F,
+                               9A83A35809499E1800B1561F,
+                               9A5373BC0955727B00A80065,
+                       );
+                       isa = PBXGroup;
+                       name = iax2;
+                       path = "";
+                       refType = 4;
+               };
+               9A83A35309499E1800B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = iax.c;
+                       path = ../libiax2/src/iax.c;
+                       refType = 2;
+               };
+               9A83A35409499E1800B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = "iax2-parser.c";
+                       path = "../libiax2/src/iax2-parser.c";
+                       refType = 2;
+               };
+               9A83A35509499E1800B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = "iax2-parser.h";
+                       path = "../libiax2/src/iax2-parser.h";
+                       refType = 2;
+               };
+               9A83A35609499E1800B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = iax2.h;
+                       path = ../libiax2/src/iax2.h;
+                       refType = 2;
+               };
+               9A83A35709499E1800B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = md5.c;
+                       path = ../libiax2/src/md5.c;
+                       refType = 2;
+               };
+               9A83A35809499E1800B1561F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = md5.h;
+                       path = ../libiax2/src/md5.h;
+                       refType = 2;
+               };
+               9A83A35909499E1800B1561F = {
+                       fileRef = 9A83A35309499E1800B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A35A09499E1800B1561F = {
+                       fileRef = 9A83A35409499E1800B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A35B09499E1800B1561F = {
+                       fileRef = 9A83A35509499E1800B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A35C09499E1800B1561F = {
+                       fileRef = 9A83A35609499E1800B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A35D09499E1800B1561F = {
+                       fileRef = 9A83A35709499E1800B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9A83A35E09499E1800B1561F = {
+                       fileRef = 9A83A35809499E1800B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA950DF0951B9F500895947 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = px_mac_core.c;
+                       path = ../portmixer/px_mac_core/px_mac_core.c;
+                       refType = 2;
+               };
+               9AA950E00951B9F500895947 = {
+                       fileRef = 9AA950DF0951B9F500895947;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA950E10951BA3000895947 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = portmixer.h;
+                       path = ../portmixer/px_common/portmixer.h;
+                       refType = 2;
+               };
+               9AA950E20951BA3000895947 = {
+                       fileRef = 9AA950E10951BA3000895947;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA950E30951BC7C00895947 = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = unixfuncs.c;
+                       path = ../unixfuncs.c;
+                       refType = 2;
+               };
+               9AA950E40951BC7C00895947 = {
+                       fileRef = 9AA950E30951BC7C00895947;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA950FA0951BDDB00895947 = {
+                       buildPhases = (
+                               9AA950FB0951BDDB00895947,
+                               9AA951270951BDDB00895947,
+                               9AA951730951BDDB00895947,
+                               9AA951760951BDDB00895947,
+                       );
+                       buildSettings = {
+                               DEBUGGING_SYMBOLS = NO;
+                               DYLIB_COMPATIBILITY_VERSION = 1;
+                               DYLIB_CURRENT_VERSION = 1;
+                               HEADER_SEARCH_PATHS = "../portaudio/pa_common ../gsm/inc ../libspeex/include";
+                               LIBRARY_STYLE = STATIC;
+                               OTHER_CFLAGS = "--std=c99 -DLIBVER='\"CVS-$(shell date +%Y/%m/%d-%H:%M)\"'";
+                               OTHER_LIBTOOL_FLAGS = "";
+                               OTHER_REZFLAGS = "";
+                               PREFIX_HEADER = ./Prefixes.h;
+                               PRODUCT_NAME = libiaxclient.a;
+                               REZ_EXECUTABLE = YES;
+                               SECTORDER_FLAGS = "";
+                               WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+                       };
+                       dependencies = (
+                       );
+                       isa = PBXLibraryTarget;
+                       name = "iaxclientlib static";
+                       productInstallPath = /usr/local/lib;
+                       productName = iaxclientlib;
+                       productReference = 9AA951770951BDDB00895947;
+               };
+               9AA950FB0951BDDB00895947 = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               9AA950FC0951BDDB00895947,
+                               9AA950FD0951BDDB00895947,
+                               9AA950FE0951BDDB00895947,
+                               9AA950FF0951BDDB00895947,
+                               9AA951000951BDDB00895947,
+                               9AA951010951BDDB00895947,
+                               9AA951020951BDDB00895947,
+                               9AA951030951BDDB00895947,
+                               9AA951040951BDDB00895947,
+                               9AA951050951BDDB00895947,
+                               9AA951060951BDDB00895947,
+                               9AA951070951BDDB00895947,
+                               9AA951080951BDDB00895947,
+                               9AA951090951BDDB00895947,
+                               9AA9510A0951BDDB00895947,
+                               9AA9510B0951BDDB00895947,
+                               9AA9510C0951BDDB00895947,
+                               9AA9510D0951BDDB00895947,
+                               9AA9510E0951BDDB00895947,
+                               9AA9510F0951BDDB00895947,
+                               9AA951100951BDDB00895947,
+                               9AA951110951BDDB00895947,
+                               9AA951120951BDDB00895947,
+                               9AA951130951BDDB00895947,
+                               9AA951140951BDDB00895947,
+                               9AA951150951BDDB00895947,
+                               9AA951160951BDDB00895947,
+                               9AA951170951BDDB00895947,
+                               9AA951180951BDDB00895947,
+                               9AA951190951BDDB00895947,
+                               9AA9511A0951BDDB00895947,
+                               9AA9511B0951BDDB00895947,
+                               9AA9511C0951BDDB00895947,
+                               9AA9511D0951BDDB00895947,
+                               9AA9511E0951BDDB00895947,
+                               9AA9511F0951BDDB00895947,
+                               9AA951200951BDDB00895947,
+                               9AA951220951BDDB00895947,
+                               9AA951230951BDDB00895947,
+                               9AA951240951BDDB00895947,
+                               9AA951250951BDDB00895947,
+                               9AA951260951BDDB00895947,
+                               9A7D78580953FEBE002BD72F,
+                               9A5373BE0955727B00A80065,
+                       );
+                       isa = PBXHeadersBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               9AA950FC0951BDDB00895947 = {
+                       fileRef = 9A83A34309499D9200B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA950FD0951BDDB00895947 = {
+                       fileRef = 9A83A34509499D9200B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA950FE0951BDDB00895947 = {
+                       fileRef = 9A83A34709499D9200B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA950FF0951BDDB00895947 = {
+                       fileRef = 9A83A34909499D9200B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951000951BDDB00895947 = {
+                       fileRef = 9A83A35509499E1800B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951010951BDDB00895947 = {
+                       fileRef = 9A83A35609499E1800B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951020951BDDB00895947 = {
+                       fileRef = 9A83A35809499E1800B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951030951BDDB00895947 = {
+                       fileRef = 9AD8E4350949CBBA0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951040951BDDB00895947 = {
+                       fileRef = 9AD8E43F0949CD690044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951050951BDDB00895947 = {
+                       fileRef = 9AD8E4410949CD690044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951060951BDDB00895947 = {
+                       fileRef = 9AD8E4480949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951070951BDDB00895947 = {
+                       fileRef = 9AD8E4490949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951080951BDDB00895947 = {
+                       fileRef = 9AD8E44B0949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951090951BDDB00895947 = {
+                       fileRef = 9AD8E44C0949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9510A0951BDDB00895947 = {
+                       fileRef = 9AD8E44E0949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9510B0951BDDB00895947 = {
+                       fileRef = 9AD8E4520949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9510C0951BDDB00895947 = {
+                       fileRef = 9AD8E4550949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9510D0951BDDB00895947 = {
+                       fileRef = 9AD8E4560949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9510E0951BDDB00895947 = {
+                       fileRef = 9AD8E4570949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9510F0951BDDB00895947 = {
+                       fileRef = 9AD8E4590949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951100951BDDB00895947 = {
+                       fileRef = 9AD8E45B0949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951110951BDDB00895947 = {
+                       fileRef = 9AD8E45D0949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951120951BDDB00895947 = {
+                       fileRef = 9AD8E45F0949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951130951BDDB00895947 = {
+                       fileRef = 9AD8E4610949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951140951BDDB00895947 = {
+                       fileRef = 9AD8E4630949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951150951BDDB00895947 = {
+                       fileRef = 9AD8E4650949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951160951BDDB00895947 = {
+                       fileRef = 9AD8E4900949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951170951BDDB00895947 = {
+                       fileRef = 9AD8E4930949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951180951BDDB00895947 = {
+                       fileRef = 9AD8E4960949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951190951BDDB00895947 = {
+                       fileRef = 9AD8E49B0949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9511A0951BDDB00895947 = {
+                       fileRef = 9AD8E4BA0949D0FC0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9511B0951BDDB00895947 = {
+                       fileRef = 9AD8E4BF0949D1340044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9511C0951BDDB00895947 = {
+                       fileRef = 9AD8E4C10949D1340044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9511D0951BDDB00895947 = {
+                       fileRef = 9AD8E4C30949D1340044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9511E0951BDDB00895947 = {
+                       fileRef = 9AD8E4DF0949D1E40044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9511F0951BDDB00895947 = {
+                       fileRef = 9AD8E4EE0949D4B10044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951200951BDDB00895947 = {
+                       fileRef = 9AD8E4EF0949D4B10044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951220951BDDB00895947 = {
+                       fileRef = 9AD8E4F40949D5600044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951230951BDDB00895947 = {
+                       fileRef = 9AD8E4F50949D5600044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951240951BDDB00895947 = {
+                       fileRef = 9AD8E4F60949D5600044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951250951BDDB00895947 = {
+                       fileRef = 9AD8E4F70949D5600044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951260951BDDB00895947 = {
+                       fileRef = 9AA950E10951BA3000895947;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951270951BDDB00895947 = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               9AA951280951BDDB00895947,
+                               9AA951290951BDDB00895947,
+                               9AA9512A0951BDDB00895947,
+                               9AA9512B0951BDDB00895947,
+                               9AA9512C0951BDDB00895947,
+                               9AA9512D0951BDDB00895947,
+                               9AA9512E0951BDDB00895947,
+                               9AA9512F0951BDDB00895947,
+                               9AA951300951BDDB00895947,
+                               9AA951310951BDDB00895947,
+                               9AA951320951BDDB00895947,
+                               9AA951330951BDDB00895947,
+                               9AA951340951BDDB00895947,
+                               9AA951350951BDDB00895947,
+                               9AA951360951BDDB00895947,
+                               9AA951370951BDDB00895947,
+                               9AA951380951BDDB00895947,
+                               9AA951390951BDDB00895947,
+                               9AA9513A0951BDDB00895947,
+                               9AA9513B0951BDDB00895947,
+                               9AA9513C0951BDDB00895947,
+                               9AA9513D0951BDDB00895947,
+                               9AA9513E0951BDDB00895947,
+                               9AA9513F0951BDDB00895947,
+                               9AA951410951BDDB00895947,
+                               9AA951420951BDDB00895947,
+                               9AA951430951BDDB00895947,
+                               9AA951440951BDDB00895947,
+                               9AA951450951BDDB00895947,
+                               9AA951460951BDDB00895947,
+                               9AA951470951BDDB00895947,
+                               9AA951480951BDDB00895947,
+                               9AA951490951BDDB00895947,
+                               9AA9514A0951BDDB00895947,
+                               9AA9514B0951BDDB00895947,
+                               9AA9514C0951BDDB00895947,
+                               9AA9514D0951BDDB00895947,
+                               9AA9514E0951BDDB00895947,
+                               9AA9514F0951BDDB00895947,
+                               9AA951500951BDDB00895947,
+                               9AA951510951BDDB00895947,
+                               9AA951520951BDDB00895947,
+                               9AA951530951BDDB00895947,
+                               9AA951540951BDDB00895947,
+                               9AA951550951BDDB00895947,
+                               9AA951560951BDDB00895947,
+                               9AA951570951BDDB00895947,
+                               9AA951580951BDDB00895947,
+                               9AA951590951BDDB00895947,
+                               9AA9515A0951BDDB00895947,
+                               9AA9515B0951BDDB00895947,
+                               9AA9515C0951BDDB00895947,
+                               9AA9515D0951BDDB00895947,
+                               9AA9515E0951BDDB00895947,
+                               9AA9515F0951BDDB00895947,
+                               9AA951600951BDDB00895947,
+                               9AA951610951BDDB00895947,
+                               9AA951620951BDDB00895947,
+                               9AA951630951BDDB00895947,
+                               9AA951640951BDDB00895947,
+                               9AA951650951BDDB00895947,
+                               9AA951660951BDDB00895947,
+                               9AA951670951BDDB00895947,
+                               9AA951680951BDDB00895947,
+                               9AA951690951BDDB00895947,
+                               9AA9516A0951BDDB00895947,
+                               9AA9516B0951BDDB00895947,
+                               9AA9516C0951BDDB00895947,
+                               9AA9516D0951BDDB00895947,
+                               9AA9516E0951BDDB00895947,
+                               9AA9516F0951BDDB00895947,
+                               9AA951700951BDDB00895947,
+                               9AA951710951BDDB00895947,
+                               9AA951720951BDDB00895947,
+                               9A7D78550953FDFD002BD72F,
+                       );
+                       isa = PBXSourcesBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               9AA951280951BDDB00895947 = {
+                       fileRef = 9A83A31809499C6B00B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951290951BDDB00895947 = {
+                       fileRef = 9A83A31909499C6B00B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9512A0951BDDB00895947 = {
+                       fileRef = 9A83A31A09499C6B00B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9512B0951BDDB00895947 = {
+                       fileRef = 9A83A31B09499C6B00B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9512C0951BDDB00895947 = {
+                       fileRef = 9A83A31C09499C6B00B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9512D0951BDDB00895947 = {
+                       fileRef = 9A83A31D09499C6B00B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9512E0951BDDB00895947 = {
+                       fileRef = 9A83A31E09499C6B00B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9512F0951BDDB00895947 = {
+                       fileRef = 9A83A31F09499C6B00B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951300951BDDB00895947 = {
+                       fileRef = 9A83A32009499C6B00B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951310951BDDB00895947 = {
+                       fileRef = 9A83A32109499C6B00B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951320951BDDB00895947 = {
+                       fileRef = 9A83A33309499CD200B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951330951BDDB00895947 = {
+                       fileRef = 9A83A33509499D0800B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951340951BDDB00895947 = {
+                       fileRef = 9A83A33609499D0800B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951350951BDDB00895947 = {
+                       fileRef = 9A83A33709499D0800B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951360951BDDB00895947 = {
+                       fileRef = 9A83A33809499D0800B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951370951BDDB00895947 = {
+                       fileRef = 9A83A33909499D0800B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951380951BDDB00895947 = {
+                       fileRef = 9A83A33A09499D0800B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951390951BDDB00895947 = {
+                       fileRef = 9A83A34209499D9200B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9513A0951BDDB00895947 = {
+                       fileRef = 9A83A34409499D9200B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9513B0951BDDB00895947 = {
+                       fileRef = 9A83A34609499D9200B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9513C0951BDDB00895947 = {
+                       fileRef = 9A83A34809499D9200B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9513D0951BDDB00895947 = {
+                       fileRef = 9A83A35309499E1800B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9513E0951BDDB00895947 = {
+                       fileRef = 9A83A35409499E1800B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9513F0951BDDB00895947 = {
+                       fileRef = 9A83A35709499E1800B1561F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951410951BDDB00895947 = {
+                       fileRef = 9AD8E4320949CB9A0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951420951BDDB00895947 = {
+                       fileRef = 9AD8E4340949CBBA0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951430951BDDB00895947 = {
+                       fileRef = 9AD8E4360949CBBA0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951440951BDDB00895947 = {
+                       fileRef = 9AD8E43C0949CD3B0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951450951BDDB00895947 = {
+                       fileRef = 9AD8E43E0949CD690044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951460951BDDB00895947 = {
+                       fileRef = 9AD8E4400949CD690044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951470951BDDB00895947 = {
+                       fileRef = 9AD8E4470949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951480951BDDB00895947 = {
+                       fileRef = 9AD8E44A0949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951490951BDDB00895947 = {
+                       fileRef = 9AD8E44D0949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9514A0951BDDB00895947 = {
+                       fileRef = 9AD8E44F0949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9514B0951BDDB00895947 = {
+                       fileRef = 9AD8E4500949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9514C0951BDDB00895947 = {
+                       fileRef = 9AD8E4510949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9514D0951BDDB00895947 = {
+                       fileRef = 9AD8E4530949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9514E0951BDDB00895947 = {
+                       fileRef = 9AD8E4540949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9514F0951BDDB00895947 = {
+                       fileRef = 9AD8E4580949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951500951BDDB00895947 = {
+                       fileRef = 9AD8E45A0949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951510951BDDB00895947 = {
+                       fileRef = 9AD8E45C0949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951520951BDDB00895947 = {
+                       fileRef = 9AD8E45E0949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951530951BDDB00895947 = {
+                       fileRef = 9AD8E4600949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951540951BDDB00895947 = {
+                       fileRef = 9AD8E4620949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951550951BDDB00895947 = {
+                       fileRef = 9AD8E4640949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951560951BDDB00895947 = {
+                       fileRef = 9AD8E4850949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951570951BDDB00895947 = {
+                       fileRef = 9AD8E4860949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951580951BDDB00895947 = {
+                       fileRef = 9AD8E4870949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951590951BDDB00895947 = {
+                       fileRef = 9AD8E4880949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9515A0951BDDB00895947 = {
+                       fileRef = 9AD8E4890949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9515B0951BDDB00895947 = {
+                       fileRef = 9AD8E48A0949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9515C0951BDDB00895947 = {
+                       fileRef = 9AD8E48B0949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9515D0951BDDB00895947 = {
+                       fileRef = 9AD8E48C0949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9515E0951BDDB00895947 = {
+                       fileRef = 9AD8E48D0949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9515F0951BDDB00895947 = {
+                       fileRef = 9AD8E48E0949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951600951BDDB00895947 = {
+                       fileRef = 9AD8E48F0949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951610951BDDB00895947 = {
+                       fileRef = 9AD8E4910949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951620951BDDB00895947 = {
+                       fileRef = 9AD8E4920949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951630951BDDB00895947 = {
+                       fileRef = 9AD8E4940949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951640951BDDB00895947 = {
+                       fileRef = 9AD8E4950949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951650951BDDB00895947 = {
+                       fileRef = 9AD8E4970949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951660951BDDB00895947 = {
+                       fileRef = 9AD8E4980949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951670951BDDB00895947 = {
+                       fileRef = 9AD8E4990949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951680951BDDB00895947 = {
+                       fileRef = 9AD8E49A0949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951690951BDDB00895947 = {
+                       fileRef = 9AD8E4B40949CFE00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9516A0951BDDB00895947 = {
+                       fileRef = 9AD8E4B60949D0080044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9516B0951BDDB00895947 = {
+                       fileRef = 9AD8E4B90949D0FC0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9516C0951BDDB00895947 = {
+                       fileRef = 9AD8E4BE0949D1340044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9516D0951BDDB00895947 = {
+                       fileRef = 9AD8E4C00949D1340044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9516E0951BDDB00895947 = {
+                       fileRef = 9AD8E4C20949D1340044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA9516F0951BDDB00895947 = {
+                       fileRef = 9AD8E4DE0949D1E40044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951700951BDDB00895947 = {
+                       fileRef = 9AD8E4ED0949D4B10044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951710951BDDB00895947 = {
+                       fileRef = 9AA950DF0951B9F500895947;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951720951BDDB00895947 = {
+                       fileRef = 9AA950E30951BC7C00895947;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951730951BDDB00895947 = {
+                       buildActionMask = 2147483647;
+                       files = (
+                               9AA951740951BDDB00895947,
+                               9AA951750951BDDB00895947,
+                       );
+                       isa = PBXFrameworksBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               9AA951740951BDDB00895947 = {
+                       fileRef = 9A0E1C200951AA7600D94F7B;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951750951BDDB00895947 = {
+                       fileRef = 9A0E1C280951AAFE00D94F7B;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AA951760951BDDB00895947 = {
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       isa = PBXRezBuildPhase;
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               9AA951770951BDDB00895947 = {
+                       isa = PBXLibraryReference;
+                       path = libiaxclient.a;
+                       refType = 3;
+               };
+               9AD8E4310949CB830044FD2F = {
+                       children = (
+                               9AD8E4320949CB9A0044FD2F,
+                               9AD8E4340949CBBA0044FD2F,
+                               9AD8E4350949CBBA0044FD2F,
+                               9AD8E4360949CBBA0044FD2F,
+                       );
+                       isa = PBXGroup;
+                       name = sox;
+                       path = "";
+                       refType = 4;
+               };
+               9AD8E4320949CB9A0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = compand.c;
+                       path = ../sox/compand.c;
+                       refType = 2;
+               };
+               9AD8E4330949CB9A0044FD2F = {
+                       fileRef = 9AD8E4320949CB9A0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4340949CBBA0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = resample.c;
+                       path = ../sox/resample.c;
+                       refType = 2;
+               };
+               9AD8E4350949CBBA0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = sox.h;
+                       path = ../sox/sox.h;
+                       refType = 2;
+               };
+               9AD8E4360949CBBA0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = soxcompat.c;
+                       path = ../sox/soxcompat.c;
+                       refType = 2;
+               };
+               9AD8E4370949CBBA0044FD2F = {
+                       fileRef = 9AD8E4340949CBBA0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4380949CBBA0044FD2F = {
+                       fileRef = 9AD8E4350949CBBA0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4390949CBBA0044FD2F = {
+                       fileRef = 9AD8E4360949CBBA0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E43A0949CC2F0044FD2F = {
+                       children = (
+                               9A83A34109499D4C00B1561F,
+                               9A83A31609499BE300B1561F,
+                               9A83A35209499DC500B1561F,
+                               9AD8E4B80949D0C10044FD2F,
+                               9AD8E4B30949CFB30044FD2F,
+                               9AD8E43B0949CCDF0044FD2F,
+                               9AD8E4310949CB830044FD2F,
+                               9AD8E4460949CDAC0044FD2F,
+                       );
+                       isa = PBXGroup;
+                       name = sources;
+                       refType = 4;
+               };
+               9AD8E43B0949CCDF0044FD2F = {
+                       children = (
+                               9AD8E43C0949CD3B0044FD2F,
+                               9AD8E43E0949CD690044FD2F,
+                               9AD8E43F0949CD690044FD2F,
+                               9AD8E4400949CD690044FD2F,
+                               9AD8E4410949CD690044FD2F,
+                       );
+                       isa = PBXGroup;
+                       name = portaudio;
+                       refType = 4;
+               };
+               9AD8E43C0949CD3B0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = pa_lib.c;
+                       path = ../portaudio/pa_common/pa_lib.c;
+                       refType = 2;
+               };
+               9AD8E43D0949CD3B0044FD2F = {
+                       fileRef = 9AD8E43C0949CD3B0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E43E0949CD690044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = pablio.c;
+                       path = ../portaudio/pablio/pablio.c;
+                       refType = 2;
+               };
+               9AD8E43F0949CD690044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = pablio.h;
+                       path = ../portaudio/pablio/pablio.h;
+                       refType = 2;
+               };
+               9AD8E4400949CD690044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = ringbuffer.c;
+                       path = ../portaudio/pablio/ringbuffer.c;
+                       refType = 2;
+               };
+               9AD8E4410949CD690044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = ringbuffer.h;
+                       path = ../portaudio/pablio/ringbuffer.h;
+                       refType = 2;
+               };
+               9AD8E4420949CD690044FD2F = {
+                       fileRef = 9AD8E43E0949CD690044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4430949CD690044FD2F = {
+                       fileRef = 9AD8E43F0949CD690044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4440949CD690044FD2F = {
+                       fileRef = 9AD8E4400949CD690044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4450949CD690044FD2F = {
+                       fileRef = 9AD8E4410949CD690044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4460949CDAC0044FD2F = {
+                       children = (
+                               9AD8E4470949CED00044FD2F,
+                               9AD8E4480949CED00044FD2F,
+                               9AD8E4490949CED00044FD2F,
+                               9AD8E44A0949CED00044FD2F,
+                               9AD8E44B0949CED00044FD2F,
+                               9AD8E44C0949CED00044FD2F,
+                               9AD8E44D0949CED00044FD2F,
+                               9AD8E44E0949CED00044FD2F,
+                               9AD8E44F0949CED00044FD2F,
+                               9AD8E4500949CED00044FD2F,
+                               9AD8E4510949CED00044FD2F,
+                               9AD8E4520949CED00044FD2F,
+                               9AD8E4530949CED00044FD2F,
+                               9AD8E4540949CED00044FD2F,
+                               9AD8E4550949CED00044FD2F,
+                               9AD8E4560949CED00044FD2F,
+                               9AD8E4570949CED00044FD2F,
+                               9AD8E4580949CED00044FD2F,
+                               9AD8E4590949CED00044FD2F,
+                               9AD8E45A0949CED00044FD2F,
+                               9AD8E45B0949CED00044FD2F,
+                               9AD8E45C0949CED00044FD2F,
+                               9AD8E45D0949CED00044FD2F,
+                               9AD8E45E0949CED00044FD2F,
+                               9AD8E45F0949CED00044FD2F,
+                               9AD8E4600949CED00044FD2F,
+                               9AD8E4610949CED00044FD2F,
+                               9AD8E4620949CED00044FD2F,
+                               9AD8E4630949CED00044FD2F,
+                               9AD8E4640949CED00044FD2F,
+                               9AD8E4650949CED00044FD2F,
+                               9AD8E4850949CF6C0044FD2F,
+                               9AD8E4860949CF6C0044FD2F,
+                               9AD8E4870949CF6C0044FD2F,
+                               9AD8E4880949CF6C0044FD2F,
+                               9AD8E4890949CF6C0044FD2F,
+                               9AD8E48A0949CF6C0044FD2F,
+                               9AD8E48B0949CF6C0044FD2F,
+                               9AD8E48C0949CF6C0044FD2F,
+                               9AD8E48D0949CF6C0044FD2F,
+                               9AD8E48E0949CF6C0044FD2F,
+                               9AD8E48F0949CF6C0044FD2F,
+                               9AD8E4900949CF6C0044FD2F,
+                               9AD8E4910949CF6C0044FD2F,
+                               9AD8E4920949CF6C0044FD2F,
+                               9AD8E4930949CF6C0044FD2F,
+                               9AD8E4940949CF6C0044FD2F,
+                               9AD8E4950949CF6C0044FD2F,
+                               9AD8E4960949CF6C0044FD2F,
+                               9AD8E4970949CF6C0044FD2F,
+                               9AD8E4980949CF6C0044FD2F,
+                               9AD8E4990949CF6C0044FD2F,
+                               9AD8E49A0949CF6C0044FD2F,
+                               9AD8E49B0949CF6C0044FD2F,
+                       );
+                       isa = PBXGroup;
+                       name = speex;
+                       refType = 4;
+               };
+               9AD8E4470949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = bits.c;
+                       path = ../libspeex/bits.c;
+                       refType = 2;
+               };
+               9AD8E4480949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = cb_search_arm4.h;
+                       path = ../libspeex/cb_search_arm4.h;
+                       refType = 2;
+               };
+               9AD8E4490949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = cb_search_sse.h;
+                       path = ../libspeex/cb_search_sse.h;
+                       refType = 2;
+               };
+               9AD8E44A0949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = cb_search.c;
+                       path = ../libspeex/cb_search.c;
+                       refType = 2;
+               };
+               9AD8E44B0949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = cb_search.h;
+                       path = ../libspeex/cb_search.h;
+                       refType = 2;
+               };
+               9AD8E44C0949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = filters_arm4.h;
+                       path = ../libspeex/filters_arm4.h;
+                       refType = 2;
+               };
+               9AD8E44D0949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = filters.c;
+                       path = ../libspeex/filters.c;
+                       refType = 2;
+               };
+               9AD8E44E0949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = filters.h;
+                       path = ../libspeex/filters.h;
+                       refType = 2;
+               };
+               9AD8E44F0949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = gain_table_lbr.c;
+                       path = ../libspeex/gain_table_lbr.c;
+                       refType = 2;
+               };
+               9AD8E4500949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = gain_table.c;
+                       path = ../libspeex/gain_table.c;
+                       refType = 2;
+               };
+               9AD8E4510949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = lpc.c;
+                       path = ../libspeex/lpc.c;
+                       refType = 2;
+               };
+               9AD8E4520949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = lpc.h;
+                       path = ../libspeex/lpc.h;
+                       refType = 2;
+               };
+               9AD8E4530949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = lsp_tables_nb.c;
+                       path = ../libspeex/lsp_tables_nb.c;
+                       refType = 2;
+               };
+               9AD8E4540949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = lsp.c;
+                       path = ../libspeex/lsp.c;
+                       refType = 2;
+               };
+               9AD8E4550949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = lsp.h;
+                       path = ../libspeex/lsp.h;
+                       refType = 2;
+               };
+               9AD8E4560949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = ltp_arm4.h;
+                       path = ../libspeex/ltp_arm4.h;
+                       refType = 2;
+               };
+               9AD8E4570949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = ltp_sse.h;
+                       path = ../libspeex/ltp_sse.h;
+                       refType = 2;
+               };
+               9AD8E4580949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = ltp.c;
+                       path = ../libspeex/ltp.c;
+                       refType = 2;
+               };
+               9AD8E4590949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = ltp.h;
+                       path = ../libspeex/ltp.h;
+                       refType = 2;
+               };
+               9AD8E45A0949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = modes.c;
+                       path = ../libspeex/modes.c;
+                       refType = 2;
+               };
+               9AD8E45B0949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = modes.h;
+                       path = ../libspeex/modes.h;
+                       refType = 2;
+               };
+               9AD8E45C0949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = nb_celp.c;
+                       path = ../libspeex/nb_celp.c;
+                       refType = 2;
+               };
+               9AD8E45D0949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = nb_celp.h;
+                       path = ../libspeex/nb_celp.h;
+                       refType = 2;
+               };
+               9AD8E45E0949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = quant_lsp.c;
+                       path = ../libspeex/quant_lsp.c;
+                       refType = 2;
+               };
+               9AD8E45F0949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = quant_lsp.h;
+                       path = ../libspeex/quant_lsp.h;
+                       refType = 2;
+               };
+               9AD8E4600949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = sb_celp.c;
+                       path = ../libspeex/sb_celp.c;
+                       refType = 2;
+               };
+               9AD8E4610949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = sb_celp.h;
+                       path = ../libspeex/sb_celp.h;
+                       refType = 2;
+               };
+               9AD8E4620949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = speex.c;
+                       path = ../libspeex/speex.c;
+                       refType = 2;
+               };
+               9AD8E4630949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = vq_arm4.h;
+                       path = ../libspeex/vq_arm4.h;
+                       refType = 2;
+               };
+               9AD8E4640949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = vq.c;
+                       path = ../libspeex/vq.c;
+                       refType = 2;
+               };
+               9AD8E4650949CED00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = vq.h;
+                       path = ../libspeex/vq.h;
+                       refType = 2;
+               };
+               9AD8E4660949CED00044FD2F = {
+                       fileRef = 9AD8E4470949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4670949CED00044FD2F = {
+                       fileRef = 9AD8E4480949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4680949CED00044FD2F = {
+                       fileRef = 9AD8E4490949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4690949CED00044FD2F = {
+                       fileRef = 9AD8E44A0949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E46A0949CED00044FD2F = {
+                       fileRef = 9AD8E44B0949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E46B0949CED00044FD2F = {
+                       fileRef = 9AD8E44C0949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E46C0949CED00044FD2F = {
+                       fileRef = 9AD8E44D0949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E46D0949CED00044FD2F = {
+                       fileRef = 9AD8E44E0949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E46E0949CED00044FD2F = {
+                       fileRef = 9AD8E44F0949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E46F0949CED00044FD2F = {
+                       fileRef = 9AD8E4500949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4700949CED00044FD2F = {
+                       fileRef = 9AD8E4510949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4710949CED00044FD2F = {
+                       fileRef = 9AD8E4520949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4720949CED00044FD2F = {
+                       fileRef = 9AD8E4530949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4730949CED00044FD2F = {
+                       fileRef = 9AD8E4540949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4740949CED00044FD2F = {
+                       fileRef = 9AD8E4550949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4750949CED00044FD2F = {
+                       fileRef = 9AD8E4560949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4760949CED00044FD2F = {
+                       fileRef = 9AD8E4570949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4770949CED00044FD2F = {
+                       fileRef = 9AD8E4580949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4780949CED00044FD2F = {
+                       fileRef = 9AD8E4590949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4790949CED00044FD2F = {
+                       fileRef = 9AD8E45A0949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E47A0949CED00044FD2F = {
+                       fileRef = 9AD8E45B0949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E47B0949CED00044FD2F = {
+                       fileRef = 9AD8E45C0949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E47C0949CED00044FD2F = {
+                       fileRef = 9AD8E45D0949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E47D0949CED00044FD2F = {
+                       fileRef = 9AD8E45E0949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E47E0949CED00044FD2F = {
+                       fileRef = 9AD8E45F0949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E47F0949CED00044FD2F = {
+                       fileRef = 9AD8E4600949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4800949CED00044FD2F = {
+                       fileRef = 9AD8E4610949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4810949CED00044FD2F = {
+                       fileRef = 9AD8E4620949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4820949CED00044FD2F = {
+                       fileRef = 9AD8E4630949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4830949CED00044FD2F = {
+                       fileRef = 9AD8E4640949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4840949CED00044FD2F = {
+                       fileRef = 9AD8E4650949CED00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4850949CF6C0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = exc_5_64_table.c;
+                       path = ../libspeex/exc_5_64_table.c;
+                       refType = 2;
+               };
+               9AD8E4860949CF6C0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = exc_5_256_table.c;
+                       path = ../libspeex/exc_5_256_table.c;
+                       refType = 2;
+               };
+               9AD8E4870949CF6C0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = exc_8_128_table.c;
+                       path = ../libspeex/exc_8_128_table.c;
+                       refType = 2;
+               };
+               9AD8E4880949CF6C0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = exc_10_16_table.c;
+                       path = ../libspeex/exc_10_16_table.c;
+                       refType = 2;
+               };
+               9AD8E4890949CF6C0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = exc_10_32_table.c;
+                       path = ../libspeex/exc_10_32_table.c;
+                       refType = 2;
+               };
+               9AD8E48A0949CF6C0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = exc_20_32_table.c;
+                       path = ../libspeex/exc_20_32_table.c;
+                       refType = 2;
+               };
+               9AD8E48B0949CF6C0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = hexc_10_32_table.c;
+                       path = ../libspeex/hexc_10_32_table.c;
+                       refType = 2;
+               };
+               9AD8E48C0949CF6C0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = hexc_table.c;
+                       path = ../libspeex/hexc_table.c;
+                       refType = 2;
+               };
+               9AD8E48D0949CF6C0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = high_lsp_tables.c;
+                       path = ../libspeex/high_lsp_tables.c;
+                       refType = 2;
+               };
+               9AD8E48E0949CF6C0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = jitter.c;
+                       path = ../libspeex/jitter.c;
+                       refType = 2;
+               };
+               9AD8E48F0949CF6C0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = lbr_48k_tables.c;
+                       path = ../libspeex/lbr_48k_tables.c;
+                       refType = 2;
+               };
+               9AD8E4900949CF6C0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = math_approx.h;
+                       path = ../libspeex/math_approx.h;
+                       refType = 2;
+               };
+               9AD8E4910949CF6C0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = mdf.c;
+                       path = ../libspeex/mdf.c;
+                       refType = 2;
+               };
+               9AD8E4920949CF6C0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = misc.c;
+                       path = ../libspeex/misc.c;
+                       refType = 2;
+               };
+               9AD8E4930949CF6C0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = misc.h;
+                       path = ../libspeex/misc.h;
+                       refType = 2;
+               };
+               9AD8E4940949CF6C0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = preprocess.c;
+                       path = ../libspeex/preprocess.c;
+                       refType = 2;
+               };
+               9AD8E4950949CF6C0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = smallft.c;
+                       path = ../libspeex/smallft.c;
+                       refType = 2;
+               };
+               9AD8E4960949CF6C0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = smallft.h;
+                       path = ../libspeex/smallft.h;
+                       refType = 2;
+               };
+               9AD8E4970949CF6C0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = speex_callbacks.c;
+                       path = ../libspeex/speex_callbacks.c;
+                       refType = 2;
+               };
+               9AD8E4980949CF6C0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = speex_header.c;
+                       path = ../libspeex/speex_header.c;
+                       refType = 2;
+               };
+               9AD8E4990949CF6C0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = stereo.c;
+                       path = ../libspeex/stereo.c;
+                       refType = 2;
+               };
+               9AD8E49A0949CF6C0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = vbr.c;
+                       path = ../libspeex/vbr.c;
+                       refType = 2;
+               };
+               9AD8E49B0949CF6C0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = vbr.h;
+                       path = ../libspeex/vbr.h;
+                       refType = 2;
+               };
+               9AD8E49C0949CF6C0044FD2F = {
+                       fileRef = 9AD8E4850949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E49D0949CF6C0044FD2F = {
+                       fileRef = 9AD8E4860949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E49E0949CF6C0044FD2F = {
+                       fileRef = 9AD8E4870949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E49F0949CF6C0044FD2F = {
+                       fileRef = 9AD8E4880949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4A00949CF6C0044FD2F = {
+                       fileRef = 9AD8E4890949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4A10949CF6C0044FD2F = {
+                       fileRef = 9AD8E48A0949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4A20949CF6C0044FD2F = {
+                       fileRef = 9AD8E48B0949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4A30949CF6C0044FD2F = {
+                       fileRef = 9AD8E48C0949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4A40949CF6C0044FD2F = {
+                       fileRef = 9AD8E48D0949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4A50949CF6C0044FD2F = {
+                       fileRef = 9AD8E48E0949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4A60949CF6C0044FD2F = {
+                       fileRef = 9AD8E48F0949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4A70949CF6C0044FD2F = {
+                       fileRef = 9AD8E4900949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4A80949CF6C0044FD2F = {
+                       fileRef = 9AD8E4910949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4A90949CF6C0044FD2F = {
+                       fileRef = 9AD8E4920949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4AA0949CF6C0044FD2F = {
+                       fileRef = 9AD8E4930949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4AB0949CF6C0044FD2F = {
+                       fileRef = 9AD8E4940949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4AC0949CF6C0044FD2F = {
+                       fileRef = 9AD8E4950949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4AD0949CF6C0044FD2F = {
+                       fileRef = 9AD8E4960949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4AE0949CF6C0044FD2F = {
+                       fileRef = 9AD8E4970949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4AF0949CF6C0044FD2F = {
+                       fileRef = 9AD8E4980949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4B00949CF6C0044FD2F = {
+                       fileRef = 9AD8E4990949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4B10949CF6C0044FD2F = {
+                       fileRef = 9AD8E49A0949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4B20949CF6C0044FD2F = {
+                       fileRef = 9AD8E49B0949CF6C0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4B30949CFB30044FD2F = {
+                       children = (
+                               9AA950E30951BC7C00895947,
+                               9AD8E4B40949CFE00044FD2F,
+                               9AD8E4B60949D0080044FD2F,
+                               9AA950DF0951B9F500895947,
+                               9AA950E10951BA3000895947,
+                       );
+                       isa = PBXGroup;
+                       name = macosx;
+                       refType = 4;
+               };
+               9AD8E4B40949CFE00044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = pa_mac_core.c;
+                       path = ../portaudio/pa_mac_core/pa_mac_core.c;
+                       refType = 2;
+               };
+               9AD8E4B50949CFE00044FD2F = {
+                       fileRef = 9AD8E4B40949CFE00044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4B60949D0080044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = pa_convert.c;
+                       path = ../portaudio/pa_common/pa_convert.c;
+                       refType = 2;
+               };
+               9AD8E4B70949D0080044FD2F = {
+                       fileRef = 9AD8E4B60949D0080044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4B80949D0C10044FD2F = {
+                       children = (
+                               9AD8E4B90949D0FC0044FD2F,
+                               9AD8E4BA0949D0FC0044FD2F,
+                               9AD8E4BE0949D1340044FD2F,
+                               9AD8E4BF0949D1340044FD2F,
+                               9AD8E4C00949D1340044FD2F,
+                               9AD8E4C10949D1340044FD2F,
+                               9AD8E4C20949D1340044FD2F,
+                               9AD8E4C30949D1340044FD2F,
+                               9AD8E4DE0949D1E40044FD2F,
+                               9AD8E4DF0949D1E40044FD2F,
+                               9AD8E4ED0949D4B10044FD2F,
+                               9AD8E4EE0949D4B10044FD2F,
+                               9AD8E4EF0949D4B10044FD2F,
+                       );
+                       isa = PBXGroup;
+                       name = iaxclient;
+                       refType = 4;
+               };
+               9AD8E4B90949D0FC0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = plc.c;
+                       path = ../spandsp/plc.c;
+                       refType = 2;
+               };
+               9AD8E4BA0949D0FC0044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = plc.h;
+                       path = ../spandsp/plc.h;
+                       refType = 2;
+               };
+               9AD8E4BB0949D0FC0044FD2F = {
+                       fileRef = 9AD8E4B90949D0FC0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4BC0949D0FC0044FD2F = {
+                       fileRef = 9AD8E4BA0949D0FC0044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4BE0949D1340044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = audio_encode.c;
+                       path = ../audio_encode.c;
+                       refType = 2;
+               };
+               9AD8E4BF0949D1340044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = audio_encode.h;
+                       path = ../audio_encode.h;
+                       refType = 2;
+               };
+               9AD8E4C00949D1340044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = audio_file.c;
+                       path = ../audio_file.c;
+                       refType = 2;
+               };
+               9AD8E4C10949D1340044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = audio_file.h;
+                       path = ../audio_file.h;
+                       refType = 2;
+               };
+               9AD8E4C20949D1340044FD2F = {
+                       fileEncoding = 30;
+                       indentWidth = 4;
+                       isa = PBXFileReference;
+                       name = audio_portaudio.c;
+                       path = ../audio_portaudio.c;
+                       refType = 2;
+                       tabWidth = 4;
+                       usesTabs = 0;
+               };
+               9AD8E4C30949D1340044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = audio_portaudio.h;
+                       path = ../audio_portaudio.h;
+                       refType = 2;
+               };
+               9AD8E4D80949D1350044FD2F = {
+                       fileRef = 9AD8E4BE0949D1340044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4D90949D1350044FD2F = {
+                       fileRef = 9AD8E4BF0949D1340044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4DA0949D1350044FD2F = {
+                       fileRef = 9AD8E4C00949D1340044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4DB0949D1350044FD2F = {
+                       fileRef = 9AD8E4C10949D1340044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4DC0949D1350044FD2F = {
+                       fileRef = 9AD8E4C20949D1340044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4DD0949D1350044FD2F = {
+                       fileRef = 9AD8E4C30949D1340044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4DE0949D1E40044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = jitterbuf.c;
+                       path = ../jitterbuf.c;
+                       refType = 2;
+               };
+               9AD8E4DF0949D1E40044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = jitterbuf.h;
+                       path = ../jitterbuf.h;
+                       refType = 2;
+               };
+               9AD8E4E00949D1E40044FD2F = {
+                       fileRef = 9AD8E4DE0949D1E40044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4E10949D1E40044FD2F = {
+                       fileRef = 9AD8E4DF0949D1E40044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4ED0949D4B10044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = iaxclient_lib.c;
+                       path = ../iaxclient_lib.c;
+                       refType = 2;
+               };
+               9AD8E4EE0949D4B10044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = iaxclient_lib.h;
+                       path = ../iaxclient_lib.h;
+                       refType = 2;
+               };
+               9AD8E4EF0949D4B10044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = iaxclient.h;
+                       path = ../iaxclient.h;
+                       refType = 2;
+               };
+               9AD8E4F00949D4B10044FD2F = {
+                       fileRef = 9AD8E4ED0949D4B10044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4F10949D4B10044FD2F = {
+                       fileRef = 9AD8E4EE0949D4B10044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4F20949D4B10044FD2F = {
+                       fileRef = 9AD8E4EF0949D4B10044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4F40949D5600044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = gsm.h;
+                       path = ../gsm/inc/gsm.h;
+                       refType = 2;
+               };
+               9AD8E4F50949D5600044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = private.h;
+                       path = ../gsm/inc/private.h;
+                       refType = 2;
+               };
+               9AD8E4F60949D5600044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = proto.h;
+                       path = ../gsm/inc/proto.h;
+                       refType = 2;
+               };
+               9AD8E4F70949D5600044FD2F = {
+                       fileEncoding = 30;
+                       isa = PBXFileReference;
+                       name = unproto.h;
+                       path = ../gsm/inc/unproto.h;
+                       refType = 2;
+               };
+               9AD8E4F90949D5600044FD2F = {
+                       fileRef = 9AD8E4F40949D5600044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4FA0949D5600044FD2F = {
+                       fileRef = 9AD8E4F50949D5600044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4FB0949D5600044FD2F = {
+                       fileRef = 9AD8E4F60949D5600044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+               9AD8E4FC0949D5600044FD2F = {
+                       fileRef = 9AD8E4F70949D5600044FD2F;
+                       isa = PBXBuildFile;
+                       settings = {
+                       };
+               };
+       };
+       rootObject = 9A83A31509499BB400B1561F;
+}
diff --git a/utils/iaxclient/lib/portaudio/LICENSE.txt b/utils/iaxclient/lib/portaudio/LICENSE.txt
new file mode 100644 (file)
index 0000000..105da3f
--- /dev/null
@@ -0,0 +1,65 @@
+Portable header file to contain:
+/*
+ * PortAudio Portable Real-Time Audio Library
+ * PortAudio API Header File
+ * Latest version available at: http://www.audiomulch.com/portaudio/
+ *
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+Implementation files to contain:
+/*
+ * PortAudio Portable Real-Time Audio Library
+ * Latest version at: http://www.audiomulch.com/portaudio/
+ * <platform> Implementation
+ * Copyright (c) 1999-2000 <author(s)>
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
\ No newline at end of file
diff --git a/utils/iaxclient/lib/portaudio/Makefile.darwin b/utils/iaxclient/lib/portaudio/Makefile.darwin
new file mode 100644 (file)
index 0000000..808124b
--- /dev/null
@@ -0,0 +1,218 @@
+#
+# PortAudio V19 Makefile.darwin
+#
+# Bjorn Roche of XO Audio (www.xoaudio.com)
+# Based on autoconf's makefile, created from Makefile generated by
+# autoconf. Autoconf files written by by Dominic Mazzoni with modifications
+# by Mikael Magnusson.
+#
+
+top_srcdir = .
+srcdir = .
+
+top_builddir = .
+OPT_LEVEL := -O2
+PREFIX = /usr/local
+prefix = $(PREFIX)
+exec_prefix = ${prefix}
+bindir = ${exec_prefix}/bin
+libdir = ${exec_prefix}/lib
+includedir = ${prefix}/include
+CC = gcc
+CFLAGS = -g -std=gnu99 -Werror -arch i386 -arch ppc -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.3 $(OPT_LEVEL) -Wall -pedantic -pipe -fPIC -DPA_BIG_ENDIAN  -Ipa_common -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DPA_USE_COREAUDIO=1 -Iinclude -Isrc/common
+LIBS = -framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon
+AR = /usr/bin/ar
+RANLIB = ranlib
+LIBTOOL = $(SHELL) $(top_builddir)/libtool
+INSTALL = /usr/bin/install -c
+INSTALL_DATA = ${INSTALL} -m 644
+SHARED_FLAGS = -framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon -dynamiclib -arch i386 -arch ppc -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.3
+DLL_LIBS = 
+CXXFLAGS = -g $(OPT_LEVEL)
+NASM = 
+NASMOPT = 
+LN_S = ln -s
+LT_RELEASE=@LT_RELEASE@
+LT_CURRENT=2
+LT_REVISION=0
+LT_AGE=0
+
+
+OTHER_OBJS = src/os/mac_osx/pa_mac_hostapis.o src/os/unix/pa_unix_util.o src/hostapi/coreaudio/pa_mac_core.o src/hostapi/coreaudio/ringbuffer.o src/hostapi/coreaudio/pa_mac_core_utilities.o src/hostapi/coreaudio/pa_mac_core_blocking.o
+
+PALIB = libportaudio.a
+PADLL = libportaudio
+PADLLV_MIN = 19
+PADLLV = 0.0.19
+PADLLEXT = .dylib
+PASHLIBNAME = $(PADLL).$(PADLLV)$(PADLLEXT)
+PAINC = include/portaudio.h
+PA_LDFLAGS = $(LDFLAGS) $(SHARED_FLAGS) -rpath $(libdir) -no-undefined -export -symbols-regex "Pa_.*" -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
+
+COMMON_OBJS = \
+       src/common/pa_allocation.o \
+       src/common/pa_converters.o \
+       src/common/pa_cpuload.o \
+       src/common/pa_dither.o \
+       src/common/pa_front.o \
+       src/common/pa_process.o \
+       src/common/pa_skeleton.o \
+       src/common/pa_stream.o \
+       src/common/pa_trace.o
+
+TESTS = \
+       bin/paqa_devs \
+       bin/paqa_errs \
+       bin/patest1 \
+       bin/patest_buffer \
+       bin/patest_callbackstop \
+       bin/patest_clip \
+       bin/patest_dither \
+       bin/patest_hang \
+       bin/patest_in_overflow \
+       bin/patest_latency \
+       bin/patest_leftright \
+       bin/patest_longsine \
+       bin/patest_many \
+       bin/patest_maxsines \
+       bin/patest_multi_sine \
+       bin/patest_out_underflow \
+       bin/patest_pink \
+       bin/patest_prime \
+       bin/patest_read_record \
+       bin/patest_read_write_wire \
+       bin/patest_record \
+       bin/patest_ringmix \
+       bin/patest_saw \
+       bin/patest_sine8 \
+       bin/patest_sine \
+       bin/patest_sine_formats \
+       bin/patest_sine_time \
+       bin/patest_start_stop \
+       bin/patest_stop \
+       bin/patest_sync \
+       bin/patest_toomanysines \
+       bin/patest_underflow \
+       bin/patest_wire \
+       bin/patest_write_sine \
+       bin/patest_write_stop \
+       bin/pa_devs \
+       bin/pa_fuzz \
+       bin/pa_minlat
+
+# Most of these don't compile yet.  Put them in TESTS, above, if
+# you want to try to compile them...
+ALL_TESTS = \
+       $(TESTS) \
+       bin/debug_convert \
+       bin/debug_dither_calc \
+       bin/debug_dual \
+       bin/debug_multi_in \
+       bin/debug_multi_out \
+       bin/debug_record \
+       bin/debug_record_reuse \
+       bin/debug_sine_amp \
+       bin/debug_sine \
+       bin/debug_sine_formats \
+       bin/debug_srate \
+       bin/debug_test1 \
+       bin/pa_devs \
+       bin/pa_fuzz \
+       bin/pa_minlat \
+       bin/paqa_devs \
+       bin/paqa_errs \
+       bin/patest1 \
+       bin/patest_buffer \
+       bin/patest_clip \
+       bin/patest_dither \
+       bin/patest_hang \
+       bin/patest_in_overflow \
+       bin/patest_latency \
+       bin/patest_leftright \
+       bin/patest_longsine \
+       bin/patest_many \
+       bin/patest_maxsines \
+       bin/patest_multi_sine \
+       bin/patest_out_underflow \
+       bin/patest_pink \
+       bin/patest_read_record \
+       bin/patest_record \
+       bin/patest_ringmix \
+       bin/patest_saw \
+       bin/patest_sine8 \
+       bin/patest_sine \
+       bin/patest_sine_formats \
+       bin/patest_sine_time \
+       bin/patest_start_stop \
+       bin/patest_stop \
+       bin/patest_sync \
+       bin/patest_toomanysines \
+       bin/patest_underflow \
+       bin/patest_wire \
+       bin/patest_write_sine
+
+OBJS = $(COMMON_OBJS) $(OTHER_OBJS)
+
+#LTOBJS:= $(OBJS:.o=.lo)
+
+all: lib/$(PALIB) lib/$(PASHLIBNAME) tests
+
+tests: bin/ $(TESTS)
+
+lib/$(PALIB): lib/ $(OBJS) Makefile.darwin $(PAINC)
+       -rm lib/$(PALIB)
+       $(AR) ruv lib/$(PALIB) $(OBJS)
+       $(RANLIB) lib/$(PALIB)
+
+lib/$(PASHLIBNAME): lib/ $(OBJS) Makefile.darwin $(PAINC)
+       $(CC) $(SHARED_FLAGS) -o lib/$(PASHLIBNAME) $(OBJS) $(DLL_LIBS) -install_name $(PREFIX)/lib/$(PASHLIBNAME) -compatibility_version $(PADLLV) -current_version $(PADLLV)
+
+$(TESTS): bin/%: lib/$(PALIB) Makefile.darwin $(PAINC) test/%.c
+       $(CC) -o $@ $(CFLAGS) test/$*.c lib/$(PALIB) $(LIBS)
+
+install: lib/$(PALIB) lib/$(PASHLIBNAME) portaudio-2.0.pc
+       $(INSTALL) -d $(PREFIX)/lib
+       $(INSTALL) -m 644 lib/$(PASHLIBNAME) $(PREFIX)/lib/$(PASHLIBNAME)
+       $(INSTALL) -m 644 lib/$(PALIB) $(PREFIX)/lib/$(PALIB)
+       cd $(PREFIX)/lib && rm -f $(PADLL)$(PADLLEXT) && ln -s $(PASHLIBNAME) $(PADLL)$(PADLLEXT)
+       $(INSTALL) -d $(PREFIX)/include
+       $(INSTALL) -m 644 include/portaudio.h $(PREFIX)/include/portaudio.h
+       $(INSTALL) -d $(PREFIX)/lib/pkgconfig
+       $(INSTALL) -m 644 portaudio-2.0.pc $(PREFIX)/lib/pkgconfig/portaudio-2.0.pc
+       @echo ""
+       @echo "------------------------------------------------------------"
+       @echo "PortAudio was successfully installed."
+       @echo ""
+       @echo "On some systems (e.g. Linux) you should run 'ldconfig' now"
+       @echo "to make the shared object available.  You may also need to"
+       @echo "modify your LD_LIBRARY_PATH environment variable to include"
+       @echo "the directory $(PREFIX)/lib"
+       @echo "------------------------------------------------------------"
+       @echo ""
+
+uninstall:
+       rm -f $(PREFIX)/lib/$(PASHLIBNAME)
+       rm -f $(PREFIX)/lib/$(PALIB)
+       rm -f $(PREFIX)/lib/$(PADLL)$(PADLLEXT)
+       rm -f $(PREFIX)/include/portaudio.h
+
+clean:
+       rm -f $(OBJS) $(TESTS) lib/$(PALIB) lib/$(PASHLIBNAME)
+
+%.o: %.c Makefile.darwin $(PAINC)
+       $(CC) -c $(CFLAGS) $< -o $@
+
+%.o: %.cpp Makefile.darwin $(PAINC)
+       $(CXX) -c $(CXXFLAGS) $< -o $@
+
+%.o: %.asm
+       $(NASM) $(NASMOPT) -o $@ $<
+
+bin:
+       mkdir bin
+
+lib:
+       mkdir lib
+
+
+
diff --git a/utils/iaxclient/lib/portaudio/Makefile.in b/utils/iaxclient/lib/portaudio/Makefile.in
new file mode 100644 (file)
index 0000000..7fd3fcc
--- /dev/null
@@ -0,0 +1,186 @@
+#
+# PortAudio V19 Makefile.in
+#
+# Dominic Mazzoni
+# Modifications by Mikael Magnusson
+#
+
+top_srcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_builddir = .
+PREFIX = @prefix@
+prefix = $(PREFIX)
+exec_prefix = @exec_prefix@
+bindir = @bindir@
+libdir = @libdir@
+includedir = @includedir@
+CC = @CC@
+CFLAGS = @CFLAGS@ -I$(top_srcdir)/include -I$(top_srcdir)/src/common -I$(top_srcdir)/src/os/unix @DEFS@
+LIBS = @LIBS@
+AR = @AR@
+RANLIB = @RANLIB@
+LIBTOOL = @LIBTOOL@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+SHARED_FLAGS = @SHARED_FLAGS@
+LDFLAGS = @LDFLAGS@
+DLL_LIBS = @DLL_LIBS@
+CXXFLAGS = @CXXFLAGS@
+NASM = @NASM@
+NASMOPT = @NASMOPT@
+LN_S = @LN_S@
+LT_RELEASE=@LT_RELEASE@
+LT_CURRENT=@LT_CURRENT@
+LT_REVISION=@LT_REVISION@
+LT_AGE=@LT_AGE@
+
+OTHER_OBJS = @OTHER_OBJS@
+
+PALIB = libportaudio.la
+PAINC = include/portaudio.h
+
+PA_LDFLAGS = $(LDFLAGS) $(SHARED_FLAGS) -rpath $(libdir) -no-undefined -export-symbols-regex "Pa_.*" -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
+#MAKEFILE = Makefile
+
+COMMON_OBJS = \
+       src/common/pa_allocation.o \
+       src/common/pa_converters.o \
+       src/common/pa_cpuload.o \
+       src/common/pa_dither.o \
+       src/common/pa_front.o \
+       src/common/pa_process.o \
+       src/common/pa_skeleton.o \
+       src/common/pa_stream.o \
+       src/common/pa_trace.o
+
+TESTS = \
+       bin/paqa_devs \
+       bin/paqa_errs \
+       bin/patest1 \
+       bin/patest_buffer \
+       bin/patest_callbackstop \
+       bin/patest_clip \
+       bin/patest_dither \
+       bin/patest_hang \
+       bin/patest_in_overflow \
+       bin/patest_latency \
+       bin/patest_leftright \
+       bin/patest_longsine \
+       bin/patest_many \
+       bin/patest_maxsines \
+       bin/patest_multi_sine \
+       bin/patest_out_underflow \
+       bin/patest_pink \
+       bin/patest_prime \
+       bin/patest_read_record \
+       bin/patest_read_write_wire \
+       bin/patest_record \
+       bin/patest_ringmix \
+       bin/patest_saw \
+       bin/patest_sine8 \
+       bin/patest_sine \
+       bin/patest_sine_formats \
+       bin/patest_sine_time \
+       bin/patest_start_stop \
+       bin/patest_stop \
+       bin/patest_toomanysines \
+       bin/patest_underflow \
+       bin/patest_wire \
+       bin/patest_write_sine \
+       bin/pa_devs \
+       bin/pa_fuzz \
+       bin/pa_minlat
+
+# Most of these don't compile yet.  Put them in TESTS, above, if
+# you want to try to compile them...
+ALL_TESTS = \
+       $(TESTS) \
+       bin/patest_sync \
+       bin/debug_convert \
+       bin/debug_dither_calc \
+       bin/debug_dual \
+       bin/debug_multi_in \
+       bin/debug_multi_out \
+       bin/debug_record \
+       bin/debug_record_reuse \
+       bin/debug_sine_amp \
+       bin/debug_sine \
+       bin/debug_sine_formats \
+       bin/debug_srate \
+       bin/debug_test1
+
+OBJS = $(COMMON_OBJS) $(OTHER_OBJS)
+
+LTOBJS:= $(OBJS:.o=.lo)
+
+all: lib/$(PALIB) #tests
+
+tests: bin-stamp $(TESTS)
+
+
+lib/$(PALIB): lib-stamp $(LTOBJS) $(MAKEFILE) $(PAINC)
+       $(LIBTOOL) --mode=link $(CC) $(PA_LDFLAGS) -o lib/$(PALIB) $(LTOBJS) $(DLL_LIBS)
+
+$(ALL_TESTS): bin/%: lib/$(PALIB) $(MAKEFILE) $(PAINC) test/%.c
+       $(LIBTOOL) --mode=link $(CC) -o $@ $(CFLAGS) $(top_srcdir)/test/$*.c lib/$(PALIB) $(LIBS)
+
+
+install: lib/$(PALIB) portaudio-2.0.pc
+       $(INSTALL) -d $(DESTDIR)$(libdir)
+       $(LIBTOOL) --mode=install $(INSTALL) lib/$(PALIB) $(DESTDIR)$(libdir)
+       $(INSTALL) -d $(DESTDIR)$(includedir)
+       $(INSTALL_DATA) -m 644 $(top_srcdir)/$(PAINC) $(DESTDIR)$(includedir)/portaudio.h
+       $(INSTALL) -d $(DESTDIR)$(libdir)/pkgconfig
+       $(INSTALL) -m 644 portaudio-2.0.pc $(DESTDIR)$(libdir)/pkgconfig/portaudio-2.0.pc
+       @echo ""
+       @echo "------------------------------------------------------------"
+       @echo "PortAudio was successfully installed."
+       @echo ""
+       @echo "On some systems (e.g. Linux) you should run 'ldconfig' now"
+       @echo "to make the shared object available.  You may also need to"
+       @echo "modify your LD_LIBRARY_PATH environment variable to include"
+       @echo "the directory $(libdir)"
+       @echo "------------------------------------------------------------"
+       @echo ""
+
+uninstall:
+       $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$(PALIB)
+       $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(includedir)/portaudio.h
+
+clean:
+       $(LIBTOOL) --mode=clean rm -f $(LTOBJS) $(ALL_TESTS) lib/$(PALIB)
+       rm -f bin-stamp lib-stamp
+       -rm -rf bin lib
+       -rmdir src/os/win src/os/unix src/os/mac_osx src/common \
+src/hostapi/oss src/hostapi/alsa src/hostapi/jack src/hostapi/wmme \
+src/hostapi/wdmks src/hostapi/dsound src/hostapi/wasapi src/hostapi src/os src
+
+distclean: clean
+       rm -f config.log config.status Makefile libtool portaudio-2.0.pc
+
+%.o: %.c $(MAKEFILE) $(PAINC)
+       $(CC) -c $(CFLAGS) $< -o $@
+
+%.lo: %.c $(MAKEFILE) $(PAINC)
+       $(LIBTOOL) --mode=compile $(CC) -c $(CFLAGS) $< -o $@
+
+%.o: %.cpp $(MAKEFILE) $(PAINC)
+       $(CXX) -c $(CXXFLAGS) $< -o $@
+
+%.o: %.asm
+       $(NASM) $(NASMOPT) -o $@ $<
+
+bin-stamp:
+       -mkdir bin
+       touch $@
+
+lib-stamp:
+       -mkdir lib
+       -mkdir -p src/os/win src/os/unix src/os/mac_osx src/common \
+src/hostapi/oss src/hostapi/alsa src/hostapi/jack src/hostapi/wmme \
+src/hostapi/wdmks src/hostapi/dsound src/hostapi/wasapi
+       touch $@
+
+Makefile: Makefile.in config.status
+       $(SHELL) config.status
diff --git a/utils/iaxclient/lib/portaudio/README.txt b/utils/iaxclient/lib/portaudio/README.txt
new file mode 100644 (file)
index 0000000..4cfc616
--- /dev/null
@@ -0,0 +1,81 @@
+README for PortAudio
+Implementations for PC DirectSound and Mac SoundManager
+
+/*
+ * PortAudio Portable Real-Time Audio Library
+ * Latest Version at: http://www.portaudio.com//
+ *
+ * Copyright (c) 1999-2000 Phil Burk and Ross Bencina
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+PortAudio is a portable audio I/O library designed for cross-platform
+support of audio. It uses a callback mechanism to request audio processing.
+Audio can be generated in various formats, including 32 bit floating point,
+and will be converted to the native format internally.
+
+Documentation:
+       See "pa_common/portaudio.h" for API spec.
+       See docs folder for a tutorial.
+       Also see http://www.portaudio.com/docs/
+       And see "pa_tests/patest_saw.c" for an example.
+
+For information on compiling programs with PortAudio, please see the
+tutorial at:
+
+  http://www.portaudio.com/docs/pa_tutorial.html
+  
+Important Files and Folders:
+       pa_common/              = platform independant code
+       pa_common/portaudio.h   = header file for PortAudio API. Specifies API.
+       pa_common/pa_lib.c      = host independant code for all implementations.
+
+    pablio                  = simple blocking read/write interface
+    
+Platform Implementations
+    pa_asio                 = ASIO for Windows and Macintosh
+    pa_beos                 = BeOS
+    pa_mac_sm               = Macintosh Sound Manager for OS 8,9 and Carbon
+    pa_mac_core             = Macintosh Core Audio for OS X
+    pa_sgi                  = Silicon Graphics AL
+    pa_unix_oss             = OSS implementation for various Unixes
+    pa_win_ds               = Windows Direct Sound
+    pa_win_wmme             = Windows MME (most widely supported)
+    
+Test Programs
+       pa_tests/pa_fuzz.c = guitar fuzz box
+       pa_tests/pa_devs.c = print a list of available devices
+       pa_tests/pa_minlat.c = determine minimum latency for your machine
+       pa_tests/paqa_devs.c = self test that opens all devices
+       pa_tests/paqa_errs.c = test error detection and reporting
+       pa_tests/patest_clip.c = hear a sine wave clipped and unclipped
+       pa_tests/patest_dither.c = hear effects of dithering (extremely subtle)
+       pa_tests/patest_pink.c = fun with pink noise
+       pa_tests/patest_record.c = record and playback some audio
+       pa_tests/patest_maxsines.c = how many sine waves can we play? Tests Pa_GetCPULoad().
+       pa_tests/patest_sine.c = output a sine wave in a simple PA app
+       pa_tests/patest_sync.c = test syncronization of audio and video
+       pa_tests/patest_wire.c = pass input to output, wire simulator
diff --git a/utils/iaxclient/lib/portaudio/SConstruct b/utils/iaxclient/lib/portaudio/SConstruct
new file mode 100644 (file)
index 0000000..b6d5f56
--- /dev/null
@@ -0,0 +1,147 @@
+import sys, os.path
+
+def rsplit(toSplit, sub, max=-1):
+    """ str.rsplit seems to have been introduced in 2.4 :( """
+    l = []
+    i = 0
+    while i != max:
+        try: idx = toSplit.rindex(sub)
+        except ValueError: break
+
+        toSplit, splitOff = toSplit[:idx], toSplit[idx + len(sub):]
+        l.insert(0, splitOff)
+        i += 1
+
+    l.insert(0, toSplit)
+    return l
+
+sconsDir = os.path.join("build", "scons")
+SConscript(os.path.join(sconsDir, "SConscript_common"))
+Import("Platform", "Posix", "ApiVer")
+
+# SConscript_opts exports PortAudio options
+optsDict = SConscript(os.path.join(sconsDir, "SConscript_opts"))
+optionsCache = os.path.join(sconsDir, "options.cache")   # Save options between runs in this cache
+options = Options(optionsCache, args=ARGUMENTS)
+for k in ("Installation Dirs", "Build Targets", "Host APIs", "Build Parameters", "Bindings"):
+    options.AddOptions(*optsDict[k])
+# Propagate options into environment
+env = Environment(options=options)
+# Save options for next run
+options.Save(optionsCache, env)
+# Generate help text for options
+env.Help(options.GenerateHelpText(env))
+
+buildDir = os.path.join("#", sconsDir, env["PLATFORM"])
+
+# Determine parameters to build tools
+if Platform in Posix:
+    baseLinkFlags = threadCFlags = "-pthread"
+    baseCxxFlags = baseCFlags = "-Wall -pedantic -pipe " + threadCFlags
+    debugCxxFlags = debugCFlags = "-g"
+    optCxxFlags = optCFlags  = "-O2"
+env["CCFLAGS"] = baseCFlags.split()
+env["CXXFLAGS"] = baseCxxFlags.split()
+env["LINKFLAGS"] = baseLinkFlags.split()
+if env["enableDebug"]:
+    env.AppendUnique(CCFLAGS=debugCFlags.split())
+    env.AppendUnique(CXXFLAGS=debugCxxFlags.split())
+if env["enableOptimize"]:
+    env.AppendUnique(CCFLAGS=optCFlags.split())
+    env.AppendUnique(CXXFLAGS=optCxxFlags.split())
+if not env["enableAsserts"]:
+    env.AppendUnique(CPPDEFINES=["-DNDEBUG"])
+if env["customCFlags"]:
+    env.Append(CCFLAGS=env["customCFlags"])
+if env["customCxxFlags"]:
+    env.Append(CXXFLAGS=env["customCxxFlags"])
+if env["customLinkFlags"]:
+    env.Append(LINKFLAGS=env["customLinkFlags"])
+
+env.Append(CPPPATH=[os.path.join("#", "include"), "common"])
+
+# Store all signatures in one file, otherwise .sconsign files will get installed along with our own files
+env.SConsignFile(os.path.join(sconsDir, ".sconsign"))
+
+env.SConscriptChdir(False)
+sources, sharedLib, staticLib, tests, portEnv = env.SConscript(os.path.join("src", "SConscript"),
+        build_dir=buildDir, duplicate=False, exports=["env"])
+
+if Platform in Posix:
+    prefix = env["prefix"]
+    includeDir = os.path.join(prefix, "include")
+    libDir = os.path.join(prefix, "lib")
+    env.Alias("install", includeDir)
+    env.Alias("install", libDir)
+
+    # pkg-config
+
+    def installPkgconfig(env, target, source):
+        tgt = str(target[0])
+        src = str(source[0])
+        f = open(src)
+        try: txt = f.read()
+        finally: f.close()
+        txt = txt.replace("@prefix@", prefix)
+        txt = txt.replace("@exec_prefix@", prefix)
+        txt = txt.replace("@libdir@", libDir)
+        txt = txt.replace("@includedir@", includeDir)
+        txt = txt.replace("@LIBS@", " ".join(["-l%s" % l for l in portEnv["LIBS"]]))
+        txt = txt.replace("@THREAD_CFLAGS@", threadCFlags)
+
+        f = open(tgt, "w")
+        try: f.write(txt)
+        finally: f.close()
+
+    pkgconfigTgt = "portaudio-%d.0.pc" % int(ApiVer.split(".", 1)[0])
+    env.Command(os.path.join(libDir, "pkgconfig", pkgconfigTgt),
+        os.path.join("#", pkgconfigTgt + ".in"), installPkgconfig)
+
+# Default to None, since if the user disables all targets and no Default is set, all targets
+# are built by default
+env.Default(None)
+if env["enableTests"]:
+    env.Default(tests)
+if env["enableShared"]:
+    env.Default(sharedLib)
+
+    if Platform in Posix:
+        def symlink(env, target, source):
+            trgt = str(target[0])
+            src = str(source[0])
+
+            if os.path.islink(trgt) or os.path.exists(trgt):
+                os.remove(trgt)
+            os.symlink(os.path.basename(src), trgt)
+
+        major, minor, micro = [int(c) for c in ApiVer.split(".")]
+        
+        soFile = "%s.%s" % (os.path.basename(str(sharedLib[0])), ApiVer)
+        env.InstallAs(target=os.path.join(libDir, soFile), source=sharedLib)
+        # Install symlinks
+        symTrgt = os.path.join(libDir, soFile)
+        env.Command(os.path.join(libDir, "libportaudio.so.%d.%d" % (major, minor)),
+            symTrgt, symlink)
+        symTrgt = rsplit(symTrgt, ".", 1)[0]
+        env.Command(os.path.join(libDir, "libportaudio.so.%d" % major), symTrgt, symlink)
+        symTrgt = rsplit(symTrgt, ".", 1)[0]
+        env.Command(os.path.join(libDir, "libportaudio.so"), symTrgt, symlink)
+
+if env["enableStatic"]:
+    env.Default(staticLib)
+    env.Install(libDir, staticLib)
+
+env.Install(includeDir, os.path.join("include", "portaudio.h"))
+
+if env["enableCxx"]:
+    env.SConscriptChdir(True)
+    cxxEnv = env.Copy()
+    sharedLibs, staticLibs, headers = env.SConscript(os.path.join("bindings", "cpp", "SConscript"),
+            exports={"env": cxxEnv, "buildDir": buildDir}, build_dir=os.path.join(buildDir, "portaudiocpp"), duplicate=False)
+    if env["enableStatic"]:
+        env.Default(staticLibs)
+        env.Install(libDir, staticLibs)
+    if env["enableShared"]:
+        env.Default(sharedLibs)
+        env.Install(libDir, sharedLibs)
+    env.Install(os.path.join(includeDir, "portaudiocpp"), headers)
diff --git a/utils/iaxclient/lib/portaudio/V19-devel-readme.txt b/utils/iaxclient/lib/portaudio/V19-devel-readme.txt
new file mode 100644 (file)
index 0000000..ae5570e
--- /dev/null
@@ -0,0 +1,222 @@
+STATUS:
+
+MME, DirectSound and ASIO versions are more-or-less working. See FIXMEs @todos
+and the proposals matrix at portaudio.com for further status.
+
+The pa_tests directory contains tests. pa_tests/README.txt notes which tests
+currently build.  
+
+The PaUtil support code is finished enough for other implementations to be
+ported. No changes are expected to be made to the definition of the PaUtil
+functions.
+
+Note that it's not yet 100% clear how the current support functions
+will interact with blocking read/write streams.
+
+BUILD INSTRUCTIONS
+
+to build tests/patest_sine.c you will need to compile and link the following
+files (MME)
+pa_common\pa_process.c
+pa_common\pa_skeleton.c
+pa_common\pa_stream.c
+pa_common\pa_trace.c
+pa_common\pa_converters.c
+pa_common\pa_cpuload.c
+pa_common\pa_dither.c
+pa_common\pa_front.c
+pa_common\pa_allocation.h
+pa_win\pa_win_util.c
+pa_win\pa_win_hostapis.c
+pa_win_wmme\pa_win_wmme.c
+
+see below for a description of these files.
+               
+
+FILES:
+
+portaudio.h
+    public api header file
+
+pa_front.c
+    implements the interface defined in portaudio.h. manages multiple host apis.
+    validates function parameters before calling through to host apis. tracks
+    open streams and closes them at Pa_Terminate().
+
+pa_util.h 
+    declares utility functions for use my implementations. including utility
+    functions which must be implemented separately for each platform.
+
+pa_hostapi.h
+    hostapi representation structure used to interface between pa_front.c
+    and implementations
+    
+pa_stream.c/h
+    stream interface and representation structures and helper functions
+    used to interface between pa_front.c and implementations
+
+pa_cpuload.c/h
+    source and header for cpu load calculation facility
+
+pa_trace.c/h
+    source and header for debug trace log facility
+
+pa_converters.c/h
+    sample buffer conversion facility
+
+pa_dither.c/h
+    dither noise generator
+
+pa_process.c/h
+    callback buffer processing facility including interleave and block adaption
+
+pa_allocation.c/h
+    allocation context for tracking groups of allocations
+
+pa_skeleton.c
+    an skeleton implementation showing how the common code can be used.
+
+pa_win_util.c
+    Win32 implementation of platform specific PaUtil functions (memory allocation,
+    usec clock, Pa_Sleep().)  The file will be used with all Win32 host APIs.
+    
+pa_win_hostapis.c
+    contains the paHostApiInitializers array and an implementation of
+    Pa_GetDefaultHostApi() for win32 builds.
+
+pa_win_wmme.c
+    Win32 host api implementation for the windows multimedia extensions audio API.
+
+pa_win_wmme.h
+    public header file containing interfaces to mme-specific functions and the
+    deviceInfo data structure.
+
+
+CODING GUIDELINES:
+
+naming conventions:
+    #defines begin with PA_
+    #defines local to a file end with _
+    global utility variables begin with paUtil
+    global utility types begin with PaUtil  (including function types)
+    global utility functions begin with PaUtil_
+    static variables end with _
+    static constants begin with const and end with _
+    static funtions have no special prefix/suffix
+
+In general, implementations should declare all of their members static,
+except for their initializer which should be exported. All exported names
+should be preceeded by Pa<MN>_ where MN is the module name, for example
+the windows mme initializer should be named PaWinWmme_Initialize().
+
+Every host api should define an initializer which returns an error code
+and a PaHostApiInterface*. The initializer should only return an error other
+than paNoError if it encounters an unexpected and fatal error (memory allocation
+error for example). In general, there may be conditions under which it returns
+a NULL interface pointer and also returns paNoError. For example, if the ASIO
+implementation detects that ASIO is not installed, it should return a
+NULL interface, and paNoError.
+
+Platform-specific shared functions should begin with Pa<PN>_ where PN is the
+platform name. eg. PaWin_ for windows, PaUnix_ for unix.
+
+The above two conventions should also be followed whenever it is necessary to
+share functions accross multiple source files.
+
+Two utilities for debug messages are provided. The PA_DEBUG macro defined in
+pa_implementation.h provides a simple way to print debug messages to stderr.
+Due to real-time performance issues, PA_DEBUG may not be suitable for use
+within the portaudio processing callback, or in other threads. In such cases
+the event tracing facility provided in pa_trace.h may be more appropriate.
+
+If PA_LOG_API_CALLS is defined, all calls to the public PortAudio API
+will be logged to stderr along with parameter and return values.
+
+
+TODO:
+    (this list is totally out of date)
+    
+    finish coding converter functions in pa_converters.c (anyone?)
+
+    implement block adaption in pa_process.c (phil?)
+
+    fix all current tests to work with new code. this should mostly involve
+    changing PortAudioStream to PaStream, and GetDefaultDeviceID to GetDefaultDevice etc.
+
+    write some new tests to exercise the multi-api functions
+
+    write (doxygen) documentation for pa_trace (phil?)
+
+    remove unused typeids from PaHostAPITypeID
+
+    create a global configuration file which documents which PA_ defines can be
+    used for configuration
+
+    need a coding standard for comment formatting
+
+    migrate directx (phil)
+
+    migrate asio (ross?, stephane?)
+
+    see top of pa_win_wmme.c for MME todo items (ross)
+
+    write style guide document (ross)
+    
+    
+DESIGN ISSUES:
+    (this list is totally out of date)
+    
+    consider removing Pa_ConvertHostApiDeviceIndexToGlobalDeviceIndex() from the API
+
+    switch to new latency parameter mechanism now (?)
+    
+    question: if input or outputDriverInfo structures are passed for a different
+    hostApi from the one being called, do we return an error or just ignore
+    them? (i think return error)
+
+    consider renaming PortAudioCallback to PaStreamCallback
+
+    consider renaming PaError, PaResult
+    
+
+ASSORTED DISORGANISED NOTES:
+
+    NOTE:
+        pa_lib.c performs the following validations for Pa_OpenStream() which we do not currently do:
+        - checks the device info to make sure that the device supports the requested sample rate,
+            it may also change the sample rate to the "closest available" sample rate if it
+            is within a particular error margin
+
+    rationale for breaking up internalPortAudioStream:
+        each implementation has its own requirements and behavior, and should be
+        able to choose the best way to operate without being limited by the
+        constraints imposed by a common infrastructure. in other words the
+        implementations should be able to pick and choose services from the
+        common infrastructure. currently identified services include:
+
+        - cpu load tracking
+        - buffering and conversion service (same code works for input and output)
+            - should support buffer multiplexing (non-integer length input and output buffers)
+            - in-place conversion where possible (only for callback, read/write always copies)
+            - should manage allocation of temporary buffers if necessary
+        - instrumentation (should be able to be disabled): callback count, framesProcessed
+        - common data: magic, streamInterface, callback, userdata
+
+
+- conversion functions: 
+       - should handle temp buffer allocation
+       - dithering (random number state per-stream)
+       - buffer size mismatches
+       - with new buffer slip rules, temp buffers may always be needed
+       - we should aim for in-place conversion wherever possible
+       - does phil's code support in-place conversion?  (yes)              
+
+- dicuss relationship between user and host buffer sizes
+       - completely independent.. individual implementations may constrain
+    host buffer sizes if necessary
+
+
+- discuss device capabilities:
+       - i'd like to be able to request certain information:
+       - channel count for example
+
diff --git a/utils/iaxclient/lib/portaudio/aclocal.m4 b/utils/iaxclient/lib/portaudio/aclocal.m4
new file mode 100644 (file)
index 0000000..9e5b4fd
--- /dev/null
@@ -0,0 +1,6627 @@
+# aclocal.m4 generated automatically by aclocal 1.6.3 -*- Autoconf -*-
+
+# Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
+# 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.
+
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+
+# serial 48 AC_PROG_LIBTOOL
+
+
+# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED)
+# -----------------------------------------------------------
+# If this macro is not defined by Autoconf, define it here.
+m4_ifdef([AC_PROVIDE_IFELSE],
+         [],
+         [m4_define([AC_PROVIDE_IFELSE],
+                [m4_ifdef([AC_PROVIDE_$1],
+                          [$2], [$3])])])
+
+
+# AC_PROG_LIBTOOL
+# ---------------
+AC_DEFUN([AC_PROG_LIBTOOL],
+[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl
+dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX
+dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX.
+  AC_PROVIDE_IFELSE([AC_PROG_CXX],
+    [AC_LIBTOOL_CXX],
+    [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX
+  ])])
+dnl And a similar setup for Fortran 77 support
+  AC_PROVIDE_IFELSE([AC_PROG_F77],
+    [AC_LIBTOOL_F77],
+    [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77
+])])
+
+dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly.
+dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run
+dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both.
+  AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+    [AC_LIBTOOL_GCJ],
+    [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+      [AC_LIBTOOL_GCJ],
+      [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],
+       [AC_LIBTOOL_GCJ],
+      [ifdef([AC_PROG_GCJ],
+            [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])
+       ifdef([A][M_PROG_GCJ],
+            [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])])
+       ifdef([LT_AC_PROG_GCJ],
+            [define([LT_AC_PROG_GCJ],
+               defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])])
+])])# AC_PROG_LIBTOOL
+
+
+# _AC_PROG_LIBTOOL
+# ----------------
+AC_DEFUN([_AC_PROG_LIBTOOL],
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl
+AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Prevent multiple expansion
+define([AC_PROG_LIBTOOL], [])
+])# _AC_PROG_LIBTOOL
+
+
+# AC_LIBTOOL_SETUP
+# ----------------
+AC_DEFUN([AC_LIBTOOL_SETUP],
+[AC_PREREQ(2.50)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+
+AC_REQUIRE([AC_PROG_LN_S])dnl
+AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl
+# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
+AC_REQUIRE([AC_OBJEXT])dnl
+AC_REQUIRE([AC_EXEEXT])dnl
+dnl
+
+AC_LIBTOOL_SYS_MAX_CMD_LEN
+AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+AC_LIBTOOL_OBJDIR
+
+AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
+_LT_AC_PROG_ECHO_BACKSLASH
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g']
+
+# Same as above, but do not quote variable references.
+[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g']
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Constants:
+rm="rm -f"
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+ltmain="$ac_aux_dir/ltmain.sh"
+ofile="$default_ofile"
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+AC_CHECK_TOOL(AR, ar, false)
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+AC_CHECK_TOOL(STRIP, strip, :)
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+test -z "$AS" && AS=as
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$LD" && LD=ld
+test -z "$LN_S" && LN_S="ln -s"
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+test -z "$NM" && NM=nm
+test -z "$SED" && SED=sed
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$RANLIB" && RANLIB=:
+test -z "$STRIP" && STRIP=:
+test -z "$ac_objext" && ac_objext=o
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    AC_PATH_MAGIC
+  fi
+  ;;
+esac
+
+AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no)
+AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL],
+enable_win32_dll=yes, enable_win32_dll=no)
+
+AC_ARG_ENABLE([libtool-lock],
+    [AC_HELP_STRING([--disable-libtool-lock],
+       [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+AC_ARG_WITH([pic],
+    [AC_HELP_STRING([--with-pic],
+       [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+    [pic_mode="$withval"],
+    [pic_mode=default])
+test -z "$pic_mode" && pic_mode=default
+
+# Check if we have a version mismatch between libtool.m4 and ltmain.sh.
+#
+# Note:  This should be in AC_LIBTOOL_SETUP, _after_ $ltmain have been defined.
+#        We also should do it _before_ AC_LIBTOOL_LANG_C_CONFIG that actually
+#        calls AC_LIBTOOL_CONFIG and creates libtool.
+#
+_LT_VERSION_CHECK
+
+# Use C for the default configuration in the libtool script
+tagname=
+AC_LIBTOOL_LANG_C_CONFIG
+_LT_AC_TAGCONFIG
+])# AC_LIBTOOL_SETUP
+
+
+# _LT_VERSION_CHECK
+# -----------------
+AC_DEFUN([_LT_VERSION_CHECK],
+[AC_MSG_CHECKING([for correct ltmain.sh version])
+if test "x$ltmain" = "x" ; then
+  AC_MSG_RESULT(no)
+  AC_MSG_ERROR([
+
+*** @<:@Gentoo@:>@ sanity check failed! ***
+*** \$ltmain is not defined, please check the patch for consistency! ***
+])
+fi
+gentoo_lt_version="1.5.22"
+gentoo_ltmain_version=`sed -n '/^[[    ]]*VERSION=/{s/^[[      ]]*VERSION=//;p;q;}' "$ltmain"`
+if test "x$gentoo_lt_version" != "x$gentoo_ltmain_version" ; then
+  AC_MSG_RESULT(no)
+  AC_MSG_ERROR([
+
+*** @<:@Gentoo@:>@ sanity check failed! ***
+*** libtool.m4 and ltmain.sh have a version mismatch! ***
+*** (libtool.m4 = $gentoo_lt_version, ltmain.sh = $gentoo_ltmain_version) ***
+
+Please run:
+
+  libtoolize --copy --force
+
+if appropriate, please contact the maintainer of this
+package (or your distribution) for help.
+])
+else
+  AC_MSG_RESULT(yes)
+fi
+])# _LT_VERSION_CHECK
+
+
+# _LT_AC_SYS_COMPILER
+# -------------------
+AC_DEFUN([_LT_AC_SYS_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_AC_SYS_COMPILER
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
+AC_DEFUN([_LT_CC_BASENAME],
+[for cc_temp in $1""; do
+  case $cc_temp in
+    compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+    distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+])
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+AC_DEFUN([_LT_COMPILER_BOILERPLATE],
+[ac_outfile=conftest.$ac_objext
+printf "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$rm conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+AC_DEFUN([_LT_LINKER_BOILERPLATE],
+[ac_outfile=conftest.$ac_objext
+printf "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$rm conftest*
+])# _LT_LINKER_BOILERPLATE
+
+
+# _LT_AC_SYS_LIBPATH_AIX
+# ----------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX],
+[AC_LINK_IFELSE(AC_LANG_PROGRAM,[
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; fi],[])
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+])# _LT_AC_SYS_LIBPATH_AIX
+
+
+# _LT_AC_SHELL_INIT(ARG)
+# ----------------------
+AC_DEFUN([_LT_AC_SHELL_INIT],
+[ifdef([AC_DIVERSION_NOTICE],
+            [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
+        [AC_DIVERT_PUSH(NOTICE)])
+$1
+AC_DIVERT_POP
+])# _LT_AC_SHELL_INIT
+
+
+# _LT_AC_PROG_ECHO_BACKSLASH
+# --------------------------
+# Add some code to the start of the generated configure script which
+# will find an echo command which doesn't interpret backslashes.
+AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH],
+[_LT_AC_SHELL_INIT([
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$ECHO in
+X*--fallback-echo)
+  # Remove one level of quotation (which was required for Make).
+  ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
+  ;;
+esac
+
+echo=${ECHO-echo}
+if test "X[$]1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X[$]1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell.
+  exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
+fi
+
+if test "X[$]1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+[$]*
+EOF
+  exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test -z "$ECHO"; then
+if test "X${echo_test_string+set}" != Xset; then
+# find a string as large as possible, as long as the shell can cope with it
+  for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
+    # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+    if (echo_test_string=`eval $cmd`) 2>/dev/null &&
+       echo_test_string=`eval $cmd` &&
+       (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
+    then
+      break
+    fi
+  done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+   echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+   test "X$echo_testing_string" = "X$echo_test_string"; then
+  :
+else
+  # The Solaris, AIX, and Digital Unix default echo programs unquote
+  # backslashes.  This makes it impossible to quote backslashes using
+  #   echo "$something" | sed 's/\\/\\\\/g'
+  #
+  # So, first we look for a working echo in the user's PATH.
+
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for dir in $PATH /usr/ucb; do
+    IFS="$lt_save_ifs"
+    if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+       test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+       echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+       test "X$echo_testing_string" = "X$echo_test_string"; then
+      echo="$dir/echo"
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+
+  if test "X$echo" = Xecho; then
+    # We didn't find a better echo, so look for alternatives.
+    if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+       echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
+       test "X$echo_testing_string" = "X$echo_test_string"; then
+      # This shell has a builtin print -r that does the trick.
+      echo='print -r'
+    elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+        test "X$CONFIG_SHELL" != X/bin/ksh; then
+      # If we have ksh, try running configure again with it.
+      ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+      export ORIGINAL_CONFIG_SHELL
+      CONFIG_SHELL=/bin/ksh
+      export CONFIG_SHELL
+      exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
+    else
+      # Try using printf.
+      echo='printf %s\n'
+      if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+        echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+        test "X$echo_testing_string" = "X$echo_test_string"; then
+       # Cool, printf works
+       :
+      elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+          test "X$echo_testing_string" = 'X\t' &&
+          echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+          test "X$echo_testing_string" = "X$echo_test_string"; then
+       CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+       export CONFIG_SHELL
+       SHELL="$CONFIG_SHELL"
+       export SHELL
+       echo="$CONFIG_SHELL [$]0 --fallback-echo"
+      elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+          test "X$echo_testing_string" = 'X\t' &&
+          echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+          test "X$echo_testing_string" = "X$echo_test_string"; then
+       echo="$CONFIG_SHELL [$]0 --fallback-echo"
+      else
+       # maybe with a smaller string...
+       prev=:
+
+       for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
+         if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
+         then
+           break
+         fi
+         prev="$cmd"
+       done
+
+       if test "$prev" != 'sed 50q "[$]0"'; then
+         echo_test_string=`eval $prev`
+         export echo_test_string
+         exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
+       else
+         # Oops.  We lost completely, so just stick with echo.
+         echo=echo
+       fi
+      fi
+    fi
+  fi
+fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+ECHO=$echo
+if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
+   ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
+fi
+
+AC_SUBST(ECHO)
+])])# _LT_AC_PROG_ECHO_BACKSLASH
+
+
+# _LT_AC_LOCK
+# -----------
+AC_DEFUN([_LT_AC_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+    [AC_HELP_STRING([--disable-libtool-lock],
+       [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.$ac_objext` in
+    *ELF-32*)
+      HPUX_IA64_MODE="32"
+      ;;
+    *ELF-64*)
+      HPUX_IA64_MODE="64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+   if test "$lt_cv_prog_gnu_ld" = yes; then
+    case `/usr/bin/file conftest.$ac_objext` in
+    *32-bit*)
+      LD="${LD-ld} -melf32bsmip"
+      ;;
+    *N32*)
+      LD="${LD-ld} -melf32bmipn32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -melf64bmip"
+      ;;
+    esac
+   else
+    case `/usr/bin/file conftest.$ac_objext` in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+   fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+    *32-bit*)
+      case $host in
+        x86_64-*linux*)
+          LD="${LD-ld} -m elf_i386"
+          ;;
+        ppc64-*linux*|powerpc64-*linux*)
+          LD="${LD-ld} -m elf32ppclinux"
+          ;;
+        s390x-*linux*)
+          LD="${LD-ld} -m elf_s390"
+          ;;
+        sparc64-*linux*)
+          LD="${LD-ld} -m elf32_sparc"
+          ;;
+      esac
+      ;;
+    *64-bit*)
+      case $host in
+        x86_64-*linux*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        ppc*-*linux*|powerpc*-*linux*)
+          LD="${LD-ld} -m elf64ppc"
+          ;;
+        s390*-*linux*)
+          LD="${LD-ld} -m elf64_s390"
+          ;;
+        sparc*-*linux*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_LANG_PUSH(C)
+     AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+     AC_LANG_POP])
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+sparc*-*solaris*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*) LD="${LD-ld} -m elf64_sparc" ;;
+      *)    LD="${LD-ld} -64" ;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw* | *-*-pw32*)
+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+  AC_CHECK_TOOL(AS, as, false)
+  AC_CHECK_TOOL(OBJDUMP, objdump, false)
+  ;;
+  ])
+esac
+
+need_locks="$enable_libtool_lock"
+
+])# _LT_AC_LOCK
+
+
+# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#              [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION],
+[AC_REQUIRE([LT_AC_PROG_SED])
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+  ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$3"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       $2=yes
+     fi
+   fi
+   $rm conftest*
+])
+
+if test x"[$]$2" = xyes; then
+    ifelse([$5], , :, [$5])
+else
+    ifelse([$6], , :, [$6])
+fi
+])# AC_LIBTOOL_COMPILER_OPTION
+
+
+# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#                          [ACTION-SUCCESS], [ACTION-FAILURE])
+# ------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([AC_LIBTOOL_LINKER_OPTION],
+[AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $3"
+   printf "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&AS_MESSAGE_LOG_FD
+       $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         $2=yes
+       fi
+     else
+       $2=yes
+     fi
+   fi
+   $rm conftest*
+   LDFLAGS="$save_LDFLAGS"
+])
+
+if test x"[$]$2" = xyes; then
+    ifelse([$4], , :, [$4])
+else
+    ifelse([$5], , :, [$5])
+fi
+])# AC_LIBTOOL_LINKER_OPTION
+
+
+# AC_LIBTOOL_SYS_MAX_CMD_LEN
+# --------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN],
+[# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+  i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536      # usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[       ]]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    # If test is not a shell built-in, we'll probably end up computing a
+    # maximum length that is only half of the actual maximum length, but
+    # we can't tell.
+    SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+    while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \
+              = "XX$teststring") >/dev/null 2>&1 &&
+           new_result=`expr "X$teststring" : ".*" 2>&1` &&
+           lt_cv_sys_max_cmd_len=$new_result &&
+           test $i != 17 # 1/2 MB should be enough
+    do
+      i=`expr $i + 1`
+      teststring=$teststring$teststring
+    done
+    teststring=
+    # Add a significant safety factor because C++ compilers can tack on massive
+    # amounts of additional arguments before passing them to the linker.
+    # It appears as though 1/2 is a usable value.
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    ;;
+  esac
+])
+if test -n $lt_cv_sys_max_cmd_len ; then
+  AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+  AC_MSG_RESULT(none)
+fi
+])# AC_LIBTOOL_SYS_MAX_CMD_LEN
+
+
+# _LT_AC_CHECK_DLFCN
+# ------------------
+AC_DEFUN([_LT_AC_CHECK_DLFCN],
+[AC_CHECK_HEADERS(dlfcn.h)dnl
+])# _LT_AC_CHECK_DLFCN
+
+
+# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+#                           ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ---------------------------------------------------------------------
+AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF],
+[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
+if test "$cross_compiling" = yes; then :
+  [$4]
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+[#line __oline__ "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL          RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL                DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL                0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW           RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW         DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW       RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW     DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW     0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+    exit (status);
+}]
+EOF
+  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) $1 ;;
+      x$lt_dlneed_uscore) $2 ;;
+      x$lt_dlunknown|x*) $3 ;;
+    esac
+  else :
+    # compilation failed
+    $3
+  fi
+fi
+rm -fr conftest*
+])# _LT_AC_TRY_DLOPEN_SELF
+
+
+# AC_LIBTOOL_DLOPEN_SELF
+# ----------------------
+AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF],
+[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+   ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+   ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    AC_CHECK_LIB([dl], [dlopen],
+               [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ])
+   ;;
+
+  *)
+    AC_CHECK_FUNC([shl_load],
+         [lt_cv_dlopen="shl_load"],
+      [AC_CHECK_LIB([dld], [shl_load],
+           [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"],
+       [AC_CHECK_FUNC([dlopen],
+             [lt_cv_dlopen="dlopen"],
+         [AC_CHECK_LIB([dl], [dlopen],
+               [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+           [AC_CHECK_LIB([svld], [dlopen],
+                 [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+             [AC_CHECK_LIB([dld], [dld_link],
+                   [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"])
+             ])
+           ])
+         ])
+       ])
+      ])
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    AC_CACHE_CHECK([whether a program can dlopen itself],
+         lt_cv_dlopen_self, [dnl
+         _LT_AC_TRY_DLOPEN_SELF(
+           lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+           lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+    ])
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+         lt_cv_dlopen_self_static, [dnl
+         _LT_AC_TRY_DLOPEN_SELF(
+           lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+           lt_cv_dlopen_self_static=no,  lt_cv_dlopen_self_static=cross)
+      ])
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+])# AC_LIBTOOL_DLOPEN_SELF
+
+
+# AC_LIBTOOL_PROG_CC_C_O([TAGNAME])
+# ---------------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler
+AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O],
+[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+  [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+  [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+   $rm -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+     fi
+   fi
+   chmod u+w . 2>&AS_MESSAGE_LOG_FD
+   $rm conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+   $rm out/* && rmdir out
+   cd ..
+   rmdir conftest
+   $rm conftest*
+])
+])# AC_LIBTOOL_PROG_CC_C_O
+
+
+# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME])
+# -----------------------------------------
+# Check to see if we can do hard links to lock some files if needed
+AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS],
+[AC_REQUIRE([_LT_AC_LOCK])dnl
+
+hard_links="nottested"
+if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  AC_MSG_CHECKING([if we can lock with hard links])
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  AC_MSG_RESULT([$hard_links])
+  if test "$hard_links" = no; then
+    AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS
+
+
+# AC_LIBTOOL_OBJDIR
+# -----------------
+AC_DEFUN([AC_LIBTOOL_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+])# AC_LIBTOOL_OBJDIR
+
+
+# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME])
+# ----------------------------------------------
+# Check hardcoding attributes.
+AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_AC_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \
+   test -n "$_LT_AC_TAGVAR(runpath_var, $1)" || \
+   test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
+
+  # We can hardcode non-existant directories.
+  if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+     test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then
+    # Linking always hardcodes the temporary library directory.
+    _LT_AC_TAGVAR(hardcode_action, $1)=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    _LT_AC_TAGVAR(hardcode_action, $1)=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  _LT_AC_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)])
+
+if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH
+
+
+# AC_LIBTOOL_SYS_LIB_STRIP
+# ------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP],
+[striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+   darwin*)
+       if test -n "$STRIP" ; then
+         striplib="$STRIP -x"
+         AC_MSG_RESULT([yes])
+       else
+  AC_MSG_RESULT([no])
+fi
+       ;;
+   *)
+  AC_MSG_RESULT([no])
+    ;;
+  esac
+fi
+])# AC_LIBTOOL_SYS_LIB_STRIP
+
+
+# AC_LIBTOOL_SYS_DYNAMIC_LINKER
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER],
+[AC_MSG_CHECKING([dynamic linker characteristics])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+if test "$GCC" = yes; then
+  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix4* | aix5*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[[01]] | aix4.[[01]].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+          echo ' yes '
+          echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+       :
+      else
+       can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[[45]]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $rm \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  linux*)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      supports_anon_versioning=no
+      case `$LD -v 2>/dev/null` in
+        *\ [01].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+        *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+        *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+        *\ 2.11.*) ;; # other 2.11 versions
+        *) supports_anon_versioning=yes ;;
+      esac
+      if test $supports_anon_versioning = yes; then
+        archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~
+cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+$echo "local: *; };" >> $output_objdir/$libname.ver~
+        $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+      else
+        $archive_expsym_cmds="$archive_cmds"
+      fi
+    else
+      ld_shlibs=no
+    fi
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
+  if test "$GCC" = yes; then
+    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+  else
+    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
+  fi
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+kfreebsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[[123]]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  # Handle Gentoo/FreeBSD as it was Linux
+  case $host_vendor in
+    gentoo)
+      version_type=linux ;;
+    *)
+      version_type=freebsd-$objformat ;;
+  esac
+
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+    linux)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+      soname_spec='${libname}${release}${shared_ext}$major'
+      need_lib_prefix=no
+      need_version=no
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+  freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  freebsd*) # from 4.6 on
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+   hppa*64*)
+     shrext_cmds='.sl'
+     hardcode_into_libs=yes
+     dynamic_linker="$host_os dld.sl"
+     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+     library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+     soname_spec='${libname}${release}${shared_ext}$major'
+     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+     ;;
+   *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+interix3*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+       if test "$lt_cv_prog_gnu_ld" = yes; then
+               version_type=linux
+       else
+               version_type=irix
+       fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,   ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+knetbsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+nto-qnx*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+    *)                         need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[[89]] | openbsd2.[[89]].*)
+       shlibpath_overrides_runpath=no
+       ;;
+      *)
+       shlibpath_overrides_runpath=yes
+       ;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      export_dynamic_flag_spec='${wl}-Blargedynsym'
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+    shlibpath_overrides_runpath=no
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    shlibpath_overrides_runpath=yes
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+       ;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+])# AC_LIBTOOL_SYS_DYNAMIC_LINKER
+
+
+# _LT_AC_TAGCONFIG
+# ----------------
+AC_DEFUN([_LT_AC_TAGCONFIG],
+[AC_ARG_WITH([tags],
+    [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@],
+        [include additional configurations @<:@automatic@:>@])],
+    [tagnames="$withval"])
+
+if test -f "$ltmain" && test -n "$tagnames"; then
+  if test ! -f "${ofile}"; then
+    AC_MSG_WARN([output file `$ofile' does not exist])
+  fi
+
+  if test -z "$LTCC"; then
+    eval "`$SHELL ${ofile} --config | grep '^LTCC='`"
+    if test -z "$LTCC"; then
+      AC_MSG_WARN([output file `$ofile' does not look like a libtool script])
+    else
+      AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile'])
+    fi
+  fi
+  if test -z "$LTCFLAGS"; then
+    eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`"
+  fi
+
+  # Extract list of available tagged configurations in $ofile.
+  # Note that this assumes the entire list is on one line.
+  available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'`
+
+  lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+  for tagname in $tagnames; do
+    IFS="$lt_save_ifs"
+    # Check whether tagname contains only valid characters
+    case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in
+    "") ;;
+    *)  AC_MSG_ERROR([invalid tag name: $tagname])
+       ;;
+    esac
+
+    if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null
+    then
+      AC_MSG_ERROR([tag name \"$tagname\" already exists])
+    fi
+
+    # Update the list of available tags.
+    if test -n "$tagname"; then
+      echo appending configuration tag \"$tagname\" to $ofile
+
+      case $tagname in
+      CXX)
+       if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+           ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+           (test "X$CXX" != "Xg++"))) ; then
+         AC_LIBTOOL_LANG_CXX_CONFIG
+       else
+         tagname=""
+       fi
+       ;;
+
+      F77)
+       if test -n "$F77" && test "X$F77" != "Xno"; then
+         AC_LIBTOOL_LANG_F77_CONFIG
+       else
+         tagname=""
+       fi
+       ;;
+
+      GCJ)
+       if test -n "$GCJ" && test "X$GCJ" != "Xno"; then
+         AC_LIBTOOL_LANG_GCJ_CONFIG
+       else
+         tagname=""
+       fi
+       ;;
+
+      RC)
+       AC_LIBTOOL_LANG_RC_CONFIG
+       ;;
+
+      *)
+       AC_MSG_ERROR([Unsupported tag name: $tagname])
+       ;;
+      esac
+
+      # Append the new tag name to the list of available tags.
+      if test -n "$tagname" ; then
+      available_tags="$available_tags $tagname"
+    fi
+    fi
+  done
+  IFS="$lt_save_ifs"
+
+  # Now substitute the updated list of available tags.
+  if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then
+    mv "${ofile}T" "$ofile"
+    chmod +x "$ofile"
+  else
+    rm -f "${ofile}T"
+    AC_MSG_ERROR([unable to update list of available tagged configurations.])
+  fi
+fi
+])# _LT_AC_TAGCONFIG
+
+
+# AC_LIBTOOL_DLOPEN
+# -----------------
+# enable checks for dlopen support
+AC_DEFUN([AC_LIBTOOL_DLOPEN],
+ [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])
+])# AC_LIBTOOL_DLOPEN
+
+
+# AC_LIBTOOL_WIN32_DLL
+# --------------------
+# declare package support for building win32 DLLs
+AC_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_BEFORE([$0], [AC_LIBTOOL_SETUP])
+])# AC_LIBTOOL_WIN32_DLL
+
+
+# AC_ENABLE_SHARED([DEFAULT])
+# ---------------------------
+# implement the --enable-shared flag
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+AC_DEFUN([AC_ENABLE_SHARED],
+[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE([shared],
+    [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+       [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+       IFS="$lt_save_ifs"
+       if test "X$pkg" = "X$p"; then
+         enable_shared=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_shared=]AC_ENABLE_SHARED_DEFAULT)
+])# AC_ENABLE_SHARED
+
+
+# AC_DISABLE_SHARED
+# -----------------
+# set the default shared flag to --disable-shared
+AC_DEFUN([AC_DISABLE_SHARED],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)
+])# AC_DISABLE_SHARED
+
+
+# AC_ENABLE_STATIC([DEFAULT])
+# ---------------------------
+# implement the --enable-static flag
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+AC_DEFUN([AC_ENABLE_STATIC],
+[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE([static],
+    [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+       [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+       IFS="$lt_save_ifs"
+       if test "X$pkg" = "X$p"; then
+         enable_static=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_static=]AC_ENABLE_STATIC_DEFAULT)
+])# AC_ENABLE_STATIC
+
+
+# AC_DISABLE_STATIC
+# -----------------
+# set the default static flag to --disable-static
+AC_DEFUN([AC_DISABLE_STATIC],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)
+])# AC_DISABLE_STATIC
+
+
+# AC_ENABLE_FAST_INSTALL([DEFAULT])
+# ---------------------------------
+# implement the --enable-fast-install flag
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+AC_DEFUN([AC_ENABLE_FAST_INSTALL],
+[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE([fast-install],
+    [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+    [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+       IFS="$lt_save_ifs"
+       if test "X$pkg" = "X$p"; then
+         enable_fast_install=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT)
+])# AC_ENABLE_FAST_INSTALL
+
+
+# AC_DISABLE_FAST_INSTALL
+# -----------------------
+# set the default to --disable-fast-install
+AC_DEFUN([AC_DISABLE_FAST_INSTALL],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)
+])# AC_DISABLE_FAST_INSTALL
+
+
+# AC_LIBTOOL_PICMODE([MODE])
+# --------------------------
+# implement the --with-pic flag
+# MODE is either `yes' or `no'.  If omitted, it defaults to `both'.
+AC_DEFUN([AC_LIBTOOL_PICMODE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+pic_mode=ifelse($#,1,$1,default)
+])# AC_LIBTOOL_PICMODE
+
+
+# AC_PROG_EGREP
+# -------------
+# This is predefined starting with Autoconf 2.54, so this conditional
+# definition can be removed once we require Autoconf 2.54 or later.
+m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP],
+[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep],
+   [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])
+ EGREP=$ac_cv_prog_egrep
+ AC_SUBST([EGREP])
+])])
+
+
+# AC_PATH_TOOL_PREFIX
+# -------------------
+# find a file program which can recognise shared library
+AC_DEFUN([AC_PATH_TOOL_PREFIX],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] |  ?:[\\/]*])
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word.  This closes a longstanding sh security hole.
+  ac_dummy="ifelse([$2], , $PATH, [$2])"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$1; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+      if test -n "$file_magic_test_file"; then
+       case $deplibs_check_method in
+       "file_magic "*)
+         file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+         MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+         if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+           $EGREP "$file_magic_regex" > /dev/null; then
+           :
+         else
+           cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+         fi ;;
+       esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  AC_MSG_RESULT($MAGIC_CMD)
+else
+  AC_MSG_RESULT(no)
+fi
+])# AC_PATH_TOOL_PREFIX
+
+
+# AC_PATH_MAGIC
+# -------------
+# find a file program which can recognise a shared library
+AC_DEFUN([AC_PATH_MAGIC],
+[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+  else
+    MAGIC_CMD=:
+  fi
+fi
+])# AC_PATH_MAGIC
+
+
+# AC_PROG_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([AC_PROG_LD],
+[AC_ARG_WITH([gnu-ld],
+    [AC_HELP_STRING([--with-gnu-ld],
+       [assume the C compiler uses GNU ld @<:@default=no@:>@])],
+    [test "$withval" = no || with_gnu_ld=yes],
+    [with_gnu_ld=no])
+AC_REQUIRE([LT_AC_PROG_SED])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by $CC])
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [[\\/]]* | ?:[[\\/]]*)
+      re_direlt='/[[^/]][[^/]]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+       test "$with_gnu_ld" != no && break
+       ;;
+      *)
+       test "$with_gnu_ld" != yes && break
+       ;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_PROG_LD_GNU
+])# AC_PROG_LD
+
+
+# AC_PROG_LD_GNU
+# --------------
+AC_DEFUN([AC_PROG_LD_GNU],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# AC_PROG_LD_GNU
+
+
+# AC_PROG_LD_RELOAD_FLAG
+# ----------------------
+# find reload flag for linker
+#   -- PORTME Some linkers may need a different reload flag.
+AC_DEFUN([AC_PROG_LD_RELOAD_FLAG],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+  lt_cv_ld_reload_flag,
+  [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  darwin*)
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
+])# AC_PROG_LD_RELOAD_FLAG
+
+
+# AC_DEPLIBS_CHECK_METHOD
+# -----------------------
+# how to check for library dependencies
+#  -- PORTME fill in with the dynamic library characteristics
+AC_DEFUN([AC_DEPLIBS_CHECK_METHOD],
+[AC_CACHE_CHECK([how to recognise dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix4* | aix5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[[45]]*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump'.
+  lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | kfreebsd*-gnu | dragonfly*)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]']
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix3*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd*)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+nto-qnx*)
+  lt_cv_deplibs_check_method=unknown
+  ;;
+
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+])
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+])# AC_DEPLIBS_CHECK_METHOD
+
+
+# AC_PROG_NM
+# ----------
+# find the pathname to a BSD-compatible name lister
+AC_DEFUN([AC_PROG_NM],
+[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_nm_to_check="${ac_tool_prefix}nm"
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then 
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS="$lt_save_ifs"
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+       # Check to see if the nm accepts a BSD-compat flag.
+       # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+       #   nm: unknown option "B" ignored
+       # Tru64's nm complains that /dev/null is an invalid object file
+       case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+       */dev/null* | *'Invalid file or object type'*)
+         lt_cv_path_NM="$tmp_nm -B"
+         break
+         ;;
+       *)
+         case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+         */dev/null*)
+           lt_cv_path_NM="$tmp_nm -p"
+           break
+           ;;
+         *)
+           lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+           continue # so that we can try to find one that supports BSD flags
+           ;;
+         esac
+         ;;
+       esac
+      fi
+    done
+    IFS="$lt_save_ifs"
+  done
+  test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi])
+NM="$lt_cv_path_NM"
+])# AC_PROG_NM
+
+
+# AC_CHECK_LIBM
+# -------------
+# check for math library
+AC_DEFUN([AC_CHECK_LIBM],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*)
+  # These system don't have libm, or don't need it
+  ;;
+*-ncr-sysv4.3*)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+  AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+  ;;
+*)
+  AC_CHECK_LIB(m, cos, LIBM="-lm")
+  ;;
+esac
+])# AC_CHECK_LIBM
+
+
+# AC_LIBLTDL_CONVENIENCE([DIRECTORY])
+# -----------------------------------
+# sets LIBLTDL to the link flags for the libltdl convenience library and
+# LTDLINCL to the include flags for the libltdl header and adds
+# --enable-ltdl-convenience to the configure arguments.  Note that
+# AC_CONFIG_SUBDIRS is not called here.  If DIRECTORY is not provided,
+# it is assumed to be `libltdl'.  LIBLTDL will be prefixed with
+# '${top_builddir}/' and LTDLINCL will be prefixed with '${top_srcdir}/'
+# (note the single quotes!).  If your package is not flat and you're not
+# using automake, define top_builddir and top_srcdir appropriately in
+# the Makefiles.
+AC_DEFUN([AC_LIBLTDL_CONVENIENCE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  case $enable_ltdl_convenience in
+  no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+  "") enable_ltdl_convenience=yes
+      ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+  esac
+  LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la
+  LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+  # For backwards non-gettext consistent compatibility...
+  INCLTDL="$LTDLINCL"
+])# AC_LIBLTDL_CONVENIENCE
+
+
+# AC_LIBLTDL_INSTALLABLE([DIRECTORY])
+# -----------------------------------
+# sets LIBLTDL to the link flags for the libltdl installable library and
+# LTDLINCL to the include flags for the libltdl header and adds
+# --enable-ltdl-install to the configure arguments.  Note that
+# AC_CONFIG_SUBDIRS is not called here.  If DIRECTORY is not provided,
+# and an installed libltdl is not found, it is assumed to be `libltdl'.
+# LIBLTDL will be prefixed with '${top_builddir}/'# and LTDLINCL with
+# '${top_srcdir}/' (note the single quotes!).  If your package is not
+# flat and you're not using automake, define top_builddir and top_srcdir
+# appropriately in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN([AC_LIBLTDL_INSTALLABLE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  AC_CHECK_LIB(ltdl, lt_dlinit,
+  [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+  [if test x"$enable_ltdl_install" = xno; then
+     AC_MSG_WARN([libltdl not installed, but installation disabled])
+   else
+     enable_ltdl_install=yes
+   fi
+  ])
+  if test x"$enable_ltdl_install" = x"yes"; then
+    ac_configure_args="$ac_configure_args --enable-ltdl-install"
+    LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la
+    LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+  else
+    ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+    LIBLTDL="-lltdl"
+    LTDLINCL=
+  fi
+  # For backwards non-gettext consistent compatibility...
+  INCLTDL="$LTDLINCL"
+])# AC_LIBLTDL_INSTALLABLE
+
+
+# AC_LIBTOOL_CXX
+# --------------
+# enable support for C++ libraries
+AC_DEFUN([AC_LIBTOOL_CXX],
+[AC_REQUIRE([_LT_AC_LANG_CXX])
+])# AC_LIBTOOL_CXX
+
+
+# _LT_AC_LANG_CXX
+# ---------------
+AC_DEFUN([_LT_AC_LANG_CXX],
+[AC_REQUIRE([AC_PROG_CXX])
+AC_REQUIRE([_LT_AC_PROG_CXXCPP])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX])
+])# _LT_AC_LANG_CXX
+
+# _LT_AC_PROG_CXXCPP
+# ------------------
+AC_DEFUN([_LT_AC_PROG_CXXCPP],
+[
+AC_REQUIRE([AC_PROG_CXX])
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
+  AC_PROG_CXXCPP
+fi
+])# _LT_AC_PROG_CXXCPP
+
+# AC_LIBTOOL_F77
+# --------------
+# enable support for Fortran 77 libraries
+AC_DEFUN([AC_LIBTOOL_F77],
+[AC_REQUIRE([_LT_AC_LANG_F77])
+])# AC_LIBTOOL_F77
+
+
+# _LT_AC_LANG_F77
+# ---------------
+AC_DEFUN([_LT_AC_LANG_F77],
+[AC_REQUIRE([AC_PROG_F77])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77])
+])# _LT_AC_LANG_F77
+
+
+# AC_LIBTOOL_GCJ
+# --------------
+# enable support for GCJ libraries
+AC_DEFUN([AC_LIBTOOL_GCJ],
+[AC_REQUIRE([_LT_AC_LANG_GCJ])
+])# AC_LIBTOOL_GCJ
+
+
+# _LT_AC_LANG_GCJ
+# ---------------
+AC_DEFUN([_LT_AC_LANG_GCJ],
+[AC_PROVIDE_IFELSE([AC_PROG_GCJ],[],
+  [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[],
+    [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[],
+      [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])],
+        [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])],
+          [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ])
+])# _LT_AC_LANG_GCJ
+
+
+# AC_LIBTOOL_RC
+# -------------
+# enable support for Windows resource files
+AC_DEFUN([AC_LIBTOOL_RC],
+[AC_REQUIRE([LT_AC_PROG_RC])
+_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC])
+])# AC_LIBTOOL_RC
+
+
+# AC_LIBTOOL_LANG_C_CONFIG
+# ------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG])
+AC_DEFUN([_LT_AC_LANG_C_CONFIG],
+[lt_save_CC="$CC"
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}\n'
+
+_LT_AC_SYS_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1)
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+AC_LIBTOOL_SYS_LIB_STRIP
+AC_LIBTOOL_DLOPEN_SELF
+
+# Report which library types will actually be built
+AC_MSG_CHECKING([if libtool supports shared libraries])
+AC_MSG_RESULT([$can_build_shared])
+
+AC_MSG_CHECKING([whether to build shared libraries])
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case $host_os in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+
+aix4* | aix5*)
+  if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+    test "$enable_shared" = yes && enable_static=no
+  fi
+    ;;
+esac
+AC_MSG_RESULT([$enable_shared])
+
+AC_MSG_CHECKING([whether to build static libraries])
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+AC_MSG_RESULT([$enable_static])
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_POP
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_C_CONFIG
+
+
+# AC_LIBTOOL_LANG_CXX_CONFIG
+# --------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)])
+AC_DEFUN([_LT_AC_LANG_CXX_CONFIG],
+[AC_LANG_PUSH(C++)
+AC_REQUIRE([AC_PROG_CXX])
+AC_REQUIRE([_LT_AC_PROG_CXXCPP])
+
+_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_AC_TAGVAR(allow_undefined_flag, $1)=
+_LT_AC_TAGVAR(always_export_symbols, $1)=no
+_LT_AC_TAGVAR(archive_expsym_cmds, $1)=
+_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_direct, $1)=no
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_AC_TAGVAR(hardcode_automatic, $1)=no
+_LT_AC_TAGVAR(module_cmds, $1)=
+_LT_AC_TAGVAR(module_expsym_cmds, $1)=
+_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_AC_TAGVAR(no_undefined_flag, $1)=
+_LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Dependencies to place before and after the object being linked:
+_LT_AC_TAGVAR(predep_objects, $1)=
+_LT_AC_TAGVAR(postdep_objects, $1)=
+_LT_AC_TAGVAR(predeps, $1)=
+_LT_AC_TAGVAR(postdeps, $1)=
+_LT_AC_TAGVAR(compiler_lib_search_path, $1)=
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }\n'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_LD=$LD
+lt_save_GCC=$GCC
+GCC=$GXX
+lt_save_with_gnu_ld=$with_gnu_ld
+lt_save_path_LD=$lt_cv_path_LD
+if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+  lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+else
+  $as_unset lt_cv_prog_gnu_ld
+fi
+if test -n "${lt_cv_path_LDCXX+set}"; then
+  lt_cv_path_LD=$lt_cv_path_LDCXX
+else
+  $as_unset lt_cv_path_LD
+fi
+test -z "${LDCXX+set}" || LD=$LDCXX
+CC=${CXX-"c++"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+
+# We don't want -fno-exception wen compiling C++ code, so set the
+# no_builtin_flag separately
+if test "$GXX" = yes; then
+  _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+else
+  _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+fi
+
+if test "$GXX" = yes; then
+  # Set up default GNU C++ configuration
+
+  AC_PROG_LD
+
+  # Check if GNU C++ uses GNU ld as the underlying linker, since the
+  # archiving commands below assume that GNU ld is being used.
+  if test "$with_gnu_ld" = yes; then
+    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+    _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+    #     investigate it a little bit more. (MM)
+    wlarc='${wl}'
+
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if eval "`$CC -print-prog-name=ld` --help 2>&1" | \
+       grep 'no-whole-archive' > /dev/null; then
+      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+  else
+    with_gnu_ld=no
+    wlarc=
+
+    # A generic and very simple default shared library creation
+    # command for GNU C++ for the case where it uses the native
+    # linker, instead of GNU ld.  If possible, this setting should
+    # overridden to take advantage of the native linker features on
+    # the platform it is being used on.
+    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+  fi
+
+  # Commands to make compiler produce verbose output that lists
+  # what "hidden" libraries, object files and flags are used when
+  # linking a shared library.
+  output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+else
+  GXX=no
+  with_gnu_ld=no
+  wlarc=
+fi
+
+# PORTME: fill in a description of your system's C++ link characteristics
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+_LT_AC_TAGVAR(ld_shlibs, $1)=yes
+case $host_os in
+  aix3*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  aix4* | aix5*)
+    if test "$host_cpu" = ia64; then
+      # On IA64, the linker does run time linking by default, so we don't
+      # have to do anything special.
+      aix_use_runtimelinking=no
+      exp_sym_flag='-Bexport'
+      no_entry_flag=""
+    else
+      aix_use_runtimelinking=no
+
+      # Test if we are trying to use run time linking or normal
+      # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+      # need to do runtime linking.
+      case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*)
+       for ld_flag in $LDFLAGS; do
+         case $ld_flag in
+         *-brtl*)
+           aix_use_runtimelinking=yes
+           break
+           ;;
+         esac
+       done
+       ;;
+      esac
+
+      exp_sym_flag='-bexport'
+      no_entry_flag='-bnoentry'
+    fi
+
+    # When large executables or shared objects are built, AIX ld can
+    # have problems creating the table of contents.  If linking a library
+    # or program results in "error TOC overflow" add -mminimal-toc to
+    # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+    # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+    _LT_AC_TAGVAR(archive_cmds, $1)=''
+    _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+    _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
+    _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+
+    if test "$GXX" = yes; then
+      case $host_os in aix4.[[012]]|aix4.[[012]].*)
+      # We only want to do this on AIX 4.2 and lower, the check
+      # below for broken collect2 doesn't work under 4.3+
+       collect2name=`${CC} -print-prog-name=collect2`
+       if test -f "$collect2name" && \
+          strings "$collect2name" | grep resolve_lib_name >/dev/null
+       then
+         # We have reworked collect2
+         _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+       else
+         # We have old collect2
+         _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
+         # It fails to find uninstalled libraries when the uninstalled
+         # path is not listed in the libpath.  Setting hardcode_minus_L
+         # to unsupported forces relinking
+         _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+         _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+       fi
+       ;;
+      esac
+      shared_flag='-shared'
+      if test "$aix_use_runtimelinking" = yes; then
+       shared_flag="$shared_flag "'${wl}-G'
+      fi
+    else
+      # not using gcc
+      if test "$host_cpu" = ia64; then
+       # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+       # chokes on -Wl,-G. The following line is correct:
+       shared_flag='-G'
+      else
+       if test "$aix_use_runtimelinking" = yes; then
+         shared_flag='${wl}-G'
+       else
+         shared_flag='${wl}-bM:SRE'
+       fi
+      fi
+    fi
+
+    # It seems that -bexpall does not export symbols beginning with
+    # underscore (_), so it is better to generate a list of symbols to export.
+    _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+    if test "$aix_use_runtimelinking" = yes; then
+      # Warning - without using the other runtime loading flags (-brtl),
+      # -berok will link without error, but may produce a broken library.
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok'
+      # Determine the default libpath from the value encoded in an empty executable.
+      _LT_AC_SYS_LIBPATH_AIX
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+     else
+      if test "$host_cpu" = ia64; then
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+      else
+       # Determine the default libpath from the value encoded in an empty executable.
+       _LT_AC_SYS_LIBPATH_AIX
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+       # Warning - without using the other run time loading flags,
+       # -berok will link without error, but may produce a broken library.
+       _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+       # Exported symbols can be pulled into shared objects from archives
+       _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+       _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+       # This is similar to how AIX traditionally builds its shared libraries.
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+      fi
+    fi
+    ;;
+
+  beos*)
+    if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+      # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+      # support --undefined.  This deserves some investigation.  FIXME
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+    else
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    fi
+    ;;
+
+  chorus*)
+    case $cc_basename in
+      *)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+    esac
+    ;;
+
+  cygwin* | mingw* | pw32*)
+    # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+    # as there is no search path for DLLs.
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+    _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+    _LT_AC_TAGVAR(always_export_symbols, $1)=no
+    _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+    if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      # If the export-symbols file already is a .def file (1st line
+      # is EXPORTS), use it as is; otherwise, prepend...
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+       cp $export_symbols $output_objdir/$soname.def;
+      else
+       echo EXPORTS > $output_objdir/$soname.def;
+       cat $export_symbols >> $output_objdir/$soname.def;
+      fi~
+      $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+    else
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    fi
+  ;;
+      darwin* | rhapsody*)
+        case $host_os in
+        rhapsody* | darwin1.[[012]])
+         _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress'
+         ;;
+       *) # Darwin 1.3 on
+         if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+           _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+         else
+           case ${MACOSX_DEPLOYMENT_TARGET} in
+             10.[[012]])
+               _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+               ;;
+             10.*)
+               _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup'
+               ;;
+           esac
+         fi
+         ;;
+        esac
+      _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_AC_TAGVAR(hardcode_direct, $1)=no
+      _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=''
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+
+    if test "$GXX" = yes ; then
+      lt_int_apple_cc_single_mod=no
+      output_verbose_link_cmd='echo'
+      if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then
+       lt_int_apple_cc_single_mod=yes
+      fi
+      if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+      else
+          _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+        fi
+        _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+        # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+          if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+            _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          else
+            _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          fi
+            _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+      else
+      case $cc_basename in
+        xlc*)
+         output_verbose_link_cmd='echo'
+          _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+          _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+          _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          ;;
+       *)
+         _LT_AC_TAGVAR(ld_shlibs, $1)=no
+          ;;
+      esac
+      fi
+        ;;
+
+  dgux*)
+    case $cc_basename in
+      ec++*)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      ghcx*)
+       # Green Hills C++ Compiler
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      *)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+    esac
+    ;;
+  freebsd[[12]]*)
+    # C++ shared libraries reported to be fairly broken before switch to ELF
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  freebsd-elf*)
+    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+    ;;
+  freebsd* | kfreebsd*-gnu | dragonfly*)
+    # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+    # conventions
+    _LT_AC_TAGVAR(ld_shlibs, $1)=yes
+    ;;
+  gnu*)
+    ;;
+  hpux9*)
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+    _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+    _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+    _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+                               # but as the default
+                               # location of the library.
+
+    case $cc_basename in
+    CC*)
+      # FIXME: insert proper C++ library support
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+    aCC*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      #
+      # There doesn't appear to be a way to prevent this compiler from
+      # explicitly linking system object files so we need to strip them
+      # from the output so that they don't get included in the library
+      # dependencies.
+      output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[[-]]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+      ;;
+    *)
+      if test "$GXX" = yes; then
+        _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+        # FIXME: insert proper C++ library support
+        _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+    esac
+    ;;
+  hpux10*|hpux11*)
+    if test $with_gnu_ld = no; then
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+      case $host_cpu in
+      hppa*64*|ia64*)
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+        ;;
+      *)
+       _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+        ;;
+      esac
+    fi
+    case $host_cpu in
+    hppa*64*|ia64*)
+      _LT_AC_TAGVAR(hardcode_direct, $1)=no
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+    *)
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+                                             # but as the default
+                                             # location of the library.
+      ;;
+    esac
+
+    case $cc_basename in
+      CC*)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      aCC*)
+       case $host_cpu in
+       hppa*64*)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+         ;;
+       ia64*)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+         ;;
+       *)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+         ;;
+       esac
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+       ;;
+      *)
+       if test "$GXX" = yes; then
+         if test $with_gnu_ld = no; then
+           case $host_cpu in
+           hppa*64*)
+             _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+             ;;
+           ia64*)
+             _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+             ;;
+           *)
+             _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+             ;;
+           esac
+         fi
+       else
+         # FIXME: insert proper C++ library support
+         _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       fi
+       ;;
+    esac
+    ;;
+  interix3*)
+    _LT_AC_TAGVAR(hardcode_direct, $1)=no
+    _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+    # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+    # Instead, shared libraries are loaded at an image base (0x10000000 by
+    # default) and relocated if they conflict, which is a slow very memory
+    # consuming and fragmenting process.  To avoid this, we pick a random,
+    # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+    # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+    _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+    ;;
+  irix5* | irix6*)
+    case $cc_basename in
+      CC*)
+       # SGI C++
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+
+       # Archives containing C++ object files must be created using
+       # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+       # necessary to make sure instantiated templates are included
+       # in the archive.
+       _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+       ;;
+      *)
+       if test "$GXX" = yes; then
+         if test "$with_gnu_ld" = no; then
+           _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+         else
+           _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib'
+         fi
+       fi
+       _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+       ;;
+    esac
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+    _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+    ;;
+  linux*)
+    case $cc_basename in
+      KCC*)
+       # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+       # KCC will only create a shared library if the output file
+       # ends with ".so" (or ".sl" for HP-UX), so rename the library
+       # to its proper name (with version) after linking.
+       _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir'
+       _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+       # Archives containing C++ object files must be created using
+       # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+       _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+       ;;
+      icpc*)
+       # Intel C++
+       with_gnu_ld=yes
+       # version 8.0 and above of icpc choke on multiply defined symbols
+       # if we add $predep_objects and $postdep_objects, however 7.1 and
+       # earlier do not add the objects themselves.
+       case `$CC -V 2>&1` in
+       *"Version 7."*)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+         _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+         ;;
+       *)  # Version 8.0 or newer
+         tmp_idyn=
+         case $host_cpu in
+           ia64*) tmp_idyn=' -i_dynamic';;
+         esac
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+         _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+         ;;
+       esac
+       _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+       _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+       _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+       ;;
+      pgCC*)
+        # Portland Group C++ compiler
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+       _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+       _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+        ;;
+      cxx*)
+       # Compaq C++
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+       runpath_var=LD_RUN_PATH
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+       _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+       ;;
+    esac
+    ;;
+  lynxos*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  m88k*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  mvs*)
+    case $cc_basename in
+      cxx*)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      *)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+    esac
+    ;;
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+      wlarc=
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+    fi
+    # Workaround some broken pre-1.5 toolchains
+    output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+    ;;
+  openbsd2*)
+    # C++ shared libraries are fairly broken
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  openbsd*)
+    _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+    _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+    _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+    if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    fi
+    output_verbose_link_cmd='echo'
+    ;;
+  osf3*)
+    case $cc_basename in
+      KCC*)
+       # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+       # KCC will only create a shared library if the output file
+       # ends with ".so" (or ".sl" for HP-UX), so rename the library
+       # to its proper name (with version) after linking.
+       _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+       _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+       # Archives containing C++ object files must be created using
+       # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+       _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+
+       ;;
+      RCC*)
+       # Rational C++ 2.4.1
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      cxx*)
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+       _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+       ;;
+      *)
+       if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+         _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+         _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+         # Commands to make compiler produce verbose output that lists
+         # what "hidden" libraries, object files and flags are used when
+         # linking a shared library.
+         output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+       else
+         # FIXME: insert proper C++ library support
+         _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       fi
+       ;;
+    esac
+    ;;
+  osf4* | osf5*)
+    case $cc_basename in
+      KCC*)
+       # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+       # KCC will only create a shared library if the output file
+       # ends with ".so" (or ".sl" for HP-UX), so rename the library
+       # to its proper name (with version) after linking.
+       _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+       _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+       # Archives containing C++ object files must be created using
+       # the KAI C++ compiler.
+       _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs'
+       ;;
+      RCC*)
+       # Rational C++ 2.4.1
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      cxx*)
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+         echo "-hidden">> $lib.exp~
+         $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp  `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~
+         $rm $lib.exp'
+
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+       _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+       ;;
+      *)
+       if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+         _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+        _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+         _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+         # Commands to make compiler produce verbose output that lists
+         # what "hidden" libraries, object files and flags are used when
+         # linking a shared library.
+         output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+       else
+         # FIXME: insert proper C++ library support
+         _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       fi
+       ;;
+    esac
+    ;;
+  psos*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  sunos4*)
+    case $cc_basename in
+      CC*)
+       # Sun C++ 4.x
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      lcc*)
+       # Lucid
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      *)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+    esac
+    ;;
+  solaris*)
+    case $cc_basename in
+      CC*)
+       # Sun C++ 4.2, 5.x and Centerline C++
+        _LT_AC_TAGVAR(archive_cmds_need_lc,$1)=yes
+       _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+       $CC -G${allow_undefined_flag}  ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+       _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+       case $host_os in
+         solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+         *)
+           # The C++ compiler is used as linker so we must use $wl
+           # flag to pass the commands to the underlying system
+           # linker. We must also pass each convience library through
+           # to the system linker between allextract/defaultextract.
+           # The C++ compiler will combine linker options so we
+           # cannot just pass the convience library names through
+           # without $wl.
+           # Supported since Solaris 2.6 (maybe 2.5.1?)
+           _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract'
+           ;;
+       esac
+       _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+
+       output_verbose_link_cmd='echo'
+
+       # Archives containing C++ object files must be created using
+       # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+       # necessary to make sure instantiated templates are included
+       # in the archive.
+       _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+       ;;
+      gcx*)
+       # Green Hills C++ Compiler
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+       # The C++ compiler must be used to create the archive.
+       _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+       ;;
+      *)
+       # GNU C++ compiler with Solaris linker
+       if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+         _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+         if $CC --version | grep -v '^2\.7' > /dev/null; then
+           _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+           _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+           # Commands to make compiler produce verbose output that lists
+           # what "hidden" libraries, object files and flags are used when
+           # linking a shared library.
+           output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
+         else
+           # g++ 2.7 appears to require `-G' NOT `-shared' on this
+           # platform.
+           _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+           _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+           # Commands to make compiler produce verbose output that lists
+           # what "hidden" libraries, object files and flags are used when
+           # linking a shared library.
+           output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
+         fi
+
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+       fi
+       ;;
+    esac
+    ;;
+  sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+    _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+    _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+    runpath_var='LD_RUN_PATH'
+
+    case $cc_basename in
+      CC*)
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+       ;;
+      *)
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+       ;;
+    esac
+    ;;
+  sysv5* | sco3.2v5* | sco5v6*)
+    # Note: We can NOT use -z defs as we might desire, because we do not
+    # link with -lc, and that would cause any symbols used from libc to
+    # always be unresolved, which means just about no library would
+    # ever link correctly.  If we're not using GNU ld we use -z text
+    # though, which does catch some bad symbols but isn't as heavy-handed
+    # as -z defs.
+    # For security reasons, it is highly recommended that you always
+    # use absolute paths for naming shared libraries, and exclude the
+    # DT_RUNPATH tag from executables and libraries.  But doing so
+    # requires that you compile everything twice, which is a pain.
+    # So that behaviour is only enabled if SCOABSPATH is set to a
+    # non-empty value in the environment.  Most likely only useful for
+    # creating official distributions of packages.
+    # This is a hack until libtool officially supports absolute path
+    # names for shared libraries.
+    _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+    _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+    _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+    _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+    _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
+    _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+    runpath_var='LD_RUN_PATH'
+
+    case $cc_basename in
+      CC*)
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       ;;
+      *)
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       ;;
+    esac
+    ;;
+  tandem*)
+    case $cc_basename in
+      NCC*)
+       # NonStop-UX NCC 3.20
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+      *)
+       # FIXME: insert proper C++ library support
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       ;;
+    esac
+    ;;
+  vxworks*)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+  *)
+    # FIXME: insert proper C++ library support
+    _LT_AC_TAGVAR(ld_shlibs, $1)=no
+    ;;
+esac
+AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)])
+test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_AC_TAGVAR(GCC, $1)="$GXX"
+_LT_AC_TAGVAR(LD, $1)="$LD"
+
+AC_LIBTOOL_POSTDEP_PREDEP($1)
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_POP
+CC=$lt_save_CC
+LDCXX=$LD
+LD=$lt_save_LD
+GCC=$lt_save_GCC
+with_gnu_ldcxx=$with_gnu_ld
+with_gnu_ld=$lt_save_with_gnu_ld
+lt_cv_path_LDCXX=$lt_cv_path_LD
+lt_cv_path_LD=$lt_save_path_LD
+lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+])# AC_LIBTOOL_LANG_CXX_CONFIG
+
+# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME])
+# ------------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library.  It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+ifelse([$1],[],[cat > conftest.$ac_ext <<EOF
+int a;
+void foo (void) { a = 0; }
+EOF
+],[$1],[CXX],[cat > conftest.$ac_ext <<EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+EOF
+],[$1],[F77],[cat > conftest.$ac_ext <<EOF
+      subroutine foo
+      implicit none
+      integer*4 a
+      a=0
+      return
+      end
+EOF
+],[$1],[GCJ],[cat > conftest.$ac_ext <<EOF
+public class foo {
+  private int a;
+  public void bar (void) {
+    a = 0;
+  }
+};
+EOF
+])
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
+
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
+
+  # The `*' in the case matches for architectures that use `case' in
+  # $output_verbose_cmd can trigger glob expansion during the loop
+  # eval without this substitution.
+  output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"`
+
+  for p in `eval $output_verbose_link_cmd`; do
+    case $p in
+
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R}" and the path.
+       # Remove the space.
+       if test $p = "-L" \
+         || test $p = "-R"; then
+        prev=$p
+        continue
+       else
+        prev=
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+        case $p in
+        -L* | -R*)
+          # Internal compiler library paths should come after those
+          # provided the user.  The postdeps already come after the
+          # user supplied libs so there is no need to process them.
+          if test -z "$_LT_AC_TAGVAR(compiler_lib_search_path, $1)"; then
+            _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+          else
+            _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${_LT_AC_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+          fi
+          ;;
+        # The "-l" case would never come before the object being
+        # linked, so don't bother handling this case.
+        esac
+       else
+        if test -z "$_LT_AC_TAGVAR(postdeps, $1)"; then
+          _LT_AC_TAGVAR(postdeps, $1)="${prev}${p}"
+        else
+          _LT_AC_TAGVAR(postdeps, $1)="${_LT_AC_TAGVAR(postdeps, $1)} ${prev}${p}"
+        fi
+       fi
+       ;;
+
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+        pre_test_object_deps_done=yes
+        continue
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+        if test -z "$_LT_AC_TAGVAR(predep_objects, $1)"; then
+          _LT_AC_TAGVAR(predep_objects, $1)="$p"
+        else
+          _LT_AC_TAGVAR(predep_objects, $1)="$_LT_AC_TAGVAR(predep_objects, $1) $p"
+        fi
+       else
+        if test -z "$_LT_AC_TAGVAR(postdep_objects, $1)"; then
+          _LT_AC_TAGVAR(postdep_objects, $1)="$p"
+        else
+          _LT_AC_TAGVAR(postdep_objects, $1)="$_LT_AC_TAGVAR(postdep_objects, $1) $p"
+        fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$rm -f confest.$objext
+
+# PORTME: override above test on systems where it is broken
+ifelse([$1],[CXX],
+[case $host_os in
+interix3*)
+  # Interix 3.5 installs completely hosed .la files for C++, so rather than
+  # hack all around it, let's just trust "g++" to DTRT.
+  _LT_AC_TAGVAR(predep_objects,$1)=
+  _LT_AC_TAGVAR(postdep_objects,$1)=
+  _LT_AC_TAGVAR(postdeps,$1)=
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC*)
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    _LT_AC_TAGVAR(postdeps,$1)='-lCstd -lCrun'
+    ;;
+  esac
+  ;;
+esac
+])
+
+case " $_LT_AC_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+])# AC_LIBTOOL_POSTDEP_PREDEP
+
+# AC_LIBTOOL_LANG_F77_CONFIG
+# --------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG], [_LT_AC_LANG_F77_CONFIG(F77)])
+AC_DEFUN([_LT_AC_LANG_F77_CONFIG],
+[AC_REQUIRE([AC_PROG_F77])
+AC_LANG_PUSH(Fortran 77)
+
+_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_AC_TAGVAR(allow_undefined_flag, $1)=
+_LT_AC_TAGVAR(always_export_symbols, $1)=no
+_LT_AC_TAGVAR(archive_expsym_cmds, $1)=
+_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_direct, $1)=no
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+_LT_AC_TAGVAR(hardcode_automatic, $1)=no
+_LT_AC_TAGVAR(module_cmds, $1)=
+_LT_AC_TAGVAR(module_expsym_cmds, $1)=
+_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_AC_TAGVAR(no_undefined_flag, $1)=
+_LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="      subroutine t\n      return\n      end\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="      program t\n      end\n"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${F77-"f77"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+
+AC_MSG_CHECKING([if libtool supports shared libraries])
+AC_MSG_RESULT([$can_build_shared])
+
+AC_MSG_CHECKING([whether to build shared libraries])
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case $host_os in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+aix4* | aix5*)
+  if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+    test "$enable_shared" = yes && enable_static=no
+  fi
+  ;;
+esac
+AC_MSG_RESULT([$enable_shared])
+
+AC_MSG_CHECKING([whether to build static libraries])
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+AC_MSG_RESULT([$enable_static])
+
+_LT_AC_TAGVAR(GCC, $1)="$G77"
+_LT_AC_TAGVAR(LD, $1)="$LD"
+
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_POP
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_F77_CONFIG
+
+
+# AC_LIBTOOL_LANG_GCJ_CONFIG
+# --------------------------
+# Ensure that the configuration vars for the C compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG], [_LT_AC_LANG_GCJ_CONFIG(GCJ)])
+AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG],
+[AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }\n'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${GCJ-"gcj"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+
+AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1)
+AC_LIBTOOL_PROG_COMPILER_PIC($1)
+AC_LIBTOOL_PROG_CC_C_O($1)
+AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1)
+AC_LIBTOOL_PROG_LD_SHLIBS($1)
+AC_LIBTOOL_SYS_DYNAMIC_LINKER($1)
+AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1)
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_RESTORE
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_GCJ_CONFIG
+
+
+# AC_LIBTOOL_LANG_RC_CONFIG
+# -------------------------
+# Ensure that the configuration vars for the Windows resource compiler are
+# suitably defined.  Those variables are subsequently used by
+# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'.
+AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG], [_LT_AC_LANG_RC_CONFIG(RC)])
+AC_DEFUN([_LT_AC_LANG_RC_CONFIG],
+[AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_AC_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_AC_SYS_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${RC-"windres"}
+compiler=$CC
+_LT_AC_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+AC_LIBTOOL_CONFIG($1)
+
+AC_LANG_RESTORE
+CC="$lt_save_CC"
+])# AC_LIBTOOL_LANG_RC_CONFIG
+
+
+# AC_LIBTOOL_CONFIG([TAGNAME])
+# ----------------------------
+# If TAGNAME is not passed, then create an initial libtool script
+# with a default configuration from the untagged config vars.  Otherwise
+# add code to config.status for appending the configuration named by
+# TAGNAME from the matching tagged config vars.
+AC_DEFUN([AC_LIBTOOL_CONFIG],
+[# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    _LT_AC_TAGVAR(compiler, $1) \
+    _LT_AC_TAGVAR(CC, $1) \
+    _LT_AC_TAGVAR(LD, $1) \
+    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1) \
+    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1) \
+    _LT_AC_TAGVAR(lt_prog_compiler_static, $1) \
+    _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) \
+    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1) \
+    _LT_AC_TAGVAR(thread_safe_flag_spec, $1) \
+    _LT_AC_TAGVAR(whole_archive_flag_spec, $1) \
+    _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) \
+    _LT_AC_TAGVAR(old_archive_cmds, $1) \
+    _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) \
+    _LT_AC_TAGVAR(predep_objects, $1) \
+    _LT_AC_TAGVAR(postdep_objects, $1) \
+    _LT_AC_TAGVAR(predeps, $1) \
+    _LT_AC_TAGVAR(postdeps, $1) \
+    _LT_AC_TAGVAR(compiler_lib_search_path, $1) \
+    _LT_AC_TAGVAR(archive_cmds, $1) \
+    _LT_AC_TAGVAR(archive_expsym_cmds, $1) \
+    _LT_AC_TAGVAR(postinstall_cmds, $1) \
+    _LT_AC_TAGVAR(postuninstall_cmds, $1) \
+    _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) \
+    _LT_AC_TAGVAR(allow_undefined_flag, $1) \
+    _LT_AC_TAGVAR(no_undefined_flag, $1) \
+    _LT_AC_TAGVAR(export_symbols_cmds, $1) \
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) \
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) \
+    _LT_AC_TAGVAR(hardcode_libdir_separator, $1) \
+    _LT_AC_TAGVAR(hardcode_automatic, $1) \
+    _LT_AC_TAGVAR(module_cmds, $1) \
+    _LT_AC_TAGVAR(module_expsym_cmds, $1) \
+    _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) \
+    _LT_AC_TAGVAR(exclude_expsyms, $1) \
+    _LT_AC_TAGVAR(include_expsyms, $1); do
+
+    case $var in
+    _LT_AC_TAGVAR(old_archive_cmds, $1) | \
+    _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) | \
+    _LT_AC_TAGVAR(archive_cmds, $1) | \
+    _LT_AC_TAGVAR(archive_expsym_cmds, $1) | \
+    _LT_AC_TAGVAR(module_cmds, $1) | \
+    _LT_AC_TAGVAR(module_expsym_cmds, $1) | \
+    _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) | \
+    _LT_AC_TAGVAR(export_symbols_cmds, $1) | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\[$]0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\[$]0 --fallback-echo"[$]/[$]0 --fallback-echo"/'`
+    ;;
+  esac
+
+ifelse([$1], [],
+  [cfgfile="${ofile}T"
+  trap "$rm \"$cfgfile\"; exit 1" 1 2 15
+  $rm -f "$cfgfile"
+  AC_MSG_NOTICE([creating $ofile])],
+  [cfgfile="$ofile"])
+
+  cat <<__EOF__ >> "$cfgfile"
+ifelse([$1], [],
+[#! $SHELL
+
+# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+#
+# This file is part of GNU Libtool:
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 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 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.
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="$SED -e 1s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# The names of the tagged configurations supported by this script.
+available_tags=
+
+# ### BEGIN LIBTOOL CONFIG],
+[# ### BEGIN LIBTOOL TAG CONFIG: $tagname])
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
+# A language-specific compiler.
+CC=$lt_[]_LT_AC_TAGVAR(compiler, $1)
+
+# Is the compiler the GNU C compiler?
+with_gcc=$_LT_AC_TAGVAR(GCC, $1)
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_[]_LT_AC_TAGVAR(LD, $1)
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1)
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1)
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1)
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1)
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1)
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1)
+archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1)
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1)
+module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1)
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1)
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1)
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1)
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1)
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1)
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1)
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1)
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1)
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1)
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1)
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1)
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1)
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1)
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1)
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1)
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1)
+
+# Symbols that must always be exported.
+include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1)
+
+ifelse([$1],[],
+[# ### END LIBTOOL CONFIG],
+[# ### END LIBTOOL TAG CONFIG: $tagname])
+
+__EOF__
+
+ifelse([$1],[], [
+  case $host_os in
+  aix3*)
+    cat <<\EOF >> "$cfgfile"
+
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+EOF
+    ;;
+  esac
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1)
+
+  mv -f "$cfgfile" "$ofile" || \
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+])
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+fi
+])# AC_LIBTOOL_CONFIG
+
+
+# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------------------
+AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI],
+[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl
+
+_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test "$GCC" = yes; then
+  _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+
+  AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+    lt_cv_prog_compiler_rtti_exceptions,
+    [-fno-rtti -fno-exceptions], [],
+    [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI
+
+
+# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+# ---------------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE],
+[AC_REQUIRE([AC_CANONICAL_HOST])
+AC_REQUIRE([AC_PROG_NM])
+AC_REQUIRE([AC_OBJEXT])
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Transform an extracted symbol line into a proper C declaration
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[[BCDT]]'
+  ;;
+cygwin* | mingw* | pw32*)
+  symcode='[[ABCDGISTW]]'
+  ;;
+hpux*) # Its linker distinguishes data from code symbols
+  if test "$host_cpu" = ia64; then
+    symcode='[[ABCDEGRST]]'
+  fi
+  lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+  lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+  ;;
+linux*)
+  if test "$host_cpu" = ia64; then
+    symcode='[[ABCDGIRSTW]]'
+    lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+    lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+  fi
+  ;;
+irix* | nonstopux*)
+  symcode='[[BCDEGRST]]'
+  ;;
+osf*)
+  symcode='[[BCDEGQRST]]'
+  ;;
+solaris*)
+  symcode='[[BDRT]]'
+  ;;
+sco3.2v5*)
+  symcode='[[DT]]'
+  ;;
+sysv4.2uw2*)
+  symcode='[[DT]]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[[ABDT]]'
+  ;;
+sysv4)
+  symcode='[[DFNSTU]]'
+  ;;
+esac
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[     ]]\($symcode$symcode*\)[[       ]][[    ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+  if AC_TRY_EVAL(ac_compile); then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+       mv -f "$nlist"T "$nlist"
+      else
+       rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if grep ' nm_test_var$' "$nlist" >/dev/null; then
+       if grep ' nm_test_func$' "$nlist" >/dev/null; then
+         cat <<EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+         # Now generate the symbol file.
+         eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext'
+
+         cat <<EOF >> conftest.$ac_ext
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr_t address;
+}
+lt_preloaded_symbols[[]] =
+{
+EOF
+         $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext
+         cat <<\EOF >> conftest.$ac_ext
+  {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+         # Now try linking the two files.
+         mv conftest.$ac_objext conftstm.$ac_objext
+         lt_save_LIBS="$LIBS"
+         lt_save_CFLAGS="$CFLAGS"
+         LIBS="conftstm.$ac_objext"
+         CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+         if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+           pipe_works=yes
+         fi
+         LIBS="$lt_save_LIBS"
+         CFLAGS="$lt_save_CFLAGS"
+       else
+         echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+       fi
+      else
+       echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+    fi
+  else
+    echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+    cat conftest.$ac_ext >&5
+  fi
+  rm -f conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  AC_MSG_RESULT(failed)
+else
+  AC_MSG_RESULT(ok)
+fi
+]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+
+
+# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME])
+# ---------------------------------------
+AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC],
+[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=
+
+AC_MSG_CHECKING([for $compiler option to produce PIC])
+ ifelse([$1],[CXX],[
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+      ;;
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | os2* | pw32*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+      ;;
+    interix3*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+       ;;
+      *)
+       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+       ;;
+      esac
+      ;;
+    *)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix4* | aix5*)
+       # All AIX code is PIC.
+       if test "$host_cpu" = ia64; then
+         # AIX 5 now supports IA64 processor
+         _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+       else
+         _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+       fi
+       ;;
+      chorus*)
+       case $cc_basename in
+       cxch68*)
+         # Green Hills C++ Compiler
+         # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+         ;;
+       esac
+       ;;
+       darwin*)
+         # PIC is the default on this platform
+         # Common symbols not allowed in MH_DYLIB files
+         case $cc_basename in
+           xlc*)
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon'
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+           ;;
+         esac
+       ;;
+      dgux*)
+       case $cc_basename in
+         ec++*)
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+           ;;
+         ghcx*)
+           # Green Hills C++ Compiler
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      freebsd* | kfreebsd*-gnu | dragonfly*)
+       # FreeBSD uses GNU C++
+       ;;
+      hpux9* | hpux10* | hpux11*)
+       case $cc_basename in
+         CC*)
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+           if test "$host_cpu" != ia64; then
+             _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+           fi
+           ;;
+         aCC*)
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+           case $host_cpu in
+           hppa*64*|ia64*)
+             # +Z the default
+             ;;
+           *)
+             _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+             ;;
+           esac
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      interix*)
+       # This is c89, which is MS Visual C++ (no shared libs)
+       # Anyone wants to do a port?
+       ;;
+      irix5* | irix6* | nonstopux*)
+       case $cc_basename in
+         CC*)
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+           # CC pic flag -KPIC is the default.
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      linux*)
+       case $cc_basename in
+         KCC*)
+           # KAI C++ Compiler
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+           ;;
+         icpc* | ecpc*)
+           # Intel C++
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+           ;;
+         pgCC*)
+           # Portland Group C++ compiler.
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+           ;;
+         cxx*)
+           # Compaq C++
+           # Make sure the PIC flag is empty.  It appears that all Alpha
+           # Linux and Compaq Tru64 Unix objects are PIC.
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      lynxos*)
+       ;;
+      m88k*)
+       ;;
+      mvs*)
+       case $cc_basename in
+         cxx*)
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      netbsd*)
+       ;;
+      osf3* | osf4* | osf5*)
+       case $cc_basename in
+         KCC*)
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+           ;;
+         RCC*)
+           # Rational C++ 2.4.1
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+           ;;
+         cxx*)
+           # Digital/Compaq C++
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+           # Make sure the PIC flag is empty.  It appears that all Alpha
+           # Linux and Compaq Tru64 Unix objects are PIC.
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      psos*)
+       ;;
+      solaris*)
+       case $cc_basename in
+         CC*)
+           # Sun C++ 4.2, 5.x and Centerline C++
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+           ;;
+         gcx*)
+           # Green Hills C++ Compiler
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      sunos4*)
+       case $cc_basename in
+         CC*)
+           # Sun C++ 4.x
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+           ;;
+         lcc*)
+           # Lucid
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      tandem*)
+       case $cc_basename in
+         NCC*)
+           # NonStop-UX NCC 3.20
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+       case $cc_basename in
+         CC*)
+           _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+           _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+           _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+           ;;
+       esac
+       ;;
+      vxworks*)
+       ;;
+      *)
+       _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+       ;;
+    esac
+  fi
+],
+[
+  if test "$GCC" = yes; then
+    _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+      ;;
+
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+
+    interix3*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      enable_shared=no
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+       # +Z the default
+       ;;
+      *)
+       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+       ;;
+      esac
+      ;;
+
+    *)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      else
+       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+      darwin*)
+        # PIC is the default on this platform
+        # Common symbols not allowed in MH_DYLIB files
+       case $cc_basename in
+         xlc*)
+         _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon'
+         _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+         ;;
+       esac
+       ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+       # +Z the default
+       ;;
+      *)
+       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+       ;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC (with -KPIC) is the default.
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    newsos6)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    linux*)
+      case $cc_basename in
+      icc* | ecc*)
+       _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      pgcc* | pgf77* | pgf90* | pgf95*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+       # which looks to be a dead project)
+       _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+        ;;
+      ccc*)
+        _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+        # All Alpha code is PIC.
+        _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+        ;;
+      esac
+      ;;
+
+    osf3* | osf4* | osf5*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # All OSF/1 code is PIC.
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    solaris*)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95*)
+       _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+      *)
+       _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+       _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+       _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    unicos*)
+      _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+
+    uts4*)
+      _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+      _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *)
+      _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+    esac
+  fi
+])
+AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)])
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then
+  AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works],
+    _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1),
+    [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [],
+    [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in
+     "" | " "*) ;;
+     *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+     esac],
+    [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+     _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=
+    ;;
+  *)
+    _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])"
+    ;;
+esac
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_AC_TAGVAR(lt_prog_compiler_static, $1)\"
+AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+  _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1),
+  $lt_tmp_static_flag,
+  [],
+  [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=])
+])
+
+
+# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME])
+# ------------------------------------
+# See if the linker supports building shared libraries.
+AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS],
+[AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+ifelse([$1],[CXX],[
+  _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  case $host_os in
+  aix4* | aix5*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+      _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+    else
+      _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+  ;;
+  cygwin* | mingw*)
+    _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([[^ ]]*\) [[^ ]]*/\1 DATA/;/^I /d;/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  *)
+    _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  esac
+],[
+  runpath_var=
+  _LT_AC_TAGVAR(allow_undefined_flag, $1)=
+  _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+  _LT_AC_TAGVAR(archive_cmds, $1)=
+  _LT_AC_TAGVAR(archive_expsym_cmds, $1)=
+  _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)=
+  _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+  _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+  _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+  _LT_AC_TAGVAR(thread_safe_flag_spec, $1)=
+  _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+  _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+  _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+  _LT_AC_TAGVAR(hardcode_direct, $1)=no
+  _LT_AC_TAGVAR(hardcode_minus_L, $1)=no
+  _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown
+  _LT_AC_TAGVAR(hardcode_automatic, $1)=no
+  _LT_AC_TAGVAR(module_cmds, $1)=
+  _LT_AC_TAGVAR(module_expsym_cmds, $1)=
+  _LT_AC_TAGVAR(always_export_symbols, $1)=no
+  _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  _LT_AC_TAGVAR(include_expsyms, $1)=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_"
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  extract_expsyms_cmds=
+  # Just being paranoid about ensuring that cc_basename is set.
+  _LT_CC_BASENAME([$compiler])
+  case $host_os in
+  cygwin* | mingw* | pw32*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  esac
+
+  _LT_AC_TAGVAR(ld_shlibs, $1)=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+    _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
+       _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+       _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>/dev/null` in
+      *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix3* | aix4* | aix5*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+      fi
+      ;;
+
+    amigaos*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+
+      # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+      # that the semantics of dynamic libraries on AmigaOS, at least up
+      # to version 4, is to share data among multiple programs linked
+      # with the same dynamic library.  Since this doesn't match the
+      # behavior of shared libraries on other platforms, we can't use
+      # them.
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+       # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+       # support --undefined.  This deserves some investigation.  FIXME
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+      # as there is no search path for DLLs.
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_AC_TAGVAR(always_export_symbols, $1)=no
+      _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+        _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+       # If the export-symbols file already is a .def file (1st line
+       # is EXPORTS), use it as is; otherwise, prepend...
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+         cp $export_symbols $output_objdir/$soname.def;
+       else
+         echo EXPORTS > $output_objdir/$soname.def;
+         cat $export_symbols >> $output_objdir/$soname.def;
+       fi~
+       $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    interix3*)
+      _LT_AC_TAGVAR(hardcode_direct, $1)=no
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    linux*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       tmp_addflag=
+       case $cc_basename,$host_cpu in
+       pgcc*)                          # Portland Group C compiler
+         _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+         tmp_addflag=' $pic_flag'
+         ;;
+       pgf77* | pgf90* | pgf95*)       # Portland Group f77 and f90 compilers
+         _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+         tmp_addflag=' $pic_flag -Mnomain' ;;
+       ecc*,ia64* | icc*,ia64*)                # Intel C compiler on ia64
+         tmp_addflag=' -i_dynamic' ;;
+       efc*,ia64* | ifort*,ia64*)      # Intel Fortran compiler on ia64
+         tmp_addflag=' -i_dynamic -nofor_main' ;;
+       ifc* | ifort*)                  # Intel Fortran compiler
+         tmp_addflag=' -nofor_main' ;;
+       esac
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+       if test $supports_anon_versioning = yes; then
+         _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~
+  cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+  $echo "local: *; };" >> $output_objdir/$libname.ver~
+         $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+       fi
+      else
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+       wlarc=
+      else
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) 
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+       cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+       ;;
+       *)
+         if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+           _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+           _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
+           _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
+         else
+           _LT_AC_TAGVAR(ld_shlibs, $1)=no
+         fi
+       ;;
+      esac
+      ;;
+
+    sunos4*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+       _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+    esac
+
+    if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no; then
+      runpath_var=
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=
+      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+       # Neither direct hardcoding nor static linking is supported with a
+       # broken collect2.
+       _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
+      fi
+      ;;
+
+    aix4* | aix5*)
+      if test "$host_cpu" = ia64; then
+       # On IA64, the linker does run time linking by default, so we don't
+       # have to do anything special.
+       aix_use_runtimelinking=no
+       exp_sym_flag='-Bexport'
+       no_entry_flag=""
+      else
+       # If we're using GNU nm, then we don't want the "-C" option.
+       # -C means demangle to AIX nm, but means don't demangle with GNU nm
+       if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+         _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+       else
+         _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols'
+       fi
+       aix_use_runtimelinking=no
+
+       # Test if we are trying to use run time linking or normal
+       # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+       # need to do runtime linking.
+       case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*)
+         for ld_flag in $LDFLAGS; do
+         if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+           aix_use_runtimelinking=yes
+           break
+         fi
+         done
+         ;;
+       esac
+
+       exp_sym_flag='-bexport'
+       no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      _LT_AC_TAGVAR(archive_cmds, $1)=''
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+
+      if test "$GCC" = yes; then
+       case $host_os in aix4.[[012]]|aix4.[[012]].*)
+       # We only want to do this on AIX 4.2 and lower, the check
+       # below for broken collect2 doesn't work under 4.3+
+         collect2name=`${CC} -print-prog-name=collect2`
+         if test -f "$collect2name" && \
+          strings "$collect2name" | grep resolve_lib_name >/dev/null
+         then
+         # We have reworked collect2
+         _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+         else
+         # We have old collect2
+         _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported
+         # It fails to find uninstalled libraries when the uninstalled
+         # path is not listed in the libpath.  Setting hardcode_minus_L
+         # to unsupported forces relinking
+         _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+         _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=
+         fi
+         ;;
+       esac
+       shared_flag='-shared'
+       if test "$aix_use_runtimelinking" = yes; then
+         shared_flag="$shared_flag "'${wl}-G'
+       fi
+      else
+       # not using gcc
+       if test "$host_cpu" = ia64; then
+       # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+       # chokes on -Wl,-G. The following line is correct:
+         shared_flag='-G'
+       else
+         if test "$aix_use_runtimelinking" = yes; then
+           shared_flag='${wl}-G'
+         else
+           shared_flag='${wl}-bM:SRE'
+         fi
+       fi
+      fi
+
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      _LT_AC_TAGVAR(always_export_symbols, $1)=yes
+      if test "$aix_use_runtimelinking" = yes; then
+       # Warning - without using the other runtime loading flags (-brtl),
+       # -berok will link without error, but may produce a broken library.
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok'
+       # Determine the default libpath from the value encoded in an empty executable.
+       _LT_AC_SYS_LIBPATH_AIX
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+       else
+       if test "$host_cpu" = ia64; then
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+         _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+         _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+       else
+        # Determine the default libpath from the value encoded in an empty executable.
+        _LT_AC_SYS_LIBPATH_AIX
+        _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+         # Warning - without using the other run time loading flags,
+         # -berok will link without error, but may produce a broken library.
+         _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+         _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+         # Exported symbols can be pulled into shared objects from archives
+         _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+         _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+         # This is similar to how AIX traditionally builds its shared libraries.
+         _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+       fi
+      fi
+      ;;
+
+    amigaos*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      # see comment about different semantics on the GNU ld section
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+
+    bsdi[[45]]*)
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true'
+      # FIXME: Should let the user specify the lib program.
+      _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs'
+      _LT_AC_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`'
+      _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      ;;
+
+    darwin* | rhapsody*)
+      case $host_os in
+        rhapsody* | darwin1.[[012]])
+         _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress'
+         ;;
+       *) # Darwin 1.3 on
+         if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+           _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+         else
+           case ${MACOSX_DEPLOYMENT_TARGET} in
+             10.[[012]])
+               _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+               ;;
+             10.*)
+               _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup'
+               ;;
+           esac
+         fi
+         ;;
+      esac
+      _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_AC_TAGVAR(hardcode_direct, $1)=no
+      _LT_AC_TAGVAR(hardcode_automatic, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+      _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=''
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+    if test "$GCC" = yes ; then
+       output_verbose_link_cmd='echo'
+        _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+      _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+      _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+      _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    else
+      case $cc_basename in
+        xlc*)
+         output_verbose_link_cmd='echo'
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+         _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+         _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          ;;
+       *)
+         _LT_AC_TAGVAR(ld_shlibs, $1)=no
+          ;;
+      esac
+    fi
+      ;;
+
+    dgux*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    freebsd1*)
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | kfreebsd*-gnu | dragonfly*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+       _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+       _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+       _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+       _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+       # hardcode_minus_L: Not really in the search PATH,
+       # but as the default location of the library.
+       _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+       case $host_cpu in
+       hppa*64*)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       ia64*)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       *)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       esac
+      else
+       case $host_cpu in
+       hppa*64*)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       ia64*)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       *)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       esac
+      fi
+      if test "$with_gnu_ld" = no; then
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+       _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+
+       case $host_cpu in
+       hppa*64*|ia64*)
+         _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+         _LT_AC_TAGVAR(hardcode_direct, $1)=no
+         _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+         ;;
+       *)
+         _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+         _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+         # hardcode_minus_L: Not really in the search PATH,
+         # but as the default location of the library.
+         _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+         ;;
+       esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    newsos6)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    openbsd*)
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+       _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      else
+       case $host_os in
+        openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+          _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+          _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+          ;;
+        *)
+          _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+          _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+          ;;
+       esac
+      fi
+      ;;
+
+    os2*)
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    osf4* | osf5*)     # as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      else
+       _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+       $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp'
+
+       # Both c and cxx compiler support -rpath directly
+       _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    solaris*)
+      _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text'
+      if test "$GCC" = yes; then
+       wlarc='${wl}'
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+         $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
+      else
+       wlarc=''
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+       $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      case $host_os in
+      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+      *)
+       # The compiler driver will combine linker options so we
+       # cannot just pass the convience library names through
+       # without $wl, iff we do not link with $LD.
+       # Luckily, gcc supports the same syntax we need for Sun Studio.
+       # Supported since Solaris 2.6 (maybe 2.5.1?)
+       case $wlarc in
+       '')
+         _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;;
+       *)
+         _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;;
+       esac ;;
+      esac
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+       # Use $CC to link under sequent, because it throws in some extra .o
+       # files that make .init and .fini sections work.
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_direct, $1)=yes
+      _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+       sni)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+         _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+       ;;
+       siemens)
+         ## LD is ld it makes a PLAMLIB
+         ## CC just makes a GrossModule.
+         _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+         _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+         _LT_AC_TAGVAR(hardcode_direct, $1)=no
+        ;;
+       motorola)
+         _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+         _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+       ;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4.3*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+       _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+       runpath_var=LD_RUN_PATH
+       hardcode_runpath_var=yes
+       _LT_AC_TAGVAR(ld_shlibs, $1)=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7*)
+      _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+      _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+      _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_AC_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      _LT_AC_TAGVAR(ld_shlibs, $1)=no
+      ;;
+    esac
+  fi
+])
+AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)])
+test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+  # Assume -lc should be added
+  _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $_LT_AC_TAGVAR(archive_cmds, $1) in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      AC_MSG_CHECKING([whether -lc should be explicitly linked in])
+      $rm conftest*
+      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)
+       pic_flag=$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1)
+        _LT_AC_TAGVAR(allow_undefined_flag, $1)=
+        if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1)
+        then
+         _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no
+        else
+         _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes
+        fi
+        _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $rm conftest*
+      AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)])
+      ;;
+    esac
+  fi
+  ;;
+esac
+])# AC_LIBTOOL_PROG_LD_SHLIBS
+
+
+# _LT_AC_FILE_LTDLL_C
+# -------------------
+# Be careful that the start marker always follows a newline.
+AC_DEFUN([_LT_AC_FILE_LTDLL_C], [
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# #ifndef __CYGWIN__
+# #  ifdef __CYGWIN32__
+# #    define __CYGWIN__ __CYGWIN32__
+# #  endif
+# #endif
+#
+# #ifdef __cplusplus
+# extern "C" {
+# #endif
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+# #ifdef __cplusplus
+# }
+# #endif
+#
+# #ifdef __CYGWIN__
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# #endif
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+#   __hDllInstance_base = hInst;
+#   return TRUE;
+# }
+# /* ltdll.c ends here */
+])# _LT_AC_FILE_LTDLL_C
+
+
+# _LT_AC_TAGVAR(VARNAME, [TAGNAME])
+# ---------------------------------
+AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])])
+
+
+# old names
+AC_DEFUN([AM_PROG_LIBTOOL],   [AC_PROG_LIBTOOL])
+AC_DEFUN([AM_ENABLE_SHARED],  [AC_ENABLE_SHARED($@)])
+AC_DEFUN([AM_ENABLE_STATIC],  [AC_ENABLE_STATIC($@)])
+AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+AC_DEFUN([AM_PROG_LD],        [AC_PROG_LD])
+AC_DEFUN([AM_PROG_NM],        [AC_PROG_NM])
+
+# This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])
+
+AC_DEFUN([LT_AC_PROG_GCJ],
+[AC_CHECK_TOOL(GCJ, gcj, no)
+  test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+  AC_SUBST(GCJFLAGS)
+])
+
+AC_DEFUN([LT_AC_PROG_RC],
+[AC_CHECK_TOOL(RC, windres, no)
+])
+
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_SED.  When it is available in   #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+# LT_AC_PROG_SED
+# --------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible.  Prefer GNU sed if found.
+AC_DEFUN([LT_AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for lt_ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+        lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+      fi
+    done
+  done
+done
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+  test ! -f $lt_ac_sed && continue
+  cat /dev/null > conftest.in
+  lt_ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+  # Check for GNU sed and select it if it is found.
+  if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+    lt_cv_path_SED=$lt_ac_sed
+    break
+  fi
+  while true; do
+    cat conftest.in conftest.in >conftest.tmp
+    mv conftest.tmp conftest.in
+    cp conftest.in conftest.nl
+    echo >>conftest.nl
+    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+    cmp -s conftest.out conftest.nl || break
+    # 10000 chars as input seems more than enough
+    test $lt_ac_count -gt 10 && break
+    lt_ac_count=`expr $lt_ac_count + 1`
+    if test $lt_ac_count -gt $lt_ac_max; then
+      lt_ac_max=$lt_ac_count
+      lt_cv_path_SED=$lt_ac_sed
+    fi
+  done
+done
+])
+SED=$lt_cv_path_SED
+AC_MSG_RESULT([$SED])
+])
+
+# pkg.m4 - Macros to locate and utilise pkg-config.            -*- Autoconf -*-
+# 
+# Copyright Â© 2004 Scott James Remnant <scott@netsplit.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.
+#
+# 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.
+
+# PKG_PROG_PKG_CONFIG([MIN-VERSION])
+# ----------------------------------
+AC_DEFUN([PKG_PROG_PKG_CONFIG],
+[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+       AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+fi
+if test -n "$PKG_CONFIG"; then
+       _pkg_min_version=m4_default([$1], [0.9.0])
+       AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+       if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+               AC_MSG_RESULT([yes])
+       else
+               AC_MSG_RESULT([no])
+               PKG_CONFIG=""
+       fi
+               
+fi[]dnl
+])# PKG_PROG_PKG_CONFIG
+
+# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+#
+# Check to see whether a particular set of modules exists.  Similar
+# to PKG_CHECK_MODULES(), but does not set variables or print errors.
+#
+#
+# Similar to PKG_CHECK_MODULES, make sure that the first instance of
+# this or PKG_CHECK_MODULES is called, or make sure to call
+# PKG_CHECK_EXISTS manually
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_EXISTS],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+if test -n "$PKG_CONFIG" && \
+    AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
+  m4_ifval([$2], [$2], [:])
+m4_ifvaln([$3], [else
+  $3])dnl
+fi])
+
+
+# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+# ---------------------------------------------
+m4_define([_PKG_CONFIG],
+[if test -n "$PKG_CONFIG"; then
+    if test -n "$$1"; then
+        pkg_cv_[]$1="$$1"
+    else
+        PKG_CHECK_EXISTS([$3],
+                         [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
+                        [pkg_failed=yes])
+    fi
+else
+       pkg_failed=untried
+fi[]dnl
+])# _PKG_CONFIG
+
+# _PKG_SHORT_ERRORS_SUPPORTED
+# -----------------------------
+AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi[]dnl
+])# _PKG_SHORT_ERRORS_SUPPORTED
+
+
+# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+# [ACTION-IF-NOT-FOUND])
+#
+#
+# Note that if there is a possibility the first call to
+# PKG_CHECK_MODULES might not happen, you should be sure to include an
+# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+#
+#
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_MODULES],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
+AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
+
+pkg_failed=no
+AC_MSG_CHECKING([for $1])
+
+_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
+_PKG_CONFIG([$1][_LIBS], [libs], [$2])
+
+m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
+and $1[]_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.])
+
+if test $pkg_failed = yes; then
+        _PKG_SHORT_ERRORS_SUPPORTED
+        if test $_pkg_short_errors_supported = yes; then
+               $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"`
+        else 
+               $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
+        fi
+       # Put the nasty error message in config.log where it belongs
+       echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
+
+       ifelse([$4], , [AC_MSG_ERROR(dnl
+[Package requirements ($2) were not met:
+
+$$1_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+_PKG_TEXT
+])],
+               [$4])
+elif test $pkg_failed = untried; then
+       ifelse([$4], , [AC_MSG_FAILURE(dnl
+[The pkg-config script could not be found or is too old.  Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+_PKG_TEXT
+
+To get pkg-config, see <http://www.freedesktop.org/software/pkgconfig>.])],
+               [$4])
+else
+       $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
+       $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
+        AC_MSG_RESULT([yes])
+       ifelse([$3], , :, [$3])
+fi[]dnl
+])# PKG_CHECK_MODULES
+
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/CHANGELOG b/utils/iaxclient/lib/portaudio/bindings/cpp/CHANGELOG
new file mode 100644 (file)
index 0000000..0201a0f
--- /dev/null
@@ -0,0 +1,178 @@
+Note: Because PortAudioCpp is now in the main PortAudio SVN repository, having these per-release changelogs probably doesn't make much sense anymore. Perhaps it's better to just note mayor changes by date from now on.\r
+\r
+PortAudioCpp v19 revision 16 06/05/22:\r
+\r
+       mblaauw:\r
+       - Added up-to-date MSVC 6.0 projects created by David Moore. Besides MSVC 6.0 users, MSVC 7.0 users may use these projects and automatically convert them to MSVC 7.0 projects.\r
+       - Changed the code and projects (MSVC 7.1 only) to be up-to-date with PortAudio's new directory structure.\r
+       - Added equivalents of the PaAsio_GetInputChannelName() and PaAsio_GetOutputChannelName() functions to the AsioDeviceAdapter wrapper-class (missing functions pointed out by David Moore).\r
+       - Added code to PortAudio's main SVN repository.\r
+\r
+PortAudioCpp v19 revision 15 (unknown release date):\r
+\r
+       mblaauw:\r
+       - Changed some exception handling code in HostApi's constructor.\r
+       - Added accessors to PortAudio PaStream from PortAudioCpp Stream (their absense being pointed out\r
+       by Tom Jordan).\r
+       - Fixed a bug/typo in MemFunToCallbackInterfaceAdapter::init() thanks to Fredrik Viklund.\r
+       - Fixed issue with concrete Stream classes possibly throwing an exception and fixed documentation w.r.t. this.\r
+       - Moved files to portaudio/binding/cpp/. Made new msvc 7.1 projects to reflect the change and removed msvc 6.0 \r
+       and 7.0 projects (because I can no longer maintain them myself). Gnu projects will probably need updating.\r
+\r
+PortAudioCpp v19 revision 14 03/10/24:\r
+\r
+       mblaauw:\r
+       - Fixed some error handling bugs in Stream and System (pointed out by Tom Jordan).\r
+       - Updated documentation a little (main page).\r
+       - Fixed order of members so initializer list was in the right order in \r
+       StreamParameters (pointed out by Ludwig Schwardt).\r
+       - Added new lines at EOF's (as indicated by Ludwig Schwardt).\r
+\r
+PortAudioCpp v19 revision 13 03/10/19:\r
+\r
+       lschwardt:\r
+       - Added build files for GNU/Linux.\r
+       - Fixed bug in Exception where the inherited what() member function (and destructor) had looser \r
+       exception specification (namely no exception specification, i.e. could throw anything) than \r
+       the std::exception base class's what() member function (which had throw(), i.e. no-throw guarantee).\r
+       - Changed the iterators so that they have a set of public typedefs instead of deriving the C++ standard \r
+       library std::iterator<> struct. G++ 2.95 doesn't support std::exception<> and composition-by-aggregation \r
+       is prefered over composition-by-inheritance in this case.\r
+       - Changed some minor things to avoid G++ warning messages.\r
+\r
+       mblaauw:\r
+       - Renamed this file (/WHATSNEW.txt) to /CHANGELOG.\r
+       - Renamed /PA_ISSUES.txt to /PA_ISSUES.\r
+       - Added /INSTALL file with some build info for GNU/Linux and VC6.\r
+       - Added MSVC 6.0 projects for building PortAudioCpp as a staticly or dynamically linkable library.\r
+       - Moved build files to /build/(gnu/ or vc6/).\r
+       - Moved Doxygen configuration files to /doc/ and output to /doc/api_reference/.\r
+       - Added a /doc/README with some info how to generate Doxygen documentation.\r
+\r
+PortAudioCpp v19 revision 12 03/09/02:\r
+\r
+       mblaauw:\r
+       - Updated code to reflect changes on V19-devel CVS branch.\r
+       - Fixed some typos in the documentation.\r
+\r
+PortAudioCpp v19 revision 11 03/07/31:\r
+\r
+       mblaauw:\r
+       - Renamed SingleDirecionStreamParameters to DirectionSpecificStreamParameters.\r
+       - Implemented BlockingStream.\r
+       - Updated code to reflect recent changes to PortAudio V19-devel.\r
+       - Fixed a potential memory leak when an exception was thrown in the HostApi \r
+       constructor.\r
+       - Renamed ``Latency'' to ``BufferSize'' in AsioDeviceAdapter.\r
+       - Updated class documentation.\r
+\r
+PortAudioCpp v19 revision 10 03/07/18:\r
+\r
+       mblaauw:\r
+       - SingleDirectionStreamParameters now has a (static) null() method.\r
+       - StreamParameters uses references for the direction-specific stream parameters \r
+       instead of pointers (use null() method (above) instead of NULL).\r
+       - StreamParameters and SingleDirectionStreamParameters must now be fully specified \r
+       and now default values are used (because this was not very useful in general and \r
+       only made things more complex).\r
+       - Updated documentation.\r
+\r
+PortAudioCpp v19 revision 09 03/06/25:\r
+\r
+       mblaauw:\r
+       - Changed some things in SingleDirectionStreamParameters to ease it's usage.\r
+       - Placed all SingleDirectionStreamParameters stuff into a separate file.\r
+       + Totally redid the callback stuff, now it's less ackward and supports C++ functions.\r
+\r
+PortAudioCpp v19 revision 08 03/06/20:\r
+\r
+       mblaauw:\r
+       - Made deconstructors for Device and HostApi private.\r
+       + Added a AsioDeviceWrapper host api specific device extension class.\r
+       - Refactored Exception into a Exception base class and PaException and PaCppException \r
+       derived classes.\r
+       - Added ASIO specific device info to the devs.cxx example.\r
+       - Fixed a bug in System::hostApiCount() and System::defaultHostApi().\r
+       + Moved Device::null to System::nullDevice.\r
+       - Fixed some bugs in Device and System.\r
+\r
+PortAudioCpp v19 revision 07 03/06/08:\r
+\r
+       mblaauw:\r
+       - Updated some doxy comments.\r
+       + Renamed CbXyz to CallbackXyz.\r
+       + Renamed all ``configurations'' to ``parameters''.\r
+       + Renamed HalfDuplexStreamConfiguration to SingleDirectionStreamConfiguration.\r
+       - Renamed SingleDirectionStreamParameters::streamParameters() to \r
+       SingleDirectionStreamParameters::paSteamParameters.\r
+       - Added a non-constant version of SingleDirectionStreamParameters::paStreamParameters().\r
+       - A few improvements to SingleDirectionStreamParameters.\r
+       - Allowed AutoSystem to be created without initializing the System singleton \r
+       (using a ctor flag).\r
+       - Added a BlockingStream class (not implemented for now).\r
+       - Fixed many bugs in the implementation of the iterators.\r
+       - Fixed a bug in Device::operator==().\r
+       + Added a C++ version of the patest_sine.c test/example.\r
+       - Added a ctor for StreamParameters for a default half-duplex stream.\r
+       - Added SingleDirectionStreamParameters::setDevice() and setNumChannels().\r
+       - Renamed System::numHostApis() to System::hostApiCount().\r
+       + Rewrote the iterators and related classes. They are now fully STL compliant. The System now \r
+       has a static array of all HostApis and all Devices. Only the System can create HostApis and \r
+       Devices and they are non-copyable now. All HostApis and Devices are now passed by-reference.\r
+       - Renamed (System::) getVersion() to version() and getVersionText() to versionText().\r
+       - Renamed (Device::) numXyzChannels() to maxXyzChannels().\r
+       - Changed some stuff in StreamParameters.\r
+       + Added a C++ version of the patest_devs.c test/example.\r
+\r
+PortAudioCpp v19 revision 06 03/06/04:\r
+\r
+       mblaauw:\r
+       + Added this file to the project (roughly, a `+' denotes a major change, a `-' a minor change).\r
+       - Added System::deviceByIndex(), useful when a Device's index is stored for instance.\r
+       - Renamed System::hostApiFromTypeId() to System::hostApiByTypeId().\r
+       - Updated and added some Doxygen documentation.\r
+       - Made Stream::usedIntputLatency(), Stream::usedOutputLatency() and \r
+       Stream::usedSampleRate() throw an paInternalError equivalent exception instead of paBadStreamPtr.\r
+       - Changed exception handling in Stream::open() functions. They now follow the PA error handling \r
+       mechanism better and a couple of bugs regarding ownership of objects were fixed.\r
+       - Renamed Device::isDefaultXyzDevice() to Device::isSystemDefaultXyzDevice().\r
+       - Added Device::isHostApiDefaultXyzDevice().\r
+       - Added StreamConfiguration::unsetFlag().\r
+       - Removed CUSTOM from SampleDataFormat.\r
+       - System::hostApiByTypeId() now throws an paInternalError if the type id was out-of-range; this \r
+       is a temporary work-around (see comments).\r
+       - Changed CbInterface to use paCallbackFun() instead of operator()().\r
+       - Renamed ``object'' to ``instance'' in CbMemFunAdapter.hxx.\r
+       - Added StreamConfiguration::setXyzHostApiSpecificSampleFormat().\r
+       - Added StreamConfiguration::isXyzSampleFormatHostApiSpecific().\r
+       - Changed error handling in System::terminate(), it can now throw an Exception.\r
+       - Added error handling in System::defaultHostApi().\r
+       - Added error handling in System::hostApisEnd().\r
+       - Changed some (but probably not all) C casts to C++ casts to avoid confusion with a \r
+       certain Python person.\r
+       - Renamed RaiiSystem to AutoSystem (class and file) as this is a come common convention.\r
+       - Renamed System::numDevices() to System::deviceCount() to be more compatible with PortAudio \r
+       (although PortAudio uses Pa_CountDevices() instead, see comment).\r
+       - Renamed HostApi::numDevices() to HostApi::deviceCount().\r
+       - Changed INC_ to INCLUDED_ in the header multiple include guards.\r
+       - Changed the order of functions in the StreamConfiguration class' header.\r
+       - Written some more info in PortAudioCpp.hxx (Doxygen).\r
+       - Added CallbackStream.hxx and CallbackStream.cxx files.\r
+       + Refactored StreamConfiguration to remove the duplication which was there. There is now a \r
+       HalfDuplexStreamConfiguration class. Also made some improvements to these classes while \r
+       doing the refactoring.\r
+       + Moved all code files to source/portaudiocpp/ and changed includes.\r
+       + Moved all header files to include/portaudiocpp/ to easy a binary build if needed. The project \r
+       must be set to have .../include/ as a path to look for includes.\r
+       + Refactored the Stream class into a Stream base class and a CallbackStream derived class.\r
+       - Renamed Stream::usingXyz() to Stream::xyz().\r
+       - Updated some doxy comments.\r
+       - Changed ``using namespace portaudio'' in .cxx files to ``namespace portaudio { ... }''.\r
+\r
+PortAudioCpp v19 revision 05 03/04/09:\r
+\r
+       mblaauw:\r
+       - Initial release on the PortAudio mailinglist.\r
+\r
+\r
+\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/SConscript b/utils/iaxclient/lib/portaudio/bindings/cpp/SConscript
new file mode 100644 (file)
index 0000000..9beb183
--- /dev/null
@@ -0,0 +1,41 @@
+import os.path
+
+Import("env", "buildDir")
+env.Append(CPPPATH="include")
+
+ApiVer = "0.0.12"
+Major, Minor, Micro = [int(c) for c in ApiVer.split(".")]
+
+sharedLibs = []
+staticLibs = []
+Import("Platform", "Posix")
+if Platform in Posix:
+    env["SHLIBSUFFIX"] = ".so.%d.%d.%d" % (Major, Minor, Micro)
+    soFile = "libportaudiocpp.so"
+    env.AppendUnique(SHLINKFLAGS="-Wl,-soname=%s.%d" % (soFile, Major))
+
+    # Create symlinks
+    def symlink(env, target, source):
+        trgt = str(target[0])
+        src = str(source[0])
+        if os.path.islink(trgt) or os.path.exists(trgt):
+            os.remove(trgt)
+        os.symlink(os.path.basename(src), trgt)
+    lnk0 = env.Command(soFile + ".%d" % (Major), soFile + ".%d.%d.%d" % (Major, Minor, Micro), symlink)
+    lnk1 = env.Command(soFile, soFile + ".%d" % (Major), symlink)
+    sharedLibs.append(lnk0)
+    sharedLibs.append(lnk1)
+
+src = [os.path.join("source", "portaudiocpp", "%s.cxx" % f) for f in ("BlockingStream", "CallbackInterface", \
+    "CallbackStream", "CFunCallbackStream","CppFunCallbackStream", "Device",
+    "DirectionSpecificStreamParameters", "Exception", "HostApi", "InterfaceCallbackStream",
+    "MemFunCallbackStream", "Stream", "StreamParameters", "System", "SystemDeviceIterator",
+    "SystemHostApiIterator")]
+env.Append(LIBS="portaudio", LIBPATH=buildDir)
+sharedLib = env.SharedLibrary("portaudiocpp", src, LIBS=["portaudio"])
+staticLib = env.Library("portaudiocpp", src, LIBS=["portaudio"])
+sharedLibs.append(sharedLib)
+staticLibs.append(staticLib)
+from glob import glob
+headers = [File(f) for f in glob(os.path.join("include", "portaudiocpp", "*"))]
+Return("sharedLibs", "staticLibs", "headers")
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/doc/README b/utils/iaxclient/lib/portaudio/bindings/cpp/doc/README
new file mode 100644 (file)
index 0000000..5e22972
--- /dev/null
@@ -0,0 +1,34 @@
+GNU/Linux:\r
+----------\r
+\r
+1) Download and install a recent version of Doxygen (preferably version 1.3.3 or \r
+later). See http://www.doxygen.org/.\r
+2) Download and install a recent version of GraphViz. See \r
+http://www.research.att.com/sw/tools/graphviz/.\r
+3) Run ``doxygen config.doxy.linux'' in this directory or load and generate the file \r
+config.doxy.linux from the Doxywizard application. Or alternatively ``make docs'' can \r
+be run from the build/gnu folder.\r
+\r
+The generated html documentation will be placed in /doc/api_reference/. To open \r
+the main page of the documentation, open the file /doc/api_reference/index.html in \r
+an html browser.\r
+\r
+\r
+Windows:\r
+--------\r
+\r
+1) Download and install a recent Doxygen (preferably version 1.3.4 or later). See \r
+http://www.doxygen.org/.\r
+2) Download and install a recent version of GraphViz. See \r
+http://www.research.att.com/sw/tools/graphviz/.\r
+3) If needed, edit the config.doxy file in an ascii text editor so that \r
+``DOT_PATH'' variable points to the folder where GraphViz is installed.\r
+4) Run ``doxygen config.doxy'' in this directory or load and generate the file \r
+config.doxy from the Doxywizard application.\r
+\r
+The generated html documentation will be placed in /doc/api_reference/. To open \r
+the main page of the documentation, open the file /doc/api_reference/index.html in \r
+an html browser.\r
+\r
+\r
+\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/doc/config.doxy b/utils/iaxclient/lib/portaudio/bindings/cpp/doc/config.doxy
new file mode 100644 (file)
index 0000000..0bfe9d3
--- /dev/null
@@ -0,0 +1,211 @@
+# Doxyfile 1.3.6
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME           = PortAudioCpp
+PROJECT_NUMBER         = 2.0
+OUTPUT_DIRECTORY       = ./
+OUTPUT_LANGUAGE        = English
+USE_WINDOWS_ENCODING   = YES
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ABBREVIATE_BRIEF       = 
+ALWAYS_DETAILED_SEC    = YES
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = NO
+STRIP_FROM_PATH        = 
+SHORT_NAMES            = YES
+JAVADOC_AUTOBRIEF      = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP         = YES
+INHERIT_DOCS           = YES
+DISTRIBUTE_GROUP_DOC   = NO
+TAB_SIZE               = 4
+ALIASES                = 
+OPTIMIZE_OUTPUT_FOR_C  = NO
+OPTIMIZE_OUTPUT_JAVA   = NO
+SUBGROUPING            = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = YES
+EXTRACT_PRIVATE        = YES
+EXTRACT_STATIC         = YES
+EXTRACT_LOCAL_CLASSES  = YES
+HIDE_UNDOC_MEMBERS     = NO
+HIDE_UNDOC_CLASSES     = NO
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = NO
+CASE_SENSE_NAMES       = YES
+HIDE_SCOPE_NAMES       = NO
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = NO
+SORT_BRIEF_DOCS        = NO
+SORT_BY_SCOPE_NAME     = NO
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = YES
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET                  = NO
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_DOC_ERROR      = YES
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           = 
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT                  = ../source \
+                         ../include
+FILE_PATTERNS          = *.hxx \
+                         *.cxx
+RECURSIVE              = YES
+EXCLUDE                = 
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = 
+EXAMPLE_PATH           = 
+EXAMPLE_PATTERNS       = 
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             = 
+INPUT_FILTER           = 
+FILTER_SOURCE_FILES    = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = NO
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION    = YES
+VERBATIM_HEADERS       = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = YES
+COLS_IN_ALPHA_INDEX    = 2
+IGNORE_PREFIX          = 
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML          = YES
+HTML_OUTPUT            = api_reference
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            = 
+HTML_FOOTER            = 
+HTML_STYLESHEET        = 
+HTML_ALIGN_MEMBERS     = YES
+GENERATE_HTMLHELP      = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = NO
+TREEVIEW_WIDTH         = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = NO
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = NO
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             = 
+XML_DTD                = 
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = NO
+EXPAND_ONLY_PREDEF     = NO
+SEARCH_INCLUDES        = YES
+INCLUDE_PATH           = 
+INCLUDE_FILE_PATTERNS  = 
+PREDEFINED             = 
+EXPAND_AS_DEFINED      = 
+SKIP_FUNCTION_MACROS   = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+TAGFILES               = 
+GENERATE_TAGFILE       = 
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = YES
+HIDE_UNDOC_RELATIONS   = YES
+HAVE_DOT               = YES
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = YES
+UML_LOOK               = YES
+TEMPLATE_RELATIONS     = YES
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = NO
+GRAPHICAL_HIERARCHY    = YES
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = "c:/Program Files/ATT/Graphviz/bin/"
+DOTFILE_DIRS           = 
+MAX_DOT_GRAPH_WIDTH    = 1024
+MAX_DOT_GRAPH_HEIGHT   = 1024
+MAX_DOT_GRAPH_DEPTH    = 0
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+SEARCHENGINE           = NO
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/doc/config.doxy.linux b/utils/iaxclient/lib/portaudio/bindings/cpp/doc/config.doxy.linux
new file mode 100644 (file)
index 0000000..38079f6
--- /dev/null
@@ -0,0 +1,210 @@
+# Doxyfile 1.3.3\r
+\r
+#---------------------------------------------------------------------------\r
+# General configuration options\r
+#---------------------------------------------------------------------------\r
+PROJECT_NAME           = PortAudioCpp\r
+PROJECT_NUMBER         = 2.0\r
+OUTPUT_DIRECTORY       = ./\r
+OUTPUT_LANGUAGE        = English\r
+USE_WINDOWS_ENCODING   = YES\r
+EXTRACT_ALL            = YES\r
+EXTRACT_PRIVATE        = YES\r
+EXTRACT_STATIC         = YES\r
+EXTRACT_LOCAL_CLASSES  = YES\r
+HIDE_UNDOC_MEMBERS     = NO\r
+HIDE_UNDOC_CLASSES     = NO\r
+HIDE_FRIEND_COMPOUNDS  = NO\r
+HIDE_IN_BODY_DOCS      = NO\r
+BRIEF_MEMBER_DESC      = YES\r
+REPEAT_BRIEF           = YES\r
+ALWAYS_DETAILED_SEC    = YES\r
+INLINE_INHERITED_MEMB  = NO\r
+FULL_PATH_NAMES        = NO\r
+STRIP_FROM_PATH        = \r
+INTERNAL_DOCS          = NO\r
+CASE_SENSE_NAMES       = YES\r
+SHORT_NAMES            = YES\r
+HIDE_SCOPE_NAMES       = NO\r
+SHOW_INCLUDE_FILES     = YES\r
+JAVADOC_AUTOBRIEF      = NO\r
+MULTILINE_CPP_IS_BRIEF = NO\r
+DETAILS_AT_TOP         = YES\r
+INHERIT_DOCS           = YES\r
+INLINE_INFO            = YES\r
+SORT_MEMBER_DOCS       = NO\r
+DISTRIBUTE_GROUP_DOC   = NO\r
+TAB_SIZE               = 4\r
+GENERATE_TODOLIST      = YES\r
+GENERATE_TESTLIST      = YES\r
+GENERATE_BUGLIST       = YES\r
+GENERATE_DEPRECATEDLIST= YES\r
+ALIASES                = \r
+ENABLED_SECTIONS       = \r
+MAX_INITIALIZER_LINES  = 30\r
+OPTIMIZE_OUTPUT_FOR_C  = NO\r
+OPTIMIZE_OUTPUT_JAVA   = NO\r
+SHOW_USED_FILES        = YES\r
+SUBGROUPING            = YES\r
+#---------------------------------------------------------------------------\r
+# configuration options related to warning and progress messages\r
+#---------------------------------------------------------------------------\r
+QUIET                  = NO\r
+WARNINGS               = YES\r
+WARN_IF_UNDOCUMENTED   = YES\r
+WARN_IF_DOC_ERROR      = YES\r
+WARN_FORMAT            = "$file:$line: $text"\r
+WARN_LOGFILE           = \r
+#---------------------------------------------------------------------------\r
+# configuration options related to the input files\r
+#---------------------------------------------------------------------------\r
+INPUT                  = ../source \\r
+                         ../include\r
+FILE_PATTERNS          = *.hxx \\r
+                         *.cxx\r
+RECURSIVE              = YES\r
+EXCLUDE                = \r
+EXCLUDE_SYMLINKS       = NO\r
+EXCLUDE_PATTERNS       = \r
+EXAMPLE_PATH           = \r
+EXAMPLE_PATTERNS       = \r
+EXAMPLE_RECURSIVE      = NO\r
+IMAGE_PATH             = \r
+INPUT_FILTER           = \r
+FILTER_SOURCE_FILES    = NO\r
+#---------------------------------------------------------------------------\r
+# configuration options related to source browsing\r
+#---------------------------------------------------------------------------\r
+SOURCE_BROWSER         = NO\r
+INLINE_SOURCES         = NO\r
+STRIP_CODE_COMMENTS    = YES\r
+REFERENCED_BY_RELATION = YES\r
+REFERENCES_RELATION    = YES\r
+VERBATIM_HEADERS       = YES\r
+#---------------------------------------------------------------------------\r
+# configuration options related to the alphabetical class index\r
+#---------------------------------------------------------------------------\r
+ALPHABETICAL_INDEX     = YES\r
+COLS_IN_ALPHA_INDEX    = 2\r
+IGNORE_PREFIX          = \r
+#---------------------------------------------------------------------------\r
+# configuration options related to the HTML output\r
+#---------------------------------------------------------------------------\r
+GENERATE_HTML          = YES\r
+HTML_OUTPUT            = api_reference\r
+HTML_FILE_EXTENSION    = .html\r
+HTML_HEADER            = \r
+HTML_FOOTER            = \r
+HTML_STYLESHEET        = \r
+HTML_ALIGN_MEMBERS     = YES\r
+GENERATE_HTMLHELP      = NO\r
+CHM_FILE               = \r
+HHC_LOCATION           = \r
+GENERATE_CHI           = NO\r
+BINARY_TOC             = NO\r
+TOC_EXPAND             = NO\r
+DISABLE_INDEX          = NO\r
+ENUM_VALUES_PER_LINE   = 4\r
+GENERATE_TREEVIEW      = NO\r
+TREEVIEW_WIDTH         = 250\r
+#---------------------------------------------------------------------------\r
+# configuration options related to the LaTeX output\r
+#---------------------------------------------------------------------------\r
+GENERATE_LATEX         = NO\r
+LATEX_OUTPUT           = latex\r
+LATEX_CMD_NAME         = latex\r
+MAKEINDEX_CMD_NAME     = makeindex\r
+COMPACT_LATEX          = NO\r
+PAPER_TYPE             = a4wide\r
+EXTRA_PACKAGES         = \r
+LATEX_HEADER           = \r
+PDF_HYPERLINKS         = NO\r
+USE_PDFLATEX           = NO\r
+LATEX_BATCHMODE        = NO\r
+LATEX_HIDE_INDICES     = NO\r
+#---------------------------------------------------------------------------\r
+# configuration options related to the RTF output\r
+#---------------------------------------------------------------------------\r
+GENERATE_RTF           = NO\r
+RTF_OUTPUT             = rtf\r
+COMPACT_RTF            = NO\r
+RTF_HYPERLINKS         = NO\r
+RTF_STYLESHEET_FILE    = \r
+RTF_EXTENSIONS_FILE    = \r
+#---------------------------------------------------------------------------\r
+# configuration options related to the man page output\r
+#---------------------------------------------------------------------------\r
+GENERATE_MAN           = NO\r
+MAN_OUTPUT             = man\r
+MAN_EXTENSION          = .3\r
+MAN_LINKS              = NO\r
+#---------------------------------------------------------------------------\r
+# configuration options related to the XML output\r
+#---------------------------------------------------------------------------\r
+GENERATE_XML           = NO\r
+XML_OUTPUT             = xml\r
+XML_SCHEMA             = \r
+XML_DTD                = \r
+#---------------------------------------------------------------------------\r
+# configuration options for the AutoGen Definitions output\r
+#---------------------------------------------------------------------------\r
+GENERATE_AUTOGEN_DEF   = NO\r
+#---------------------------------------------------------------------------\r
+# configuration options related to the Perl module output\r
+#---------------------------------------------------------------------------\r
+GENERATE_PERLMOD       = NO\r
+PERLMOD_LATEX          = NO\r
+PERLMOD_PRETTY         = YES\r
+PERLMOD_MAKEVAR_PREFIX = \r
+#---------------------------------------------------------------------------\r
+# Configuration options related to the preprocessor   \r
+#---------------------------------------------------------------------------\r
+ENABLE_PREPROCESSING   = YES\r
+MACRO_EXPANSION        = NO\r
+EXPAND_ONLY_PREDEF     = NO\r
+SEARCH_INCLUDES        = YES\r
+INCLUDE_PATH           = \r
+INCLUDE_FILE_PATTERNS  = \r
+PREDEFINED             = \r
+EXPAND_AS_DEFINED      = \r
+SKIP_FUNCTION_MACROS   = YES\r
+#---------------------------------------------------------------------------\r
+# Configuration::addtions related to external references   \r
+#---------------------------------------------------------------------------\r
+TAGFILES               = \r
+GENERATE_TAGFILE       = \r
+ALLEXTERNALS           = NO\r
+EXTERNAL_GROUPS        = YES\r
+PERL_PATH              = /usr/bin/perl\r
+#---------------------------------------------------------------------------\r
+# Configuration options related to the dot tool   \r
+#---------------------------------------------------------------------------\r
+CLASS_DIAGRAMS         = YES\r
+HIDE_UNDOC_RELATIONS   = YES\r
+HAVE_DOT               = YES\r
+CLASS_GRAPH            = YES\r
+COLLABORATION_GRAPH    = YES\r
+UML_LOOK               = YES\r
+TEMPLATE_RELATIONS     = YES\r
+INCLUDE_GRAPH          = YES\r
+INCLUDED_BY_GRAPH      = YES\r
+CALL_GRAPH             = NO\r
+GRAPHICAL_HIERARCHY    = YES\r
+DOT_IMAGE_FORMAT       = png\r
+DOT_PATH               = "/usr/bin/dot"\r
+DOTFILE_DIRS           = \r
+MAX_DOT_GRAPH_WIDTH    = 1024\r
+MAX_DOT_GRAPH_HEIGHT   = 1024\r
+MAX_DOT_GRAPH_DEPTH    = 0\r
+GENERATE_LEGEND        = YES\r
+DOT_CLEANUP            = YES\r
+#---------------------------------------------------------------------------\r
+# Configuration::addtions related to the search engine   \r
+#---------------------------------------------------------------------------\r
+SEARCHENGINE           = NO\r
+CGI_NAME               = search.cgi\r
+CGI_URL                = \r
+DOC_URL                = \r
+DOC_ABSPATH            = \r
+BIN_ABSPATH            = /usr/local/bin/\r
+EXT_DOC_PATHS          = \r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/example/devs.cxx b/utils/iaxclient/lib/portaudio/bindings/cpp/example/devs.cxx
new file mode 100644 (file)
index 0000000..31a560f
--- /dev/null
@@ -0,0 +1,177 @@
+#include <iostream>
+#include "portaudiocpp/PortAudioCpp.hxx"
+
+#ifdef WIN32
+#include "portaudiocpp/AsioDeviceAdapter.hxx"
+#endif
+
+// ---------------------------------------------------------------------------------------
+
+void printSupportedStandardSampleRates(
+               const portaudio::DirectionSpecificStreamParameters &inputParameters, 
+               const portaudio::DirectionSpecificStreamParameters &outputParameters)
+{
+       static double STANDARD_SAMPLE_RATES[] = {
+               8000.0, 9600.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0,
+               44100.0, 48000.0, 88200.0, 96000.0, -1 }; // negative terminated list
+
+       int printCount = 0;
+
+       for (int i = 0; STANDARD_SAMPLE_RATES[i] > 0; ++i)
+       {
+               portaudio::StreamParameters tmp = portaudio::StreamParameters(inputParameters, outputParameters, STANDARD_SAMPLE_RATES[i], 0, paNoFlag);
+
+               if (tmp.isSupported())
+               {
+                       if (printCount == 0)
+                       {
+                               std::cout << "    " << STANDARD_SAMPLE_RATES[i]; // 8.2
+                               printCount = 1;
+                       }
+                       else if (printCount == 4)
+                       {
+                               std::cout << "," << std::endl;
+                               std::cout << "    " << STANDARD_SAMPLE_RATES[i]; // 8.2
+                               printCount = 1;
+                       }
+                       else
+                       {
+                               std::cout << ", " << STANDARD_SAMPLE_RATES[i]; // 8.2
+                               ++printCount;
+                       }
+               }
+       }
+
+       if (printCount == 0)
+               std::cout << "None" << std::endl;
+       else
+               std::cout << std::endl;
+}
+
+// ---------------------------------------------------------------------------------------
+
+int main(int, char*[]);
+int main(int, char*[])
+{
+       try
+       {
+               portaudio::AutoSystem autoSys;
+
+               portaudio::System &sys = portaudio::System::instance();
+
+               std::cout << "PortAudio version number = " << sys.version() << std::endl;
+               std::cout << "PortAudio version text = '" << sys.versionText() << "'" << std::endl;
+
+               int numDevices = sys.deviceCount();
+               std::cout << "Number of devices = " << numDevices << std::endl;
+
+               for (portaudio::System::DeviceIterator i = sys.devicesBegin(); i != sys.devicesEnd(); ++i)
+               {
+                       std::cout << "--------------------------------------- device #" << (*i).index() << std::endl;
+
+                       // Mark global and API specific default devices:
+                       bool defaultDisplayed = false;
+
+                       if ((*i).isSystemDefaultInputDevice())
+                       {
+                               std::cout << "[ Default Input";
+                               defaultDisplayed = true;
+                       }
+                       else if ((*i).isHostApiDefaultInputDevice())
+                       {
+                               std::cout << "[ Default " << (*i).hostApi().name() << " Input";
+                               defaultDisplayed = true;
+                       }
+
+                       if ((*i).isSystemDefaultOutputDevice())
+                       {
+                               std::cout << (defaultDisplayed ? "," : "[");
+                               std::cout << " Default Output";
+                               defaultDisplayed = true;
+                       }
+                       else if ((*i).isHostApiDefaultOutputDevice())
+                       {
+                               std::cout << (defaultDisplayed ? "," : "[");
+                               std::cout << " Default " << (*i).hostApi().name() << " Output";
+                               defaultDisplayed = true;
+                       }
+                       
+                       if (defaultDisplayed)
+                               std::cout << " ]" << std::endl;
+
+                       // Print device info:
+                       std::cout << "Name                        = " << (*i).name() << std::endl;
+                       std::cout << "Host API                    = " << (*i).hostApi().name() << std::endl;
+                       std::cout << "Max inputs = " << (*i).maxInputChannels() << ", Max outputs = " << (*i).maxOutputChannels() << std::endl;
+
+                       std::cout << "Default low input latency   = " << (*i).defaultLowInputLatency() << std::endl; // 8.3
+                       std::cout << "Default low output latency  = " << (*i).defaultLowOutputLatency() << std::endl; // 8.3
+                       std::cout << "Default high input latency  = " << (*i).defaultHighInputLatency() << std::endl; // 8.3
+                       std::cout << "Default high output latency = " << (*i).defaultHighOutputLatency() << std::endl; // 8.3
+
+#ifdef WIN32
+                       // ASIO specific latency information:
+                       if ((*i).hostApi().typeId() == paASIO)
+                       {
+                               portaudio::AsioDeviceAdapter asioDevice((*i));
+
+                               std::cout << "ASIO minimum buffer size    = " << asioDevice.minBufferSize() << std::endl;
+                               std::cout << "ASIO maximum buffer size    = " << asioDevice.maxBufferSize() << std::endl;
+                               std::cout << "ASIO preferred buffer size  = " << asioDevice.preferredBufferSize() << std::endl;
+
+                               if (asioDevice.granularity() == -1)
+                                       std::cout << "ASIO buffer granularity     = power of 2" << std::endl;
+                               else
+                                       std::cout << "ASIO buffer granularity     = " << asioDevice.granularity() << std::endl;
+                       }
+#endif // WIN32
+
+                       std::cout << "Default sample rate         = " << (*i).defaultSampleRate() << std::endl; // 8.2
+
+                       // Poll for standard sample rates:
+                       portaudio::DirectionSpecificStreamParameters inputParameters((*i), (*i).maxInputChannels(), portaudio::INT16, true, 0.0, NULL);
+                       portaudio::DirectionSpecificStreamParameters outputParameters((*i), (*i).maxOutputChannels(), portaudio::INT16, true, 0.0, NULL);
+
+                       if (inputParameters.numChannels() > 0)
+                       {
+                               std::cout << "Supported standard sample rates" << std::endl;
+                               std::cout << " for half-duplex 16 bit " << inputParameters.numChannels() << " channel input = " << std::endl;
+                               printSupportedStandardSampleRates(inputParameters, portaudio::DirectionSpecificStreamParameters::null());
+                       }
+
+                       if (outputParameters.numChannels() > 0)
+                       {
+                               std::cout << "Supported standard sample rates" << std::endl;
+                               std::cout << " for half-duplex 16 bit " << outputParameters.numChannels() << " channel output = " << std::endl;
+                               printSupportedStandardSampleRates(portaudio::DirectionSpecificStreamParameters::null(), outputParameters);
+                       }
+
+                       if (inputParameters.numChannels() > 0 && outputParameters.numChannels() > 0)
+                       {
+                               std::cout << "Supported standard sample rates" << std::endl;
+                               std::cout << " for full-duplex 16 bit " << inputParameters.numChannels() << " channel input, " << outputParameters.numChannels() << " channel output = " << std::endl;
+                               printSupportedStandardSampleRates(inputParameters, outputParameters);
+                       }
+               }
+
+               std::cout << "----------------------------------------------" << std::endl;
+       }
+       catch (const portaudio::PaException &e)
+       {
+               std::cout << "A PortAudio error occured: " << e.paErrorText() << std::endl;
+       }
+       catch (const portaudio::PaCppException &e)
+       {
+               std::cout << "A PortAudioCpp error occured: " << e.what() << std::endl;
+       }
+       catch (const std::exception &e)
+       {
+               std::cout << "A generic exception occured: " << e.what() << std::endl;
+       }
+       catch (...)
+       {
+               std::cout << "An unknown exception occured." << std::endl;
+       }
+
+       return 0;
+}
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/example/sine.cxx b/utils/iaxclient/lib/portaudio/bindings/cpp/example/sine.cxx
new file mode 100644 (file)
index 0000000..577a247
--- /dev/null
@@ -0,0 +1,137 @@
+// ---------------------------------------------------------------------------------------\r
+\r
+#include <iostream>\r
+#include <cmath>\r
+#include <cassert>\r
+#include <cstddef>\r
+#include "portaudiocpp/PortAudioCpp.hxx"\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// Some constants:\r
+const int NUM_SECONDS = 5;\r
+const double SAMPLE_RATE = 44100.0;\r
+const int FRAMES_PER_BUFFER = 64;\r
+const int TABLE_SIZE = 200;\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// SineGenerator class:\r
+class SineGenerator\r
+{\r
+public:\r
+       SineGenerator(int tableSize) : tableSize_(tableSize), leftPhase_(0), rightPhase_(0)\r
+       {\r
+               const double PI = 3.14159265;\r
+               table_ = new float[tableSize];\r
+               for (int i = 0; i < tableSize; ++i)\r
+               {\r
+                       table_[i] = 0.125f * (float)sin(((double)i/(double)tableSize)*PI*2.);\r
+               }\r
+       }\r
+\r
+       ~SineGenerator()\r
+       {\r
+               delete[] table_;\r
+       }\r
+\r
+       int generate(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, \r
+               const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags)\r
+       {\r
+               assert(outputBuffer != NULL);\r
+\r
+               float **out = static_cast<float **>(outputBuffer);\r
+\r
+               for (unsigned int i = 0; i < framesPerBuffer; ++i)\r
+               {\r
+                       out[0][i] = table_[leftPhase_];\r
+                       out[1][i] = table_[rightPhase_];\r
+\r
+                       leftPhase_ += 1;\r
+                       if (leftPhase_ >= tableSize_)\r
+                               leftPhase_ -= tableSize_;\r
+\r
+                       rightPhase_ += 3;\r
+                       if (rightPhase_ >= tableSize_)\r
+                               rightPhase_ -= tableSize_;\r
+               }\r
+\r
+               return paContinue;\r
+       }\r
+\r
+private:\r
+       float *table_;\r
+       int tableSize_;\r
+       int leftPhase_;\r
+       int rightPhase_;\r
+};\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// main:\r
+int main(int, char *[]);\r
+int main(int, char *[])\r
+{\r
+       try\r
+       {\r
+               // Create a SineGenerator object:\r
+               SineGenerator sineGenerator(TABLE_SIZE);\r
+\r
+               std::cout << "Setting up PortAudio..." << std::endl;\r
+\r
+               // Set up the System:\r
+               portaudio::AutoSystem autoSys;\r
+               portaudio::System &sys = portaudio::System::instance();\r
+\r
+               // Set up the parameters required to open a (Callback)Stream:\r
+               portaudio::DirectionSpecificStreamParameters outParams(sys.defaultOutputDevice(), 2, portaudio::FLOAT32, false, sys.defaultOutputDevice().defaultLowOutputLatency(), NULL);\r
+               portaudio::StreamParameters params(portaudio::DirectionSpecificStreamParameters::null(), outParams, SAMPLE_RATE, FRAMES_PER_BUFFER, paClipOff);\r
+\r
+               std::cout << "Opening stereo output stream..." << std::endl;\r
+\r
+               // Create (and open) a new Stream, using the SineGenerator::generate function as a callback:\r
+               portaudio::MemFunCallbackStream<SineGenerator> stream(params, sineGenerator, &SineGenerator::generate);\r
+\r
+               std::cout << "Starting playback for " << NUM_SECONDS << " seconds." << std::endl;\r
+\r
+               // Start the Stream (audio playback starts):\r
+               stream.start();\r
+\r
+               // Wait for 5 seconds:\r
+               sys.sleep(NUM_SECONDS * 1000);\r
+\r
+               std::cout << "Closing stream..." <<std::endl;\r
+\r
+               // Stop the Stream (not strictly needed as termintating the System will also stop all open Streams):\r
+               stream.stop();\r
+\r
+               // Close the Stream (not strictly needed as terminating the System will also close all open Streams):\r
+               stream.close();\r
+\r
+               // Terminate the System (not strictly needed as the AutoSystem will also take care of this when it \r
+               // goes out of scope):\r
+               sys.terminate();\r
+\r
+               std::cout << "Test finished." << std::endl;\r
+       }\r
+       catch (const portaudio::PaException &e)\r
+       {\r
+               std::cout << "A PortAudio error occured: " << e.paErrorText() << std::endl;\r
+       }\r
+       catch (const portaudio::PaCppException &e)\r
+       {\r
+               std::cout << "A PortAudioCpp error occured: " << e.what() << std::endl;\r
+       }\r
+       catch (const std::exception &e)\r
+       {\r
+               std::cout << "A generic exception occured: " << e.what() << std::endl;\r
+       }\r
+       catch (...)\r
+       {\r
+               std::cout << "An unknown exception occured." << std::endl;\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
+\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/AsioDeviceAdapter.hxx b/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/AsioDeviceAdapter.hxx
new file mode 100644 (file)
index 0000000..1964b6a
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef INCLUDED_PORTAUDIO_ASIODEVICEADAPTER_HXX
+#define INCLUDED_PORTAUDIO_ASIODEVICEADAPTER_HXX
+
+namespace portaudio
+{
+
+       // Forward declaration(s):
+       class Device;
+
+       // Declaration(s):
+       //////
+       /// @brief Adapts the given Device to an ASIO specific extension.
+       ///
+       /// Deleting the AsioDeviceAdapter does not affect the underlaying 
+       /// Device.
+       //////
+       class AsioDeviceAdapter
+       {
+       public:
+               AsioDeviceAdapter(Device &device);
+
+               Device &device();
+
+               long minBufferSize() const;
+               long maxBufferSize() const;
+               long preferredBufferSize() const;
+               long granularity() const;
+
+               void showControlPanel(void *systemSpecific);
+
+               const char *inputChannelName(int channelIndex) const;\r
+               const char *outputChannelName(int channelIndex) const;
+
+       private:
+               Device *device_;
+
+               long minBufferSize_;
+               long maxBufferSize_;
+               long preferredBufferSize_;
+               long granularity_;
+       };
+}
+
+#endif // INCLUDED_PORTAUDIO_ASIODEVICEADAPTER_HXX
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/AutoSystem.hxx b/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/AutoSystem.hxx
new file mode 100644 (file)
index 0000000..16cac5e
--- /dev/null
@@ -0,0 +1,62 @@
+#ifndef INCLUDED_PORTAUDIO_AUTOSYSTEM_HXX\r
+#define INCLUDED_PORTAUDIO_AUTOSYSTEM_HXX\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#include "portaudiocpp/System.hxx"\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+namespace portaudio\r
+{\r
+\r
+\r
+       //////\r
+       /// @brief A RAII idiom class to ensure automatic clean-up when an exception is \r
+       /// raised.\r
+       ///\r
+       /// A simple helper class which uses the 'Resource Acquisition is Initialization' \r
+       /// idiom (RAII). Use this class to initialize/terminate the System rather than \r
+       /// using System directly. AutoSystem must be created on stack and must be valid \r
+       /// throughout the time you wish to use PortAudioCpp. Your 'main' function might be \r
+       /// a good place for it.\r
+       ///\r
+       /// To avoid having to type portaudio::System::instance().xyz() all the time, it's usually \r
+       /// a good idea to make a reference to the System which can be accessed directly.\r
+       /// @verbatim\r
+       /// portaudio::AutoSys autoSys;\r
+       /// portaudio::System &sys = portaudio::System::instance();\r
+       /// @endverbatim\r
+       //////\r
+       class AutoSystem\r
+       {\r
+       public:\r
+               AutoSystem(bool initialize = true)\r
+               {\r
+                       if (initialize)\r
+                               System::initialize();\r
+               }\r
+\r
+               ~AutoSystem()\r
+               {\r
+                       if (System::exists())\r
+                               System::terminate();\r
+               }\r
+\r
+               void initialize()\r
+               {\r
+                       System::initialize();\r
+               }\r
+\r
+               void terminate()\r
+               {\r
+                       System::terminate();\r
+               }\r
+       };\r
+\r
+\r
+} // namespace portaudio\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#endif // INCLUDED_PORTAUDIO_AUTOSYSTEM_HXX\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/BlockingStream.hxx b/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/BlockingStream.hxx
new file mode 100644 (file)
index 0000000..37fa766
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef INCLUDED_PORTAUDIO_BLOCKINGSTREAM_HXX\r
+#define INCLUDED_PORTAUDIO_BLOCKINGSTREAM_HXX\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#include "portaudiocpp/Stream.hxx"\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+namespace portaudio\r
+{\r
+\r
+\r
+\r
+       //////\r
+       /// @brief Stream class for blocking read/write-style input and output.\r
+       //////\r
+       class BlockingStream : public Stream\r
+       {\r
+       public:\r
+               BlockingStream();\r
+               BlockingStream(const StreamParameters &parameters);\r
+               ~BlockingStream();\r
+\r
+               void open(const StreamParameters &parameters);\r
+\r
+               void read(void *buffer, unsigned long numFrames);\r
+               void write(const void *buffer, unsigned long numFrames);\r
+\r
+               signed long availableReadSize() const;\r
+               signed long availableWriteSize() const;\r
+\r
+       private:\r
+               BlockingStream(const BlockingStream &); // non-copyable\r
+               BlockingStream &operator=(const BlockingStream &); // non-copyable\r
+       };\r
+\r
+\r
+\r
+} // portaudio\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#endif // INCLUDED_PORTAUDIO_BLOCKINGSTREAM_HXX\r
+\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/CFunCallbackStream.hxx b/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/CFunCallbackStream.hxx
new file mode 100644 (file)
index 0000000..b3e3b5c
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef INCLUDED_PORTAUDIO_CFUNCALLBACKSTREAM_HXX\r
+#define INCLUDED_PORTAUDIO_CFUNCALLBACKSTREAM_HXX\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#include "portaudio.h"\r
+\r
+#include "portaudiocpp/CallbackStream.hxx"\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// Forward declaration(s)\r
+namespace portaudio\r
+{\r
+       class StreamParameters;\r
+}\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// Declaration(s):\r
+namespace portaudio\r
+{\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       //////\r
+       /// @brief Callback stream using a free function with C linkage. It's important that the function \r
+       /// the passed function pointer points to is declared ``extern "C"''.\r
+       //////\r
+       class CFunCallbackStream : public CallbackStream\r
+       {\r
+       public:\r
+               CFunCallbackStream();\r
+               CFunCallbackStream(const StreamParameters &parameters, PaStreamCallback *funPtr, void *userData);\r
+               ~CFunCallbackStream();\r
+               \r
+               void open(const StreamParameters &parameters, PaStreamCallback *funPtr, void *userData);\r
+\r
+       private:\r
+               CFunCallbackStream(const CFunCallbackStream &); // non-copyable\r
+               CFunCallbackStream &operator=(const CFunCallbackStream &); // non-copyable\r
+       };\r
+\r
+       // -----------------------------------------------------------------------------------\r
+} // portaudio\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#endif // INCLUDED_PORTAUDIO_MEMFUNCALLBACKSTREAM_HXX\r
+\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/CallbackInterface.hxx b/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/CallbackInterface.hxx
new file mode 100644 (file)
index 0000000..d498ec5
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef INCLUDED_PORTAUDIO_CALLBACKINTERFACE_HXX\r
+#define INCLUDED_PORTAUDIO_CALLBACKINTERFACE_HXX\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#include "portaudio.h"\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+namespace portaudio\r
+{\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       //////\r
+       /// @brief Interface for an object that's callable as a PortAudioCpp callback object (ie that implements the \r
+       /// paCallbackFun method).\r
+       //////\r
+       class CallbackInterface\r
+       {\r
+       public:\r
+               virtual ~CallbackInterface() {}\r
+\r
+               virtual int paCallbackFun(const void *inputBuffer, void *outputBuffer, unsigned long numFrames, \r
+                       const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags) = 0;\r
+       };\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       namespace impl\r
+       {\r
+               extern "C"\r
+               {\r
+                       int callbackInterfaceToPaCallbackAdapter(const void *inputBuffer, void *outputBuffer, unsigned long numFrames, \r
+                               const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, \r
+                               void *userData);\r
+               } // extern "C"\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+} // namespace portaudio\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#endif // INCLUDED_PORTAUDIO_CALLBACKINTERFACE_HXX\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/CallbackStream.hxx b/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/CallbackStream.hxx
new file mode 100644 (file)
index 0000000..0382275
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef INCLUDED_PORTAUDIO_CALLBACKSTREAM_HXX\r
+#define INCLUDED_PORTAUDIO_CALLBACKSTREAM_HXX\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#include "portaudio.h"\r
+\r
+#include "portaudiocpp/Stream.hxx"\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// Declaration(s):\r
+namespace portaudio\r
+{\r
+\r
+\r
+       //////\r
+       /// @brief Base class for all Streams which use a callback-based mechanism.\r
+       //////\r
+       class CallbackStream : public Stream\r
+       {\r
+       protected:\r
+               CallbackStream();\r
+               virtual ~CallbackStream();\r
+\r
+       public:\r
+               // stream info (time-varying)\r
+               double cpuLoad() const;\r
+\r
+       private:\r
+               CallbackStream(const CallbackStream &); // non-copyable\r
+               CallbackStream &operator=(const CallbackStream &); // non-copyable\r
+       };\r
+\r
+\r
+} // namespace portaudio\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#endif // INCLUDED_PORTAUDIO_CALLBACKSTREAM_HXX\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/CppFunCallbackStream.hxx b/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/CppFunCallbackStream.hxx
new file mode 100644 (file)
index 0000000..e0c0012
--- /dev/null
@@ -0,0 +1,86 @@
+#ifndef INCLUDED_PORTAUDIO_CPPFUNCALLBACKSTREAM_HXX\r
+#define INCLUDED_PORTAUDIO_CPPFUNCALLBACKSTREAM_HXX\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#include "portaudio.h"\r
+\r
+#include "portaudiocpp/CallbackStream.hxx"\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// Forward declaration(s):\r
+namespace portaudio\r
+{\r
+       class StreamParameters;\r
+}\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// Declaration(s):\r
+namespace portaudio\r
+{\r
+\r
+\r
+       namespace impl\r
+       {\r
+               extern "C"\r
+               {\r
+                       int cppCallbackToPaCallbackAdapter(const void *inputBuffer, void *outputBuffer, unsigned long numFrames, \r
+                               const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, \r
+                               void *userData);\r
+               } // extern "C"\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       //////\r
+       /// @brief Callback stream using a C++ function (either a free function or a static function) \r
+       /// callback.\r
+       //////\r
+       class FunCallbackStream : public CallbackStream\r
+       {\r
+       public:\r
+               typedef int (*CallbackFunPtr)(const void *inputBuffer, void *outputBuffer, unsigned long numFrames, \r
+                       const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, \r
+                       void *userData);\r
+\r
+               // -------------------------------------------------------------------------------\r
+\r
+               //////\r
+               /// @brief Simple structure containing a function pointer to the C++ callback function and a \r
+               /// (void) pointer to the user supplied data.\r
+               //////\r
+               struct CppToCCallbackData\r
+               {\r
+                       CppToCCallbackData();\r
+                       CppToCCallbackData(CallbackFunPtr funPtr, void *userData);\r
+                       void init(CallbackFunPtr funPtr, void *userData);\r
+\r
+                       CallbackFunPtr funPtr;\r
+                       void *userData;\r
+               };\r
+\r
+               // -------------------------------------------------------------------------------\r
+\r
+               FunCallbackStream();\r
+               FunCallbackStream(const StreamParameters &parameters, CallbackFunPtr funPtr, void *userData);\r
+               ~FunCallbackStream();\r
+\r
+               void open(const StreamParameters &parameters, CallbackFunPtr funPtr, void *userData);\r
+\r
+       private:\r
+               FunCallbackStream(const FunCallbackStream &); // non-copyable\r
+               FunCallbackStream &operator=(const FunCallbackStream &); // non-copyable\r
+\r
+               CppToCCallbackData adapterData_;\r
+\r
+               void open(const StreamParameters &parameters);\r
+       };\r
+\r
+\r
+} // portaudio\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#endif // INCLUDED_PORTAUDIO_CPPFUNCALLBACKSTREAM_HXX\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/Device.hxx b/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/Device.hxx
new file mode 100644 (file)
index 0000000..ffde7aa
--- /dev/null
@@ -0,0 +1,91 @@
+#ifndef INCLUDED_PORTAUDIO_DEVICE_HXX\r
+#define INCLUDED_PORTAUDIO_DEVICE_HXX\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#include <iterator>\r
+\r
+#include "portaudio.h"\r
+\r
+#include "portaudiocpp/SampleDataFormat.hxx"\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// Forward declaration(s):\r
+namespace portaudio\r
+{\r
+       class System;\r
+       class HostApi;\r
+}\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// Declaration(s):\r
+namespace portaudio\r
+{\r
+\r
+       //////\r
+       /// @brief Class which represents a PortAudio device in the System.\r
+       ///\r
+       /// A single physical device in the system may have multiple PortAudio \r
+       /// Device representations using different HostApi 's though. A Device \r
+       /// can be half-duplex or full-duplex. A half-duplex Device can be used \r
+       /// to create a half-duplex Stream. A full-duplex Device can be used to \r
+       /// create a full-duplex Stream. If supported by the HostApi, two \r
+       /// half-duplex Devices can even be used to create a full-duplex Stream.\r
+       ///\r
+       /// Note that Device objects are very light-weight and can be passed around \r
+       /// by-value.\r
+       //////\r
+       class Device\r
+       {\r
+       public:\r
+               // query info: name, max in channels, max out channels, \r
+               // default low/hight input/output latency, default sample rate\r
+               PaDeviceIndex index() const;\r
+               const char *name() const;\r
+               int maxInputChannels() const;\r
+               int maxOutputChannels() const;\r
+               PaTime defaultLowInputLatency() const;\r
+               PaTime defaultHighInputLatency() const;\r
+               PaTime defaultLowOutputLatency() const;\r
+               PaTime defaultHighOutputLatency() const;\r
+               double defaultSampleRate() const;\r
+\r
+               bool isInputOnlyDevice() const; // extended\r
+               bool isOutputOnlyDevice() const; // extended\r
+               bool isFullDuplexDevice() const; // extended\r
+               bool isSystemDefaultInputDevice() const; // extended\r
+               bool isSystemDefaultOutputDevice() const; // extended\r
+               bool isHostApiDefaultInputDevice() const; // extended\r
+               bool isHostApiDefaultOutputDevice() const; // extended\r
+\r
+               bool operator==(const Device &rhs);\r
+               bool operator!=(const Device &rhs);\r
+\r
+               // host api reference\r
+               HostApi &hostApi();\r
+               const HostApi &hostApi() const;\r
+\r
+       private:\r
+               PaDeviceIndex index_;\r
+               const PaDeviceInfo *info_;\r
+\r
+       private:\r
+               friend class System;\r
+               \r
+               explicit Device(PaDeviceIndex index);\r
+               ~Device();\r
+\r
+               Device(const Device &); // non-copyable\r
+               Device &operator=(const Device &); // non-copyable\r
+       };\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+} // namespace portaudio\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#endif // INCLUDED_PORTAUDIO_DEVICE_HXX\r
+\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/DirectionSpecificStreamParameters.hxx b/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/DirectionSpecificStreamParameters.hxx
new file mode 100644 (file)
index 0000000..dd5ae0b
--- /dev/null
@@ -0,0 +1,77 @@
+#ifndef INCLUDED_PORTAUDIO_SINGLEDIRECTIONSTREAMPARAMETERS_HXX\r
+#define INCLUDED_PORTAUDIO_SINGLEDIRECTIONSTREAMPARAMETERS_HXX\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#include <cstddef>\r
+\r
+#include "portaudio.h"\r
+\r
+#include "portaudiocpp/System.hxx"\r
+#include "portaudiocpp/SampleDataFormat.hxx"\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// Forward declaration(s):\r
+namespace portaudio\r
+{\r
+       class Device;\r
+}\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// Declaration(s):\r
+namespace portaudio\r
+{\r
+\r
+       //////\r
+       /// @brief All parameters for one direction (either in or out) of a Stream. Together with \r
+       /// parameters common to both directions, two DirectionSpecificStreamParameters can make up \r
+       /// a StreamParameters object which contains all parameters for a Stream.\r
+       //////\r
+       class DirectionSpecificStreamParameters\r
+       {\r
+       public:\r
+               static DirectionSpecificStreamParameters null();\r
+\r
+               DirectionSpecificStreamParameters();\r
+               DirectionSpecificStreamParameters(const Device &device, int numChannels, SampleDataFormat format, \r
+                       bool interleaved, PaTime suggestedLatency, void *hostApiSpecificStreamInfo);\r
+\r
+               // Set up methods:\r
+               void setDevice(const Device &device);\r
+               void setNumChannels(int numChannels);\r
+\r
+               void setSampleFormat(SampleDataFormat format, bool interleaved = true);\r
+               void setHostApiSpecificSampleFormat(PaSampleFormat format, bool interleaved = true);\r
+\r
+               void setSuggestedLatency(PaTime latency);\r
+\r
+               void setHostApiSpecificStreamInfo(void *streamInfo);\r
+\r
+               // Accessor methods:\r
+               PaStreamParameters *paStreamParameters();\r
+               const PaStreamParameters *paStreamParameters() const;\r
+\r
+               Device &device() const;\r
+               int numChannels() const;\r
+\r
+               SampleDataFormat sampleFormat() const;\r
+               bool isSampleFormatInterleaved() const;\r
+               bool isSampleFormatHostApiSpecific() const;\r
+               PaSampleFormat hostApiSpecificSampleFormat() const;\r
+\r
+               PaTime suggestedLatency() const;\r
+\r
+               void *hostApiSpecificStreamInfo() const;\r
+       \r
+       private:\r
+               PaStreamParameters paStreamParameters_;\r
+       };\r
+\r
+\r
+} // namespace portaudio\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#endif // INCLUDED_PORTAUDIO_SINGLEDIRECTIONSTREAMPARAMETERS_HXX\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/Exception.hxx b/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/Exception.hxx
new file mode 100644 (file)
index 0000000..a70c2f1
--- /dev/null
@@ -0,0 +1,108 @@
+#ifndef INCLUDED_PORTAUDIO_EXCEPTION_HXX\r
+#define INCLUDED_PORTAUDIO_EXCEPTION_HXX\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#include <exception>\r
+\r
+#include "portaudio.h"\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+namespace portaudio\r
+{\r
+\r
+       //////\r
+       /// @brief Base class for all exceptions PortAudioCpp can throw.\r
+       ///\r
+       /// Class is derived from std::exception.\r
+       //////\r
+       class Exception : public std::exception\r
+       {\r
+       public:\r
+               virtual ~Exception() throw() {}\r
+\r
+               virtual const char *what() const throw() = 0;\r
+       };\r
+       \r
+       // -----------------------------------------------------------------------------------\r
+\r
+       //////\r
+       /// @brief Wrapper for PortAudio error codes to C++ exceptions.\r
+       ///\r
+       /// It wraps up PortAudio's error handling mechanism using \r
+       /// C++ exceptions and is derived from std::exception for \r
+       /// easy exception handling and to ease integration with \r
+       /// other code.\r
+       ///\r
+       /// To know what exceptions each function may throw, look up \r
+       /// the errors that can occure in the PortAudio documentation \r
+       /// for the equivalent functions.\r
+       ///\r
+       /// Some functions are likely to throw an exception (such as \r
+       /// Stream::open(), etc) and these should always be called in \r
+       /// try{} catch{} blocks and the thrown exceptions should be \r
+       /// handled properly (ie. the application shouldn't just abort, \r
+       /// but merely display a warning dialog to the user or something).\r
+       /// However nearly all functions in PortAudioCpp are capable \r
+       /// of throwing exceptions. When a function like Stream::isStopped() \r
+       /// throws an exception, it's such an exceptional state that it's \r
+       /// not likely that it can be recovered. PaExceptions such as these \r
+       /// can ``safely'' be left to be handled by some outer catch-all-like \r
+       /// mechanism for unrecoverable errors.\r
+       //////\r
+       class PaException : public Exception\r
+       {\r
+       public:\r
+               explicit PaException(PaError error);\r
+\r
+               const char *what() const throw();\r
+\r
+               PaError paError() const;\r
+               const char *paErrorText() const;\r
+\r
+               bool isHostApiError() const; // extended\r
+               long lastHostApiError() const;\r
+               const char *lastHostApiErrorText() const;\r
+\r
+               bool operator==(const PaException &rhs) const;\r
+               bool operator!=(const PaException &rhs) const;\r
+\r
+       private:\r
+               PaError error_;\r
+       };\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       //////\r
+       /// @brief Exceptions specific to PortAudioCpp (ie. exceptions which do not have an \r
+       /// equivalent PortAudio error code).\r
+       //////\r
+       class PaCppException : public Exception\r
+       {\r
+       public:\r
+               enum ExceptionSpecifier\r
+               {\r
+                       UNABLE_TO_ADAPT_DEVICE\r
+               };\r
+\r
+               PaCppException(ExceptionSpecifier specifier);\r
+\r
+               const char *what() const throw();\r
+\r
+               ExceptionSpecifier specifier() const;\r
+\r
+               bool operator==(const PaCppException &rhs) const;\r
+               bool operator!=(const PaCppException &rhs) const;\r
+\r
+       private:\r
+               ExceptionSpecifier specifier_;\r
+       };\r
+\r
+\r
+} // namespace portaudio\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#endif // INCLUDED_PORTAUDIO_EXCEPTION_HXX\r
+\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/HostApi.hxx b/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/HostApi.hxx
new file mode 100644 (file)
index 0000000..899fc42
--- /dev/null
@@ -0,0 +1,76 @@
+#ifndef INCLUDED_PORTAUDIO_HOSTAPI_HXX\r
+#define INCLUDED_PORTAUDIO_HOSTAPI_HXX\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#include "portaudio.h"\r
+\r
+#include "portaudiocpp/System.hxx"\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// Forward declaration(s):\r
+namespace portaudio\r
+{\r
+       class Device;\r
+}\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// Declaration(s):\r
+namespace portaudio\r
+{\r
+\r
+\r
+       //////\r
+       /// @brief HostApi represents a host API (usually type of driver) in the System.\r
+       ///\r
+       /// A single System can support multiple HostApi's each one typically having \r
+       /// a set of Devices using that HostApi (usually driver type). All Devices in \r
+       /// the HostApi can be enumerated and the default input/output Device for this \r
+       /// HostApi can be retreived.\r
+       //////\r
+       class HostApi\r
+       {\r
+       public:\r
+               typedef System::DeviceIterator DeviceIterator;\r
+\r
+               // query info: id, name, numDevices\r
+               PaHostApiTypeId typeId() const;\r
+               PaHostApiIndex index() const;\r
+               const char *name() const;\r
+               int deviceCount() const;\r
+\r
+               // iterate devices\r
+               DeviceIterator devicesBegin();\r
+               DeviceIterator devicesEnd();\r
+\r
+               // default devices\r
+               Device &defaultInputDevice() const;\r
+               Device &defaultOutputDevice() const;\r
+\r
+               // comparison operators\r
+               bool operator==(const HostApi &rhs) const;\r
+               bool operator!=(const HostApi &rhs) const;\r
+\r
+       private:\r
+               const PaHostApiInfo *info_;\r
+               Device **devices_;\r
+\r
+       private:\r
+               friend class System;\r
+\r
+               explicit HostApi(PaHostApiIndex index);\r
+               ~HostApi();\r
+\r
+               HostApi(const HostApi &); // non-copyable\r
+               HostApi &operator=(const HostApi &); // non-copyable\r
+       };\r
+\r
+\r
+}\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#endif // INCLUDED_PORTAUDIO_HOSTAPI_HXX\r
+\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/InterfaceCallbackStream.hxx b/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/InterfaceCallbackStream.hxx
new file mode 100644 (file)
index 0000000..e496dd2
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef INCLUDED_PORTAUDIO_INTERFACECALLBACKSTREAM_HXX\r
+#define INCLUDED_PORTAUDIO_INTERFACECALLBACKSTREAM_HXX\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#include "portaudio.h"\r
+\r
+#include "portaudiocpp/CallbackStream.hxx"\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// Forward declaration(s)\r
+namespace portaudio\r
+{\r
+       class StreamParameters;\r
+       class CallbackInterface;\r
+}\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// Declaration(s):\r
+namespace portaudio\r
+{\r
+\r
+\r
+       //////\r
+       /// @brief Callback stream using an instance of an object that's derived from the CallbackInterface \r
+       /// interface.\r
+       //////\r
+       class InterfaceCallbackStream : public CallbackStream\r
+       {\r
+       public:\r
+               InterfaceCallbackStream();\r
+               InterfaceCallbackStream(const StreamParameters &parameters, CallbackInterface &instance);\r
+               ~InterfaceCallbackStream();\r
+               \r
+               void open(const StreamParameters &parameters, CallbackInterface &instance);\r
+\r
+       private:\r
+               InterfaceCallbackStream(const InterfaceCallbackStream &); // non-copyable\r
+               InterfaceCallbackStream &operator=(const InterfaceCallbackStream &); // non-copyable\r
+       };\r
+\r
+\r
+} // portaudio\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#endif // INCLUDED_PORTAUDIO_INTERFACECALLBACKSTREAM_HXX\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/MemFunCallbackStream.hxx b/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/MemFunCallbackStream.hxx
new file mode 100644 (file)
index 0000000..a9e50ca
--- /dev/null
@@ -0,0 +1,107 @@
+#ifndef INCLUDED_PORTAUDIO_MEMFUNCALLBACKSTREAM_HXX\r
+#define INCLUDED_PORTAUDIO_MEMFUNCALLBACKSTREAM_HXX\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#include "portaudio.h"\r
+\r
+#include "portaudiocpp/CallbackStream.hxx"\r
+#include "portaudiocpp/CallbackInterface.hxx"\r
+#include "portaudiocpp/StreamParameters.hxx"\r
+#include "portaudiocpp/Exception.hxx"\r
+#include "portaudiocpp/InterfaceCallbackStream.hxx"\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+namespace portaudio\r
+{\r
+\r
+\r
+       //////\r
+       /// @brief Callback stream using a class's member function as a callback. Template argument T is the type of the \r
+       /// class of which a member function is going to be used.\r
+       ///\r
+       /// Example usage:\r
+       /// @verbatim MemFunCallback<MyClass> stream = MemFunCallbackStream(parameters, *this, &MyClass::myCallbackFunction); @endverbatim\r
+       //////\r
+       template<typename T>\r
+       class MemFunCallbackStream : public CallbackStream\r
+       {\r
+       public:\r
+               typedef int (T::*CallbackFunPtr)(const void *, void *, unsigned long, const PaStreamCallbackTimeInfo *, \r
+                       PaStreamCallbackFlags);\r
+\r
+               // -------------------------------------------------------------------------------\r
+\r
+               MemFunCallbackStream()\r
+               {\r
+               }\r
+\r
+               MemFunCallbackStream(const StreamParameters &parameters, T &instance, CallbackFunPtr memFun) : adapter_(instance, memFun)\r
+               {\r
+                       open(parameters);\r
+               }\r
+\r
+               ~MemFunCallbackStream()\r
+               {\r
+                       close();\r
+               }\r
+\r
+               void open(const StreamParameters &parameters, T &instance, CallbackFunPtr memFun)\r
+               {\r
+                       // XXX: need to check if already open?\r
+\r
+                       adapter_.init(instance, memFun);\r
+                       open(parameters);\r
+               }\r
+\r
+       private:\r
+               MemFunCallbackStream(const MemFunCallbackStream &); // non-copyable\r
+               MemFunCallbackStream &operator=(const MemFunCallbackStream &); // non-copyable\r
+\r
+               //////\r
+               /// @brief Inner class which adapts a member function callback to a CallbackInterface compliant \r
+               /// class (so it can be adapted using the paCallbackAdapter function).\r
+               //////\r
+               class MemFunToCallbackInterfaceAdapter : public CallbackInterface\r
+               {\r
+               public:\r
+                       MemFunToCallbackInterfaceAdapter() {}\r
+                       MemFunToCallbackInterfaceAdapter(T &instance, CallbackFunPtr memFun) : instance_(&instance), memFun_(memFun) {}\r
+\r
+                       void init(T &instance, CallbackFunPtr memFun)\r
+                       {\r
+                               instance_ = &instance;\r
+                               memFun_ = memFun;\r
+                       }\r
+\r
+                       int paCallbackFun(const void *inputBuffer, void *outputBuffer, unsigned long numFrames, \r
+                               const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags)\r
+                       {\r
+                               return (instance_->*memFun_)(inputBuffer, outputBuffer, numFrames, timeInfo, statusFlags);\r
+                       }\r
+\r
+               private:\r
+                       T *instance_;\r
+                       CallbackFunPtr memFun_;\r
+               };\r
+\r
+               MemFunToCallbackInterfaceAdapter adapter_;\r
+\r
+               void open(const StreamParameters &parameters)\r
+               {\r
+                       PaError err = Pa_OpenStream(&stream_, parameters.inputParameters().paStreamParameters(), parameters.outputParameters().paStreamParameters(), \r
+                               parameters.sampleRate(), parameters.framesPerBuffer(), parameters.flags(), &impl::callbackInterfaceToPaCallbackAdapter, \r
+                               static_cast<void *>(&adapter_));\r
+\r
+                       if (err != paNoError)\r
+                               throw PaException(err);\r
+               }\r
+       };\r
+\r
+\r
+} // portaudio\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#endif // INCLUDED_PORTAUDIO_MEMFUNCALLBACKSTREAM_HXX\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/PortAudioCpp.hxx b/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/PortAudioCpp.hxx
new file mode 100644 (file)
index 0000000..f11e7fb
--- /dev/null
@@ -0,0 +1,109 @@
+#ifndef INCLUDED_PORTAUDIO_PORTAUDIOCPP_HXX\r
+#define INCLUDED_PORTAUDIO_PORTAUDIOCPP_HXX\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+//////\r
+/// @mainpage PortAudioCpp\r
+///\r
+///    <h1>PortAudioCpp - A Native C++ Binding of PortAudio V19</h1>\r
+/// <h2>PortAudio</h2>\r
+/// <p>\r
+///   PortAudio is a portable and mature C API for accessing audio hardware. It offers both callback-based and blocking \r
+///   style input and output, deals with sample data format conversions, dithering and much more. There are a large number \r
+///   of implementations available for various platforms including Windows MME, Windows DirectX, Windows and MacOS (Classic) \r
+///   ASIO, MacOS Classic SoundManager, MacOS X CoreAudio, OSS (Linux), Linux ALSA, JACK (MacOS X and Linux) and SGI Irix \r
+///   AL. Note that, currently not all of these implementations are equally complete or up-to-date (as PortAudio V19 is \r
+///   still in development). Because PortAudio has a C API, it can easily be called from a variety of other programming \r
+///   languages.\r
+/// </p>\r
+/// <h2>PortAudioCpp</h2>\r
+/// <p>\r
+///   Although, it is possible to use PortAudio's C API from within a C++ program, this is usually a little awkward \r
+///   as procedural and object-oriented paradigms need to be mixed. PortAudioCpp aims to resolve this by encapsulating \r
+///   PortAudio's C API to form an equivalent object-oriented C++ API. It provides a more natural integration of PortAudio \r
+///   into C++ programs as well as a more structured interface. PortAudio's concepts were preserved as much as possible and \r
+///   no additional features were added except for some `convenience methods'.\r
+/// </p>\r
+/// <p>\r
+///   PortAudioCpp's main features are:\r
+///   <ul>\r
+///     <li>Structured object model.</li>\r
+///     <li>C++ exception handling instead of C-style error return codes.</li>\r
+///     <li>Handling of callbacks using free functions (C and C++), static functions, member functions or instances of classes \r
+///     derived from a given interface.</li>\r
+///     <li>STL compliant iterators to host APIs and devices.</li>\r
+///     <li>Some additional convenience functions to more easily set up and use PortAudio.</li>\r
+///   </ul>\r
+/// </p>\r
+/// <p>\r
+///   PortAudioCpp requires a recent version of the PortAudio V19 source code. This can be obtained from CVS or as a snapshot \r
+///   from the website. The examples also require the ASIO 2 SDK which can be obtained from the Steinberg website. Alternatively, the \r
+///   examples can easily be modified to compile without needing ASIO.\r
+/// </p>\r
+/// <p>\r
+///   Supported platforms:\r
+///   <ul>\r
+///     <li>Microsoft Visual C++ 6.0, 7.0 (.NET 2002) and 7.1 (.NET 2003).</li>\r
+///     <li>GNU G++ 2.95 and G++ 3.3.</li>\r
+///   </ul>\r
+///   Other platforms should be easily supported as PortAudioCpp is platform-independent and (reasonably) C++ standard compliant.\r
+/// </p>\r
+/// <p>\r
+///   This documentation mainly provides information specific to PortAudioCpp. For a more complete explaination of all of the \r
+///   concepts used, please consult the PortAudio documentation.\r
+/// </p>\r
+/// <p>\r
+///   PortAudioCpp was developed by Merlijn Blaauw with many great suggestions and help from Ross Bencina. Ludwig Schwardt provided \r
+///   GNU/Linux build files and checked G++ compatibility. PortAudioCpp may be used under the same licensing, conditions and \r
+///   warranty as PortAudio. See <a href="http://www.portaudio.com/license.html">the PortAudio license</a> for more details.\r
+/// </p>\r
+/// <h2>Links</h2>\r
+/// <p>\r
+///   <a href="http://www.portaudio.com/">Official PortAudio site.</a><br>\r
+/// </p>\r
+//////\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+//////\r
+/// @namespace portaudio\r
+///\r
+/// To avoid name collision, everything in PortAudioCpp is in the portaudio \r
+/// namespace. If this name is too long it's usually pretty safe to use an \r
+/// alias like ``namespace pa = portaudio;''.\r
+//////\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+//////\r
+/// @file PortAudioCpp.hxx\r
+/// An include-all header file (for lazy programmers and using pre-compiled headers).\r
+//////\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#include "portaudio.h"\r
+\r
+#include "portaudiocpp/AutoSystem.hxx"\r
+#include "portaudiocpp/BlockingStream.hxx"\r
+#include "portaudiocpp/CallbackInterface.hxx"\r
+#include "portaudiocpp/CallbackStream.hxx"\r
+#include "portaudiocpp/CFunCallbackStream.hxx"\r
+#include "portaudiocpp/CppFunCallbackStream.hxx"\r
+#include "portaudiocpp/Device.hxx"\r
+#include "portaudiocpp/Exception.hxx"\r
+#include "portaudiocpp/HostApi.hxx"\r
+#include "portaudiocpp/InterfaceCallbackStream.hxx"\r
+#include "portaudiocpp/MemFunCallbackStream.hxx"\r
+#include "portaudiocpp/SampleDataFormat.hxx"\r
+#include "portaudiocpp/DirectionSpecificStreamParameters.hxx"\r
+#include "portaudiocpp/Stream.hxx"\r
+#include "portaudiocpp/StreamParameters.hxx"\r
+#include "portaudiocpp/System.hxx"\r
+#include "portaudiocpp/SystemDeviceIterator.hxx"\r
+#include "portaudiocpp/SystemHostApiIterator.hxx"\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#endif // INCLUDED_PORTAUDIO_PORTAUDIOCPP_HXX\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/SampleDataFormat.hxx b/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/SampleDataFormat.hxx
new file mode 100644 (file)
index 0000000..a7e25b2
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef INCLUDED_PORTAUDIO_SAMPLEDATAFORMAT_HXX\r
+#define INCLUDED_PORTAUDIO_SAMPLEDATAFORMAT_HXX\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#include "portaudio.h"\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+namespace portaudio\r
+{\r
+\r
+\r
+       //////\r
+       /// @brief PortAudio sample data formats.\r
+       ///\r
+       /// Small helper enum to wrap the PortAudio defines.\r
+       //////\r
+       enum SampleDataFormat\r
+       {\r
+               INVALID_FORMAT  = 0,\r
+               FLOAT32                 = paFloat32,\r
+               INT32                   = paInt32,\r
+               INT24                   = paInt24,\r
+               INT16                   = paInt16,\r
+               INT8                    = paInt8,\r
+               UINT8                   = paUInt8\r
+       };\r
+\r
+\r
+} // namespace portaudio\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#endif // INCLUDED_PORTAUDIO_SAMPLEDATAFORMAT_HXX\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/Stream.hxx b/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/Stream.hxx
new file mode 100644 (file)
index 0000000..8a255ec
--- /dev/null
@@ -0,0 +1,82 @@
+#ifndef INCLUDED_PORTAUDIO_STREAM_HXX\r
+#define INCLUDED_PORTAUDIO_STREAM_HXX\r
+\r
+#include "portaudio.h"\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// Forward declaration(s):\r
+namespace portaudio\r
+{\r
+       class StreamParameters;\r
+}\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// Declaration(s):\r
+namespace portaudio\r
+{\r
+\r
+\r
+       //////\r
+       /// @brief A Stream represents an active or inactive input and/or output data \r
+       /// stream in the System.\r
+       /// \r
+       /// Concrete Stream classes should ensure themselves being in a closed state at \r
+       /// destruction (i.e. by calling their own close() method in their deconstructor). \r
+       /// Following good C++ programming practices, care must be taken to ensure no \r
+       /// exceptions are thrown by the deconstructor of these classes. As a consequence, \r
+       /// clients need to explicitly call close() to ensure the stream closed successfully.\r
+       ///\r
+       /// The Stream object can be used to manipulate the Stream's state. Also, time-constant \r
+       /// and time-varying information about the Stream can be retreived.\r
+       //////\r
+       class Stream\r
+       {\r
+       public:\r
+               // Opening/closing:\r
+               virtual ~Stream();\r
+\r
+               virtual void close();\r
+               bool isOpen() const;\r
+\r
+               // Additional set up:\r
+               void setStreamFinishedCallback(PaStreamFinishedCallback *callback);\r
+\r
+               // State management:\r
+               void start();\r
+               void stop();\r
+               void abort();\r
+\r
+               bool isStopped() const;\r
+               bool isActive() const;\r
+\r
+               // Stream info (time-constant, but might become time-variant soon):\r
+               PaTime inputLatency() const;\r
+               PaTime outputLatency() const;\r
+               double sampleRate() const;\r
+\r
+               // Stream info (time-varying):\r
+               PaTime time() const;\r
+\r
+               // Accessors for PortAudio PaStream, useful for interfacing \r
+               // with PortAudio add-ons (such as PortMixer) for instance:\r
+               const PaStream *paStream() const;\r
+               PaStream *paStream();\r
+\r
+       protected:\r
+               Stream(); // abstract class\r
+\r
+               PaStream *stream_;\r
+\r
+       private:\r
+               Stream(const Stream &); // non-copyable\r
+               Stream &operator=(const Stream &); // non-copyable\r
+       };\r
+\r
+\r
+} // namespace portaudio\r
+\r
+\r
+#endif // INCLUDED_PORTAUDIO_STREAM_HXX\r
+\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/StreamParameters.hxx b/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/StreamParameters.hxx
new file mode 100644 (file)
index 0000000..2b6aa2e
--- /dev/null
@@ -0,0 +1,77 @@
+#ifndef INCLUDED_PORTAUDIO_STREAMPARAMETERS_HXX\r
+#define INCLUDED_PORTAUDIO_STREAMPARAMETERS_HXX\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#include "portaudio.h"\r
+\r
+#include "portaudiocpp/DirectionSpecificStreamParameters.hxx"\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// Declaration(s):\r
+namespace portaudio\r
+{\r
+\r
+       //////\r
+       /// @brief The entire set of parameters needed to configure and open \r
+       /// a Stream.\r
+       ///\r
+       /// It contains parameters of input, output and shared parameters. \r
+       /// Using the isSupported() method, the StreamParameters can be \r
+       /// checked if opening a Stream using this StreamParameters would \r
+       /// succeed or not. Accessors are provided to higher-level parameters \r
+       /// aswell as the lower-level parameters which are mainly intended for \r
+       /// internal use.\r
+       //////\r
+       class StreamParameters\r
+       {\r
+       public:\r
+               StreamParameters();\r
+               StreamParameters(const DirectionSpecificStreamParameters &inputParameters, \r
+                       const DirectionSpecificStreamParameters &outputParameters, double sampleRate, \r
+                       unsigned long framesPerBuffer, PaStreamFlags flags);\r
+\r
+               // Set up for direction-specific:\r
+               void setInputParameters(const DirectionSpecificStreamParameters &parameters);\r
+               void setOutputParameters(const DirectionSpecificStreamParameters &parameters);\r
+\r
+               // Set up for common parameters:\r
+               void setSampleRate(double sampleRate);\r
+               void setFramesPerBuffer(unsigned long framesPerBuffer);\r
+               void setFlag(PaStreamFlags flag);\r
+               void unsetFlag(PaStreamFlags flag);\r
+               void clearFlags();\r
+\r
+               // Validation:\r
+               bool isSupported() const;\r
+\r
+               // Accessors (direction-specific):\r
+               DirectionSpecificStreamParameters &inputParameters();\r
+               const DirectionSpecificStreamParameters &inputParameters() const;\r
+               DirectionSpecificStreamParameters &outputParameters();\r
+               const DirectionSpecificStreamParameters &outputParameters() const;\r
+\r
+               // Accessors (common):\r
+               double sampleRate() const;\r
+               unsigned long framesPerBuffer() const;\r
+               PaStreamFlags flags() const;\r
+               bool isFlagSet(PaStreamFlags flag) const;\r
+\r
+       private:\r
+               // Half-duplex specific parameters:\r
+               DirectionSpecificStreamParameters inputParameters_;\r
+               DirectionSpecificStreamParameters outputParameters_;\r
+\r
+               // Common parameters:\r
+               double sampleRate_;\r
+               unsigned long framesPerBuffer_;\r
+               PaStreamFlags flags_;\r
+       };\r
+\r
+\r
+} // namespace portaudio\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#endif // INCLUDED_PORTAUDIO_STREAMPARAMETERS_HXX\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/System.hxx b/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/System.hxx
new file mode 100644 (file)
index 0000000..f5fb713
--- /dev/null
@@ -0,0 +1,107 @@
+#ifndef INCLUDED_PORTAUDIO_SYSTEM_HXX\r
+#define INCLUDED_PORTAUDIO_SYSTEM_HXX\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#include "portaudio.h"\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// Forward declaration(s):\r
+namespace portaudio\r
+{\r
+       class Device;\r
+       class Stream;\r
+       class HostApi;\r
+}\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// Declaration(s):\r
+namespace portaudio\r
+{\r
+\r
+\r
+       //////\r
+       /// @brief System singleton which represents the PortAudio system.\r
+       ///\r
+       /// The System is used to initialize/terminate PortAudio and provide \r
+       /// a single acccess point to the PortAudio System (instance()).\r
+       /// It can be used to iterate through all HostApi 's in the System as \r
+       /// well as all devices in the System. It also provides some utility \r
+       /// functionality of PortAudio.\r
+       ///\r
+       /// Terminating the System will also abort and close the open streams. \r
+       /// The Stream objects will need to be deallocated by the client though \r
+       /// (it's usually a good idea to have them cleaned up automatically).\r
+       //////\r
+       class System\r
+       {\r
+       public:\r
+               class HostApiIterator; // forward declaration\r
+               class DeviceIterator; // forward declaration\r
+\r
+               // -------------------------------------------------------------------------------\r
+\r
+               static int version();\r
+               static const char *versionText();\r
+\r
+               static void initialize();\r
+               static void terminate();\r
+\r
+               static System &instance();\r
+               static bool exists();\r
+\r
+               // -------------------------------------------------------------------------------\r
+\r
+               // host apis:\r
+               HostApiIterator hostApisBegin();\r
+               HostApiIterator hostApisEnd();\r
+\r
+               HostApi &defaultHostApi();\r
+\r
+               HostApi &hostApiByTypeId(PaHostApiTypeId type);\r
+               HostApi &hostApiByIndex(PaHostApiIndex index);\r
+\r
+               int hostApiCount();\r
+\r
+               // -------------------------------------------------------------------------------\r
+\r
+               // devices:\r
+               DeviceIterator devicesBegin();\r
+               DeviceIterator devicesEnd();\r
+\r
+               Device &defaultInputDevice();\r
+               Device &defaultOutputDevice();\r
+\r
+               Device &deviceByIndex(PaDeviceIndex index);\r
+\r
+               int deviceCount();\r
+\r
+               static Device &nullDevice();\r
+\r
+               // -------------------------------------------------------------------------------\r
+\r
+               // misc:\r
+               void sleep(long msec);\r
+               int sizeOfSample(PaSampleFormat format);\r
+\r
+       private:\r
+               System();\r
+               ~System();\r
+\r
+               static System *instance_;\r
+               static int initCount_;\r
+\r
+               static HostApi **hostApis_;\r
+               static Device **devices_;\r
+\r
+               static Device *nullDevice_;\r
+       };\r
+\r
+\r
+} // namespace portaudio\r
+\r
+\r
+#endif // INCLUDED_PORTAUDIO_SYSTEM_HXX\r
+\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/SystemDeviceIterator.hxx b/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/SystemDeviceIterator.hxx
new file mode 100644 (file)
index 0000000..613fc3d
--- /dev/null
@@ -0,0 +1,66 @@
+#ifndef INCLUDED_PORTAUDIO_SYSTEMDEVICEITERATOR_HXX\r
+#define INCLUDED_PORTAUDIO_SYSTEMDEVICEITERATOR_HXX\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#include <iterator>\r
+#include <cstddef>\r
+\r
+#include "portaudiocpp/System.hxx"\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// Forward declaration(s):\r
+namespace portaudio\r
+{\r
+       class Device;\r
+       class HostApi;\r
+}\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// Declaration(s):\r
+namespace portaudio\r
+{\r
+\r
+       \r
+       //////\r
+       /// @brief Iterator class for iterating through all Devices in a System.\r
+       ///\r
+       /// Devices will be iterated by iterating all Devices in each \r
+       /// HostApi in the System. Compliant with the STL bidirectional \r
+       /// iterator concept.\r
+       //////\r
+       class System::DeviceIterator\r
+       {\r
+       public:\r
+               typedef std::bidirectional_iterator_tag iterator_category;\r
+               typedef Device value_type;\r
+               typedef ptrdiff_t difference_type;\r
+               typedef Device * pointer;\r
+               typedef Device & reference;\r
+\r
+               Device &operator*() const;\r
+               Device *operator->() const;\r
+\r
+               DeviceIterator &operator++();\r
+               DeviceIterator operator++(int);\r
+               DeviceIterator &operator--();\r
+               DeviceIterator operator--(int);\r
+\r
+               bool operator==(const DeviceIterator &rhs);\r
+               bool operator!=(const DeviceIterator &rhs);\r
+\r
+       private:\r
+               friend class System;\r
+               friend class HostApi;\r
+               Device **ptr_;\r
+       };\r
+\r
+\r
+} // namespace portaudio\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#endif // INCLUDED_PORTAUDIO_SYSTEMDEVICEITERATOR_HXX\r
+\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/SystemHostApiIterator.hxx b/utils/iaxclient/lib/portaudio/bindings/cpp/include/portaudiocpp/SystemHostApiIterator.hxx
new file mode 100644 (file)
index 0000000..b9b13b8
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef INCLUDED_PORTAUDIO_SYSTEMHOSTAPIITERATOR_HXX\r
+#define INCLUDED_PORTAUDIO_SYSTEMHOSTAPIITERATOR_HXX\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#include <iterator>\r
+#include <cstddef>\r
+\r
+#include "portaudiocpp/System.hxx"\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// Forward declaration(s):\r
+namespace portaudio\r
+{\r
+       class HostApi;\r
+}\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+// Declaration(s):\r
+namespace portaudio\r
+{\r
+\r
+\r
+       //////\r
+       /// @brief Iterator class for iterating through all HostApis in a System.\r
+       ///\r
+       /// Compliant with the STL bidirectional iterator concept.\r
+       //////\r
+       class System::HostApiIterator\r
+       {\r
+       public:\r
+               typedef std::bidirectional_iterator_tag iterator_category;\r
+               typedef Device value_type;\r
+               typedef ptrdiff_t difference_type;\r
+               typedef HostApi * pointer;\r
+               typedef HostApi & reference;\r
+\r
+               HostApi &operator*() const;\r
+               HostApi *operator->() const;\r
+\r
+               HostApiIterator &operator++();\r
+               HostApiIterator operator++(int);\r
+               HostApiIterator &operator--();\r
+               HostApiIterator operator--(int);\r
+\r
+               bool operator==(const HostApiIterator &rhs);\r
+               bool operator!=(const HostApiIterator &rhs);\r
+\r
+       private:\r
+               friend class System;\r
+               HostApi **ptr_;\r
+       };\r
+\r
+\r
+} // namespace portaudio\r
+\r
+// ---------------------------------------------------------------------------------------\r
+\r
+#endif // INCLUDED_PORTAUDIO_SYSTEMHOSTAPIITERATOR_HXX\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/AsioDeviceAdapter.cxx b/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/AsioDeviceAdapter.cxx
new file mode 100644 (file)
index 0000000..c4ee25f
--- /dev/null
@@ -0,0 +1,83 @@
+#include "portaudiocpp/AsioDeviceAdapter.hxx"\r
+\r
+#include "portaudio.h"\r
+#include "pa_asio.h"\r
+\r
+#include "portaudiocpp/Device.hxx"\r
+#include "portaudiocpp/HostApi.hxx"\r
+#include "portaudiocpp/Exception.hxx"\r
+\r
+namespace portaudio\r
+{\r
+       AsioDeviceAdapter::AsioDeviceAdapter(Device &device)\r
+       {\r
+               if (device.hostApi().typeId() != paASIO)\r
+                       throw PaCppException(PaCppException::UNABLE_TO_ADAPT_DEVICE);\r
+\r
+               device_ = &device;\r
+\r
+               PaError err = PaAsio_GetAvailableLatencyValues(device_->index(), &minBufferSize_, &maxBufferSize_, \r
+                       &preferredBufferSize_, &granularity_);\r
+\r
+               if (err != paNoError)\r
+                       throw PaException(err);\r
+\r
+       }\r
+\r
+       Device &AsioDeviceAdapter::device()\r
+       {\r
+               return *device_;\r
+       }\r
+\r
+       long AsioDeviceAdapter::minBufferSize() const\r
+       {\r
+               return minBufferSize_;\r
+       }\r
+\r
+       long AsioDeviceAdapter::maxBufferSize() const\r
+       {\r
+               return maxBufferSize_;\r
+       }\r
+\r
+       long AsioDeviceAdapter::preferredBufferSize() const\r
+       {\r
+               return preferredBufferSize_;\r
+       }\r
+\r
+       long AsioDeviceAdapter::granularity() const\r
+       {\r
+               return granularity_;\r
+       }\r
+\r
+       void AsioDeviceAdapter::showControlPanel(void *systemSpecific)\r
+       {\r
+               PaError err = PaAsio_ShowControlPanel(device_->index(), systemSpecific);\r
+\r
+               if (err != paNoError)\r
+                       throw PaException(err);\r
+       }\r
+\r
+       const char *AsioDeviceAdapter::inputChannelName(int channelIndex) const\r
+       {\r
+               const char *channelName;\r
+               PaError err = PaAsio_GetInputChannelName(device_->index(), channelIndex, &channelName);
+
+               if (err != paNoError)
+                       throw PaException(err);
+
+               return channelName;
+       }\r
+\r
+       const char *AsioDeviceAdapter::outputChannelName(int channelIndex) const\r
+       {\r
+               const char *channelName;\r
+               PaError err = PaAsio_GetOutputChannelName(device_->index(), channelIndex, &channelName);
+
+               if (err != paNoError)
+                       throw PaException(err);
+
+               return channelName;
+       }\r
+}\r
+\r
+\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/BlockingStream.cxx b/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/BlockingStream.cxx
new file mode 100644 (file)
index 0000000..c21535f
--- /dev/null
@@ -0,0 +1,100 @@
+#include "portaudiocpp/BlockingStream.hxx"\r
+\r
+#include "portaudio.h"\r
+\r
+#include "portaudiocpp/StreamParameters.hxx"\r
+#include "portaudiocpp/Exception.hxx"\r
+\r
+namespace portaudio\r
+{\r
+\r
+       // --------------------------------------------------------------------------------------\r
+\r
+       BlockingStream::BlockingStream()\r
+       {\r
+       }\r
+\r
+       BlockingStream::BlockingStream(const StreamParameters &parameters)\r
+       {\r
+               open(parameters);\r
+       }\r
+\r
+       BlockingStream::~BlockingStream()\r
+       {\r
+               try\r
+               {\r
+                       close();\r
+               }\r
+               catch (...)\r
+               {\r
+                       // ignore all errors\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------------------------\r
+\r
+       void BlockingStream::open(const StreamParameters &parameters)\r
+       {\r
+               PaError err = Pa_OpenStream(&stream_, parameters.inputParameters().paStreamParameters(), parameters.outputParameters().paStreamParameters(), \r
+                       parameters.sampleRate(), parameters.framesPerBuffer(), parameters.flags(), NULL, NULL);\r
+\r
+               if (err != paNoError)\r
+               {\r
+                       throw PaException(err);\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------------------------\r
+\r
+       void BlockingStream::read(void *buffer, unsigned long numFrames)\r
+       {\r
+               PaError err = Pa_ReadStream(stream_, buffer, numFrames);\r
+\r
+               if (err != paNoError)\r
+               {\r
+                       throw PaException(err);\r
+               }\r
+       }\r
+\r
+       void BlockingStream::write(const void *buffer, unsigned long numFrames)\r
+       {\r
+               PaError err = Pa_WriteStream(stream_, buffer, numFrames);\r
+\r
+               if (err != paNoError)\r
+               {\r
+                       throw PaException(err);\r
+               }\r
+       }\r
+\r
+       // --------------------------------------------------------------------------------------\r
+\r
+       signed long BlockingStream::availableReadSize() const\r
+       {\r
+               signed long avail = Pa_GetStreamReadAvailable(stream_);\r
+\r
+               if (avail < 0)\r
+               {\r
+                       throw PaException(avail);\r
+               }\r
+\r
+               return avail;\r
+       }\r
+\r
+       signed long BlockingStream::availableWriteSize() const\r
+       {\r
+               signed long avail = Pa_GetStreamWriteAvailable(stream_);\r
+\r
+               if (avail < 0)\r
+               {\r
+                       throw PaException(avail);\r
+               }\r
+\r
+               return avail;\r
+       }\r
+\r
+       // --------------------------------------------------------------------------------------\r
+\r
+} // portaudio\r
+\r
+\r
+\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/CFunCallbackStream.cxx b/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/CFunCallbackStream.cxx
new file mode 100644 (file)
index 0000000..fd2fb53
--- /dev/null
@@ -0,0 +1,41 @@
+#include "portaudiocpp/CFunCallbackStream.hxx"\r
+\r
+#include "portaudiocpp/StreamParameters.hxx"\r
+#include "portaudiocpp/Exception.hxx"\r
+\r
+namespace portaudio\r
+{\r
+       CFunCallbackStream::CFunCallbackStream()\r
+       {\r
+       }\r
+\r
+       CFunCallbackStream::CFunCallbackStream(const StreamParameters &parameters, PaStreamCallback *funPtr, void *userData)\r
+       {\r
+               open(parameters, funPtr, userData);\r
+       }\r
+\r
+       CFunCallbackStream::~CFunCallbackStream()\r
+       {\r
+               try\r
+               {\r
+                       close();\r
+               }\r
+               catch (...)\r
+               {\r
+                       // ignore all errors\r
+               }\r
+       }\r
+\r
+       // ---------------------------------------------------------------------------------==\r
+\r
+       void CFunCallbackStream::open(const StreamParameters &parameters, PaStreamCallback *funPtr, void *userData)\r
+       {\r
+               PaError err = Pa_OpenStream(&stream_, parameters.inputParameters().paStreamParameters(), parameters.outputParameters().paStreamParameters(), \r
+                       parameters.sampleRate(), parameters.framesPerBuffer(), parameters.flags(), funPtr, userData);\r
+\r
+               if (err != paNoError)\r
+               {\r
+                       throw PaException(err);\r
+               }\r
+       }\r
+}\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/CallbackInterface.cxx b/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/CallbackInterface.cxx
new file mode 100644 (file)
index 0000000..7e34312
--- /dev/null
@@ -0,0 +1,25 @@
+#include "portaudiocpp/CallbackInterface.hxx"\r
+\r
+namespace portaudio\r
+{\r
+\r
+       namespace impl\r
+       {\r
+\r
+               //////\r
+               /// Adapts any CallbackInterface object to a C-callable function (ie this function). A \r
+               /// pointer to the object should be passed as ``userData'' when setting up the callback.\r
+               //////\r
+               int callbackInterfaceToPaCallbackAdapter(const void *inputBuffer, void *outputBuffer, unsigned long numFrames, \r
+                       const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData)\r
+               {\r
+                       CallbackInterface *cb = static_cast<CallbackInterface *>(userData);\r
+                       return cb->paCallbackFun(inputBuffer, outputBuffer, numFrames, timeInfo, statusFlags);\r
+               }\r
+\r
+\r
+       } // namespace impl\r
+\r
+} // namespace portaudio\r
+\r
+\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/CallbackStream.cxx b/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/CallbackStream.cxx
new file mode 100644 (file)
index 0000000..4204dbb
--- /dev/null
@@ -0,0 +1,20 @@
+#include "portaudiocpp/CallbackStream.hxx"\r
+\r
+namespace portaudio\r
+{\r
+       CallbackStream::CallbackStream()\r
+       {\r
+       }\r
+\r
+       CallbackStream::~CallbackStream()\r
+       {\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+       \r
+       double CallbackStream::cpuLoad() const\r
+       {\r
+               return Pa_GetStreamCpuLoad(stream_);\r
+       }\r
+\r
+} // namespace portaudio\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/CppFunCallbackStream.cxx b/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/CppFunCallbackStream.cxx
new file mode 100644 (file)
index 0000000..9538139
--- /dev/null
@@ -0,0 +1,81 @@
+#include "portaudiocpp/CppFunCallbackStream.hxx"\r
+\r
+#include "portaudiocpp/StreamParameters.hxx"\r
+#include "portaudiocpp/Exception.hxx"\r
+\r
+namespace portaudio\r
+{\r
+       namespace impl\r
+       {\r
+               //////\r
+               /// Adapts any a C++ callback to a C-callable function (ie this function). A \r
+               /// pointer to a struct with the C++ function pointer and the actual user data should be \r
+               /// passed as the ``userData'' parameter when setting up the callback.\r
+               //////\r
+               int cppCallbackToPaCallbackAdapter(const void *inputBuffer, void *outputBuffer, unsigned long numFrames, \r
+                       const PaStreamCallbackTimeInfo *timeInfo, PaStreamCallbackFlags statusFlags, void *userData)\r
+               {\r
+                       FunCallbackStream::CppToCCallbackData *data = static_cast<FunCallbackStream::CppToCCallbackData *>(userData);\r
+                       return data->funPtr(inputBuffer, outputBuffer, numFrames, timeInfo, statusFlags, data->userData);\r
+               }\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       FunCallbackStream::CppToCCallbackData::CppToCCallbackData()\r
+       {\r
+       }\r
+\r
+       FunCallbackStream::CppToCCallbackData::CppToCCallbackData(CallbackFunPtr funPtr, void *userData) : funPtr(funPtr), userData(userData)\r
+       {\r
+       }\r
+\r
+       void FunCallbackStream::CppToCCallbackData::init(CallbackFunPtr funPtr, void *userData)\r
+       {\r
+               this->funPtr = funPtr;\r
+               this->userData = userData;\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       FunCallbackStream::FunCallbackStream()\r
+       {\r
+       }\r
+\r
+       FunCallbackStream::FunCallbackStream(const StreamParameters &parameters, CallbackFunPtr funPtr, void *userData) : adapterData_(funPtr, userData)\r
+       {\r
+               open(parameters);\r
+       }\r
+\r
+       FunCallbackStream::~FunCallbackStream()\r
+       {\r
+               try\r
+               {\r
+                       close();\r
+               }\r
+               catch (...)\r
+               {\r
+                       // ignore all errors\r
+               }\r
+       }\r
+\r
+       void FunCallbackStream::open(const StreamParameters &parameters, CallbackFunPtr funPtr, void *userData)\r
+       {\r
+               adapterData_.init(funPtr, userData);\r
+               open(parameters);\r
+       }\r
+\r
+       void FunCallbackStream::open(const StreamParameters &parameters)\r
+       {\r
+               PaError err = Pa_OpenStream(&stream_, parameters.inputParameters().paStreamParameters(), parameters.outputParameters().paStreamParameters(), \r
+                       parameters.sampleRate(), parameters.framesPerBuffer(), parameters.flags(), &impl::cppCallbackToPaCallbackAdapter, \r
+                       static_cast<void *>(&adapterData_));\r
+\r
+               if (err != paNoError)\r
+               {\r
+                       throw PaException(err);\r
+               }\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+}\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/Device.cxx b/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/Device.cxx
new file mode 100644 (file)
index 0000000..cd7eb7c
--- /dev/null
@@ -0,0 +1,168 @@
+#include "portaudiocpp/Device.hxx"\r
+\r
+#include <cstddef>\r
+\r
+#include "portaudiocpp/HostApi.hxx"\r
+#include "portaudiocpp/System.hxx"\r
+#include "portaudiocpp/Exception.hxx"\r
+\r
+namespace portaudio\r
+{\r
+\r
+               // -------------------------------------------------------------------------------\r
+\r
+               Device::Device(PaDeviceIndex index) : index_(index)\r
+               {\r
+                       if (index == paNoDevice)\r
+                               info_ = NULL;\r
+                       else\r
+                               info_ = Pa_GetDeviceInfo(index);\r
+               }\r
+\r
+               Device::~Device()\r
+               {\r
+               }\r
+\r
+               PaDeviceIndex Device::index() const\r
+               {\r
+                       return index_;\r
+               }\r
+\r
+               const char *Device::name() const\r
+               {\r
+                       if (info_ == NULL)\r
+                               return "";\r
+\r
+                       return info_->name;\r
+               }\r
+\r
+               int Device::maxInputChannels() const\r
+               {\r
+                       if (info_ == NULL)\r
+                               return 0;\r
+\r
+                       return info_->maxInputChannels;\r
+               }\r
+\r
+               int Device::maxOutputChannels() const\r
+               {\r
+                       if (info_ == NULL)\r
+                               return 0;\r
+\r
+                       return info_->maxOutputChannels;\r
+               }\r
+\r
+               PaTime Device::defaultLowInputLatency() const\r
+               {\r
+                       if (info_ == NULL)\r
+                               return static_cast<PaTime>(0.0);\r
+\r
+                       return info_->defaultLowInputLatency;\r
+               }\r
+\r
+               PaTime Device::defaultHighInputLatency() const\r
+               {\r
+                       if (info_ == NULL)\r
+                               return static_cast<PaTime>(0.0);\r
+\r
+                       return info_->defaultHighInputLatency;\r
+               }\r
+\r
+               PaTime Device::defaultLowOutputLatency() const\r
+               {\r
+                       if (info_ == NULL)\r
+                               return static_cast<PaTime>(0.0);\r
+\r
+                       return info_->defaultLowOutputLatency;\r
+               }\r
+\r
+               PaTime Device::defaultHighOutputLatency() const\r
+               {\r
+                       if (info_ == NULL)\r
+                               return static_cast<PaTime>(0.0);\r
+\r
+                       return info_->defaultHighOutputLatency;\r
+               }\r
+\r
+               double Device::defaultSampleRate() const\r
+               {\r
+                       if (info_ == NULL)\r
+                               return 0.0;\r
+\r
+                       return info_->defaultSampleRate;\r
+               }\r
+\r
+               // -------------------------------------------------------------------------------\r
+\r
+               bool Device::isInputOnlyDevice() const\r
+               {\r
+                       return (maxOutputChannels() == 0);\r
+               }\r
+\r
+               bool Device::isOutputOnlyDevice() const\r
+               {\r
+                       return (maxInputChannels() == 0);\r
+               }\r
+\r
+               bool Device::isFullDuplexDevice() const\r
+               {\r
+                       return (maxInputChannels() > 0 && maxOutputChannels() > 0);\r
+               }\r
+\r
+               bool Device::isSystemDefaultInputDevice() const\r
+               {\r
+                       return (System::instance().defaultInputDevice() == *this);\r
+               }\r
+\r
+               bool Device::isSystemDefaultOutputDevice() const\r
+               {\r
+                       return (System::instance().defaultOutputDevice() == *this);\r
+               }\r
+\r
+               bool Device::isHostApiDefaultInputDevice() const\r
+               {\r
+                       return (hostApi().defaultInputDevice() == *this);\r
+               }\r
+\r
+               bool Device::isHostApiDefaultOutputDevice() const\r
+               {\r
+                       return (hostApi().defaultOutputDevice() == *this);\r
+               }\r
+\r
+               // -------------------------------------------------------------------------------\r
+\r
+               bool Device::operator==(const Device &rhs)\r
+               {\r
+                       return (index_ == rhs.index_);\r
+               }\r
+\r
+               bool Device::operator!=(const Device &rhs)\r
+               {\r
+                       return !(*this == rhs);\r
+               }\r
+\r
+               // -------------------------------------------------------------------------------\r
+\r
+               HostApi &Device::hostApi()\r
+               {\r
+                       // NOTE: will cause an exception when called for the null device\r
+                       if (info_ == NULL)\r
+                               throw PaException(paInternalError);\r
+\r
+                       return System::instance().hostApiByIndex(info_->hostApi);\r
+               }\r
+\r
+               const HostApi &Device::hostApi() const\r
+               {\r
+                       // NOTE; will cause an exception when called for the null device\r
+                       if (info_ == NULL)\r
+                               throw PaException(paInternalError);\r
+\r
+                       return System::instance().hostApiByIndex(info_->hostApi);\r
+               }\r
+\r
+               // -------------------------------------------------------------------------------\r
+\r
+} // namespace portaudio\r
+\r
+\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/DirectionSpecificStreamParameters.cxx b/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/DirectionSpecificStreamParameters.cxx
new file mode 100644 (file)
index 0000000..d3c307c
--- /dev/null
@@ -0,0 +1,163 @@
+#include "portaudiocpp/DirectionSpecificStreamParameters.hxx"\r
+\r
+#include "portaudiocpp/Device.hxx"\r
+\r
+namespace portaudio\r
+{\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       //////\r
+       /// Returns a `nil' DirectionSpecificStreamParameters object. This can be used to \r
+       /// specify that one direction of a Stream is not required (i.e. when creating \r
+       /// a half-duplex Stream). All fields of the null DirectionSpecificStreamParameters \r
+       /// object are invalid except for the device and the number of channel, which are set \r
+       /// to paNoDevice and 0 respectively.\r
+       //////\r
+       DirectionSpecificStreamParameters DirectionSpecificStreamParameters::null()\r
+       {\r
+               DirectionSpecificStreamParameters tmp;\r
+               tmp.paStreamParameters_.device = paNoDevice;\r
+               tmp.paStreamParameters_.channelCount = 0;\r
+               return tmp;\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       //////\r
+       /// Default constructor -- all parameters will be uninitialized.\r
+       //////\r
+       DirectionSpecificStreamParameters::DirectionSpecificStreamParameters()\r
+       {\r
+       }\r
+\r
+       //////\r
+       /// Constructor which sets all required fields.\r
+       //////\r
+       DirectionSpecificStreamParameters::DirectionSpecificStreamParameters(const Device &device, int numChannels, \r
+               SampleDataFormat format, bool interleaved, PaTime suggestedLatency, void *hostApiSpecificStreamInfo)\r
+       {\r
+               setDevice(device);\r
+               setNumChannels(numChannels);\r
+               setSampleFormat(format, interleaved);\r
+               setSuggestedLatency(suggestedLatency);\r
+               setHostApiSpecificStreamInfo(hostApiSpecificStreamInfo);\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       void DirectionSpecificStreamParameters::setDevice(const Device &device)\r
+       {\r
+               paStreamParameters_.device = device.index();\r
+       }\r
+\r
+       void DirectionSpecificStreamParameters::setNumChannels(int numChannels)\r
+       {\r
+               paStreamParameters_.channelCount = numChannels;\r
+       }\r
+\r
+       void DirectionSpecificStreamParameters::setSampleFormat(SampleDataFormat format, bool interleaved)\r
+       {\r
+               paStreamParameters_.sampleFormat = static_cast<PaSampleFormat>(format);\r
+\r
+               if (!interleaved)\r
+                       paStreamParameters_.sampleFormat |= paNonInterleaved;\r
+       }\r
+\r
+       void DirectionSpecificStreamParameters::setHostApiSpecificSampleFormat(PaSampleFormat format, bool interleaved)\r
+       {\r
+               paStreamParameters_.sampleFormat = format;\r
+\r
+               paStreamParameters_.sampleFormat |= paCustomFormat;\r
+\r
+               if (!interleaved)\r
+                       paStreamParameters_.sampleFormat |= paNonInterleaved;\r
+       }\r
+\r
+       void DirectionSpecificStreamParameters::setSuggestedLatency(PaTime latency)\r
+       {\r
+               paStreamParameters_.suggestedLatency = latency;\r
+       }\r
+\r
+       void DirectionSpecificStreamParameters::setHostApiSpecificStreamInfo(void *streamInfo)\r
+       {\r
+               paStreamParameters_.hostApiSpecificStreamInfo = streamInfo;\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       PaStreamParameters *DirectionSpecificStreamParameters::paStreamParameters()\r
+       {\r
+               if (paStreamParameters_.channelCount > 0 && paStreamParameters_.device != paNoDevice)\r
+                       return &paStreamParameters_;\r
+               else\r
+                       return NULL;\r
+       }\r
+\r
+       const PaStreamParameters *DirectionSpecificStreamParameters::paStreamParameters() const\r
+       {\r
+               if (paStreamParameters_.channelCount > 0 && paStreamParameters_.device != paNoDevice)\r
+                       return &paStreamParameters_;\r
+               else\r
+                       return NULL;\r
+       }\r
+\r
+       Device &DirectionSpecificStreamParameters::device() const\r
+       {\r
+               return System::instance().deviceByIndex(paStreamParameters_.device);\r
+       }\r
+\r
+       int DirectionSpecificStreamParameters::numChannels() const\r
+       {\r
+               return paStreamParameters_.channelCount;\r
+       }\r
+\r
+       //////\r
+       /// Returns the (non host api-specific) sample format, without including \r
+       /// the paNonInterleaved flag. If the sample format is host api-spefific, \r
+       /// INVALID_FORMAT (0) will be returned.\r
+       //////\r
+       SampleDataFormat DirectionSpecificStreamParameters::sampleFormat() const\r
+       {\r
+               if (isSampleFormatHostApiSpecific())\r
+                       return INVALID_FORMAT;\r
+               else\r
+                       return static_cast<SampleDataFormat>(paStreamParameters_.sampleFormat & ~paNonInterleaved);\r
+       }\r
+\r
+       bool DirectionSpecificStreamParameters::isSampleFormatInterleaved() const\r
+       {\r
+               return ((paStreamParameters_.sampleFormat & paNonInterleaved) == 0);\r
+       }\r
+\r
+       bool DirectionSpecificStreamParameters::isSampleFormatHostApiSpecific() const\r
+       {\r
+               return ((paStreamParameters_.sampleFormat & paCustomFormat) == 0);\r
+       }\r
+\r
+       //////\r
+       /// Returns the host api-specific sample format, without including any \r
+       /// paCustomFormat or paNonInterleaved flags. Will return 0 if the sample format is \r
+       /// not host api-specific.\r
+       //////\r
+       PaSampleFormat DirectionSpecificStreamParameters::hostApiSpecificSampleFormat() const\r
+       {\r
+               if (isSampleFormatHostApiSpecific())\r
+                       return paStreamParameters_.sampleFormat & ~paCustomFormat & ~paNonInterleaved;\r
+               else\r
+                       return 0;\r
+       }\r
+\r
+       PaTime DirectionSpecificStreamParameters::suggestedLatency() const\r
+       {\r
+               return paStreamParameters_.suggestedLatency;\r
+       }\r
+\r
+       void *DirectionSpecificStreamParameters::hostApiSpecificStreamInfo() const\r
+       {\r
+               return paStreamParameters_.hostApiSpecificStreamInfo;\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+} // namespace portaudio\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/Exception.cxx b/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/Exception.cxx
new file mode 100644 (file)
index 0000000..2e7e701
--- /dev/null
@@ -0,0 +1,123 @@
+#include "portaudiocpp/Exception.hxx"\r
+\r
+namespace portaudio\r
+{\r
+       // -----------------------------------------------------------------------------------\r
+       // PaException:\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       //////\r
+       ///  Wraps a PortAudio error into a PortAudioCpp PaException.\r
+       //////\r
+       PaException::PaException(PaError error) : error_(error)\r
+       {\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       //////\r
+       /// Alias for paErrorText(), to have std::exception compliance.\r
+       //////\r
+       const char *PaException::what() const throw()\r
+       {\r
+               return paErrorText();\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       //////\r
+       /// Returns the PortAudio error code (PaError).\r
+       //////\r
+       PaError PaException::paError() const\r
+       {\r
+               return error_;\r
+       }\r
+\r
+       //////\r
+       /// Returns the error as a (zero-terminated) text string.\r
+       //////\r
+       const char *PaException::paErrorText() const\r
+       {\r
+               return Pa_GetErrorText(error_);\r
+       }\r
+\r
+       //////\r
+       /// Returns true is the error is a HostApi error.\r
+       //////\r
+       bool PaException::isHostApiError() const\r
+       {\r
+               return (error_ == paUnanticipatedHostError);\r
+       }\r
+\r
+       //////\r
+       /// Returns the last HostApi error (which is the current one if \r
+       /// isHostApiError() returns true) as an error code.\r
+       //////\r
+       long PaException::lastHostApiError() const\r
+       {\r
+               return Pa_GetLastHostErrorInfo()->errorCode;\r
+       }\r
+\r
+       //////\r
+       /// Returns the last HostApi error (which is the current one if \r
+       /// isHostApiError() returns true) as a (zero-terminated) text \r
+       /// string, if it's available.\r
+       //////\r
+       const char *PaException::lastHostApiErrorText() const\r
+       {\r
+               return Pa_GetLastHostErrorInfo()->errorText;\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       bool PaException::operator==(const PaException &rhs) const\r
+       {\r
+               return (error_ == rhs.error_);\r
+       }\r
+\r
+       bool PaException::operator!=(const PaException &rhs) const\r
+       {\r
+               return !(*this == rhs);\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+       // PaCppException:\r
+       // -----------------------------------------------------------------------------------\r
+       \r
+       PaCppException::PaCppException(ExceptionSpecifier specifier) : specifier_(specifier)\r
+       {\r
+       }\r
+\r
+       const char *PaCppException::what() const throw()\r
+       {\r
+               switch (specifier_)\r
+               {\r
+                       case UNABLE_TO_ADAPT_DEVICE:\r
+                       {\r
+                               return "Unable to adapt the given device to the specified host api specific device extension";\r
+                       }\r
+               }\r
+\r
+               return "Unknown exception";\r
+       }\r
+\r
+       PaCppException::ExceptionSpecifier PaCppException::specifier() const\r
+       {\r
+               return specifier_;\r
+       }\r
+\r
+       bool PaCppException::operator==(const PaCppException &rhs) const\r
+       {\r
+               return (specifier_ == rhs.specifier_);\r
+       }\r
+\r
+       bool PaCppException::operator!=(const PaCppException &rhs) const\r
+       {\r
+               return !(*this == rhs);\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+} // namespace portaudio\r
+\r
+\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/HostApi.cxx b/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/HostApi.cxx
new file mode 100644 (file)
index 0000000..c6ae019
--- /dev/null
@@ -0,0 +1,121 @@
+#include "portaudiocpp/HostApi.hxx"\r
+\r
+#include "portaudiocpp/System.hxx"\r
+#include "portaudiocpp/Device.hxx"\r
+#include "portaudiocpp/SystemDeviceIterator.hxx"\r
+#include "portaudiocpp/Exception.hxx"\r
+\r
+namespace portaudio\r
+{\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       HostApi::HostApi(PaHostApiIndex index) : devices_(NULL)\r
+       {\r
+               try\r
+               {\r
+                       info_ = Pa_GetHostApiInfo(index);\r
+\r
+                       // Create and populate devices array:\r
+                       int numDevices = deviceCount();\r
+\r
+                       devices_ = new Device*[numDevices];\r
+\r
+                       for (int i = 0; i < numDevices; ++i)\r
+                       {\r
+                               PaDeviceIndex deviceIndex = Pa_HostApiDeviceIndexToDeviceIndex(index, i);\r
+\r
+                               if (deviceIndex < 0)\r
+                               {\r
+                                       throw PaException(deviceIndex);\r
+                               }\r
+\r
+                               devices_[i] = &System::instance().deviceByIndex(deviceIndex);\r
+                       }\r
+               }\r
+               catch (const std::exception &e)\r
+               {\r
+                       // Delete any (partially) constructed objects (deconstructor isn't called):\r
+                       delete[] devices_; // devices_ is either NULL or valid\r
+\r
+                       // Re-throw exception:\r
+                       throw e;\r
+               }\r
+       }\r
+\r
+       HostApi::~HostApi()\r
+       {\r
+               // Destroy devices array:\r
+               delete[] devices_;\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       PaHostApiTypeId HostApi::typeId() const\r
+       {\r
+               return info_->type;\r
+       }\r
+\r
+       PaHostApiIndex HostApi::index() const\r
+       {\r
+               PaHostApiIndex index = Pa_HostApiTypeIdToHostApiIndex(typeId());\r
+\r
+               if (index < 0)\r
+                       throw PaException(index);\r
+\r
+               return index;\r
+       }\r
+\r
+       const char *HostApi::name() const\r
+       {\r
+               return info_->name;\r
+       }\r
+\r
+       int HostApi::deviceCount() const\r
+       {\r
+               return info_->deviceCount;\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       HostApi::DeviceIterator HostApi::devicesBegin()\r
+       {\r
+               DeviceIterator tmp;\r
+               tmp.ptr_ = &devices_[0]; // begin (first element)\r
+               return tmp;\r
+       }\r
+\r
+       HostApi::DeviceIterator HostApi::devicesEnd()\r
+       {\r
+               DeviceIterator tmp;\r
+               tmp.ptr_ = &devices_[deviceCount()]; // end (one past last element)\r
+               return tmp;\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       Device &HostApi::defaultInputDevice() const\r
+       {\r
+               return System::instance().deviceByIndex(info_->defaultInputDevice);\r
+       }\r
+\r
+       Device &HostApi::defaultOutputDevice() const\r
+       {\r
+               return System::instance().deviceByIndex(info_->defaultOutputDevice);\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       bool HostApi::operator==(const HostApi &rhs) const\r
+       {\r
+               return (typeId() == rhs.typeId());\r
+       }\r
+\r
+       bool HostApi::operator!=(const HostApi &rhs) const\r
+       {\r
+               return !(*this == rhs);\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+} // namespace portaudio\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/InterfaceCallbackStream.cxx b/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/InterfaceCallbackStream.cxx
new file mode 100644 (file)
index 0000000..09e02de
--- /dev/null
@@ -0,0 +1,45 @@
+#include "portaudiocpp/InterfaceCallbackStream.hxx"\r
+\r
+#include "portaudiocpp/StreamParameters.hxx"\r
+#include "portaudiocpp/Exception.hxx"\r
+#include "portaudiocpp/CallbackInterface.hxx"\r
+\r
+namespace portaudio\r
+{\r
+\r
+       // ---------------------------------------------------------------------------------==\r
+\r
+       InterfaceCallbackStream::InterfaceCallbackStream()\r
+       {\r
+       }\r
+\r
+       InterfaceCallbackStream::InterfaceCallbackStream(const StreamParameters &parameters, CallbackInterface &instance)\r
+       {\r
+               open(parameters, instance);\r
+       }\r
+\r
+       InterfaceCallbackStream::~InterfaceCallbackStream()\r
+       {\r
+               try\r
+               {\r
+                       close();\r
+               }\r
+               catch (...)\r
+               {\r
+                       // ignore all errors\r
+               }\r
+       }\r
+\r
+       // ---------------------------------------------------------------------------------==\r
+\r
+       void InterfaceCallbackStream::open(const StreamParameters &parameters, CallbackInterface &instance)\r
+       {\r
+               PaError err = Pa_OpenStream(&stream_, parameters.inputParameters().paStreamParameters(), parameters.outputParameters().paStreamParameters(), \r
+                       parameters.sampleRate(), parameters.framesPerBuffer(), parameters.flags(), &impl::callbackInterfaceToPaCallbackAdapter, static_cast<void *>(&instance));\r
+\r
+               if (err != paNoError)\r
+               {\r
+                       throw PaException(err);\r
+               }\r
+       }\r
+}\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/MemFunCallbackStream.cxx b/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/MemFunCallbackStream.cxx
new file mode 100644 (file)
index 0000000..113fe5a
--- /dev/null
@@ -0,0 +1,4 @@
+#include "portaudiocpp/MemFunCallbackStream.hxx"\r
+\r
+// (... template class ...)\r
+\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/Stream.cxx b/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/Stream.cxx
new file mode 100644 (file)
index 0000000..3b21f09
--- /dev/null
@@ -0,0 +1,195 @@
+#include "portaudiocpp/Stream.hxx"\r
+\r
+#include <cstddef>\r
+\r
+#include "portaudiocpp/Exception.hxx"\r
+#include "portaudiocpp/System.hxx"\r
+\r
+namespace portaudio\r
+{\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       Stream::Stream() : stream_(NULL)\r
+       {\r
+       }\r
+\r
+       Stream::~Stream()\r
+       {\r
+               // (can't call close here, \r
+               // the derived class should atleast call \r
+               // close() in it's deconstructor)\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       //////\r
+       /// Closes the Stream if it's open, else does nothing.\r
+       //////\r
+       void Stream::close()\r
+       {\r
+               if (isOpen() && System::exists())\r
+               {\r
+                       PaError err = Pa_CloseStream(stream_);\r
+                       stream_ = NULL;\r
+\r
+                       if (err != paNoError)\r
+                               throw PaException(err);\r
+               }\r
+       }\r
+\r
+       //////\r
+       /// Returns true if the Stream is open.\r
+       //////\r
+       bool Stream::isOpen() const\r
+       {\r
+               return (stream_ != NULL);\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       void Stream::setStreamFinishedCallback(PaStreamFinishedCallback *callback)\r
+       {\r
+               PaError err = Pa_SetStreamFinishedCallback(stream_, callback);\r
+\r
+               if (err != paNoError)\r
+                       throw PaException(err);\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       void Stream::start()\r
+       {\r
+               PaError err = Pa_StartStream(stream_);\r
+\r
+               if (err != paNoError)\r
+                       throw PaException(err);\r
+       }\r
+\r
+       void Stream::stop()\r
+       {\r
+               PaError err = Pa_StopStream(stream_);\r
+\r
+               if (err != paNoError)\r
+                       throw PaException(err);\r
+       }\r
+\r
+       void Stream::abort()\r
+       {\r
+               PaError err = Pa_AbortStream(stream_);\r
+\r
+               if (err != paNoError)\r
+                       throw PaException(err);\r
+       }\r
+\r
+       bool Stream::isStopped() const\r
+       {\r
+               PaError ret = Pa_IsStreamStopped(stream_);\r
+\r
+               if (ret < 0)\r
+                       throw PaException(ret);\r
+\r
+               return (ret == 1);\r
+       }\r
+\r
+       bool Stream::isActive() const\r
+       {\r
+               PaError ret = Pa_IsStreamActive(stream_);\r
+\r
+               if (ret < 0)\r
+                       throw PaException(ret);\r
+\r
+               return (ret == 1);\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       //////\r
+       /// Returns the best known input latency for the Stream. This value may differ from the \r
+       /// suggested input latency set in the StreamParameters. Includes all sources of \r
+       /// latency known to PortAudio such as internal buffering, and Host API reported latency. \r
+       /// Doesn't include any estimates of unknown latency.\r
+       //////\r
+       PaTime Stream::inputLatency() const\r
+       {\r
+               const PaStreamInfo *info = Pa_GetStreamInfo(stream_);\r
+               if (info == NULL)\r
+               {\r
+                       throw PaException(paInternalError);\r
+                       return PaTime(0.0);\r
+               }\r
+\r
+               return info->inputLatency;\r
+       }\r
+\r
+       //////\r
+       /// Returns the best known output latency for the Stream. This value may differ from the \r
+       /// suggested output latency set in the StreamParameters. Includes all sources of \r
+       /// latency known to PortAudio such as internal buffering, and Host API reported latency. \r
+       /// Doesn't include any estimates of unknown latency.\r
+       //////\r
+       PaTime Stream::outputLatency() const\r
+       {\r
+               const PaStreamInfo *info = Pa_GetStreamInfo(stream_);\r
+               if (info == NULL)\r
+               {\r
+                       throw PaException(paInternalError);\r
+                       return PaTime(0.0);\r
+               }\r
+\r
+               return info->outputLatency;\r
+       }\r
+\r
+       //////\r
+       /// Returns the sample rate of the Stream. Usually this will be the \r
+       /// best known estimate of the used sample rate. For instance when opening a \r
+       /// Stream setting 44100.0 Hz in the StreamParameters, the actual sample \r
+       /// rate might be something like 44103.2 Hz (due to imperfections in the \r
+       /// sound card hardware).\r
+       //////\r
+       double Stream::sampleRate() const\r
+       {\r
+               const PaStreamInfo *info = Pa_GetStreamInfo(stream_);\r
+               if (info == NULL)\r
+               {\r
+                       throw PaException(paInternalError);\r
+                       return 0.0;\r
+               }\r
+\r
+               return info->sampleRate;\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       PaTime Stream::time() const\r
+       {\r
+               return Pa_GetStreamTime(stream_);\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       //////\r
+       /// Accessor (const) for PortAudio PaStream pointer, useful for interfacing with \r
+       /// PortAudio add-ons such as PortMixer for instance. Normally accessing this \r
+       /// pointer should not be needed as PortAudioCpp aims to provide all of PortAudio's \r
+       /// functionality.\r
+       //////\r
+       const PaStream *Stream::paStream() const\r
+       {\r
+               return stream_;\r
+       }\r
+\r
+       //////\r
+       /// Accessor (non-const) for PortAudio PaStream pointer, useful for interfacing with \r
+       /// PortAudio add-ons such as PortMixer for instance. Normally accessing this \r
+       /// pointer should not be needed as PortAudioCpp aims to provide all of PortAudio's \r
+       /// functionality.\r
+       //////\r
+       PaStream *Stream::paStream()\r
+       {\r
+               return stream_;\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+} // namespace portaudio\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/StreamParameters.cxx b/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/StreamParameters.cxx
new file mode 100644 (file)
index 0000000..670873b
--- /dev/null
@@ -0,0 +1,165 @@
+#include "portaudiocpp/StreamParameters.hxx"\r
+\r
+#include <cstddef>\r
+\r
+#include "portaudiocpp/Device.hxx"\r
+\r
+namespace portaudio\r
+{\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       //////\r
+       /// Default constructor; does nothing.\r
+       //////\r
+       StreamParameters::StreamParameters()\r
+       {\r
+       }\r
+\r
+       //////\r
+       /// Sets up the all parameters needed to open either a half-duplex or full-duplex Stream.\r
+       ///\r
+       /// @param inputParameters The parameters for the input direction of the to-be opened \r
+       /// Stream or DirectionSpecificStreamParameters::null() for an output-only Stream.\r
+       /// @param outputParameters The parameters for the output direction of the to-be opened\r
+       /// Stream or DirectionSpecificStreamParameters::null() for an input-only Stream.\r
+       /// @param sampleRate The to-be opened Stream's sample rate in Hz.\r
+       /// @param framesPerBuffer The number of frames per buffer for a CallbackStream, or \r
+       /// the preferred buffer granularity for a BlockingStream.\r
+       /// @param flags The flags for the to-be opened Stream; default paNoFlag.\r
+       //////\r
+       StreamParameters::StreamParameters(const DirectionSpecificStreamParameters &inputParameters, \r
+               const DirectionSpecificStreamParameters &outputParameters, double sampleRate, unsigned long framesPerBuffer, \r
+               PaStreamFlags flags) : inputParameters_(inputParameters), outputParameters_(outputParameters), \r
+               sampleRate_(sampleRate), framesPerBuffer_(framesPerBuffer), flags_(flags)\r
+       {\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       //////\r
+       /// Sets the requested sample rate. If this sample rate isn't supported by the hardware, the \r
+       /// Stream will fail to open. The real-life sample rate used might differ slightly due to \r
+       /// imperfections in the sound card hardware; use Stream::sampleRate() to retreive the \r
+       /// best known estimate for this value.\r
+       //////\r
+       void StreamParameters::setSampleRate(double sampleRate)\r
+       {\r
+               sampleRate_ = sampleRate;\r
+       }\r
+\r
+       //////\r
+       /// Either the number of frames per buffer for a CallbackStream, or \r
+       /// the preferred buffer granularity for a BlockingStream. See PortAudio \r
+       /// documentation.\r
+       //////\r
+       void StreamParameters::setFramesPerBuffer(unsigned long framesPerBuffer)\r
+       {\r
+               framesPerBuffer_ = framesPerBuffer;\r
+       }\r
+\r
+       //////\r
+       /// Sets the specified flag or does nothing when the flag is already set. Doesn't \r
+       /// `unset' any previously existing flags (use clearFlags() for that).\r
+       //////\r
+       void StreamParameters::setFlag(PaStreamFlags flag)\r
+       {\r
+               flags_ |= flag;\r
+       }\r
+\r
+       //////\r
+       /// Unsets the specified flag or does nothing if the flag isn't set. Doesn't affect \r
+       /// any other flags.\r
+       //////\r
+       void StreamParameters::unsetFlag(PaStreamFlags flag)\r
+       {\r
+               flags_ &= ~flag;\r
+       }\r
+\r
+       //////\r
+       /// Clears or `unsets' all set flags.\r
+       //////\r
+       void StreamParameters::clearFlags()\r
+       {\r
+               flags_ = paNoFlag;\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       void StreamParameters::setInputParameters(const DirectionSpecificStreamParameters &parameters)\r
+       {\r
+               inputParameters_ = parameters;\r
+       }\r
+\r
+       void StreamParameters::setOutputParameters(const DirectionSpecificStreamParameters &parameters)\r
+       {\r
+               outputParameters_ = parameters;\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       bool StreamParameters::isSupported() const\r
+       {\r
+               return (Pa_IsFormatSupported(inputParameters_.paStreamParameters(), \r
+                       outputParameters_.paStreamParameters(), sampleRate_) == paFormatIsSupported);\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       double StreamParameters::sampleRate() const\r
+       {\r
+               return sampleRate_;\r
+       }\r
+\r
+       unsigned long StreamParameters::framesPerBuffer() const\r
+       {\r
+               return framesPerBuffer_;\r
+       }\r
+\r
+       //////\r
+       /// Returns all currently set flags as a binary combined \r
+       /// integer value (PaStreamFlags). Use isFlagSet() to \r
+       /// avoid dealing with the bitmasks.\r
+       //////\r
+       PaStreamFlags StreamParameters::flags() const\r
+       {\r
+               return flags_;\r
+       }\r
+\r
+       //////\r
+       /// Returns true if the specified flag is currently set \r
+       /// or false if it isn't.\r
+       //////\r
+       bool StreamParameters::isFlagSet(PaStreamFlags flag) const\r
+       {\r
+               return ((flags_ & flag) != 0);\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       DirectionSpecificStreamParameters &StreamParameters::inputParameters()\r
+       {\r
+               return inputParameters_;\r
+       }\r
+\r
+       const DirectionSpecificStreamParameters &StreamParameters::inputParameters() const\r
+       {\r
+               return inputParameters_;\r
+       }\r
+\r
+       DirectionSpecificStreamParameters &StreamParameters::outputParameters()\r
+       {\r
+               return outputParameters_;\r
+       }\r
+\r
+       const DirectionSpecificStreamParameters &StreamParameters::outputParameters() const\r
+       {\r
+               return outputParameters_;\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+} // namespace portaudio\r
+\r
+\r
+\r
+\r
+\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/System.cxx b/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/System.cxx
new file mode 100644 (file)
index 0000000..692c7a1
--- /dev/null
@@ -0,0 +1,308 @@
+#include "portaudiocpp/System.hxx"\r
+\r
+#include <cstddef>\r
+#include <cassert>\r
+\r
+#include "portaudiocpp/HostApi.hxx"\r
+#include "portaudiocpp/Device.hxx"\r
+#include "portaudiocpp/Stream.hxx"\r
+#include "portaudiocpp/Exception.hxx"\r
+#include "portaudiocpp/SystemHostApiIterator.hxx"\r
+#include "portaudiocpp/SystemDeviceIterator.hxx"\r
+\r
+namespace portaudio\r
+{\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       // Static members:\r
+       System *System::instance_ = NULL;\r
+       int System::initCount_ = 0;\r
+       HostApi **System::hostApis_ = NULL;\r
+       Device **System::devices_ = NULL;\r
+       Device *System::nullDevice_ = NULL;\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       int System::version()\r
+       {\r
+               return Pa_GetVersion();\r
+       }\r
+\r
+       const char *System::versionText()\r
+       {\r
+               return Pa_GetVersionText();\r
+       }\r
+\r
+       void System::initialize()\r
+       {\r
+               ++initCount_;\r
+\r
+               if (initCount_ == 1)\r
+               {\r
+                       // Create singleton:\r
+                       assert(instance_ == NULL);\r
+                       instance_ = new System();\r
+\r
+                       // Initialize the PortAudio system:\r
+                       {\r
+                               PaError err = Pa_Initialize();\r
+\r
+                               if (err != paNoError)\r
+                                       throw PaException(err);\r
+                       }\r
+\r
+                       // Create and populate device array:\r
+                       {\r
+                               int numDevices = instance().deviceCount();\r
+\r
+                               devices_ = new Device*[numDevices];\r
+\r
+                               for (int i = 0; i < numDevices; ++i)\r
+                                       devices_[i] = new Device(i);\r
+                       }\r
+\r
+                       // Create and populate host api array:\r
+                       {\r
+                               int numHostApis = instance().hostApiCount();\r
+\r
+                               hostApis_ = new HostApi*[numHostApis];\r
+\r
+                               for (int i = 0; i < numHostApis; ++i)\r
+                                       hostApis_[i] = new HostApi(i);\r
+                       }\r
+                       \r
+                       // Create null device:\r
+                       nullDevice_ = new Device(paNoDevice);\r
+               }\r
+       }\r
+\r
+       void System::terminate()\r
+       {\r
+               PaError err = paNoError;\r
+\r
+               if (initCount_ == 1)\r
+               {\r
+                       // Destroy null device:\r
+                       delete nullDevice_;\r
+\r
+                       // Destroy host api array:\r
+                       {\r
+                               if (hostApis_ != NULL)\r
+                               {\r
+                                       int numHostApis = instance().hostApiCount();\r
+\r
+                                       for (int i = 0; i < numHostApis; ++i)\r
+                                               delete hostApis_[i];\r
+\r
+                                       delete[] hostApis_;\r
+                                       hostApis_ = NULL;\r
+                               }\r
+                       }\r
+\r
+                       // Destroy device array:\r
+                       {\r
+                               if (devices_ != NULL)\r
+                               {\r
+                                       int numDevices = instance().deviceCount();\r
+\r
+                                       for (int i = 0; i < numDevices; ++i)\r
+                                               delete devices_[i];\r
+\r
+                                       delete[] devices_;\r
+                                       devices_ = NULL;\r
+                               }\r
+                       }\r
+\r
+                       // Terminate the PortAudio system:\r
+                       assert(instance_ != NULL);\r
+                       err = Pa_Terminate();\r
+\r
+                       // Destroy singleton:\r
+                       delete instance_;\r
+                       instance_ = NULL;\r
+               }\r
+\r
+               if (initCount_ > 0)\r
+                       --initCount_;\r
+\r
+               if (err != paNoError)\r
+                       throw PaException(err);\r
+       }\r
+\r
+\r
+       System &System::instance()\r
+       {\r
+               assert(exists());\r
+\r
+               return *instance_;\r
+       }\r
+\r
+       bool System::exists()\r
+       {\r
+               return (instance_ != NULL);\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       System::HostApiIterator System::hostApisBegin()\r
+       {\r
+               System::HostApiIterator tmp;\r
+               tmp.ptr_ = &hostApis_[0]; // begin (first element)\r
+               return tmp;\r
+       }\r
+\r
+       System::HostApiIterator System::hostApisEnd()\r
+       {\r
+               int count = hostApiCount();\r
+\r
+               System::HostApiIterator tmp;\r
+               tmp.ptr_ = &hostApis_[count]; // end (one past last element)\r
+               return tmp;\r
+       }\r
+\r
+       HostApi &System::defaultHostApi()\r
+       {\r
+               PaHostApiIndex defaultHostApi = Pa_GetDefaultHostApi();\r
+\r
+               if (defaultHostApi < 0)\r
+                       throw PaException(defaultHostApi);\r
+\r
+               return *hostApis_[defaultHostApi];\r
+       }\r
+\r
+       HostApi &System::hostApiByTypeId(PaHostApiTypeId type)\r
+       {\r
+               PaHostApiIndex index = Pa_HostApiTypeIdToHostApiIndex(type);\r
+\r
+               if (index < 0)\r
+                       throw PaException(index);\r
+\r
+               return *hostApis_[index];\r
+       }\r
+\r
+       HostApi &System::hostApiByIndex(PaHostApiIndex index)\r
+       {\r
+               if (index < 0 || index >= hostApiCount())\r
+                       throw PaException(paInternalError);\r
+\r
+               return *hostApis_[index];\r
+       }\r
+\r
+       int System::hostApiCount()\r
+       {\r
+               PaHostApiIndex count = Pa_GetHostApiCount();\r
+\r
+               if (count < 0)\r
+                       throw PaException(count);\r
+\r
+               return count;\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       System::DeviceIterator System::devicesBegin()\r
+       {\r
+               DeviceIterator tmp;\r
+               tmp.ptr_ = &devices_[0];\r
+\r
+               return tmp;\r
+       }\r
+\r
+       System::DeviceIterator System::devicesEnd()\r
+       {\r
+               int count = deviceCount();\r
+\r
+               DeviceIterator tmp;\r
+               tmp.ptr_ = &devices_[count];\r
+\r
+               return tmp;\r
+       }\r
+\r
+       //////\r
+       /// Returns the System's default input Device, or the null Device if none \r
+       /// was available.\r
+       //////\r
+       Device &System::defaultInputDevice()\r
+       {\r
+               PaDeviceIndex index = Pa_GetDefaultInputDevice();\r
+               return deviceByIndex(index);\r
+       }\r
+\r
+       //////\r
+       /// Returns the System's default output Device, or the null Device if none \r
+       /// was available.\r
+       //////\r
+       Device &System::defaultOutputDevice()\r
+       {\r
+               PaDeviceIndex index = Pa_GetDefaultOutputDevice();\r
+               return deviceByIndex(index);\r
+       }\r
+\r
+       //////\r
+       /// Returns the Device for the given index.\r
+       /// Will throw a paInternalError equivalent PaException if the given index \r
+       /// is out of range.\r
+       //////\r
+       Device &System::deviceByIndex(PaDeviceIndex index)\r
+       {\r
+               if (index < -1 || index >= deviceCount())\r
+               {\r
+                       throw PaException(paInternalError);\r
+               }\r
+\r
+               if (index == -1)\r
+                       return System::instance().nullDevice();\r
+\r
+               return *devices_[index];\r
+       }\r
+\r
+       int System::deviceCount()\r
+       {\r
+               PaDeviceIndex count = Pa_GetDeviceCount();\r
+\r
+               if (count < 0)\r
+                       throw PaException(count);\r
+\r
+               return count;\r
+       }\r
+\r
+       Device &System::nullDevice()\r
+       {\r
+               return *nullDevice_;\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       void System::sleep(long msec)\r
+       {\r
+               Pa_Sleep(msec);\r
+       }\r
+\r
+       int System::sizeOfSample(PaSampleFormat format)\r
+       {\r
+               PaError err = Pa_GetSampleSize(format);\r
+               if (err < 0)\r
+               {\r
+                       throw PaException(err);\r
+                       return 0;\r
+               }\r
+\r
+               return err;\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       System::System()\r
+       {\r
+               // (left blank intentionally)\r
+       }\r
+\r
+       System::~System()\r
+       {\r
+               // (left blank intentionally)\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+} // namespace portaudio\r
+\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/SystemDeviceIterator.cxx b/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/SystemDeviceIterator.cxx
new file mode 100644 (file)
index 0000000..c3c00f7
--- /dev/null
@@ -0,0 +1,60 @@
+#include "portaudiocpp/SystemDeviceIterator.hxx"\r
+\r
+namespace portaudio\r
+{\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       Device &System::DeviceIterator::operator*() const\r
+       {\r
+               return **ptr_;\r
+       }\r
+\r
+       Device *System::DeviceIterator::operator->() const\r
+       {\r
+               return &**this;\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       System::DeviceIterator &System::DeviceIterator::operator++()\r
+       {\r
+               ++ptr_;\r
+               return *this;\r
+       }\r
+\r
+       System::DeviceIterator System::DeviceIterator::operator++(int)\r
+       {\r
+               System::DeviceIterator prev = *this;\r
+               ++*this;\r
+               return prev;\r
+       }\r
+\r
+       System::DeviceIterator &System::DeviceIterator::operator--()\r
+       {\r
+               --ptr_;\r
+               return *this;\r
+       }\r
+\r
+       System::DeviceIterator System::DeviceIterator::operator--(int)\r
+       {\r
+               System::DeviceIterator prev = *this;\r
+               --*this;\r
+               return prev;\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       bool System::DeviceIterator::operator==(const System::DeviceIterator &rhs)\r
+       {\r
+               return (ptr_ == rhs.ptr_);\r
+       }\r
+\r
+       bool System::DeviceIterator::operator!=(const System::DeviceIterator &rhs)\r
+       {\r
+               return !(*this == rhs);\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+} // namespace portaudio\r
+\r
+\r
diff --git a/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/SystemHostApiIterator.cxx b/utils/iaxclient/lib/portaudio/bindings/cpp/source/portaudiocpp/SystemHostApiIterator.cxx
new file mode 100644 (file)
index 0000000..f34ca40
--- /dev/null
@@ -0,0 +1,59 @@
+#include "portaudiocpp/SystemHostApiIterator.hxx"\r
+\r
+namespace portaudio\r
+{\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       HostApi &System::HostApiIterator::operator*() const\r
+       {\r
+               return **ptr_;\r
+       }\r
+\r
+       HostApi *System::HostApiIterator::operator->() const\r
+       {\r
+               return &**this;\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       System::HostApiIterator &System::HostApiIterator::operator++()\r
+       {\r
+               ++ptr_;\r
+               return *this;\r
+       }\r
+\r
+       System::HostApiIterator System::HostApiIterator::operator++(int)\r
+       {\r
+               System::HostApiIterator prev = *this;\r
+               ++*this;\r
+               return prev;\r
+       }\r
+\r
+       System::HostApiIterator &System::HostApiIterator::operator--()\r
+       {\r
+               --ptr_;\r
+               return *this;\r
+       }\r
+\r
+       System::HostApiIterator System::HostApiIterator::operator--(int)\r
+       {\r
+               System::HostApiIterator prev = *this;\r
+               --*this;\r
+               return prev;\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+\r
+       bool System::HostApiIterator::operator==(const System::HostApiIterator &rhs)\r
+       {\r
+               return (ptr_ == rhs.ptr_);\r
+       }\r
+\r
+       bool System::HostApiIterator::operator!=(const System::HostApiIterator &rhs)\r
+       {\r
+               return !(*this == rhs);\r
+       }\r
+\r
+       // -----------------------------------------------------------------------------------\r
+} // namespace portaudio\r
+\r
diff --git a/utils/iaxclient/lib/portaudio/config.doxy b/utils/iaxclient/lib/portaudio/config.doxy
new file mode 100644 (file)
index 0000000..1c3e33a
--- /dev/null
@@ -0,0 +1,237 @@
+# Doxyfile 1.4.6
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME           = PortAudio
+PROJECT_NUMBER         = 2.0
+OUTPUT_DIRECTORY       = ./doc/
+CREATE_SUBDIRS         = NO
+OUTPUT_LANGUAGE        = English
+USE_WINDOWS_ENCODING   = NO
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = NO
+STRIP_FROM_PATH        = 
+STRIP_FROM_INC_PATH    = 
+SHORT_NAMES            = NO
+JAVADOC_AUTOBRIEF      = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP         = NO
+INHERIT_DOCS           = YES
+SEPARATE_MEMBER_PAGES  = NO
+TAB_SIZE               = 8
+ALIASES                = 
+OPTIMIZE_OUTPUT_FOR_C  = YES
+OPTIMIZE_OUTPUT_JAVA   = NO
+BUILTIN_STL_SUPPORT    = NO
+DISTRIBUTE_GROUP_DOC   = NO
+SUBGROUPING            = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = YES
+EXTRACT_PRIVATE        = NO
+EXTRACT_STATIC         = NO
+EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_METHODS  = NO
+HIDE_UNDOC_MEMBERS     = NO
+HIDE_UNDOC_CLASSES     = NO
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = NO
+CASE_SENSE_NAMES       = YES
+HIDE_SCOPE_NAMES       = NO
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+SORT_BRIEF_DOCS        = NO
+SORT_BY_SCOPE_NAME     = NO
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = YES
+SHOW_DIRECTORIES       = NO
+FILE_VERSION_FILTER    = 
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET                  = NO
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_DOC_ERROR      = YES
+WARN_NO_PARAMDOC       = NO
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           = 
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT                  = src \
+                         include \
+                         test
+FILE_PATTERNS          = *.h \
+                         *.c \
+                         *.cpp
+RECURSIVE              = YES
+EXCLUDE                = 
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = 
+EXAMPLE_PATH           = 
+EXAMPLE_PATTERNS       = 
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             = 
+INPUT_FILTER           = 
+FILTER_PATTERNS        = 
+FILTER_SOURCE_FILES    = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = NO
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION    = YES
+USE_HTAGS              = NO
+VERBATIM_HEADERS       = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = NO
+COLS_IN_ALPHA_INDEX    = 5
+IGNORE_PREFIX          = 
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML          = YES
+HTML_OUTPUT            = html
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            = 
+HTML_FOOTER            = 
+HTML_STYLESHEET        = 
+HTML_ALIGN_MEMBERS     = YES
+GENERATE_HTMLHELP      = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = NO
+TREEVIEW_WIDTH         = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = NO
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = NO
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             = 
+XML_DTD                = 
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = NO
+EXPAND_ONLY_PREDEF     = NO
+SEARCH_INCLUDES        = YES
+INCLUDE_PATH           = 
+INCLUDE_FILE_PATTERNS  = 
+PREDEFINED             = 
+EXPAND_AS_DEFINED      = 
+SKIP_FUNCTION_MACROS   = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+TAGFILES               = 
+GENERATE_TAGFILE       = 
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = NO
+HIDE_UNDOC_RELATIONS   = NO
+HAVE_DOT               = NO
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = YES
+GROUP_GRAPHS           = YES
+UML_LOOK               = NO
+TEMPLATE_RELATIONS     = YES
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = NO
+GRAPHICAL_HIERARCHY    = YES
+DIRECTORY_GRAPH        = YES
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = 
+DOTFILE_DIRS           = 
+MAX_DOT_GRAPH_WIDTH    = 1024
+MAX_DOT_GRAPH_HEIGHT   = 1024
+MAX_DOT_GRAPH_DEPTH    = 1000
+DOT_TRANSPARENT        = NO
+DOT_MULTI_TARGETS      = NO
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+SEARCHENGINE           = NO
diff --git a/utils/iaxclient/lib/portaudio/config.guess b/utils/iaxclient/lib/portaudio/config.guess
new file mode 100755 (executable)
index 0000000..cc726cd
--- /dev/null
@@ -0,0 +1,1388 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+timestamp='2003-02-22'
+
+# 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., 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 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
+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 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # 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 -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { 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 ;'
+
+# 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 0 ;;
+    amiga:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    arc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    hp300:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mac68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    macppc:OpenBSD:*:*)
+       echo powerpc-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+       echo m88k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    mvmeppc:OpenBSD:*:*)
+       echo powerpc-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    pmax:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sgi:OpenBSD:*:*)
+       echo mipseb-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    sun3:OpenBSD:*:*)
+       echo m68k-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+       echo mipsel-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    *:OpenBSD:*:*)
+       echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+       exit 0 ;;
+    alpha:OSF1:*:*)
+       if test $UNAME_RELEASE = "V4.0"; then
+               UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+       fi
+       # 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 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/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+       exit 0 ;;
+    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 0 ;;
+    21064:Windows_NT:50:3)
+       echo alpha-dec-winnt3.5
+       exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+       echo m68k-unknown-sysv4
+       exit 0;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+       echo ${UNAME_MACHINE}-unknown-amigaos
+       exit 0 ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+       echo ${UNAME_MACHINE}-unknown-morphos
+       exit 0 ;;
+    *:OS/390:*:*)
+       echo i370-ibm-openedition
+       exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+       echo arm-acorn-riscix${UNAME_RELEASE}
+       exit 0;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+       echo hppa1.1-hitachi-hiuxmpp
+       exit 0;;
+    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 0 ;;
+    NILE*:*:*:dcosx)
+       echo pyramid-pyramid-svr4
+       exit 0 ;;
+    DRS?6000:UNIX_SV:4.2*:7*)
+       case `/usr/bin/uname -p` in
+           sparc) echo sparc-icl-nx7 && exit 0 ;;
+       esac ;;
+    sun4H:SunOS:5.*:*)
+       echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+       echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    i86pc:SunOS:5.*:*)
+       echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    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 0 ;;
+    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 0 ;;
+    sun3*:SunOS:*:*)
+       echo m68k-sun-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    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 0 ;;
+    aushp:SunOS:*:*)
+       echo sparc-auspex-sunos${UNAME_RELEASE}
+       exit 0 ;;
+    # 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 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+       echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+       exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    powerpc:machten:*:*)
+       echo powerpc-apple-machten${UNAME_RELEASE}
+       exit 0 ;;
+    RISC*:Mach:*:*)
+       echo mips-dec-mach_bsd4.3
+       exit 0 ;;
+    RISC*:ULTRIX:*:*)
+       echo mips-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+       echo vax-dec-ultrix${UNAME_RELEASE}
+       exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+       echo clipper-intergraph-clix${UNAME_RELEASE}
+       exit 0 ;;
+    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 \
+         && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+         && exit 0
+       echo mips-mips-riscos${UNAME_RELEASE}
+       exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+       echo powerpc-motorola-powermax
+       exit 0 ;;
+    Motorola:*:4.3:PL8-*)
+       echo powerpc-harris-powermax
+       exit 0 ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+       echo powerpc-harris-powermax
+       exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+       echo powerpc-harris-powerunix
+       exit 0 ;;
+    m88k:CX/UX:7*:*)
+       echo m88k-harris-cxux7
+       exit 0 ;;
+    m88k:*:4*:R4*)
+       echo m88k-motorola-sysv4
+       exit 0 ;;
+    m88k:*:3*:R3*)
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    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 0 ;;
+    M88*:DolphinOS:*:*)        # DolphinOS (SVR3)
+       echo m88k-dolphin-sysv3
+       exit 0 ;;
+    M88*:*:R3*:*)
+       # Delta 88k system running SVR3
+       echo m88k-motorola-sysv3
+       exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+       echo m88k-tektronix-sysv3
+       exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+       echo m68k-tektronix-bsd
+       exit 0 ;;
+    *:IRIX*:*:*)
+       echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+       exit 0 ;;
+    ????????: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 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+       echo i386-ibm-aix
+       exit 0 ;;
+    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 0 ;;
+    *: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
+               $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+               echo rs6000-ibm-aix3.2.5
+       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 0 ;;
+    *: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 0 ;;
+    *:AIX:*:*)
+       echo rs6000-ibm-aix
+       exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+       echo romp-ibm-bsd4.4
+       exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+       echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+       exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+       echo rs6000-bull-bosx
+       exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+       echo m68k-bull-sysv3
+       exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+       echo m68k-hp-bsd
+       exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+       echo m68k-hp-bsd4.4
+       exit 0 ;;
+    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
+           # avoid double evaluation of $set_cc_for_build
+           test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
+           if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
+           then
+               HP_ARCH="hppa2.0w"
+           else
+               HP_ARCH="hppa64"
+           fi
+       fi
+       echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+       exit 0 ;;
+    ia64:HP-UX:*:*)
+       HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+       echo ia64-hp-hpux${HPUX_REV}
+       exit 0 ;;
+    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 && $dummy && exit 0
+       echo unknown-hitachi-hiuxwe2
+       exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+       echo hppa1.1-hp-bsd
+       exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+       echo hppa1.0-hp-bsd
+       exit 0 ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+       echo hppa1.0-hp-mpeix
+       exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+       echo hppa1.1-hp-osf
+       exit 0 ;;
+    hp8??:OSF1:*:*)
+       echo hppa1.0-hp-osf
+       exit 0 ;;
+    i*86:OSF1:*:*)
+       if [ -x /usr/sbin/sysversion ] ; then
+           echo ${UNAME_MACHINE}-unknown-osf1mk
+       else
+           echo ${UNAME_MACHINE}-unknown-osf1
+       fi
+       exit 0 ;;
+    parisc*:Lites*:*:*)
+       echo hppa1.1-hp-lites
+       exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+       echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+       echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+       echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+       echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+       echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    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 0 ;;
+    CRAY*TS:*:*:*)
+       echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*T3E:*:*:*)
+       echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    CRAY*SV1:*:*:*)
+       echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+       exit 0 ;;
+    *:UNICOS/mp:*:*)
+       echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' 
+       exit 0 ;;
+    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 0 ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+       echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    sparc*:BSD/OS:*:*)
+       echo sparc-unknown-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:BSD/OS:*:*)
+       echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+       exit 0 ;;
+    *:FreeBSD:*:*)
+       # Determine whether the default compiler uses glibc.
+       eval $set_cc_for_build
+       sed 's/^        //' << EOF >$dummy.c
+       #include <features.h>
+       #if __GLIBC__ >= 2
+       LIBC=gnu
+       #else
+       LIBC=
+       #endif
+EOF
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+       echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
+       exit 0 ;;
+    i*:CYGWIN*:*)
+       echo ${UNAME_MACHINE}-pc-cygwin
+       exit 0 ;;
+    i*:MINGW*:*)
+       echo ${UNAME_MACHINE}-pc-mingw32
+       exit 0 ;;
+    i*:PW*:*)
+       echo ${UNAME_MACHINE}-pc-pw32
+       exit 0 ;;
+    x86:Interix*:3*)
+       echo i586-pc-interix3
+       exit 0 ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+       echo i${UNAME_MACHINE}-pc-mks
+       exit 0 ;;
+    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 0 ;;
+    i*:UWIN*:*)
+       echo ${UNAME_MACHINE}-pc-uwin
+       exit 0 ;;
+    p*:CYGWIN*:*)
+       echo powerpcle-unknown-cygwin
+       exit 0 ;;
+    prep*:SunOS:5.*:*)
+       echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+       exit 0 ;;
+    *:GNU:*:*)
+       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+       exit 0 ;;
+    i*86:Minix:*:*)
+       echo ${UNAME_MACHINE}-pc-minix
+       exit 0 ;;
+    arm*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    ia64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    m68*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    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 | grep ^CPU=`
+       test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+       ;;
+    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 | grep ^CPU=`
+       test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+       ;;
+    ppc:Linux:*:*)
+       echo powerpc-unknown-linux-gnu
+       exit 0 ;;
+    ppc64:Linux:*:*)
+       echo powerpc64-unknown-linux-gnu
+       exit 0 ;;
+    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 0 ;;
+    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 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+       echo hppa64-unknown-linux-gnu
+       exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+       echo ${UNAME_MACHINE}-ibm-linux
+       exit 0 ;;
+    sh*:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       exit 0 ;;
+    x86_64:Linux:*:*)
+       echo x86_64-unknown-linux-gnu
+       exit 0 ;;
+    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 0 ;;
+         coff-i386)
+               echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+               exit 0 ;;
+         "")
+               # 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 0 ;;
+       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
+       #ifdef __INTEL_COMPILER
+       LIBC=gnu
+       #else
+       LIBC=gnuaout
+       #endif
+       #endif
+EOF
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+       test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
+       test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+       ;;
+    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 0 ;;
+    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 0 ;;
+    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 0 ;;
+    i*86:XTS-300:*:STOP)
+       echo ${UNAME_MACHINE}-unknown-stop
+       exit 0 ;;
+    i*86:atheos:*:*)
+       echo ${UNAME_MACHINE}-unknown-atheos
+       exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+       echo i386-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    i*86:*DOS:*:*)
+       echo ${UNAME_MACHINE}-pc-msdosdjgpp
+       exit 0 ;;
+    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 0 ;;
+    i*86:*:5:[78]*)
+       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 0 ;;
+    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 0 ;;
+    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 0 ;;
+    Intel:Mach:3*:*)
+       echo i386-pc-mach3
+       exit 0 ;;
+    paragon:*:*:*)
+       echo i860-intel-osf1
+       exit 0 ;;
+    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 0 ;;
+    mini*:CTIX:SYS*5:*)
+       # "miniframe"
+       echo m68010-convergent-sysv
+       exit 0 ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+       echo m68k-convergent-sysv
+       exit 0 ;;
+    M680?0:D-NIX:5.3:*)
+       echo m68k-diab-dnix
+       exit 0 ;;
+    M68*:*:R3V[567]*:*)
+       test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[34]??:*: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)
+       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 0
+       /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+         && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+       echo m68k-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+       echo m68k-atari-sysv4
+       exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+       echo sparc-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    rs6000:LynxOS:2.*:*)
+       echo rs6000-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+       echo powerpc-unknown-lynxos${UNAME_RELEASE}
+       exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+       echo mips-dde-sysv${UNAME_RELEASE}
+       exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    RM*:SINIX-*:*:*)
+       echo mips-sni-sysv4
+       exit 0 ;;
+    *: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 0 ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+       # From Gerald Hewes <hewes@openmarket.com>.
+       # How about differentiating between stratus architectures? -djm
+       echo hppa1.1-stratus-sysv4
+       exit 0 ;;
+    *:*:*:FTX*)
+       # From seanf@swdc.stratus.com.
+       echo i860-stratus-sysv4
+       exit 0 ;;
+    *:VOS:*:*)
+       # From Paul.Green@stratus.com.
+       echo hppa1.1-stratus-vos
+       exit 0 ;;
+    mc68*:A/UX:*:*)
+       echo m68k-apple-aux${UNAME_RELEASE}
+       exit 0 ;;
+    news*:NEWS-OS:6*:*)
+       echo mips-sony-newsos6
+       exit 0 ;;
+    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 0 ;;
+    BeBox:BeOS:*:*)    # BeOS running on hardware made by Be, PPC only.
+       echo powerpc-be-beos
+       exit 0 ;;
+    BeMac:BeOS:*:*)    # BeOS running on Mac or Mac clone, PPC only.
+       echo powerpc-apple-beos
+       exit 0 ;;
+    BePC:BeOS:*:*)     # BeOS running on Intel PC compatible.
+       echo i586-pc-beos
+       exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+       echo sx4-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+       echo sx5-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    SX-6:SUPER-UX:*:*)
+       echo sx6-nec-superux${UNAME_RELEASE}
+       exit 0 ;;
+    Power*:Rhapsody:*:*)
+       echo powerpc-apple-rhapsody${UNAME_RELEASE}
+       exit 0 ;;
+    *:Rhapsody:*:*)
+       echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+       exit 0 ;;
+    *:Darwin:*:*)
+       case `uname -p` in
+           *86) UNAME_PROCESSOR=i686 ;;
+           powerpc) UNAME_PROCESSOR=powerpc ;;
+       esac
+       echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+       exit 0 ;;
+    *: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 0 ;;
+    *:QNX:*:4*)
+       echo i386-pc-qnx
+       exit 0 ;;
+    NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*)
+       echo nsr-tandem-nsk${UNAME_RELEASE}
+       exit 0 ;;
+    *:NonStop-UX:*:*)
+       echo mips-compaq-nonstopux
+       exit 0 ;;
+    BS2000:POSIX*:*:*)
+       echo bs2000-siemens-sysv
+       exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+       echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+       exit 0 ;;
+    *: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 0 ;;
+    *:TOPS-10:*:*)
+       echo pdp10-unknown-tops10
+       exit 0 ;;
+    *:TENEX:*:*)
+       echo pdp10-unknown-tenex
+       exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+       echo pdp10-dec-tops20
+       exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+       echo pdp10-xkl-tops20
+       exit 0 ;;
+    *:TOPS-20:*:*)
+       echo pdp10-unknown-tops20
+       exit 0 ;;
+    *:ITS:*:*)
+       echo pdp10-unknown-its
+       exit 0 ;;
+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"); 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 && $dummy && exit 0
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# 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 0 ;;
+    c2*)
+       if getsysinfo -f scalar_acc
+       then echo c32-convex-bsd
+       else echo c2-convex-bsd
+       fi
+       exit 0 ;;
+    c34*)
+       echo c34-convex-bsd
+       exit 0 ;;
+    c38*)
+       echo c38-convex-bsd
+       exit 0 ;;
+    c4*)
+       echo c4-convex-bsd
+       exit 0 ;;
+    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
+
+    ftp://ftp.gnu.org/pub/gnu/config/
+
+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/utils/iaxclient/lib/portaudio/config.sub b/utils/iaxclient/lib/portaudio/config.sub
new file mode 100755 (executable)
index 0000000..9772e87
--- /dev/null
@@ -0,0 +1,1489 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+timestamp='2003-02-22'
+
+# 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., 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.
+
+# 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
+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 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # 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 0;;
+
+    * )
+       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* | freebsd*-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)
+               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
+               ;;
+       -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/'`
+               ;;
+       -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] \
+       | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+       | clipper \
+       | d10v | d30v | dlx | dsp16xx \
+       | fr30 | frv \
+       | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+       | i370 | i860 | i960 | ia64 \
+       | ip2k \
+       | m32r | m68000 | m68k | m88k | mcore \
+       | mips | mipsbe | mipseb | mipsel | mipsle \
+       | mips16 \
+       | mips64 | mips64el \
+       | mips64vr | mips64vrel \
+       | mips64orion | mips64orionel \
+       | mips64vr4100 | mips64vr4100el \
+       | mips64vr4300 | mips64vr4300el \
+       | mips64vr5000 | mips64vr5000el \
+       | mipsisa32 | mipsisa32el \
+       | mipsisa32r2 | mipsisa32r2el \
+       | mipsisa64 | mipsisa64el \
+       | mipsisa64sb1 | mipsisa64sb1el \
+       | mipsisa64sr71k | mipsisa64sr71kel \
+       | mipstx39 | mipstx39el \
+       | mn10200 | mn10300 \
+       | msp430 \
+       | ns16k | ns32k \
+       | openrisc | or32 \
+       | pdp10 | pdp11 | pj | pjl \
+       | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+       | pyramid \
+       | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+       | sh64 | sh64le \
+       | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
+       | strongarm \
+       | tahoe | thumb | tic80 | tron \
+       | v850 | v850e \
+       | we32k \
+       | x86 | xscale | xstormy16 | xtensa \
+       | z8k)
+               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)
+               ;;
+
+       # 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-* \
+       | bs2000-* \
+       | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+       | clipper-* | 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-* \
+       | m32r-* \
+       | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+       | m88110-* | m88k-* | mcore-* \
+       | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+       | mips16-* \
+       | mips64-* | mips64el-* \
+       | mips64vr-* | mips64vrel-* \
+       | mips64orion-* | mips64orionel-* \
+       | mips64vr4100-* | mips64vr4100el-* \
+       | mips64vr4300-* | mips64vr4300el-* \
+       | mips64vr5000-* | mips64vr5000el-* \
+       | mipsisa32-* | mipsisa32el-* \
+       | mipsisa32r2-* | mipsisa32r2el-* \
+       | mipsisa64-* | mipsisa64el-* \
+       | mipsisa64sb1-* | mipsisa64sb1el-* \
+       | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+       | mipstx39-* | mipstx39el-* \
+       | msp430-* \
+       | none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
+       | orion-* \
+       | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+       | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+       | pyramid-* \
+       | romp-* | rs6000-* \
+       | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+       | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+       | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+       | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+       | tahoe-* | thumb-* \
+       | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+       | tron-* \
+       | v850-* | v850e-* | vax-* \
+       | we32k-* \
+       | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
+       | xtensa-* \
+       | ymp-* \
+       | z8k-*)
+               ;;
+       # 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
+               ;;
+       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
+               ;;
+       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
+               ;;
+       crds | unos)
+               basic_machine=m68k-crds
+               ;;
+       cris | cris-* | etrax*)
+               basic_machine=cris-axis
+               ;;
+       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
+               ;;
+       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
+               ;;
+       mmix*)
+               basic_machine=mmix-knuth
+               os=-mmixware
+               ;;
+       monitor)
+               basic_machine=m68k-rom68k
+               os=-coff
+               ;;
+       morphos)
+               basic_machine=powerpc-unknown
+               os=-morphos
+               ;;
+       msdos)
+               basic_machine=i386-pc
+               os=-msdos
+               ;;
+       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
+               ;;
+       nv1)
+               basic_machine=nv1-cray
+               os=-unicosmp
+               ;;
+       nsr-tandem)
+               basic_machine=nsr-tandem
+               ;;
+       op50n-* | op60c-*)
+               basic_machine=hppa1.1-oki
+               os=-proelf
+               ;;
+       or32 | or32-*)
+               basic_machine=or32-unknown
+               os=-coff
+               ;;
+       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
+               ;;
+       pentium | p5 | k5 | k6 | nexgen | viac3)
+               basic_machine=i586-pc
+               ;;
+       pentiumpro | p6 | 6x86 | athlon | athlon_*)
+               basic_machine=i686-pc
+               ;;
+       pentiumii | pentium2)
+               basic_machine=i686-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-*)
+               basic_machine=i686-`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
+               ;;
+       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
+               ;;
+       sequent)
+               basic_machine=i386-sequent
+               ;;
+       sh)
+               basic_machine=sh-hitachi
+               os=-hms
+               ;;
+       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
+               ;;
+        tic4x | c4x*)
+               basic_machine=tic4x-unknown
+               os=-coff
+               ;;
+       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
+               ;;
+       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
+               ;;
+       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
+               ;;
+       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
+               ;;
+       sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
+               basic_machine=sh-unknown
+               ;;
+       sh64)
+               basic_machine=sh64-unknown
+               ;;
+       sparc | 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* | -netbsd* | -openbsd* | -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* | -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*)
+       # 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* \
+             | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+               ;;
+       -mac*)
+               os=`echo $os | sed -e 's|mac|macos|'`
+               ;;
+       -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
+               ;;
+       -wince*)
+               os=-wince
+               ;;
+       -osfrose*)
+               os=-osfrose
+               ;;
+       -osf*)
+               os=-osf
+               ;;
+       -utek*)
+               os=-bsd
+               ;;
+       -dynix*)
+               os=-bsd
+               ;;
+       -acis*)
+               os=-aos
+               ;;
+       -atheos*)
+               os=-atheos
+               ;;
+       -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
+               ;;
+       -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
+               ;;
+       -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
+               ;;
+       # 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
+               ;;
+       *-ibm)
+               os=-aix
+               ;;
+       *-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
+                               ;;
+                       -ptx*)
+                               vendor=sequent
+                               ;;
+                       -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 0
+
+# 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/utils/iaxclient/lib/portaudio/configure b/utils/iaxclient/lib/portaudio/configure
new file mode 100755 (executable)
index 0000000..9221cd1
--- /dev/null
@@ -0,0 +1,21839 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# 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.
+## --------------------- ##
+## 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
+
+
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$ECHO in
+X*--fallback-echo)
+  # Remove one level of quotation (which was required for Make).
+  ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','`
+  ;;
+esac
+
+echo=${ECHO-echo}
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell.
+  exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test -z "$ECHO"; then
+if test "X${echo_test_string+set}" != Xset; then
+# find a string as large as possible, as long as the shell can cope with it
+  for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+    # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+    if (echo_test_string=`eval $cmd`) 2>/dev/null &&
+       echo_test_string=`eval $cmd` &&
+       (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
+    then
+      break
+    fi
+  done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+   echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+   test "X$echo_testing_string" = "X$echo_test_string"; then
+  :
+else
+  # The Solaris, AIX, and Digital Unix default echo programs unquote
+  # backslashes.  This makes it impossible to quote backslashes using
+  #   echo "$something" | sed 's/\\/\\\\/g'
+  #
+  # So, first we look for a working echo in the user's PATH.
+
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for dir in $PATH /usr/ucb; do
+    IFS="$lt_save_ifs"
+    if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+       test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+       echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+       test "X$echo_testing_string" = "X$echo_test_string"; then
+      echo="$dir/echo"
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+
+  if test "X$echo" = Xecho; then
+    # We didn't find a better echo, so look for alternatives.
+    if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+       echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
+       test "X$echo_testing_string" = "X$echo_test_string"; then
+      # This shell has a builtin print -r that does the trick.
+      echo='print -r'
+    elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+        test "X$CONFIG_SHELL" != X/bin/ksh; then
+      # If we have ksh, try running configure again with it.
+      ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+      export ORIGINAL_CONFIG_SHELL
+      CONFIG_SHELL=/bin/ksh
+      export CONFIG_SHELL
+      exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
+    else
+      # Try using printf.
+      echo='printf %s\n'
+      if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+        echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+        test "X$echo_testing_string" = "X$echo_test_string"; then
+       # Cool, printf works
+       :
+      elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+          test "X$echo_testing_string" = 'X\t' &&
+          echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+          test "X$echo_testing_string" = "X$echo_test_string"; then
+       CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+       export CONFIG_SHELL
+       SHELL="$CONFIG_SHELL"
+       export SHELL
+       echo="$CONFIG_SHELL $0 --fallback-echo"
+      elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+          test "X$echo_testing_string" = 'X\t' &&
+          echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+          test "X$echo_testing_string" = "X$echo_test_string"; then
+       echo="$CONFIG_SHELL $0 --fallback-echo"
+      else
+       # maybe with a smaller string...
+       prev=:
+
+       for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+         if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
+         then
+           break
+         fi
+         prev="$cmd"
+       done
+
+       if test "$prev" != 'sed 50q "$0"'; then
+         echo_test_string=`eval $prev`
+         export echo_test_string
+         exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
+       else
+         # Oops.  We lost completely, so just stick with echo.
+         echo=echo
+       fi
+      fi
+    fi
+  fi
+fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+ECHO=$echo
+if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+   ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
+fi
+
+
+
+
+tagnames=${tagnames+${tagnames},}CXX
+
+tagnames=${tagnames+${tagnames},}F77
+
+# 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=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="include/portaudio.h"
+# 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 CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT build build_cpu build_vendor build_os host host_cpu host_vendor host_os EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB STRIP ac_ct_STRIP DLLTOOL ac_ct_DLLTOOL AS ac_ct_AS OBJDUMP ac_ct_OBJDUMP CPP CXX CXXFLAGS ac_ct_CXX CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA PKG_CONFIG ac_pt_PKG_CONFIG JACK_CFLAGS JACK_LIBS LT_CURRENT LT_REVISION LT_AGE OTHER_OBJS PADLL SHARED_FLAGS THREAD_CFLAGS DLL_LIBS NASM NASMOPT 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
+ac_env_CXX_set=${CXX+set}
+ac_env_CXX_value=$CXX
+ac_cv_env_CXX_set=${CXX+set}
+ac_cv_env_CXX_value=$CXX
+ac_env_CXXFLAGS_set=${CXXFLAGS+set}
+ac_env_CXXFLAGS_value=$CXXFLAGS
+ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set}
+ac_cv_env_CXXFLAGS_value=$CXXFLAGS
+ac_env_CXXCPP_set=${CXXCPP+set}
+ac_env_CXXCPP_value=$CXXCPP
+ac_cv_env_CXXCPP_set=${CXXCPP+set}
+ac_cv_env_CXXCPP_value=$CXXCPP
+ac_env_F77_set=${F77+set}
+ac_env_F77_value=$F77
+ac_cv_env_F77_set=${F77+set}
+ac_cv_env_F77_value=$F77
+ac_env_FFLAGS_set=${FFLAGS+set}
+ac_env_FFLAGS_value=$FFLAGS
+ac_cv_env_FFLAGS_set=${FFLAGS+set}
+ac_cv_env_FFLAGS_value=$FFLAGS
+ac_env_PKG_CONFIG_set=${PKG_CONFIG+set}
+ac_env_PKG_CONFIG_value=$PKG_CONFIG
+ac_cv_env_PKG_CONFIG_set=${PKG_CONFIG+set}
+ac_cv_env_PKG_CONFIG_value=$PKG_CONFIG
+ac_env_JACK_CFLAGS_set=${JACK_CFLAGS+set}
+ac_env_JACK_CFLAGS_value=$JACK_CFLAGS
+ac_cv_env_JACK_CFLAGS_set=${JACK_CFLAGS+set}
+ac_cv_env_JACK_CFLAGS_value=$JACK_CFLAGS
+ac_env_JACK_LIBS_set=${JACK_LIBS+set}
+ac_env_JACK_LIBS_value=$JACK_LIBS
+ac_cv_env_JACK_LIBS_set=${JACK_LIBS+set}
+ac_cv_env_JACK_LIBS_value=$JACK_LIBS
+
+#
+# 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 this package 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]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-debug-output
+  --enable-shared[=PKGS]
+                          build shared libraries [default=yes]
+  --enable-static[=PKGS]
+                          build static libraries [default=yes]
+  --enable-fast-install[=PKGS]
+                          optimize for fast installation [default=yes]
+  --disable-libtool-lock  avoid locking (might break parallel builds)
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-alsa (default=yes)
+  --with-jack (default=yes)
+  --with-oss (default=yes)
+  --with-host_os (no default)
+  --with-winapi ((wmme/directx/asio) default=wmme)
+  --with-macapi ((asio/core/sm) default=core)
+  --with-asiodir (default=/usr/local/asiosdk2)
+  --with-dxdir (default=/usr/local/dx7sdk)
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+  --with-pic              try to use only PIC/non-PIC objects [default=use
+                          both]
+  --with-tags[=TAGS]
+                          include additional configurations [automatic]
+
+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
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  CXXCPP      C++ preprocessor
+  F77         Fortran 77 compiler command
+  FFLAGS      Fortran 77 compiler flags
+  PKG_CONFIG  path to pkg-config utility
+  JACK_CFLAGS C compiler flags for JACK, overriding pkg-config
+  JACK_LIBS   linker flags for JACK, overriding pkg-config
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_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
+
+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 $as_me, 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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-alsa or --without-alsa was given.
+if test "${with_alsa+set}" = set; then
+  withval="$with_alsa"
+  with_alsa=$withval
+else
+  with_alsa="yes"
+fi;
+
+
+# Check whether --with-jack or --without-jack was given.
+if test "${with_jack+set}" = set; then
+  withval="$with_jack"
+  with_jack=$withval
+else
+  with_jack="yes"
+fi;
+
+
+# Check whether --with-oss or --without-oss was given.
+if test "${with_oss+set}" = set; then
+  withval="$with_oss"
+  with_oss=$withval
+else
+  with_oss="yes"
+fi;
+
+
+# Check whether --with-host_os or --without-host_os was given.
+if test "${with_host_os+set}" = set; then
+  withval="$with_host_os"
+  host_os=$withval
+fi;
+
+
+# Check whether --with-winapi or --without-winapi was given.
+if test "${with_winapi+set}" = set; then
+  withval="$with_winapi"
+  with_winapi=$withval
+else
+  with_winapi="wmme"
+fi;
+
+
+# Check whether --with-macapi or --without-macapi was given.
+if test "${with_macapi+set}" = set; then
+  withval="$with_macapi"
+  with_macapi=$withval
+else
+  with_macapi="core"
+fi;
+
+
+# Check whether --with-asiodir or --without-asiodir was given.
+if test "${with_asiodir+set}" = set; then
+  withval="$with_asiodir"
+  with_asiodir=$withval
+else
+  with_asiodir="/usr/local/asiosdk2"
+fi;
+
+
+# Check whether --with-dxdir or --without-dxdir was given.
+if test "${with_dxdir+set}" = set; then
+  withval="$with_dxdir"
+  with_dxdir=$withval
+else
+  with_dxdir="/usr/local/dx7sdk"
+fi;
+
+# Check whether --enable-debug-output or --disable-debug-output was given.
+if test "${enable_debug_output+set}" = set; then
+  enableval="$enable_debug_output"
+  if test x$enableval != xno ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define PA_ENABLE_DEBUG_OUTPUT
+_ACEOF
+
+          fi
+
+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
+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
+
+
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+  enableval="$enable_shared"
+  p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+       IFS="$lt_save_ifs"
+       if test "X$pkg" = "X$p"; then
+         enable_shared=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_shared=yes
+fi;
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+  enableval="$enable_static"
+  p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+       IFS="$lt_save_ifs"
+       if test "X$pkg" = "X$p"; then
+         enable_static=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_static=yes
+fi;
+
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+  enableval="$enable_fast_install"
+  p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+       IFS="$lt_save_ifs"
+       if test "X$pkg" = "X$p"; then
+         enable_fast_install=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_fast_install=yes
+fi;
+
+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 for a sed that does not truncate output" >&5
+echo $ECHO_N "checking for a sed that does not truncate output... $ECHO_C" >&6
+if test "${lt_cv_path_SED+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for lt_ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+        lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+      fi
+    done
+  done
+done
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+  test ! -f $lt_ac_sed && continue
+  cat /dev/null > conftest.in
+  lt_ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+  # Check for GNU sed and select it if it is found.
+  if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+    lt_cv_path_SED=$lt_ac_sed
+    break
+  fi
+  while true; do
+    cat conftest.in conftest.in >conftest.tmp
+    mv conftest.tmp conftest.in
+    cp conftest.in conftest.nl
+    echo >>conftest.nl
+    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+    cmp -s conftest.out conftest.nl || break
+    # 10000 chars as input seems more than enough
+    test $lt_ac_count -gt 10 && break
+    lt_ac_count=`expr $lt_ac_count + 1`
+    if test $lt_ac_count -gt $lt_ac_max; then
+      lt_ac_max=$lt_ac_count
+      lt_cv_path_SED=$lt_ac_sed
+    fi
+  done
+done
+
+fi
+
+SED=$lt_cv_path_SED
+echo "$as_me:$LINENO: result: $SED" >&5
+echo "${ECHO_T}$SED" >&6
+
+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
+
+
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+  withval="$with_gnu_ld"
+  test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi;
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  echo "$as_me:$LINENO: checking for ld used by $CC" >&5
+echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  echo "$as_me:$LINENO: checking for GNU ld" >&5
+echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6
+else
+  echo "$as_me:$LINENO: checking for non-GNU ld" >&5
+echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6
+fi
+if test "${lt_cv_path_LD+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+       test "$with_gnu_ld" != no && break
+       ;;
+      *)
+       test "$with_gnu_ld" != yes && break
+       ;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  echo "$as_me:$LINENO: result: $LD" >&5
+echo "${ECHO_T}$LD" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
+echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
+   { (exit 1); exit 1; }; }
+echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
+echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6
+if test "${lt_cv_prog_gnu_ld+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
+echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+echo "$as_me:$LINENO: checking for $LD option to reload object files" >&5
+echo $ECHO_N "checking for $LD option to reload object files... $ECHO_C" >&6
+if test "${lt_cv_ld_reload_flag+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_ld_reload_flag='-r'
+fi
+echo "$as_me:$LINENO: result: $lt_cv_ld_reload_flag" >&5
+echo "${ECHO_T}$lt_cv_ld_reload_flag" >&6
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  darwin*)
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
+
+echo "$as_me:$LINENO: checking for BSD-compatible nm" >&5
+echo $ECHO_N "checking for BSD-compatible nm... $ECHO_C" >&6
+if test "${lt_cv_path_NM+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_nm_to_check="${ac_tool_prefix}nm"
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS="$lt_save_ifs"
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+       # Check to see if the nm accepts a BSD-compat flag.
+       # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+       #   nm: unknown option "B" ignored
+       # Tru64's nm complains that /dev/null is an invalid object file
+       case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+       */dev/null* | *'Invalid file or object type'*)
+         lt_cv_path_NM="$tmp_nm -B"
+         break
+         ;;
+       *)
+         case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+         */dev/null*)
+           lt_cv_path_NM="$tmp_nm -p"
+           break
+           ;;
+         *)
+           lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+           continue # so that we can try to find one that supports BSD flags
+           ;;
+         esac
+         ;;
+       esac
+      fi
+    done
+    IFS="$lt_save_ifs"
+  done
+  test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi
+fi
+echo "$as_me:$LINENO: result: $lt_cv_path_NM" >&5
+echo "${ECHO_T}$lt_cv_path_NM" >&6
+NM="$lt_cv_path_NM"
+
+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
+
+echo "$as_me:$LINENO: checking how to recognise dependent libraries" >&5
+echo $ECHO_N "checking how to recognise dependent libraries... $ECHO_C" >&6
+if test "${lt_cv_deplibs_check_method+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix4* | aix5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[45]*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump'.
+  lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | kfreebsd*-gnu | dragonfly*)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix3*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd*)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+nto-qnx*)
+  lt_cv_deplibs_check_method=unknown
+  ;;
+
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_deplibs_check_method" >&5
+echo "${ECHO_T}$lt_cv_deplibs_check_method" >&6
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+  enableval="$enable_libtool_lock"
+
+fi;
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  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
+    case `/usr/bin/file conftest.$ac_objext` in
+    *ELF-32*)
+      HPUX_IA64_MODE="32"
+      ;;
+    *ELF-64*)
+      HPUX_IA64_MODE="64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '#line 3177 "configure"' > conftest.$ac_ext
+  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
+   if test "$lt_cv_prog_gnu_ld" = yes; then
+    case `/usr/bin/file conftest.$ac_objext` in
+    *32-bit*)
+      LD="${LD-ld} -melf32bsmip"
+      ;;
+    *N32*)
+      LD="${LD-ld} -melf32bmipn32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -melf64bmip"
+      ;;
+    esac
+   else
+    case `/usr/bin/file conftest.$ac_objext` in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+   fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  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
+    case `/usr/bin/file conftest.o` in
+    *32-bit*)
+      case $host in
+        x86_64-*linux*)
+          LD="${LD-ld} -m elf_i386"
+          ;;
+        ppc64-*linux*|powerpc64-*linux*)
+          LD="${LD-ld} -m elf32ppclinux"
+          ;;
+        s390x-*linux*)
+          LD="${LD-ld} -m elf_s390"
+          ;;
+        sparc64-*linux*)
+          LD="${LD-ld} -m elf32_sparc"
+          ;;
+      esac
+      ;;
+    *64-bit*)
+      case $host in
+        x86_64-*linux*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        ppc*-*linux*|powerpc*-*linux*)
+          LD="${LD-ld} -m elf64ppc"
+          ;;
+        s390*-*linux*)
+          LD="${LD-ld} -m elf64_s390"
+          ;;
+        sparc*-*linux*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  echo "$as_me:$LINENO: checking whether the C compiler needs -belf" >&5
+echo $ECHO_N "checking whether the C compiler needs -belf... $ECHO_C" >&6
+if test "${lt_cv_cc_needs_belf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  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
+
+     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
+  lt_cv_cc_needs_belf=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+lt_cv_cc_needs_belf=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext 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
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_cc_needs_belf" >&5
+echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+sparc*-*solaris*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  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
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*) LD="${LD-ld} -m elf64_sparc" ;;
+      *)    LD="${LD-ld} -64" ;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-cygwin* | *-*-mingw* | *-*-pw32*)
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; 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_DLLTOOL+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$DLLTOOL"; then
+  ac_cv_prog_DLLTOOL="$DLLTOOL" # 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_DLLTOOL="${ac_tool_prefix}dlltool"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+  echo "$as_me:$LINENO: result: $DLLTOOL" >&5
+echo "${ECHO_T}$DLLTOOL" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_DLLTOOL"; then
+  ac_ct_DLLTOOL=$DLLTOOL
+  # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; 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_DLLTOOL+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_DLLTOOL"; then
+  ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # 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_DLLTOOL="dlltool"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_DLLTOOL" && ac_cv_prog_ac_ct_DLLTOOL="false"
+fi
+fi
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+  echo "$as_me:$LINENO: result: $ac_ct_DLLTOOL" >&5
+echo "${ECHO_T}$ac_ct_DLLTOOL" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  DLLTOOL=$ac_ct_DLLTOOL
+else
+  DLLTOOL="$ac_cv_prog_DLLTOOL"
+fi
+
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
+set dummy ${ac_tool_prefix}as; 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_AS+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AS"; then
+  ac_cv_prog_AS="$AS" # 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_AS="${ac_tool_prefix}as"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+AS=$ac_cv_prog_AS
+if test -n "$AS"; then
+  echo "$as_me:$LINENO: result: $AS" >&5
+echo "${ECHO_T}$AS" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_AS"; then
+  ac_ct_AS=$AS
+  # Extract the first word of "as", so it can be a program name with args.
+set dummy as; 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_AS+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_AS"; then
+  ac_cv_prog_ac_ct_AS="$ac_ct_AS" # 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_AS="as"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_AS" && ac_cv_prog_ac_ct_AS="false"
+fi
+fi
+ac_ct_AS=$ac_cv_prog_ac_ct_AS
+if test -n "$ac_ct_AS"; then
+  echo "$as_me:$LINENO: result: $ac_ct_AS" >&5
+echo "${ECHO_T}$ac_ct_AS" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  AS=$ac_ct_AS
+else
+  AS="$ac_cv_prog_AS"
+fi
+
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; 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_OBJDUMP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$OBJDUMP"; then
+  ac_cv_prog_OBJDUMP="$OBJDUMP" # 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_OBJDUMP="${ac_tool_prefix}objdump"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+  echo "$as_me:$LINENO: result: $OBJDUMP" >&5
+echo "${ECHO_T}$OBJDUMP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+  ac_ct_OBJDUMP=$OBJDUMP
+  # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; 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_OBJDUMP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_OBJDUMP"; then
+  ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # 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_OBJDUMP="objdump"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_OBJDUMP" && ac_cv_prog_ac_ct_OBJDUMP="false"
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+  echo "$as_me:$LINENO: result: $ac_ct_OBJDUMP" >&5
+echo "${ECHO_T}$ac_ct_OBJDUMP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  OBJDUMP=$ac_ct_OBJDUMP
+else
+  OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+  ;;
+
+esac
+
+need_locks="$enable_libtool_lock"
+
+
+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 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 dlfcn.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 the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_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
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
+  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_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # 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_CXX="$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
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  echo "$as_me:$LINENO: result: $CXX" >&5
+echo "${ECHO_T}$CXX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in $CCC g++ c++ gpp aCC CC cxx cc++ cl FCC KCC RCC xlC_r xlC
+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_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # 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_CXX="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5
+echo "${ECHO_T}$ac_ct_CXX" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CXX" && break
+done
+test -n "$ac_ct_CXX" || ac_ct_CXX="g++"
+
+  CXX=$ac_ct_CXX
+fi
+
+
+# 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); }
+
+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_cxx_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_cxx_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_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_cxx_compiler_gnu" >&6
+GXX=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+CXXFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5
+echo $ECHO_N "checking whether $CXX accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cxx_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_cxx_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_cxx_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cxx_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cxx_g" >&6
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+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_cxx_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_cxx_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
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
+  ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_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
+if test -z "$CXXCPP"; then
+  if test "${ac_cv_prog_CXXCPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CXXCPP needs to be expanded
+    for CXXCPP in "$CXX -E" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_cxx_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_cxx_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_cxx_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_cxx_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_cxx_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_CXXCPP=$CXXCPP
+
+fi
+  CXXCPP=$ac_cv_prog_CXXCPP
+else
+  ac_cv_prog_CXXCPP=$CXXCPP
+fi
+echo "$as_me:$LINENO: result: $CXXCPP" >&5
+echo "${ECHO_T}$CXXCPP" >&6
+ac_preproc_ok=false
+for ac_cxx_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_cxx_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_cxx_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_cxx_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_cxx_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 \"$CXXCPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+fi
+
+
+ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran
+  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_F77+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$F77"; then
+  ac_cv_prog_F77="$F77" # 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_F77="$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
+F77=$ac_cv_prog_F77
+if test -n "$F77"; then
+  echo "$as_me:$LINENO: result: $F77" >&5
+echo "${ECHO_T}$F77" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$F77" && break
+  done
+fi
+if test -z "$F77"; then
+  ac_ct_F77=$F77
+  for ac_prog in g77 f77 xlf frt pgf77 fort77 fl32 af77 f90 xlf90 pgf90 epcf90 f95 fort xlf95 ifc efc pgf95 lf95 gfortran
+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_F77+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_F77"; then
+  ac_cv_prog_ac_ct_F77="$ac_ct_F77" # 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_F77="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_F77=$ac_cv_prog_ac_ct_F77
+if test -n "$ac_ct_F77"; then
+  echo "$as_me:$LINENO: result: $ac_ct_F77" >&5
+echo "${ECHO_T}$ac_ct_F77" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_F77" && break
+done
+
+  F77=$ac_ct_F77
+fi
+
+
+# Provide some information about the compiler.
+echo "$as_me:4909:" \
+     "checking for Fortran 77 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); }
+rm -f a.out
+
+# If we don't use `.F' as extension, the preprocessor is not run on the
+# input file.  (Note that this only needs to work for GNU compilers.)
+ac_save_ext=$ac_ext
+ac_ext=F
+echo "$as_me:$LINENO: checking whether we are using the GNU Fortran 77 compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU Fortran 77 compiler... $ECHO_C" >&6
+if test "${ac_cv_f77_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+      program main
+#ifndef __GNUC__
+       choke me
+#endif
+
+      end
+_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_f77_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_f77_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_f77_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_f77_compiler_gnu" >&6
+ac_ext=$ac_save_ext
+ac_test_FFLAGS=${FFLAGS+set}
+ac_save_FFLAGS=$FFLAGS
+FFLAGS=
+echo "$as_me:$LINENO: checking whether $F77 accepts -g" >&5
+echo $ECHO_N "checking whether $F77 accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_f77_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  FFLAGS=-g
+cat >conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_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_f77_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_f77_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_f77_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_f77_g" >&5
+echo "${ECHO_T}$ac_cv_prog_f77_g" >&6
+if test "$ac_test_FFLAGS" = set; then
+  FFLAGS=$ac_save_FFLAGS
+elif test $ac_cv_prog_f77_g = yes; then
+  if test "x$ac_cv_f77_compiler_gnu" = xyes; then
+    FFLAGS="-g -O2"
+  else
+    FFLAGS="-g"
+  fi
+else
+  if test "x$ac_cv_f77_compiler_gnu" = xyes; then
+    FFLAGS="-O2"
+  else
+    FFLAGS=
+  fi
+fi
+
+G77=`test $ac_compiler_gnu = yes && echo yes`
+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
+
+
+
+# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
+
+# find the maximum length of command line arguments
+echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5
+echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6
+if test "${lt_cv_sys_max_cmd_len+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+    i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536      # usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[        ]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    # If test is not a shell built-in, we'll probably end up computing a
+    # maximum length that is only half of the actual maximum length, but
+    # we can't tell.
+    SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+    while (test "X"`$SHELL $0 --fallback-echo "X$teststring" 2>/dev/null` \
+              = "XX$teststring") >/dev/null 2>&1 &&
+           new_result=`expr "X$teststring" : ".*" 2>&1` &&
+           lt_cv_sys_max_cmd_len=$new_result &&
+           test $i != 17 # 1/2 MB should be enough
+    do
+      i=`expr $i + 1`
+      teststring=$teststring$teststring
+    done
+    teststring=
+    # Add a significant safety factor because C++ compilers can tack on massive
+    # amounts of additional arguments before passing them to the linker.
+    # It appears as though 1/2 is a usable value.
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    ;;
+  esac
+
+fi
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+  echo "$as_me:$LINENO: result: $lt_cv_sys_max_cmd_len" >&5
+echo "${ECHO_T}$lt_cv_sys_max_cmd_len" >&6
+else
+  echo "$as_me:$LINENO: result: none" >&5
+echo "${ECHO_T}none" >&6
+fi
+
+
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5
+echo $ECHO_N "checking command to parse $NM output from $compiler object... $ECHO_C" >&6
+if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform an extracted symbol line into a proper C declaration
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[BCDT]'
+  ;;
+cygwin* | mingw* | pw32*)
+  symcode='[ABCDGISTW]'
+  ;;
+hpux*) # Its linker distinguishes data from code symbols
+  if test "$host_cpu" = ia64; then
+    symcode='[ABCDEGRST]'
+  fi
+  lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+  lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+  ;;
+linux*)
+  if test "$host_cpu" = ia64; then
+    symcode='[ABCDGIRSTW]'
+    lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+    lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (lt_ptr) \&\2},/p'"
+  fi
+  ;;
+irix* | nonstopux*)
+  symcode='[BCDEGRST]'
+  ;;
+osf*)
+  symcode='[BCDEGQRST]'
+  ;;
+solaris*)
+  symcode='[BDRT]'
+  ;;
+sco3.2v5*)
+  symcode='[DT]'
+  ;;
+sysv4.2uw2*)
+  symcode='[DT]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[ABDT]'
+  ;;
+sysv4)
+  symcode='[DFNSTU]'
+  ;;
+esac
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[      ]\($symcode$symcode*\)[         ][      ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+  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
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if { (eval echo "$as_me:$LINENO: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\"") >&5
+  (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+       mv -f "$nlist"T "$nlist"
+      else
+       rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if grep ' nm_test_var$' "$nlist" >/dev/null; then
+       if grep ' nm_test_func$' "$nlist" >/dev/null; then
+         cat <<EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+         # Now generate the symbol file.
+         eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext'
+
+         cat <<EOF >> conftest.$ac_ext
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+  const char *name;
+  lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{
+EOF
+         $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext
+         cat <<\EOF >> conftest.$ac_ext
+  {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+         # Now try linking the two files.
+         mv conftest.$ac_objext conftstm.$ac_objext
+         lt_save_LIBS="$LIBS"
+         lt_save_CFLAGS="$CFLAGS"
+         LIBS="conftstm.$ac_objext"
+         CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+         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); } && test -s conftest${ac_exeext}; then
+           pipe_works=yes
+         fi
+         LIBS="$lt_save_LIBS"
+         CFLAGS="$lt_save_CFLAGS"
+       else
+         echo "cannot find nm_test_func in $nlist" >&5
+       fi
+      else
+       echo "cannot find nm_test_var in $nlist" >&5
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+    fi
+  else
+    echo "$progname: failed program was:" >&5
+    cat conftest.$ac_ext >&5
+  fi
+  rm -f conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  echo "$as_me:$LINENO: result: failed" >&5
+echo "${ECHO_T}failed" >&6
+else
+  echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6
+fi
+
+echo "$as_me:$LINENO: checking for objdir" >&5
+echo $ECHO_N "checking for objdir... $ECHO_C" >&6
+if test "${lt_cv_objdir+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+echo "$as_me:$LINENO: result: $lt_cv_objdir" >&5
+echo "${ECHO_T}$lt_cv_objdir" >&6
+objdir=$lt_cv_objdir
+
+
+
+
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Constants:
+rm="rm -f"
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+ltmain="$ac_aux_dir/ltmain.sh"
+ofile="$default_ofile"
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; 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_AR+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # 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_AR="${ac_tool_prefix}ar"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  echo "$as_me:$LINENO: result: $AR" >&5
+echo "${ECHO_T}$AR" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+  ac_ct_AR=$AR
+  # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; 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_AR+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_AR"; then
+  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # 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_AR="ar"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_AR" && ac_cv_prog_ac_ct_AR="false"
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+  echo "$as_me:$LINENO: result: $ac_ct_AR" >&5
+echo "${ECHO_T}$ac_ct_AR" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  AR=$ac_ct_AR
+else
+  AR="$ac_cv_prog_AR"
+fi
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; 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_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # 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_RANLIB="${ac_tool_prefix}ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; 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_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # 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_RANLIB="ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  RANLIB=$ac_ct_RANLIB
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; 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_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # 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_STRIP="${ac_tool_prefix}strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; 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_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # 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_STRIP="strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  STRIP=$ac_ct_STRIP
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+test -z "$AS" && AS=as
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$LD" && LD=ld
+test -z "$LN_S" && LN_S="ln -s"
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+test -z "$NM" && NM=nm
+test -z "$SED" && SED=sed
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$RANLIB" && RANLIB=:
+test -z "$STRIP" && STRIP=:
+test -z "$ac_objext" && ac_objext=o
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    echo "$as_me:$LINENO: checking for ${ac_tool_prefix}file" >&5
+echo $ECHO_N "checking for ${ac_tool_prefix}file... $ECHO_C" >&6
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/${ac_tool_prefix}file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+      if test -n "$file_magic_test_file"; then
+       case $deplibs_check_method in
+       "file_magic "*)
+         file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+         MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+         if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+           $EGREP "$file_magic_regex" > /dev/null; then
+           :
+         else
+           cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+         fi ;;
+       esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
+echo "${ECHO_T}$MAGIC_CMD" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    echo "$as_me:$LINENO: checking for file" >&5
+echo $ECHO_N "checking for file... $ECHO_C" >&6
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/file"
+      if test -n "$file_magic_test_file"; then
+       case $deplibs_check_method in
+       "file_magic "*)
+         file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+         MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+         if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+           $EGREP "$file_magic_regex" > /dev/null; then
+           :
+         else
+           cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+         fi ;;
+       esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  echo "$as_me:$LINENO: result: $MAGIC_CMD" >&5
+echo "${ECHO_T}$MAGIC_CMD" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  else
+    MAGIC_CMD=:
+  fi
+fi
+
+  fi
+  ;;
+esac
+
+enable_dlopen=no
+enable_win32_dll=yes
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+  enableval="$enable_libtool_lock"
+
+fi;
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+
+# Check whether --with-pic or --without-pic was given.
+if test "${with_pic+set}" = set; then
+  withval="$with_pic"
+  pic_mode="$withval"
+else
+  pic_mode=default
+fi;
+test -z "$pic_mode" && pic_mode=default
+
+# Check if we have a version mismatch between libtool.m4 and ltmain.sh.
+#
+# Note:  This should be in AC_LIBTOOL_SETUP, _after_ $ltmain have been defined.
+#        We also should do it _before_ AC_LIBTOOL_LANG_C_CONFIG that actually
+#        calls AC_LIBTOOL_CONFIG and creates libtool.
+#
+echo "$as_me:$LINENO: checking for correct ltmain.sh version" >&5
+echo $ECHO_N "checking for correct ltmain.sh version... $ECHO_C" >&6
+if test "x$ltmain" = "x" ; then
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  { { echo "$as_me:$LINENO: error:
+
+*** [Gentoo] sanity check failed! ***
+*** \$ltmain is not defined, please check the patch for consistency! ***
+" >&5
+echo "$as_me: error:
+
+*** [Gentoo] sanity check failed! ***
+*** \$ltmain is not defined, please check the patch for consistency! ***
+" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+gentoo_lt_version="1.5.22"
+gentoo_ltmain_version=`sed -n '/^[     ]*VERSION=/{s/^[        ]*VERSION=//;p;q;}' "$ltmain"`
+if test "x$gentoo_lt_version" != "x$gentoo_ltmain_version" ; then
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  { { echo "$as_me:$LINENO: error:
+
+*** [Gentoo] sanity check failed! ***
+*** libtool.m4 and ltmain.sh have a version mismatch! ***
+*** (libtool.m4 = $gentoo_lt_version, ltmain.sh = $gentoo_ltmain_version) ***
+
+Please run:
+
+  libtoolize --copy --force
+
+if appropriate, please contact the maintainer of this
+package (or your distribution) for help.
+" >&5
+echo "$as_me: error:
+
+*** [Gentoo] sanity check failed! ***
+*** libtool.m4 and ltmain.sh have a version mismatch! ***
+*** (libtool.m4 = $gentoo_lt_version, ltmain.sh = $gentoo_ltmain_version) ***
+
+Please run:
+
+  libtoolize --copy --force
+
+if appropriate, please contact the maintainer of this
+package (or your distribution) for help.
+" >&2;}
+   { (exit 1); exit 1; }; }
+else
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+fi
+
+
+# Use C for the default configuration in the libtool script
+tagname=
+lt_save_CC="$CC"
+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
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}\n'
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$rm conftest*
+
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$rm conftest*
+
+
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+  lt_prog_compiler_no_builtin_flag=' -fno-builtin'
+
+
+echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6
+if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_prog_compiler_rtti_exceptions=no
+  ac_outfile=conftest.$ac_objext
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="-fno-rtti -fno-exceptions"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:6033: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:6037: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_rtti_exceptions=yes
+     fi
+   fi
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+    lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+    :
+fi
+
+fi
+
+lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
+
+  if test "$GCC" = yes; then
+    lt_prog_compiler_wl='-Wl,'
+    lt_prog_compiler_static='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+      ;;
+
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic='-fno-common'
+      ;;
+
+    interix3*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      lt_prog_compiler_can_build_shared=no
+      enable_shared=no
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       lt_prog_compiler_pic=-Kconform_pic
+      fi
+      ;;
+
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+       # +Z the default
+       ;;
+      *)
+       lt_prog_compiler_pic='-fPIC'
+       ;;
+      esac
+      ;;
+
+    *)
+      lt_prog_compiler_pic='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      lt_prog_compiler_wl='-Wl,'
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       lt_prog_compiler_static='-Bstatic'
+      else
+       lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+      darwin*)
+        # PIC is the default on this platform
+        # Common symbols not allowed in MH_DYLIB files
+       case $cc_basename in
+         xlc*)
+         lt_prog_compiler_pic='-qnocommon'
+         lt_prog_compiler_wl='-Wl,'
+         ;;
+       esac
+       ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+       # +Z the default
+       ;;
+      *)
+       lt_prog_compiler_pic='+Z'
+       ;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      lt_prog_compiler_static='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC (with -KPIC) is the default.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    newsos6)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    linux*)
+      case $cc_basename in
+      icc* | ecc*)
+       lt_prog_compiler_wl='-Wl,'
+       lt_prog_compiler_pic='-KPIC'
+       lt_prog_compiler_static='-static'
+        ;;
+      pgcc* | pgf77* | pgf90* | pgf95*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+       # which looks to be a dead project)
+       lt_prog_compiler_wl='-Wl,'
+       lt_prog_compiler_pic='-fpic'
+       lt_prog_compiler_static='-Bstatic'
+        ;;
+      ccc*)
+        lt_prog_compiler_wl='-Wl,'
+        # All Alpha code is PIC.
+        lt_prog_compiler_static='-non_shared'
+        ;;
+      esac
+      ;;
+
+    osf3* | osf4* | osf5*)
+      lt_prog_compiler_wl='-Wl,'
+      # All OSF/1 code is PIC.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    solaris*)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95*)
+       lt_prog_compiler_wl='-Qoption ld ';;
+      *)
+       lt_prog_compiler_wl='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      lt_prog_compiler_wl='-Qoption ld '
+      lt_prog_compiler_pic='-PIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+       lt_prog_compiler_pic='-Kconform_pic'
+       lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    unicos*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_can_build_shared=no
+      ;;
+
+    uts4*)
+      lt_prog_compiler_pic='-pic'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *)
+      lt_prog_compiler_can_build_shared=no
+      ;;
+    esac
+  fi
+
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic" >&6
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+
+echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic works... $ECHO_C" >&6
+if test "${lt_prog_compiler_pic_works+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_pic_works=no
+  ac_outfile=conftest.$ac_objext
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:6301: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:6305: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_prog_compiler_pic_works=yes
+     fi
+   fi
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_works" >&6
+
+if test x"$lt_prog_compiler_pic_works" = xyes; then
+    case $lt_prog_compiler_pic in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+     esac
+else
+    lt_prog_compiler_pic=
+     lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic=
+    ;;
+  *)
+    lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+    ;;
+esac
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6
+if test "${lt_prog_compiler_static_works+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_static_works=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   printf "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_prog_compiler_static_works=yes
+       fi
+     else
+       lt_prog_compiler_static_works=yes
+     fi
+   fi
+   $rm conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works" >&5
+echo "${ECHO_T}$lt_prog_compiler_static_works" >&6
+
+if test x"$lt_prog_compiler_static_works" = xyes; then
+    :
+else
+    lt_prog_compiler_static=
+fi
+
+
+echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
+if test "${lt_cv_prog_compiler_c_o+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $rm -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:6405: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:6409: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $rm conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+   $rm out/* && rmdir out
+   cd ..
+   rmdir conftest
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_c_o" >&6
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  echo "$as_me:$LINENO: result: $hard_links" >&5
+echo "${ECHO_T}$hard_links" >&6
+  if test "$hard_links" = no; then
+    { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6
+
+  runpath_var=
+  allow_undefined_flag=
+  enable_shared_with_static_runtimes=no
+  archive_cmds=
+  archive_expsym_cmds=
+  old_archive_From_new_cmds=
+  old_archive_from_expsyms_cmds=
+  export_dynamic_flag_spec=
+  whole_archive_flag_spec=
+  thread_safe_flag_spec=
+  hardcode_libdir_flag_spec=
+  hardcode_libdir_flag_spec_ld=
+  hardcode_libdir_separator=
+  hardcode_direct=no
+  hardcode_minus_L=no
+  hardcode_shlibpath_var=unsupported
+  link_all_deplibs=unknown
+  hardcode_automatic=no
+  module_cmds=
+  module_expsym_cmds=
+  always_export_symbols=no
+  export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  include_expsyms=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  extract_expsyms_cmds=
+  # Just being paranoid about ensuring that cc_basename is set.
+  for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+  case $host_os in
+  cygwin* | mingw* | pw32*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  esac
+
+  ld_shlibs=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
+       whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+       whole_archive_flag_spec=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>/dev/null` in
+      *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix3* | aix4* | aix5*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+       ld_shlibs=no
+       cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+      fi
+      ;;
+
+    amigaos*)
+      archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+
+      # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+      # that the semantics of dynamic libraries on AmigaOS, at least up
+      # to version 4, is to share data among multiple programs linked
+      # with the same dynamic library.  Since this doesn't match the
+      # behavior of shared libraries on other platforms, we can't use
+      # them.
+      ld_shlibs=no
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       allow_undefined_flag=unsupported
+       # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+       # support --undefined.  This deserves some investigation.  FIXME
+       archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+       ld_shlibs=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+      # as there is no search path for DLLs.
+      hardcode_libdir_flag_spec='-L$libdir'
+      allow_undefined_flag=unsupported
+      always_export_symbols=no
+      enable_shared_with_static_runtimes=yes
+      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+       # If the export-symbols file already is a .def file (1st line
+       # is EXPORTS), use it as is; otherwise, prepend...
+       archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+         cp $export_symbols $output_objdir/$soname.def;
+       else
+         echo EXPORTS > $output_objdir/$soname.def;
+         cat $export_symbols >> $output_objdir/$soname.def;
+       fi~
+       $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+       ld_shlibs=no
+      fi
+      ;;
+
+    interix3*)
+      hardcode_direct=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    linux*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       tmp_addflag=
+       case $cc_basename,$host_cpu in
+       pgcc*)                          # Portland Group C compiler
+         whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+         tmp_addflag=' $pic_flag'
+         ;;
+       pgf77* | pgf90* | pgf95*)       # Portland Group f77 and f90 compilers
+         whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+         tmp_addflag=' $pic_flag -Mnomain' ;;
+       ecc*,ia64* | icc*,ia64*)                # Intel C compiler on ia64
+         tmp_addflag=' -i_dynamic' ;;
+       efc*,ia64* | ifort*,ia64*)      # Intel Fortran compiler on ia64
+         tmp_addflag=' -i_dynamic -nofor_main' ;;
+       ifc* | ifort*)                  # Intel Fortran compiler
+         tmp_addflag=' -nofor_main' ;;
+       esac
+       archive_cmds='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+       if test $supports_anon_versioning = yes; then
+         archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~
+  cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+  $echo "local: *; };" >> $output_objdir/$libname.ver~
+         $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+       fi
+      else
+       ld_shlibs=no
+      fi
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+       archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+       wlarc=
+      else
+       archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+       ld_shlibs=no
+       cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+       ld_shlibs=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+       ld_shlibs=no
+       cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+       ;;
+       *)
+         if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+           hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+           archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
+           archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
+         else
+           ld_shlibs=no
+         fi
+       ;;
+      esac
+      ;;
+
+    sunos4*)
+      archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+       ld_shlibs=no
+      fi
+      ;;
+    esac
+
+    if test "$ld_shlibs" = no; then
+      runpath_var=
+      hardcode_libdir_flag_spec=
+      export_dynamic_flag_spec=
+      whole_archive_flag_spec=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      allow_undefined_flag=unsupported
+      always_export_symbols=yes
+      archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+       # Neither direct hardcoding nor static linking is supported with a
+       # broken collect2.
+       hardcode_direct=unsupported
+      fi
+      ;;
+
+    aix4* | aix5*)
+      if test "$host_cpu" = ia64; then
+       # On IA64, the linker does run time linking by default, so we don't
+       # have to do anything special.
+       aix_use_runtimelinking=no
+       exp_sym_flag='-Bexport'
+       no_entry_flag=""
+      else
+       # If we're using GNU nm, then we don't want the "-C" option.
+       # -C means demangle to AIX nm, but means don't demangle with GNU nm
+       if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+         export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+       else
+         export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+       fi
+       aix_use_runtimelinking=no
+
+       # Test if we are trying to use run time linking or normal
+       # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+       # need to do runtime linking.
+       case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+         for ld_flag in $LDFLAGS; do
+         if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+           aix_use_runtimelinking=yes
+           break
+         fi
+         done
+         ;;
+       esac
+
+       exp_sym_flag='-bexport'
+       no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      archive_cmds=''
+      hardcode_direct=yes
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+
+      if test "$GCC" = yes; then
+       case $host_os in aix4.[012]|aix4.[012].*)
+       # We only want to do this on AIX 4.2 and lower, the check
+       # below for broken collect2 doesn't work under 4.3+
+         collect2name=`${CC} -print-prog-name=collect2`
+         if test -f "$collect2name" && \
+          strings "$collect2name" | grep resolve_lib_name >/dev/null
+         then
+         # We have reworked collect2
+         hardcode_direct=yes
+         else
+         # We have old collect2
+         hardcode_direct=unsupported
+         # It fails to find uninstalled libraries when the uninstalled
+         # path is not listed in the libpath.  Setting hardcode_minus_L
+         # to unsupported forces relinking
+         hardcode_minus_L=yes
+         hardcode_libdir_flag_spec='-L$libdir'
+         hardcode_libdir_separator=
+         fi
+         ;;
+       esac
+       shared_flag='-shared'
+       if test "$aix_use_runtimelinking" = yes; then
+         shared_flag="$shared_flag "'${wl}-G'
+       fi
+      else
+       # not using gcc
+       if test "$host_cpu" = ia64; then
+       # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+       # chokes on -Wl,-G. The following line is correct:
+         shared_flag='-G'
+       else
+         if test "$aix_use_runtimelinking" = yes; then
+           shared_flag='${wl}-G'
+         else
+           shared_flag='${wl}-bM:SRE'
+         fi
+       fi
+      fi
+
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      always_export_symbols=yes
+      if test "$aix_use_runtimelinking" = yes; then
+       # Warning - without using the other runtime loading flags (-brtl),
+       # -berok will link without error, but may produce a broken library.
+       allow_undefined_flag='-berok'
+       # Determine the default libpath from the value encoded in an empty executable.
+       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
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; 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_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+       hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+       archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+       else
+       if test "$host_cpu" = ia64; then
+         hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+         allow_undefined_flag="-z nodefs"
+         archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+       else
+        # Determine the default libpath from the value encoded in an empty executable.
+        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
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; 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_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+         # Warning - without using the other run time loading flags,
+         # -berok will link without error, but may produce a broken library.
+         no_undefined_flag=' ${wl}-bernotok'
+         allow_undefined_flag=' ${wl}-berok'
+         # Exported symbols can be pulled into shared objects from archives
+         whole_archive_flag_spec='$convenience'
+         archive_cmds_need_lc=yes
+         # This is similar to how AIX traditionally builds its shared libraries.
+         archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+       fi
+      fi
+      ;;
+
+    amigaos*)
+      archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      # see comment about different semantics on the GNU ld section
+      ld_shlibs=no
+      ;;
+
+    bsdi[45]*)
+      export_dynamic_flag_spec=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      hardcode_libdir_flag_spec=' '
+      allow_undefined_flag=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      old_archive_From_new_cmds='true'
+      # FIXME: Should let the user specify the lib program.
+      old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs'
+      fix_srcfile_path='`cygpath -w "$srcfile"`'
+      enable_shared_with_static_runtimes=yes
+      ;;
+
+    darwin* | rhapsody*)
+      case $host_os in
+        rhapsody* | darwin1.[012])
+         allow_undefined_flag='${wl}-undefined ${wl}suppress'
+         ;;
+       *) # Darwin 1.3 on
+         if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+           allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+         else
+           case ${MACOSX_DEPLOYMENT_TARGET} in
+             10.[012])
+               allow_undefined_flag='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+               ;;
+             10.*)
+               allow_undefined_flag='${wl}-undefined ${wl}dynamic_lookup'
+               ;;
+           esac
+         fi
+         ;;
+      esac
+      archive_cmds_need_lc=no
+      hardcode_direct=no
+      hardcode_automatic=yes
+      hardcode_shlibpath_var=unsupported
+      whole_archive_flag_spec=''
+      link_all_deplibs=yes
+    if test "$GCC" = yes ; then
+       output_verbose_link_cmd='echo'
+        archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+      module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+      archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+      module_expsym_cmds='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    else
+      case $cc_basename in
+        xlc*)
+         output_verbose_link_cmd='echo'
+         archive_cmds='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+         module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+         archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          module_expsym_cmds='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          ;;
+       *)
+         ld_shlibs=no
+          ;;
+      esac
+    fi
+      ;;
+
+    dgux*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    freebsd1*)
+      ld_shlibs=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | kfreebsd*-gnu | dragonfly*)
+      archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+       archive_cmds='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+       archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_direct=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L=yes
+      export_dynamic_flag_spec='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+       archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+       hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+       hardcode_libdir_separator=:
+
+       hardcode_direct=yes
+       export_dynamic_flag_spec='${wl}-E'
+
+       # hardcode_minus_L: Not really in the search PATH,
+       # but as the default location of the library.
+       hardcode_minus_L=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+       case $host_cpu in
+       hppa*64*)
+         archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       ia64*)
+         archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       *)
+         archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       esac
+      else
+       case $host_cpu in
+       hppa*64*)
+         archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       ia64*)
+         archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       *)
+         archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       esac
+      fi
+      if test "$with_gnu_ld" = no; then
+       hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+       hardcode_libdir_separator=:
+
+       case $host_cpu in
+       hppa*64*|ia64*)
+         hardcode_libdir_flag_spec_ld='+b $libdir'
+         hardcode_direct=no
+         hardcode_shlibpath_var=no
+         ;;
+       *)
+         hardcode_direct=yes
+         export_dynamic_flag_spec='${wl}-E'
+
+         # hardcode_minus_L: Not really in the search PATH,
+         # but as the default location of the library.
+         hardcode_minus_L=yes
+         ;;
+       esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+       archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+       archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+       hardcode_libdir_flag_spec_ld='-rpath $libdir'
+      fi
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      link_all_deplibs=yes
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+       archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+       archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    newsos6)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_shlibpath_var=no
+      ;;
+
+    openbsd*)
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+       archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+       hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+       export_dynamic_flag_spec='${wl}-E'
+      else
+       case $host_os in
+        openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+          archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+          hardcode_libdir_flag_spec='-R$libdir'
+          ;;
+        *)
+          archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+          hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+          ;;
+       esac
+      fi
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      allow_undefined_flag=unsupported
+      archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_From_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+       allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+       archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+       allow_undefined_flag=' -expect_unresolved \*'
+       archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      ;;
+
+    osf4* | osf5*)     # as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+       allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+       archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+       hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      else
+       allow_undefined_flag=' -expect_unresolved \*'
+       archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+       archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+       $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp'
+
+       # Both c and cxx compiler support -rpath directly
+       hardcode_libdir_flag_spec='-rpath $libdir'
+      fi
+      hardcode_libdir_separator=:
+      ;;
+
+    solaris*)
+      no_undefined_flag=' -z text'
+      if test "$GCC" = yes; then
+       wlarc='${wl}'
+       archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+         $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
+      else
+       wlarc=''
+       archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+       archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+       $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_shlibpath_var=no
+      case $host_os in
+      solaris2.[0-5] | solaris2.[0-5].*) ;;
+      *)
+       # The compiler driver will combine linker options so we
+       # cannot just pass the convience library names through
+       # without $wl, iff we do not link with $LD.
+       # Luckily, gcc supports the same syntax we need for Sun Studio.
+       # Supported since Solaris 2.6 (maybe 2.5.1?)
+       case $wlarc in
+       '')
+         whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
+       *)
+         whole_archive_flag_spec='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;;
+       esac ;;
+      esac
+      link_all_deplibs=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+       # Use $CC to link under sequent, because it throws in some extra .o
+       # files that make .init and .fini sections work.
+       archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+       sni)
+         archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+         hardcode_direct=yes # is this really true???
+       ;;
+       siemens)
+         ## LD is ld it makes a PLAMLIB
+         ## CC just makes a GrossModule.
+         archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+         reload_cmds='$CC -r -o $output$reload_objs'
+         hardcode_direct=no
+        ;;
+       motorola)
+         archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+         hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+       ;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4.3*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var=no
+      export_dynamic_flag_spec='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+       hardcode_shlibpath_var=no
+       runpath_var=LD_RUN_PATH
+       hardcode_runpath_var=yes
+       ld_shlibs=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*)
+      no_undefined_flag='${wl}-z,text'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+       archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      no_undefined_flag='${wl}-z,text'
+      allow_undefined_flag='${wl}-z,nodefs'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      export_dynamic_flag_spec='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+       archive_cmds='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       archive_cmds='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      ld_shlibs=no
+      ;;
+    esac
+  fi
+
+echo "$as_me:$LINENO: result: $ld_shlibs" >&5
+echo "${ECHO_T}$ld_shlibs" >&6
+test "$ld_shlibs" = no && can_build_shared=no
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6
+      $rm conftest*
+      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      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); } 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$lt_prog_compiler_wl
+       pic_flag=$lt_prog_compiler_pic
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$allow_undefined_flag
+        allow_undefined_flag=
+        if { (eval echo "$as_me:$LINENO: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
+  (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+        then
+         archive_cmds_need_lc=no
+        else
+         archive_cmds_need_lc=yes
+        fi
+        allow_undefined_flag=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $rm conftest*
+      echo "$as_me:$LINENO: result: $archive_cmds_need_lc" >&5
+echo "${ECHO_T}$archive_cmds_need_lc" >&6
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+if test "$GCC" = yes; then
+  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix4* | aix5*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+          echo ' yes '
+          echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+       :
+      else
+       can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $rm \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  linux*)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      supports_anon_versioning=no
+      case `$LD -v 2>/dev/null` in
+        *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+        *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+        *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+        *\ 2.11.*) ;; # other 2.11 versions
+        *) supports_anon_versioning=yes ;;
+      esac
+      if test $supports_anon_versioning = yes; then
+        archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~
+cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+$echo "local: *; };" >> $output_objdir/$libname.ver~
+        $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+      else
+        $archive_expsym_cmds="$archive_cmds"
+      fi
+    else
+      ld_shlibs=no
+    fi
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
+  if test "$GCC" = yes; then
+    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+  else
+    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
+  fi
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+kfreebsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[123]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  # Handle Gentoo/FreeBSD as it was Linux
+  case $host_vendor in
+    gentoo)
+      version_type=linux ;;
+    *)
+      version_type=freebsd-$objformat ;;
+  esac
+
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+    linux)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+      soname_spec='${libname}${release}${shared_ext}$major'
+      need_lib_prefix=no
+      need_version=no
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  freebsd*) # from 4.6 on
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+   hppa*64*)
+     shrext_cmds='.sl'
+     hardcode_into_libs=yes
+     dynamic_linker="$host_os dld.sl"
+     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+     library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+     soname_spec='${libname}${release}${shared_ext}$major'
+     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+     ;;
+   *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+interix3*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+       if test "$lt_cv_prog_gnu_ld" = yes; then
+               version_type=linux
+       else
+               version_type=irix
+       fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,       ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+knetbsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+nto-qnx*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+    *)                         need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+       shlibpath_overrides_runpath=no
+       ;;
+      *)
+       shlibpath_overrides_runpath=yes
+       ;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      export_dynamic_flag_spec='${wl}-Blargedynsym'
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+    shlibpath_overrides_runpath=no
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    shlibpath_overrides_runpath=yes
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+       ;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+echo "${ECHO_T}$dynamic_linker" >&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+   test -n "$runpath_var" || \
+   test "X$hardcode_automatic" = "Xyes" ; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, )" != no &&
+     test "$hardcode_minus_L" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+echo "$as_me:$LINENO: result: $hardcode_action" >&5
+echo "${ECHO_T}$hardcode_action" >&6
+
+if test "$hardcode_action" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+striplib=
+old_striplib=
+echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5
+echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+   darwin*)
+       if test -n "$STRIP" ; then
+         striplib="$STRIP -x"
+         echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+       else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+       ;;
+   *)
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+    ;;
+  esac
+fi
+
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+   ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+   ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $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 dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  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_dl_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dl_dlopen=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_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+if test $ac_cv_lib_dl_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+
+fi
+
+   ;;
+
+  *)
+    echo "$as_me:$LINENO: checking for shl_load" >&5
+echo $ECHO_N "checking for shl_load... $ECHO_C" >&6
+if test "${ac_cv_func_shl_load+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 shl_load to an innocuous variant, in case <limits.h> declares shl_load.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define shl_load innocuous_shl_load
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char shl_load (); 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 shl_load
+
+/* 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 shl_load ();
+/* 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_shl_load) || defined (__stub___shl_load)
+choke me
+#else
+char (*f) () = shl_load;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != shl_load;
+  ;
+  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_func_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_shl_load=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5
+echo "${ECHO_T}$ac_cv_func_shl_load" >&6
+if test $ac_cv_func_shl_load = yes; then
+  lt_cv_dlopen="shl_load"
+else
+  echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
+echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $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 shl_load ();
+int
+main ()
+{
+shl_load ();
+  ;
+  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_dld_shl_load=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_shl_load=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_dld_shl_load" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
+if test $ac_cv_lib_dld_shl_load = yes; then
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"
+else
+  echo "$as_me:$LINENO: checking for dlopen" >&5
+echo $ECHO_N "checking for dlopen... $ECHO_C" >&6
+if test "${ac_cv_func_dlopen+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 dlopen to an innocuous variant, in case <limits.h> declares dlopen.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define dlopen innocuous_dlopen
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char dlopen (); 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 dlopen
+
+/* 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 dlopen ();
+/* 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_dlopen) || defined (__stub___dlopen)
+choke me
+#else
+char (*f) () = dlopen;
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+int
+main ()
+{
+return f != dlopen;
+  ;
+  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_func_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_func_dlopen=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5
+echo "${ECHO_T}$ac_cv_func_dlopen" >&6
+if test $ac_cv_func_dlopen = yes; then
+  lt_cv_dlopen="dlopen"
+else
+  echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
+echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $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 dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  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_dl_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dl_dlopen=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_dl_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
+if test $ac_cv_lib_dl_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5
+echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6
+if test "${ac_cv_lib_svld_dlopen+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld  $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 dlopen ();
+int
+main ()
+{
+dlopen ();
+  ;
+  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_svld_dlopen=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_svld_dlopen=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_svld_dlopen" >&5
+echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6
+if test $ac_cv_lib_svld_dlopen = yes; then
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+  echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5
+echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6
+if test "${ac_cv_lib_dld_dld_link+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $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 dld_link ();
+int
+main ()
+{
+dld_link ();
+  ;
+  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_dld_dld_link=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dld_dld_link=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_dld_dld_link" >&5
+echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6
+if test $ac_cv_lib_dld_dld_link = yes; then
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5
+echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6
+if test "${lt_cv_dlopen_self+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+         if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+#line 8787 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL          RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL                DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL                0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW           RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW         DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW       RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW     DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW     0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+    exit (status);
+}
+EOF
+  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); } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5
+echo "${ECHO_T}$lt_cv_dlopen_self" >&6
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5
+echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6
+if test "${lt_cv_dlopen_self_static+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+         if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self_static=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<EOF
+#line 8887 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL          RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL                DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL                0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW           RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW         DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW       RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW     DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW     0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+    exit (status);
+}
+EOF
+  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); } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self_static=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5
+echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+
+# Report which library types will actually be built
+echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5
+echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $can_build_shared" >&5
+echo "${ECHO_T}$can_build_shared" >&6
+
+echo "$as_me:$LINENO: checking whether to build shared libraries" >&5
+echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case $host_os in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+
+aix4* | aix5*)
+  if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+    test "$enable_shared" = yes && enable_static=no
+  fi
+    ;;
+esac
+echo "$as_me:$LINENO: result: $enable_shared" >&5
+echo "${ECHO_T}$enable_shared" >&6
+
+echo "$as_me:$LINENO: checking whether to build static libraries" >&5
+echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+echo "$as_me:$LINENO: result: $enable_static" >&5
+echo "${ECHO_T}$enable_static" >&6
+
+# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    compiler \
+    CC \
+    LD \
+    lt_prog_compiler_wl \
+    lt_prog_compiler_pic \
+    lt_prog_compiler_static \
+    lt_prog_compiler_no_builtin_flag \
+    export_dynamic_flag_spec \
+    thread_safe_flag_spec \
+    whole_archive_flag_spec \
+    enable_shared_with_static_runtimes \
+    old_archive_cmds \
+    old_archive_from_new_cmds \
+    predep_objects \
+    postdep_objects \
+    predeps \
+    postdeps \
+    compiler_lib_search_path \
+    archive_cmds \
+    archive_expsym_cmds \
+    postinstall_cmds \
+    postuninstall_cmds \
+    old_archive_from_expsyms_cmds \
+    allow_undefined_flag \
+    no_undefined_flag \
+    export_symbols_cmds \
+    hardcode_libdir_flag_spec \
+    hardcode_libdir_flag_spec_ld \
+    hardcode_libdir_separator \
+    hardcode_automatic \
+    module_cmds \
+    module_expsym_cmds \
+    lt_cv_prog_compiler_c_o \
+    exclude_expsyms \
+    include_expsyms; do
+
+    case $var in
+    old_archive_cmds | \
+    old_archive_from_new_cmds | \
+    archive_cmds | \
+    archive_expsym_cmds | \
+    module_cmds | \
+    module_expsym_cmds | \
+    old_archive_from_expsyms_cmds | \
+    export_symbols_cmds | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\$0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+cfgfile="${ofile}T"
+  trap "$rm \"$cfgfile\"; exit 1" 1 2 15
+  $rm -f "$cfgfile"
+  { echo "$as_me:$LINENO: creating $ofile" >&5
+echo "$as_me: creating $ofile" >&6;}
+
+  cat <<__EOF__ >> "$cfgfile"
+#! $SHELL
+
+# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+#
+# This file is part of GNU Libtool:
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 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 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.
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="$SED -e 1s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# The names of the tagged configurations supported by this script.
+available_tags=
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
+# A language-specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_predep_objects
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_postdep_objects
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_predeps
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_postdeps
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$hardcode_automatic
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# ### END LIBTOOL CONFIG
+
+__EOF__
+
+
+  case $host_os in
+  aix3*)
+    cat <<\EOF >> "$cfgfile"
+
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+EOF
+    ;;
+  esac
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1)
+
+  mv -f "$cfgfile" "$ofile" || \
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+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
+
+CC="$lt_save_CC"
+
+
+# Check whether --with-tags or --without-tags was given.
+if test "${with_tags+set}" = set; then
+  withval="$with_tags"
+  tagnames="$withval"
+fi;
+
+if test -f "$ltmain" && test -n "$tagnames"; then
+  if test ! -f "${ofile}"; then
+    { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not exist" >&5
+echo "$as_me: WARNING: output file \`$ofile' does not exist" >&2;}
+  fi
+
+  if test -z "$LTCC"; then
+    eval "`$SHELL ${ofile} --config | grep '^LTCC='`"
+    if test -z "$LTCC"; then
+      { echo "$as_me:$LINENO: WARNING: output file \`$ofile' does not look like a libtool script" >&5
+echo "$as_me: WARNING: output file \`$ofile' does not look like a libtool script" >&2;}
+    else
+      { echo "$as_me:$LINENO: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&5
+echo "$as_me: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&2;}
+    fi
+  fi
+  if test -z "$LTCFLAGS"; then
+    eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`"
+  fi
+
+  # Extract list of available tagged configurations in $ofile.
+  # Note that this assumes the entire list is on one line.
+  available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'`
+
+  lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+  for tagname in $tagnames; do
+    IFS="$lt_save_ifs"
+    # Check whether tagname contains only valid characters
+    case `$echo "X$tagname" | $Xsed -e 's:[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]::g'` in
+    "") ;;
+    *)  { { echo "$as_me:$LINENO: error: invalid tag name: $tagname" >&5
+echo "$as_me: error: invalid tag name: $tagname" >&2;}
+   { (exit 1); exit 1; }; }
+       ;;
+    esac
+
+    if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null
+    then
+      { { echo "$as_me:$LINENO: error: tag name \"$tagname\" already exists" >&5
+echo "$as_me: error: tag name \"$tagname\" already exists" >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+
+    # Update the list of available tags.
+    if test -n "$tagname"; then
+      echo appending configuration tag \"$tagname\" to $ofile
+
+      case $tagname in
+      CXX)
+       if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+           ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+           (test "X$CXX" != "Xg++"))) ; then
+         ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+
+archive_cmds_need_lc_CXX=no
+allow_undefined_flag_CXX=
+always_export_symbols_CXX=no
+archive_expsym_cmds_CXX=
+export_dynamic_flag_spec_CXX=
+hardcode_direct_CXX=no
+hardcode_libdir_flag_spec_CXX=
+hardcode_libdir_flag_spec_ld_CXX=
+hardcode_libdir_separator_CXX=
+hardcode_minus_L_CXX=no
+hardcode_shlibpath_var_CXX=unsupported
+hardcode_automatic_CXX=no
+module_cmds_CXX=
+module_expsym_cmds_CXX=
+link_all_deplibs_CXX=unknown
+old_archive_cmds_CXX=$old_archive_cmds
+no_undefined_flag_CXX=
+whole_archive_flag_spec_CXX=
+enable_shared_with_static_runtimes_CXX=no
+
+# Dependencies to place before and after the object being linked:
+predep_objects_CXX=
+postdep_objects_CXX=
+predeps_CXX=
+postdeps_CXX=
+compiler_lib_search_path_CXX=
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+objext_CXX=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$rm conftest*
+
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$rm conftest*
+
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_LD=$LD
+lt_save_GCC=$GCC
+GCC=$GXX
+lt_save_with_gnu_ld=$with_gnu_ld
+lt_save_path_LD=$lt_cv_path_LD
+if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+  lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+else
+  $as_unset lt_cv_prog_gnu_ld
+fi
+if test -n "${lt_cv_path_LDCXX+set}"; then
+  lt_cv_path_LD=$lt_cv_path_LDCXX
+else
+  $as_unset lt_cv_path_LD
+fi
+test -z "${LDCXX+set}" || LD=$LDCXX
+CC=${CXX-"c++"}
+compiler=$CC
+compiler_CXX=$CC
+for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+
+# We don't want -fno-exception wen compiling C++ code, so set the
+# no_builtin_flag separately
+if test "$GXX" = yes; then
+  lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
+else
+  lt_prog_compiler_no_builtin_flag_CXX=
+fi
+
+if test "$GXX" = yes; then
+  # Set up default GNU C++ configuration
+
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+  withval="$with_gnu_ld"
+  test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi;
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  echo "$as_me:$LINENO: checking for ld used by $CC" >&5
+echo $ECHO_N "checking for ld used by $CC... $ECHO_C" >&6
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  echo "$as_me:$LINENO: checking for GNU ld" >&5
+echo $ECHO_N "checking for GNU ld... $ECHO_C" >&6
+else
+  echo "$as_me:$LINENO: checking for non-GNU ld" >&5
+echo $ECHO_N "checking for non-GNU ld... $ECHO_C" >&6
+fi
+if test "${lt_cv_path_LD+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+       test "$with_gnu_ld" != no && break
+       ;;
+      *)
+       test "$with_gnu_ld" != yes && break
+       ;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  echo "$as_me:$LINENO: result: $LD" >&5
+echo "${ECHO_T}$LD" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+test -z "$LD" && { { echo "$as_me:$LINENO: error: no acceptable ld found in \$PATH" >&5
+echo "$as_me: error: no acceptable ld found in \$PATH" >&2;}
+   { (exit 1); exit 1; }; }
+echo "$as_me:$LINENO: checking if the linker ($LD) is GNU ld" >&5
+echo $ECHO_N "checking if the linker ($LD) is GNU ld... $ECHO_C" >&6
+if test "${lt_cv_prog_gnu_ld+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_gnu_ld" >&5
+echo "${ECHO_T}$lt_cv_prog_gnu_ld" >&6
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+  # Check if GNU C++ uses GNU ld as the underlying linker, since the
+  # archiving commands below assume that GNU ld is being used.
+  if test "$with_gnu_ld" = yes; then
+    archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+    archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+    hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
+    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+    #     investigate it a little bit more. (MM)
+    wlarc='${wl}'
+
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if eval "`$CC -print-prog-name=ld` --help 2>&1" | \
+       grep 'no-whole-archive' > /dev/null; then
+      whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      whole_archive_flag_spec_CXX=
+    fi
+  else
+    with_gnu_ld=no
+    wlarc=
+
+    # A generic and very simple default shared library creation
+    # command for GNU C++ for the case where it uses the native
+    # linker, instead of GNU ld.  If possible, this setting should
+    # overridden to take advantage of the native linker features on
+    # the platform it is being used on.
+    archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+  fi
+
+  # Commands to make compiler produce verbose output that lists
+  # what "hidden" libraries, object files and flags are used when
+  # linking a shared library.
+  output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+else
+  GXX=no
+  with_gnu_ld=no
+  wlarc=
+fi
+
+# PORTME: fill in a description of your system's C++ link characteristics
+echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6
+ld_shlibs_CXX=yes
+case $host_os in
+  aix3*)
+    # FIXME: insert proper C++ library support
+    ld_shlibs_CXX=no
+    ;;
+  aix4* | aix5*)
+    if test "$host_cpu" = ia64; then
+      # On IA64, the linker does run time linking by default, so we don't
+      # have to do anything special.
+      aix_use_runtimelinking=no
+      exp_sym_flag='-Bexport'
+      no_entry_flag=""
+    else
+      aix_use_runtimelinking=no
+
+      # Test if we are trying to use run time linking or normal
+      # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+      # need to do runtime linking.
+      case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+       for ld_flag in $LDFLAGS; do
+         case $ld_flag in
+         *-brtl*)
+           aix_use_runtimelinking=yes
+           break
+           ;;
+         esac
+       done
+       ;;
+      esac
+
+      exp_sym_flag='-bexport'
+      no_entry_flag='-bnoentry'
+    fi
+
+    # When large executables or shared objects are built, AIX ld can
+    # have problems creating the table of contents.  If linking a library
+    # or program results in "error TOC overflow" add -mminimal-toc to
+    # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+    # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+    archive_cmds_CXX=''
+    hardcode_direct_CXX=yes
+    hardcode_libdir_separator_CXX=':'
+    link_all_deplibs_CXX=yes
+
+    if test "$GXX" = yes; then
+      case $host_os in aix4.[012]|aix4.[012].*)
+      # We only want to do this on AIX 4.2 and lower, the check
+      # below for broken collect2 doesn't work under 4.3+
+       collect2name=`${CC} -print-prog-name=collect2`
+       if test -f "$collect2name" && \
+          strings "$collect2name" | grep resolve_lib_name >/dev/null
+       then
+         # We have reworked collect2
+         hardcode_direct_CXX=yes
+       else
+         # We have old collect2
+         hardcode_direct_CXX=unsupported
+         # It fails to find uninstalled libraries when the uninstalled
+         # path is not listed in the libpath.  Setting hardcode_minus_L
+         # to unsupported forces relinking
+         hardcode_minus_L_CXX=yes
+         hardcode_libdir_flag_spec_CXX='-L$libdir'
+         hardcode_libdir_separator_CXX=
+       fi
+       ;;
+      esac
+      shared_flag='-shared'
+      if test "$aix_use_runtimelinking" = yes; then
+       shared_flag="$shared_flag "'${wl}-G'
+      fi
+    else
+      # not using gcc
+      if test "$host_cpu" = ia64; then
+       # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+       # chokes on -Wl,-G. The following line is correct:
+       shared_flag='-G'
+      else
+       if test "$aix_use_runtimelinking" = yes; then
+         shared_flag='${wl}-G'
+       else
+         shared_flag='${wl}-bM:SRE'
+       fi
+      fi
+    fi
+
+    # It seems that -bexpall does not export symbols beginning with
+    # underscore (_), so it is better to generate a list of symbols to export.
+    always_export_symbols_CXX=yes
+    if test "$aix_use_runtimelinking" = yes; then
+      # Warning - without using the other runtime loading flags (-brtl),
+      # -berok will link without error, but may produce a broken library.
+      allow_undefined_flag_CXX='-berok'
+      # Determine the default libpath from the value encoded in an empty executable.
+      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_cxx_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
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; 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_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+      hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+      archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+     else
+      if test "$host_cpu" = ia64; then
+       hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
+       allow_undefined_flag_CXX="-z nodefs"
+       archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+      else
+       # Determine the default libpath from the value encoded in an empty executable.
+       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_cxx_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
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; 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_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+       hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+       # Warning - without using the other run time loading flags,
+       # -berok will link without error, but may produce a broken library.
+       no_undefined_flag_CXX=' ${wl}-bernotok'
+       allow_undefined_flag_CXX=' ${wl}-berok'
+       # Exported symbols can be pulled into shared objects from archives
+       whole_archive_flag_spec_CXX='$convenience'
+       archive_cmds_need_lc_CXX=yes
+       # This is similar to how AIX traditionally builds its shared libraries.
+       archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+      fi
+    fi
+    ;;
+
+  beos*)
+    if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+      allow_undefined_flag_CXX=unsupported
+      # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+      # support --undefined.  This deserves some investigation.  FIXME
+      archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+    else
+      ld_shlibs_CXX=no
+    fi
+    ;;
+
+  chorus*)
+    case $cc_basename in
+      *)
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+    esac
+    ;;
+
+  cygwin* | mingw* | pw32*)
+    # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
+    # as there is no search path for DLLs.
+    hardcode_libdir_flag_spec_CXX='-L$libdir'
+    allow_undefined_flag_CXX=unsupported
+    always_export_symbols_CXX=no
+    enable_shared_with_static_runtimes_CXX=yes
+
+    if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+      archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      # If the export-symbols file already is a .def file (1st line
+      # is EXPORTS), use it as is; otherwise, prepend...
+      archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+       cp $export_symbols $output_objdir/$soname.def;
+      else
+       echo EXPORTS > $output_objdir/$soname.def;
+       cat $export_symbols >> $output_objdir/$soname.def;
+      fi~
+      $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+    else
+      ld_shlibs_CXX=no
+    fi
+  ;;
+      darwin* | rhapsody*)
+        case $host_os in
+        rhapsody* | darwin1.[012])
+         allow_undefined_flag_CXX='${wl}-undefined ${wl}suppress'
+         ;;
+       *) # Darwin 1.3 on
+         if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+           allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+         else
+           case ${MACOSX_DEPLOYMENT_TARGET} in
+             10.[012])
+               allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+               ;;
+             10.*)
+               allow_undefined_flag_CXX='${wl}-undefined ${wl}dynamic_lookup'
+               ;;
+           esac
+         fi
+         ;;
+        esac
+      archive_cmds_need_lc_CXX=no
+      hardcode_direct_CXX=no
+      hardcode_automatic_CXX=yes
+      hardcode_shlibpath_var_CXX=unsupported
+      whole_archive_flag_spec_CXX=''
+      link_all_deplibs_CXX=yes
+
+    if test "$GXX" = yes ; then
+      lt_int_apple_cc_single_mod=no
+      output_verbose_link_cmd='echo'
+      if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then
+       lt_int_apple_cc_single_mod=yes
+      fi
+      if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+       archive_cmds_CXX='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+      else
+          archive_cmds_CXX='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+        fi
+        module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+        # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+          if test "X$lt_int_apple_cc_single_mod" = Xyes ; then
+            archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          else
+            archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          fi
+            module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+      else
+      case $cc_basename in
+        xlc*)
+         output_verbose_link_cmd='echo'
+          archive_cmds_CXX='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+          module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+          archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          ;;
+       *)
+         ld_shlibs_CXX=no
+          ;;
+      esac
+      fi
+        ;;
+
+  dgux*)
+    case $cc_basename in
+      ec++*)
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+      ghcx*)
+       # Green Hills C++ Compiler
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+      *)
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+    esac
+    ;;
+  freebsd[12]*)
+    # C++ shared libraries reported to be fairly broken before switch to ELF
+    ld_shlibs_CXX=no
+    ;;
+  freebsd-elf*)
+    archive_cmds_need_lc_CXX=no
+    ;;
+  freebsd* | kfreebsd*-gnu | dragonfly*)
+    # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+    # conventions
+    ld_shlibs_CXX=yes
+    ;;
+  gnu*)
+    ;;
+  hpux9*)
+    hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+    hardcode_libdir_separator_CXX=:
+    export_dynamic_flag_spec_CXX='${wl}-E'
+    hardcode_direct_CXX=yes
+    hardcode_minus_L_CXX=yes # Not in the search PATH,
+                               # but as the default
+                               # location of the library.
+
+    case $cc_basename in
+    CC*)
+      # FIXME: insert proper C++ library support
+      ld_shlibs_CXX=no
+      ;;
+    aCC*)
+      archive_cmds_CXX='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      #
+      # There doesn't appear to be a way to prevent this compiler from
+      # explicitly linking system object files so we need to strip them
+      # from the output so that they don't get included in the library
+      # dependencies.
+      output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[-]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+      ;;
+    *)
+      if test "$GXX" = yes; then
+        archive_cmds_CXX='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+      fi
+      ;;
+    esac
+    ;;
+  hpux10*|hpux11*)
+    if test $with_gnu_ld = no; then
+      hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator_CXX=:
+
+      case $host_cpu in
+      hppa*64*|ia64*)
+       hardcode_libdir_flag_spec_ld_CXX='+b $libdir'
+        ;;
+      *)
+       export_dynamic_flag_spec_CXX='${wl}-E'
+        ;;
+      esac
+    fi
+    case $host_cpu in
+    hppa*64*|ia64*)
+      hardcode_direct_CXX=no
+      hardcode_shlibpath_var_CXX=no
+      ;;
+    *)
+      hardcode_direct_CXX=yes
+      hardcode_minus_L_CXX=yes # Not in the search PATH,
+                                             # but as the default
+                                             # location of the library.
+      ;;
+    esac
+
+    case $cc_basename in
+      CC*)
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+      aCC*)
+       case $host_cpu in
+       hppa*64*)
+         archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+         ;;
+       ia64*)
+         archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+         ;;
+       *)
+         archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+         ;;
+       esac
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+       ;;
+      *)
+       if test "$GXX" = yes; then
+         if test $with_gnu_ld = no; then
+           case $host_cpu in
+           hppa*64*)
+             archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+             ;;
+           ia64*)
+             archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+             ;;
+           *)
+             archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+             ;;
+           esac
+         fi
+       else
+         # FIXME: insert proper C++ library support
+         ld_shlibs_CXX=no
+       fi
+       ;;
+    esac
+    ;;
+  interix3*)
+    hardcode_direct_CXX=no
+    hardcode_shlibpath_var_CXX=no
+    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+    export_dynamic_flag_spec_CXX='${wl}-E'
+    # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+    # Instead, shared libraries are loaded at an image base (0x10000000 by
+    # default) and relocated if they conflict, which is a slow very memory
+    # consuming and fragmenting process.  To avoid this, we pick a random,
+    # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+    # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+    archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+    archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+    ;;
+  irix5* | irix6*)
+    case $cc_basename in
+      CC*)
+       # SGI C++
+       archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+
+       # Archives containing C++ object files must be created using
+       # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+       # necessary to make sure instantiated templates are included
+       # in the archive.
+       old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
+       ;;
+      *)
+       if test "$GXX" = yes; then
+         if test "$with_gnu_ld" = no; then
+           archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+         else
+           archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib'
+         fi
+       fi
+       link_all_deplibs_CXX=yes
+       ;;
+    esac
+    hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+    hardcode_libdir_separator_CXX=:
+    ;;
+  linux*)
+    case $cc_basename in
+      KCC*)
+       # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+       # KCC will only create a shared library if the output file
+       # ends with ".so" (or ".sl" for HP-UX), so rename the library
+       # to its proper name (with version) after linking.
+       archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+       archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+
+       hardcode_libdir_flag_spec_CXX='${wl}--rpath,$libdir'
+       export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+       # Archives containing C++ object files must be created using
+       # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+       old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
+       ;;
+      icpc*)
+       # Intel C++
+       with_gnu_ld=yes
+       # version 8.0 and above of icpc choke on multiply defined symbols
+       # if we add $predep_objects and $postdep_objects, however 7.1 and
+       # earlier do not add the objects themselves.
+       case `$CC -V 2>&1` in
+       *"Version 7."*)
+         archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+         archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+         ;;
+       *)  # Version 8.0 or newer
+         tmp_idyn=
+         case $host_cpu in
+           ia64*) tmp_idyn=' -i_dynamic';;
+         esac
+         archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+         archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+         ;;
+       esac
+       archive_cmds_need_lc_CXX=no
+       hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+       export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+       whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+       ;;
+      pgCC*)
+        # Portland Group C++ compiler
+       archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+       archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+
+       hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
+       export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+       whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+        ;;
+      cxx*)
+       # Compaq C++
+       archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+       runpath_var=LD_RUN_PATH
+       hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+       hardcode_libdir_separator_CXX=:
+
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+       ;;
+    esac
+    ;;
+  lynxos*)
+    # FIXME: insert proper C++ library support
+    ld_shlibs_CXX=no
+    ;;
+  m88k*)
+    # FIXME: insert proper C++ library support
+    ld_shlibs_CXX=no
+    ;;
+  mvs*)
+    case $cc_basename in
+      cxx*)
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+      *)
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+    esac
+    ;;
+  netbsd*)
+    if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+      archive_cmds_CXX='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+      wlarc=
+      hardcode_libdir_flag_spec_CXX='-R$libdir'
+      hardcode_direct_CXX=yes
+      hardcode_shlibpath_var_CXX=no
+    fi
+    # Workaround some broken pre-1.5 toolchains
+    output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+    ;;
+  openbsd2*)
+    # C++ shared libraries are fairly broken
+    ld_shlibs_CXX=no
+    ;;
+  openbsd*)
+    hardcode_direct_CXX=yes
+    hardcode_shlibpath_var_CXX=no
+    archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+    if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+      archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+      export_dynamic_flag_spec_CXX='${wl}-E'
+      whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    fi
+    output_verbose_link_cmd='echo'
+    ;;
+  osf3*)
+    case $cc_basename in
+      KCC*)
+       # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+       # KCC will only create a shared library if the output file
+       # ends with ".so" (or ".sl" for HP-UX), so rename the library
+       # to its proper name (with version) after linking.
+       archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+       hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+       hardcode_libdir_separator_CXX=:
+
+       # Archives containing C++ object files must be created using
+       # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+       old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
+
+       ;;
+      RCC*)
+       # Rational C++ 2.4.1
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+      cxx*)
+       allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+       archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+
+       hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+       hardcode_libdir_separator_CXX=:
+
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+       ;;
+      *)
+       if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+         allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+         archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+
+         hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+         hardcode_libdir_separator_CXX=:
+
+         # Commands to make compiler produce verbose output that lists
+         # what "hidden" libraries, object files and flags are used when
+         # linking a shared library.
+         output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+       else
+         # FIXME: insert proper C++ library support
+         ld_shlibs_CXX=no
+       fi
+       ;;
+    esac
+    ;;
+  osf4* | osf5*)
+    case $cc_basename in
+      KCC*)
+       # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+       # KCC will only create a shared library if the output file
+       # ends with ".so" (or ".sl" for HP-UX), so rename the library
+       # to its proper name (with version) after linking.
+       archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+       hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+       hardcode_libdir_separator_CXX=:
+
+       # Archives containing C++ object files must be created using
+       # the KAI C++ compiler.
+       old_archive_cmds_CXX='$CC -o $oldlib $oldobjs'
+       ;;
+      RCC*)
+       # Rational C++ 2.4.1
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+      cxx*)
+       allow_undefined_flag_CXX=' -expect_unresolved \*'
+       archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+       archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+         echo "-hidden">> $lib.exp~
+         $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp  `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~
+         $rm $lib.exp'
+
+       hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+       hardcode_libdir_separator_CXX=:
+
+       # Commands to make compiler produce verbose output that lists
+       # what "hidden" libraries, object files and flags are used when
+       # linking a shared library.
+       #
+       # There doesn't appear to be a way to prevent this compiler from
+       # explicitly linking system object files so we need to strip them
+       # from the output so that they don't get included in the library
+       # dependencies.
+       output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list'
+       ;;
+      *)
+       if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+         allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+        archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+
+         hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+         hardcode_libdir_separator_CXX=:
+
+         # Commands to make compiler produce verbose output that lists
+         # what "hidden" libraries, object files and flags are used when
+         # linking a shared library.
+         output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"'
+
+       else
+         # FIXME: insert proper C++ library support
+         ld_shlibs_CXX=no
+       fi
+       ;;
+    esac
+    ;;
+  psos*)
+    # FIXME: insert proper C++ library support
+    ld_shlibs_CXX=no
+    ;;
+  sunos4*)
+    case $cc_basename in
+      CC*)
+       # Sun C++ 4.x
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+      lcc*)
+       # Lucid
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+      *)
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+    esac
+    ;;
+  solaris*)
+    case $cc_basename in
+      CC*)
+       # Sun C++ 4.2, 5.x and Centerline C++
+        archive_cmds_need_lc_CXX=yes
+       no_undefined_flag_CXX=' -zdefs'
+       archive_cmds_CXX='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+       archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+       $CC -G${allow_undefined_flag}  ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+       hardcode_libdir_flag_spec_CXX='-R$libdir'
+       hardcode_shlibpath_var_CXX=no
+       case $host_os in
+         solaris2.[0-5] | solaris2.[0-5].*) ;;
+         *)
+           # The C++ compiler is used as linker so we must use $wl
+           # flag to pass the commands to the underlying system
+           # linker. We must also pass each convience library through
+           # to the system linker between allextract/defaultextract.
+           # The C++ compiler will combine linker options so we
+           # cannot just pass the convience library names through
+           # without $wl.
+           # Supported since Solaris 2.6 (maybe 2.5.1?)
+           whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract'
+           ;;
+       esac
+       link_all_deplibs_CXX=yes
+
+       output_verbose_link_cmd='echo'
+
+       # Archives containing C++ object files must be created using
+       # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+       # necessary to make sure instantiated templates are included
+       # in the archive.
+       old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+       ;;
+      gcx*)
+       # Green Hills C++ Compiler
+       archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+       # The C++ compiler must be used to create the archive.
+       old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+       ;;
+      *)
+       # GNU C++ compiler with Solaris linker
+       if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+         no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
+         if $CC --version | grep -v '^2\.7' > /dev/null; then
+           archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+           archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+           # Commands to make compiler produce verbose output that lists
+           # what "hidden" libraries, object files and flags are used when
+           # linking a shared library.
+           output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
+         else
+           # g++ 2.7 appears to require `-G' NOT `-shared' on this
+           # platform.
+           archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+           archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+               $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp'
+
+           # Commands to make compiler produce verbose output that lists
+           # what "hidden" libraries, object files and flags are used when
+           # linking a shared library.
+           output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\""
+         fi
+
+         hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
+       fi
+       ;;
+    esac
+    ;;
+  sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+    no_undefined_flag_CXX='${wl}-z,text'
+    archive_cmds_need_lc_CXX=no
+    hardcode_shlibpath_var_CXX=no
+    runpath_var='LD_RUN_PATH'
+
+    case $cc_basename in
+      CC*)
+       archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+       ;;
+      *)
+       archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+       ;;
+    esac
+    ;;
+  sysv5* | sco3.2v5* | sco5v6*)
+    # Note: We can NOT use -z defs as we might desire, because we do not
+    # link with -lc, and that would cause any symbols used from libc to
+    # always be unresolved, which means just about no library would
+    # ever link correctly.  If we're not using GNU ld we use -z text
+    # though, which does catch some bad symbols but isn't as heavy-handed
+    # as -z defs.
+    # For security reasons, it is highly recommended that you always
+    # use absolute paths for naming shared libraries, and exclude the
+    # DT_RUNPATH tag from executables and libraries.  But doing so
+    # requires that you compile everything twice, which is a pain.
+    # So that behaviour is only enabled if SCOABSPATH is set to a
+    # non-empty value in the environment.  Most likely only useful for
+    # creating official distributions of packages.
+    # This is a hack until libtool officially supports absolute path
+    # names for shared libraries.
+    no_undefined_flag_CXX='${wl}-z,text'
+    allow_undefined_flag_CXX='${wl}-z,nodefs'
+    archive_cmds_need_lc_CXX=no
+    hardcode_shlibpath_var_CXX=no
+    hardcode_libdir_flag_spec_CXX='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+    hardcode_libdir_separator_CXX=':'
+    link_all_deplibs_CXX=yes
+    export_dynamic_flag_spec_CXX='${wl}-Bexport'
+    runpath_var='LD_RUN_PATH'
+
+    case $cc_basename in
+      CC*)
+       archive_cmds_CXX='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       ;;
+      *)
+       archive_cmds_CXX='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       ;;
+    esac
+    ;;
+  tandem*)
+    case $cc_basename in
+      NCC*)
+       # NonStop-UX NCC 3.20
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+      *)
+       # FIXME: insert proper C++ library support
+       ld_shlibs_CXX=no
+       ;;
+    esac
+    ;;
+  vxworks*)
+    # FIXME: insert proper C++ library support
+    ld_shlibs_CXX=no
+    ;;
+  *)
+    # FIXME: insert proper C++ library support
+    ld_shlibs_CXX=no
+    ;;
+esac
+echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5
+echo "${ECHO_T}$ld_shlibs_CXX" >&6
+test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+GCC_CXX="$GXX"
+LD_CXX="$LD"
+
+
+cat > conftest.$ac_ext <<EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+EOF
+
+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
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
+
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
+
+  # The `*' in the case matches for architectures that use `case' in
+  # $output_verbose_cmd can trigger glob expansion during the loop
+  # eval without this substitution.
+  output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"`
+
+  for p in `eval $output_verbose_link_cmd`; do
+    case $p in
+
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R}" and the path.
+       # Remove the space.
+       if test $p = "-L" \
+         || test $p = "-R"; then
+        prev=$p
+        continue
+       else
+        prev=
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+        case $p in
+        -L* | -R*)
+          # Internal compiler library paths should come after those
+          # provided the user.  The postdeps already come after the
+          # user supplied libs so there is no need to process them.
+          if test -z "$compiler_lib_search_path_CXX"; then
+            compiler_lib_search_path_CXX="${prev}${p}"
+          else
+            compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}"
+          fi
+          ;;
+        # The "-l" case would never come before the object being
+        # linked, so don't bother handling this case.
+        esac
+       else
+        if test -z "$postdeps_CXX"; then
+          postdeps_CXX="${prev}${p}"
+        else
+          postdeps_CXX="${postdeps_CXX} ${prev}${p}"
+        fi
+       fi
+       ;;
+
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+        pre_test_object_deps_done=yes
+        continue
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+        if test -z "$predep_objects_CXX"; then
+          predep_objects_CXX="$p"
+        else
+          predep_objects_CXX="$predep_objects_CXX $p"
+        fi
+       else
+        if test -z "$postdep_objects_CXX"; then
+          postdep_objects_CXX="$p"
+        else
+          postdep_objects_CXX="$postdep_objects_CXX $p"
+        fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling CXX test program"
+fi
+
+$rm -f confest.$objext
+
+# PORTME: override above test on systems where it is broken
+case $host_os in
+interix3*)
+  # Interix 3.5 installs completely hosed .la files for C++, so rather than
+  # hack all around it, let's just trust "g++" to DTRT.
+  predep_objects_CXX=
+  postdep_objects_CXX=
+  postdeps_CXX=
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC*)
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    postdeps_CXX='-lCstd -lCrun'
+    ;;
+  esac
+  ;;
+esac
+
+
+case " $postdeps_CXX " in
+*" -lc "*) archive_cmds_need_lc_CXX=no ;;
+esac
+
+lt_prog_compiler_wl_CXX=
+lt_prog_compiler_pic_CXX=
+lt_prog_compiler_static_CXX=
+
+echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
+
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    lt_prog_compiler_wl_CXX='-Wl,'
+    lt_prog_compiler_static_CXX='-static'
+
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       lt_prog_compiler_static_CXX='-Bstatic'
+      fi
+      ;;
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4'
+      ;;
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | os2* | pw32*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic_CXX='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      lt_prog_compiler_pic_CXX=
+      ;;
+    interix3*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       lt_prog_compiler_pic_CXX=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+       ;;
+      *)
+       lt_prog_compiler_pic_CXX='-fPIC'
+       ;;
+      esac
+      ;;
+    *)
+      lt_prog_compiler_pic_CXX='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix4* | aix5*)
+       # All AIX code is PIC.
+       if test "$host_cpu" = ia64; then
+         # AIX 5 now supports IA64 processor
+         lt_prog_compiler_static_CXX='-Bstatic'
+       else
+         lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'
+       fi
+       ;;
+      chorus*)
+       case $cc_basename in
+       cxch68*)
+         # Green Hills C++ Compiler
+         # _LT_AC_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+         ;;
+       esac
+       ;;
+       darwin*)
+         # PIC is the default on this platform
+         # Common symbols not allowed in MH_DYLIB files
+         case $cc_basename in
+           xlc*)
+           lt_prog_compiler_pic_CXX='-qnocommon'
+           lt_prog_compiler_wl_CXX='-Wl,'
+           ;;
+         esac
+       ;;
+      dgux*)
+       case $cc_basename in
+         ec++*)
+           lt_prog_compiler_pic_CXX='-KPIC'
+           ;;
+         ghcx*)
+           # Green Hills C++ Compiler
+           lt_prog_compiler_pic_CXX='-pic'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      freebsd* | kfreebsd*-gnu | dragonfly*)
+       # FreeBSD uses GNU C++
+       ;;
+      hpux9* | hpux10* | hpux11*)
+       case $cc_basename in
+         CC*)
+           lt_prog_compiler_wl_CXX='-Wl,'
+           lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+           if test "$host_cpu" != ia64; then
+             lt_prog_compiler_pic_CXX='+Z'
+           fi
+           ;;
+         aCC*)
+           lt_prog_compiler_wl_CXX='-Wl,'
+           lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+           case $host_cpu in
+           hppa*64*|ia64*)
+             # +Z the default
+             ;;
+           *)
+             lt_prog_compiler_pic_CXX='+Z'
+             ;;
+           esac
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      interix*)
+       # This is c89, which is MS Visual C++ (no shared libs)
+       # Anyone wants to do a port?
+       ;;
+      irix5* | irix6* | nonstopux*)
+       case $cc_basename in
+         CC*)
+           lt_prog_compiler_wl_CXX='-Wl,'
+           lt_prog_compiler_static_CXX='-non_shared'
+           # CC pic flag -KPIC is the default.
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      linux*)
+       case $cc_basename in
+         KCC*)
+           # KAI C++ Compiler
+           lt_prog_compiler_wl_CXX='--backend -Wl,'
+           lt_prog_compiler_pic_CXX='-fPIC'
+           ;;
+         icpc* | ecpc*)
+           # Intel C++
+           lt_prog_compiler_wl_CXX='-Wl,'
+           lt_prog_compiler_pic_CXX='-KPIC'
+           lt_prog_compiler_static_CXX='-static'
+           ;;
+         pgCC*)
+           # Portland Group C++ compiler.
+           lt_prog_compiler_wl_CXX='-Wl,'
+           lt_prog_compiler_pic_CXX='-fpic'
+           lt_prog_compiler_static_CXX='-Bstatic'
+           ;;
+         cxx*)
+           # Compaq C++
+           # Make sure the PIC flag is empty.  It appears that all Alpha
+           # Linux and Compaq Tru64 Unix objects are PIC.
+           lt_prog_compiler_pic_CXX=
+           lt_prog_compiler_static_CXX='-non_shared'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      lynxos*)
+       ;;
+      m88k*)
+       ;;
+      mvs*)
+       case $cc_basename in
+         cxx*)
+           lt_prog_compiler_pic_CXX='-W c,exportall'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      netbsd*)
+       ;;
+      osf3* | osf4* | osf5*)
+       case $cc_basename in
+         KCC*)
+           lt_prog_compiler_wl_CXX='--backend -Wl,'
+           ;;
+         RCC*)
+           # Rational C++ 2.4.1
+           lt_prog_compiler_pic_CXX='-pic'
+           ;;
+         cxx*)
+           # Digital/Compaq C++
+           lt_prog_compiler_wl_CXX='-Wl,'
+           # Make sure the PIC flag is empty.  It appears that all Alpha
+           # Linux and Compaq Tru64 Unix objects are PIC.
+           lt_prog_compiler_pic_CXX=
+           lt_prog_compiler_static_CXX='-non_shared'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      psos*)
+       ;;
+      solaris*)
+       case $cc_basename in
+         CC*)
+           # Sun C++ 4.2, 5.x and Centerline C++
+           lt_prog_compiler_pic_CXX='-KPIC'
+           lt_prog_compiler_static_CXX='-Bstatic'
+           lt_prog_compiler_wl_CXX='-Qoption ld '
+           ;;
+         gcx*)
+           # Green Hills C++ Compiler
+           lt_prog_compiler_pic_CXX='-PIC'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      sunos4*)
+       case $cc_basename in
+         CC*)
+           # Sun C++ 4.x
+           lt_prog_compiler_pic_CXX='-pic'
+           lt_prog_compiler_static_CXX='-Bstatic'
+           ;;
+         lcc*)
+           # Lucid
+           lt_prog_compiler_pic_CXX='-pic'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      tandem*)
+       case $cc_basename in
+         NCC*)
+           # NonStop-UX NCC 3.20
+           lt_prog_compiler_pic_CXX='-KPIC'
+           ;;
+         *)
+           ;;
+       esac
+       ;;
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+       case $cc_basename in
+         CC*)
+           lt_prog_compiler_wl_CXX='-Wl,'
+           lt_prog_compiler_pic_CXX='-KPIC'
+           lt_prog_compiler_static_CXX='-Bstatic'
+           ;;
+       esac
+       ;;
+      vxworks*)
+       ;;
+      *)
+       lt_prog_compiler_can_build_shared_CXX=no
+       ;;
+    esac
+  fi
+
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_CXX" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_CXX" >&6
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_CXX"; then
+
+echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
+echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... $ECHO_C" >&6
+if test "${lt_prog_compiler_pic_works_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_pic_works_CXX=no
+  ac_outfile=conftest.$ac_objext
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:11227: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:11231: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_prog_compiler_pic_works_CXX=yes
+     fi
+   fi
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_CXX" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_works_CXX" >&6
+
+if test x"$lt_prog_compiler_pic_works_CXX" = xyes; then
+    case $lt_prog_compiler_pic_CXX in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
+     esac
+else
+    lt_prog_compiler_pic_CXX=
+     lt_prog_compiler_can_build_shared_CXX=no
+fi
+
+fi
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic_CXX=
+    ;;
+  *)
+    lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"
+    ;;
+esac
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"
+echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6
+if test "${lt_prog_compiler_static_works_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_static_works_CXX=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   printf "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_prog_compiler_static_works_CXX=yes
+       fi
+     else
+       lt_prog_compiler_static_works_CXX=yes
+     fi
+   fi
+   $rm conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_CXX" >&5
+echo "${ECHO_T}$lt_prog_compiler_static_works_CXX" >&6
+
+if test x"$lt_prog_compiler_static_works_CXX" = xyes; then
+    :
+else
+    lt_prog_compiler_static_CXX=
+fi
+
+
+echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
+if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_prog_compiler_c_o_CXX=no
+   $rm -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:11331: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:11335: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o_CXX=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $rm conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+   $rm out/* && rmdir out
+   cd ..
+   rmdir conftest
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_c_o_CXX" >&6
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  echo "$as_me:$LINENO: result: $hard_links" >&5
+echo "${ECHO_T}$hard_links" >&6
+  if test "$hard_links" = no; then
+    { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6
+
+  export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  case $host_os in
+  aix4* | aix5*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+      export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+    else
+      export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    export_symbols_cmds_CXX="$ltdll_cmds"
+  ;;
+  cygwin* | mingw*)
+    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([^ ]*\) [^ ]*/\1 DATA/;/^I /d;/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  *)
+    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  esac
+
+echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5
+echo "${ECHO_T}$ld_shlibs_CXX" >&6
+test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_CXX" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc_CXX=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds_CXX in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6
+      $rm conftest*
+      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      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); } 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$lt_prog_compiler_wl_CXX
+       pic_flag=$lt_prog_compiler_pic_CXX
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$allow_undefined_flag_CXX
+        allow_undefined_flag_CXX=
+        if { (eval echo "$as_me:$LINENO: \"$archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
+  (eval $archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+        then
+         archive_cmds_need_lc_CXX=no
+        else
+         archive_cmds_need_lc_CXX=yes
+        fi
+        allow_undefined_flag_CXX=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $rm conftest*
+      echo "$as_me:$LINENO: result: $archive_cmds_need_lc_CXX" >&5
+echo "${ECHO_T}$archive_cmds_need_lc_CXX" >&6
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+if test "$GCC" = yes; then
+  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix4* | aix5*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+          echo ' yes '
+          echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+       :
+      else
+       can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $rm \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  linux*)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      supports_anon_versioning=no
+      case `$LD -v 2>/dev/null` in
+        *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+        *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+        *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+        *\ 2.11.*) ;; # other 2.11 versions
+        *) supports_anon_versioning=yes ;;
+      esac
+      if test $supports_anon_versioning = yes; then
+        archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~
+cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+$echo "local: *; };" >> $output_objdir/$libname.ver~
+        $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+      else
+        $archive_expsym_cmds="$archive_cmds"
+      fi
+    else
+      ld_shlibs=no
+    fi
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
+  if test "$GCC" = yes; then
+    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+  else
+    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
+  fi
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+kfreebsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[123]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  # Handle Gentoo/FreeBSD as it was Linux
+  case $host_vendor in
+    gentoo)
+      version_type=linux ;;
+    *)
+      version_type=freebsd-$objformat ;;
+  esac
+
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+    linux)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+      soname_spec='${libname}${release}${shared_ext}$major'
+      need_lib_prefix=no
+      need_version=no
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  freebsd*) # from 4.6 on
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+   hppa*64*)
+     shrext_cmds='.sl'
+     hardcode_into_libs=yes
+     dynamic_linker="$host_os dld.sl"
+     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+     library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+     soname_spec='${libname}${release}${shared_ext}$major'
+     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+     ;;
+   *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+interix3*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+       if test "$lt_cv_prog_gnu_ld" = yes; then
+               version_type=linux
+       else
+               version_type=irix
+       fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,       ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+knetbsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+nto-qnx*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+    *)                         need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+       shlibpath_overrides_runpath=no
+       ;;
+      *)
+       shlibpath_overrides_runpath=yes
+       ;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      export_dynamic_flag_spec='${wl}-Blargedynsym'
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+    shlibpath_overrides_runpath=no
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    shlibpath_overrides_runpath=yes
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+       ;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+echo "${ECHO_T}$dynamic_linker" >&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
+hardcode_action_CXX=
+if test -n "$hardcode_libdir_flag_spec_CXX" || \
+   test -n "$runpath_var_CXX" || \
+   test "X$hardcode_automatic_CXX" = "Xyes" ; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct_CXX" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, CXX)" != no &&
+     test "$hardcode_minus_L_CXX" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action_CXX=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action_CXX=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action_CXX=unsupported
+fi
+echo "$as_me:$LINENO: result: $hardcode_action_CXX" >&5
+echo "${ECHO_T}$hardcode_action_CXX" >&6
+
+if test "$hardcode_action_CXX" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+
+# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    compiler_CXX \
+    CC_CXX \
+    LD_CXX \
+    lt_prog_compiler_wl_CXX \
+    lt_prog_compiler_pic_CXX \
+    lt_prog_compiler_static_CXX \
+    lt_prog_compiler_no_builtin_flag_CXX \
+    export_dynamic_flag_spec_CXX \
+    thread_safe_flag_spec_CXX \
+    whole_archive_flag_spec_CXX \
+    enable_shared_with_static_runtimes_CXX \
+    old_archive_cmds_CXX \
+    old_archive_from_new_cmds_CXX \
+    predep_objects_CXX \
+    postdep_objects_CXX \
+    predeps_CXX \
+    postdeps_CXX \
+    compiler_lib_search_path_CXX \
+    archive_cmds_CXX \
+    archive_expsym_cmds_CXX \
+    postinstall_cmds_CXX \
+    postuninstall_cmds_CXX \
+    old_archive_from_expsyms_cmds_CXX \
+    allow_undefined_flag_CXX \
+    no_undefined_flag_CXX \
+    export_symbols_cmds_CXX \
+    hardcode_libdir_flag_spec_CXX \
+    hardcode_libdir_flag_spec_ld_CXX \
+    hardcode_libdir_separator_CXX \
+    hardcode_automatic_CXX \
+    module_cmds_CXX \
+    module_expsym_cmds_CXX \
+    lt_cv_prog_compiler_c_o_CXX \
+    exclude_expsyms_CXX \
+    include_expsyms_CXX; do
+
+    case $var in
+    old_archive_cmds_CXX | \
+    old_archive_from_new_cmds_CXX | \
+    archive_cmds_CXX | \
+    archive_expsym_cmds_CXX | \
+    module_cmds_CXX | \
+    module_expsym_cmds_CXX | \
+    old_archive_from_expsyms_cmds_CXX | \
+    export_symbols_cmds_CXX | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\$0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+cfgfile="$ofile"
+
+  cat <<__EOF__ >> "$cfgfile"
+# ### BEGIN LIBTOOL TAG CONFIG: $tagname
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_CXX
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
+# A language-specific compiler.
+CC=$lt_compiler_CXX
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC_CXX
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_LD_CXX
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_CXX
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_CXX
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_CXX
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec_CXX
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds_CXX
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds_CXX
+archive_expsym_cmds=$lt_archive_expsym_cmds_CXX
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_module_cmds_CXX
+module_expsym_cmds=$lt_module_expsym_cmds_CXX
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_predep_objects_CXX
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_postdep_objects_CXX
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_predeps_CXX
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_postdeps_CXX
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_CXX
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_CXX
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_CXX
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_CXX
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct_CXX
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L_CXX
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$hardcode_automatic_CXX
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_CXX
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path_CXX"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols_CXX
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_CXX
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_CXX
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_CXX
+
+# ### END LIBTOOL TAG CONFIG: $tagname
+
+__EOF__
+
+
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+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
+
+CC=$lt_save_CC
+LDCXX=$LD
+LD=$lt_save_LD
+GCC=$lt_save_GCC
+with_gnu_ldcxx=$with_gnu_ld
+with_gnu_ld=$lt_save_with_gnu_ld
+lt_cv_path_LDCXX=$lt_cv_path_LD
+lt_cv_path_LD=$lt_save_path_LD
+lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+
+       else
+         tagname=""
+       fi
+       ;;
+
+      F77)
+       if test -n "$F77" && test "X$F77" != "Xno"; then
+
+ac_ext=f
+ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5'
+ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_f77_compiler_gnu
+
+
+archive_cmds_need_lc_F77=no
+allow_undefined_flag_F77=
+always_export_symbols_F77=no
+archive_expsym_cmds_F77=
+export_dynamic_flag_spec_F77=
+hardcode_direct_F77=no
+hardcode_libdir_flag_spec_F77=
+hardcode_libdir_flag_spec_ld_F77=
+hardcode_libdir_separator_F77=
+hardcode_minus_L_F77=no
+hardcode_automatic_F77=no
+module_cmds_F77=
+module_expsym_cmds_F77=
+link_all_deplibs_F77=unknown
+old_archive_cmds_F77=$old_archive_cmds
+no_undefined_flag_F77=
+whole_archive_flag_spec_F77=
+enable_shared_with_static_runtimes_F77=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+objext_F77=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="      subroutine t\n      return\n      end\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="      program t\n      end\n"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$rm conftest*
+
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$rm conftest*
+
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${F77-"f77"}
+compiler=$CC
+compiler_F77=$CC
+for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+
+echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5
+echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $can_build_shared" >&5
+echo "${ECHO_T}$can_build_shared" >&6
+
+echo "$as_me:$LINENO: checking whether to build shared libraries" >&5
+echo $ECHO_N "checking whether to build shared libraries... $ECHO_C" >&6
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case $host_os in
+aix3*)
+  test "$enable_shared" = yes && enable_static=no
+  if test -n "$RANLIB"; then
+    archive_cmds="$archive_cmds~\$RANLIB \$lib"
+    postinstall_cmds='$RANLIB $lib'
+  fi
+  ;;
+aix4* | aix5*)
+  if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+    test "$enable_shared" = yes && enable_static=no
+  fi
+  ;;
+esac
+echo "$as_me:$LINENO: result: $enable_shared" >&5
+echo "${ECHO_T}$enable_shared" >&6
+
+echo "$as_me:$LINENO: checking whether to build static libraries" >&5
+echo $ECHO_N "checking whether to build static libraries... $ECHO_C" >&6
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+echo "$as_me:$LINENO: result: $enable_static" >&5
+echo "${ECHO_T}$enable_static" >&6
+
+GCC_F77="$G77"
+LD_F77="$LD"
+
+lt_prog_compiler_wl_F77=
+lt_prog_compiler_pic_F77=
+lt_prog_compiler_static_F77=
+
+echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
+
+  if test "$GCC" = yes; then
+    lt_prog_compiler_wl_F77='-Wl,'
+    lt_prog_compiler_static_F77='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       lt_prog_compiler_static_F77='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      lt_prog_compiler_pic_F77='-m68020 -resident32 -malways-restore-a4'
+      ;;
+
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic_F77='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic_F77='-fno-common'
+      ;;
+
+    interix3*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      lt_prog_compiler_can_build_shared_F77=no
+      enable_shared=no
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       lt_prog_compiler_pic_F77=-Kconform_pic
+      fi
+      ;;
+
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+       # +Z the default
+       ;;
+      *)
+       lt_prog_compiler_pic_F77='-fPIC'
+       ;;
+      esac
+      ;;
+
+    *)
+      lt_prog_compiler_pic_F77='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       lt_prog_compiler_static_F77='-Bstatic'
+      else
+       lt_prog_compiler_static_F77='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+      darwin*)
+        # PIC is the default on this platform
+        # Common symbols not allowed in MH_DYLIB files
+       case $cc_basename in
+         xlc*)
+         lt_prog_compiler_pic_F77='-qnocommon'
+         lt_prog_compiler_wl_F77='-Wl,'
+         ;;
+       esac
+       ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic_F77='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+       # +Z the default
+       ;;
+      *)
+       lt_prog_compiler_pic_F77='+Z'
+       ;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      lt_prog_compiler_static_F77='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      # PIC (with -KPIC) is the default.
+      lt_prog_compiler_static_F77='-non_shared'
+      ;;
+
+    newsos6)
+      lt_prog_compiler_pic_F77='-KPIC'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    linux*)
+      case $cc_basename in
+      icc* | ecc*)
+       lt_prog_compiler_wl_F77='-Wl,'
+       lt_prog_compiler_pic_F77='-KPIC'
+       lt_prog_compiler_static_F77='-static'
+        ;;
+      pgcc* | pgf77* | pgf90* | pgf95*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+       # which looks to be a dead project)
+       lt_prog_compiler_wl_F77='-Wl,'
+       lt_prog_compiler_pic_F77='-fpic'
+       lt_prog_compiler_static_F77='-Bstatic'
+        ;;
+      ccc*)
+        lt_prog_compiler_wl_F77='-Wl,'
+        # All Alpha code is PIC.
+        lt_prog_compiler_static_F77='-non_shared'
+        ;;
+      esac
+      ;;
+
+    osf3* | osf4* | osf5*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      # All OSF/1 code is PIC.
+      lt_prog_compiler_static_F77='-non_shared'
+      ;;
+
+    solaris*)
+      lt_prog_compiler_pic_F77='-KPIC'
+      lt_prog_compiler_static_F77='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95*)
+       lt_prog_compiler_wl_F77='-Qoption ld ';;
+      *)
+       lt_prog_compiler_wl_F77='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      lt_prog_compiler_wl_F77='-Qoption ld '
+      lt_prog_compiler_pic_F77='-PIC'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      lt_prog_compiler_pic_F77='-KPIC'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+       lt_prog_compiler_pic_F77='-Kconform_pic'
+       lt_prog_compiler_static_F77='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      lt_prog_compiler_pic_F77='-KPIC'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    unicos*)
+      lt_prog_compiler_wl_F77='-Wl,'
+      lt_prog_compiler_can_build_shared_F77=no
+      ;;
+
+    uts4*)
+      lt_prog_compiler_pic_F77='-pic'
+      lt_prog_compiler_static_F77='-Bstatic'
+      ;;
+
+    *)
+      lt_prog_compiler_can_build_shared_F77=no
+      ;;
+    esac
+  fi
+
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_F77" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_F77" >&6
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_F77"; then
+
+echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5
+echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... $ECHO_C" >&6
+if test "${lt_prog_compiler_pic_works_F77+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_pic_works_F77=no
+  ac_outfile=conftest.$ac_objext
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic_F77"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:12938: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:12942: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_prog_compiler_pic_works_F77=yes
+     fi
+   fi
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_F77" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_works_F77" >&6
+
+if test x"$lt_prog_compiler_pic_works_F77" = xyes; then
+    case $lt_prog_compiler_pic_F77 in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic_F77=" $lt_prog_compiler_pic_F77" ;;
+     esac
+else
+    lt_prog_compiler_pic_F77=
+     lt_prog_compiler_can_build_shared_F77=no
+fi
+
+fi
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic_F77=
+    ;;
+  *)
+    lt_prog_compiler_pic_F77="$lt_prog_compiler_pic_F77"
+    ;;
+esac
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_F77 eval lt_tmp_static_flag=\"$lt_prog_compiler_static_F77\"
+echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6
+if test "${lt_prog_compiler_static_works_F77+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_static_works_F77=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   printf "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_prog_compiler_static_works_F77=yes
+       fi
+     else
+       lt_prog_compiler_static_works_F77=yes
+     fi
+   fi
+   $rm conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_F77" >&5
+echo "${ECHO_T}$lt_prog_compiler_static_works_F77" >&6
+
+if test x"$lt_prog_compiler_static_works_F77" = xyes; then
+    :
+else
+    lt_prog_compiler_static_F77=
+fi
+
+
+echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
+if test "${lt_cv_prog_compiler_c_o_F77+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_prog_compiler_c_o_F77=no
+   $rm -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:13042: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:13046: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o_F77=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $rm conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+   $rm out/* && rmdir out
+   cd ..
+   rmdir conftest
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_F77" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_c_o_F77" >&6
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_F77" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  echo "$as_me:$LINENO: result: $hard_links" >&5
+echo "${ECHO_T}$hard_links" >&6
+  if test "$hard_links" = no; then
+    { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6
+
+  runpath_var=
+  allow_undefined_flag_F77=
+  enable_shared_with_static_runtimes_F77=no
+  archive_cmds_F77=
+  archive_expsym_cmds_F77=
+  old_archive_From_new_cmds_F77=
+  old_archive_from_expsyms_cmds_F77=
+  export_dynamic_flag_spec_F77=
+  whole_archive_flag_spec_F77=
+  thread_safe_flag_spec_F77=
+  hardcode_libdir_flag_spec_F77=
+  hardcode_libdir_flag_spec_ld_F77=
+  hardcode_libdir_separator_F77=
+  hardcode_direct_F77=no
+  hardcode_minus_L_F77=no
+  hardcode_shlibpath_var_F77=unsupported
+  link_all_deplibs_F77=unknown
+  hardcode_automatic_F77=no
+  module_cmds_F77=
+  module_expsym_cmds_F77=
+  always_export_symbols_F77=no
+  export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  include_expsyms_F77=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  exclude_expsyms_F77="_GLOBAL_OFFSET_TABLE_"
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  extract_expsyms_cmds=
+  # Just being paranoid about ensuring that cc_basename is set.
+  for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+  case $host_os in
+  cygwin* | mingw* | pw32*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  esac
+
+  ld_shlibs_F77=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec_F77='${wl}--rpath ${wl}$libdir'
+    export_dynamic_flag_spec_F77='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
+       whole_archive_flag_spec_F77="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+       whole_archive_flag_spec_F77=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>/dev/null` in
+      *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix3* | aix4* | aix5*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+       ld_shlibs_F77=no
+       cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+      fi
+      ;;
+
+    amigaos*)
+      archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_minus_L_F77=yes
+
+      # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+      # that the semantics of dynamic libraries on AmigaOS, at least up
+      # to version 4, is to share data among multiple programs linked
+      # with the same dynamic library.  Since this doesn't match the
+      # behavior of shared libraries on other platforms, we can't use
+      # them.
+      ld_shlibs_F77=no
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       allow_undefined_flag_F77=unsupported
+       # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+       # support --undefined.  This deserves some investigation.  FIXME
+       archive_cmds_F77='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+       ld_shlibs_F77=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, F77) is actually meaningless,
+      # as there is no search path for DLLs.
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      allow_undefined_flag_F77=unsupported
+      always_export_symbols_F77=no
+      enable_shared_with_static_runtimes_F77=yes
+      export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+        archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+       # If the export-symbols file already is a .def file (1st line
+       # is EXPORTS), use it as is; otherwise, prepend...
+       archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+         cp $export_symbols $output_objdir/$soname.def;
+       else
+         echo EXPORTS > $output_objdir/$soname.def;
+         cat $export_symbols >> $output_objdir/$soname.def;
+       fi~
+       $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+       ld_shlibs_F77=no
+      fi
+      ;;
+
+    interix3*)
+      hardcode_direct_F77=no
+      hardcode_shlibpath_var_F77=no
+      hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec_F77='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_expsym_cmds_F77='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    linux*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       tmp_addflag=
+       case $cc_basename,$host_cpu in
+       pgcc*)                          # Portland Group C compiler
+         whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+         tmp_addflag=' $pic_flag'
+         ;;
+       pgf77* | pgf90* | pgf95*)       # Portland Group f77 and f90 compilers
+         whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+         tmp_addflag=' $pic_flag -Mnomain' ;;
+       ecc*,ia64* | icc*,ia64*)                # Intel C compiler on ia64
+         tmp_addflag=' -i_dynamic' ;;
+       efc*,ia64* | ifort*,ia64*)      # Intel Fortran compiler on ia64
+         tmp_addflag=' -i_dynamic -nofor_main' ;;
+       ifc* | ifort*)                  # Intel Fortran compiler
+         tmp_addflag=' -nofor_main' ;;
+       esac
+       archive_cmds_F77='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+       if test $supports_anon_versioning = yes; then
+         archive_expsym_cmds_F77='$echo "{ global:" > $output_objdir/$libname.ver~
+  cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+  $echo "local: *; };" >> $output_objdir/$libname.ver~
+         $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+       fi
+      else
+       ld_shlibs_F77=no
+      fi
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+       archive_cmds_F77='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+       wlarc=
+      else
+       archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+       ld_shlibs_F77=no
+       cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+       ld_shlibs_F77=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+       ld_shlibs_F77=no
+       cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+       ;;
+       *)
+         if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+           hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+           archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
+           archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
+         else
+           ld_shlibs_F77=no
+         fi
+       ;;
+      esac
+      ;;
+
+    sunos4*)
+      archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      hardcode_direct_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+       ld_shlibs_F77=no
+      fi
+      ;;
+    esac
+
+    if test "$ld_shlibs_F77" = no; then
+      runpath_var=
+      hardcode_libdir_flag_spec_F77=
+      export_dynamic_flag_spec_F77=
+      whole_archive_flag_spec_F77=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      allow_undefined_flag_F77=unsupported
+      always_export_symbols_F77=yes
+      archive_expsym_cmds_F77='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L_F77=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+       # Neither direct hardcoding nor static linking is supported with a
+       # broken collect2.
+       hardcode_direct_F77=unsupported
+      fi
+      ;;
+
+    aix4* | aix5*)
+      if test "$host_cpu" = ia64; then
+       # On IA64, the linker does run time linking by default, so we don't
+       # have to do anything special.
+       aix_use_runtimelinking=no
+       exp_sym_flag='-Bexport'
+       no_entry_flag=""
+      else
+       # If we're using GNU nm, then we don't want the "-C" option.
+       # -C means demangle to AIX nm, but means don't demangle with GNU nm
+       if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+         export_symbols_cmds_F77='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+       else
+         export_symbols_cmds_F77='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+       fi
+       aix_use_runtimelinking=no
+
+       # Test if we are trying to use run time linking or normal
+       # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+       # need to do runtime linking.
+       case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+         for ld_flag in $LDFLAGS; do
+         if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+           aix_use_runtimelinking=yes
+           break
+         fi
+         done
+         ;;
+       esac
+
+       exp_sym_flag='-bexport'
+       no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      archive_cmds_F77=''
+      hardcode_direct_F77=yes
+      hardcode_libdir_separator_F77=':'
+      link_all_deplibs_F77=yes
+
+      if test "$GCC" = yes; then
+       case $host_os in aix4.[012]|aix4.[012].*)
+       # We only want to do this on AIX 4.2 and lower, the check
+       # below for broken collect2 doesn't work under 4.3+
+         collect2name=`${CC} -print-prog-name=collect2`
+         if test -f "$collect2name" && \
+          strings "$collect2name" | grep resolve_lib_name >/dev/null
+         then
+         # We have reworked collect2
+         hardcode_direct_F77=yes
+         else
+         # We have old collect2
+         hardcode_direct_F77=unsupported
+         # It fails to find uninstalled libraries when the uninstalled
+         # path is not listed in the libpath.  Setting hardcode_minus_L
+         # to unsupported forces relinking
+         hardcode_minus_L_F77=yes
+         hardcode_libdir_flag_spec_F77='-L$libdir'
+         hardcode_libdir_separator_F77=
+         fi
+         ;;
+       esac
+       shared_flag='-shared'
+       if test "$aix_use_runtimelinking" = yes; then
+         shared_flag="$shared_flag "'${wl}-G'
+       fi
+      else
+       # not using gcc
+       if test "$host_cpu" = ia64; then
+       # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+       # chokes on -Wl,-G. The following line is correct:
+         shared_flag='-G'
+       else
+         if test "$aix_use_runtimelinking" = yes; then
+           shared_flag='${wl}-G'
+         else
+           shared_flag='${wl}-bM:SRE'
+         fi
+       fi
+      fi
+
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      always_export_symbols_F77=yes
+      if test "$aix_use_runtimelinking" = yes; then
+       # Warning - without using the other runtime loading flags (-brtl),
+       # -berok will link without error, but may produce a broken library.
+       allow_undefined_flag_F77='-berok'
+       # Determine the default libpath from the value encoded in an empty executable.
+       cat >conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_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_f77_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
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; 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_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+       hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath"
+       archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+       else
+       if test "$host_cpu" = ia64; then
+         hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib'
+         allow_undefined_flag_F77="-z nodefs"
+         archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+       else
+        # Determine the default libpath from the value encoded in an empty executable.
+        cat >conftest.$ac_ext <<_ACEOF
+      program main
+
+      end
+_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_f77_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
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; 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_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+        hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath"
+         # Warning - without using the other run time loading flags,
+         # -berok will link without error, but may produce a broken library.
+         no_undefined_flag_F77=' ${wl}-bernotok'
+         allow_undefined_flag_F77=' ${wl}-berok'
+         # Exported symbols can be pulled into shared objects from archives
+         whole_archive_flag_spec_F77='$convenience'
+         archive_cmds_need_lc_F77=yes
+         # This is similar to how AIX traditionally builds its shared libraries.
+         archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+       fi
+      fi
+      ;;
+
+    amigaos*)
+      archive_cmds_F77='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_minus_L_F77=yes
+      # see comment about different semantics on the GNU ld section
+      ld_shlibs_F77=no
+      ;;
+
+    bsdi[45]*)
+      export_dynamic_flag_spec_F77=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      hardcode_libdir_flag_spec_F77=' '
+      allow_undefined_flag_F77=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      archive_cmds_F77='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      old_archive_From_new_cmds_F77='true'
+      # FIXME: Should let the user specify the lib program.
+      old_archive_cmds_F77='lib /OUT:$oldlib$oldobjs$old_deplibs'
+      fix_srcfile_path_F77='`cygpath -w "$srcfile"`'
+      enable_shared_with_static_runtimes_F77=yes
+      ;;
+
+    darwin* | rhapsody*)
+      case $host_os in
+        rhapsody* | darwin1.[012])
+         allow_undefined_flag_F77='${wl}-undefined ${wl}suppress'
+         ;;
+       *) # Darwin 1.3 on
+         if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+           allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+         else
+           case ${MACOSX_DEPLOYMENT_TARGET} in
+             10.[012])
+               allow_undefined_flag_F77='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+               ;;
+             10.*)
+               allow_undefined_flag_F77='${wl}-undefined ${wl}dynamic_lookup'
+               ;;
+           esac
+         fi
+         ;;
+      esac
+      archive_cmds_need_lc_F77=no
+      hardcode_direct_F77=no
+      hardcode_automatic_F77=yes
+      hardcode_shlibpath_var_F77=unsupported
+      whole_archive_flag_spec_F77=''
+      link_all_deplibs_F77=yes
+    if test "$GCC" = yes ; then
+       output_verbose_link_cmd='echo'
+        archive_cmds_F77='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+      module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+      archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+      module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    else
+      case $cc_basename in
+        xlc*)
+         output_verbose_link_cmd='echo'
+         archive_cmds_F77='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+         module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+         archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          ;;
+       *)
+         ld_shlibs_F77=no
+          ;;
+      esac
+    fi
+      ;;
+
+    dgux*)
+      archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    freebsd1*)
+      ld_shlibs_F77=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      hardcode_libdir_flag_spec_F77='-R$libdir'
+      hardcode_direct_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct_F77=yes
+      hardcode_minus_L_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | kfreebsd*-gnu | dragonfly*)
+      archive_cmds_F77='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      hardcode_libdir_flag_spec_F77='-R$libdir'
+      hardcode_direct_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+       archive_cmds_F77='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+       archive_cmds_F77='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator_F77=:
+      hardcode_direct_F77=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L_F77=yes
+      export_dynamic_flag_spec_F77='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+       archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+       hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
+       hardcode_libdir_separator_F77=:
+
+       hardcode_direct_F77=yes
+       export_dynamic_flag_spec_F77='${wl}-E'
+
+       # hardcode_minus_L: Not really in the search PATH,
+       # but as the default location of the library.
+       hardcode_minus_L_F77=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+       case $host_cpu in
+       hppa*64*)
+         archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       ia64*)
+         archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       *)
+         archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       esac
+      else
+       case $host_cpu in
+       hppa*64*)
+         archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       ia64*)
+         archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       *)
+         archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       esac
+      fi
+      if test "$with_gnu_ld" = no; then
+       hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir'
+       hardcode_libdir_separator_F77=:
+
+       case $host_cpu in
+       hppa*64*|ia64*)
+         hardcode_libdir_flag_spec_ld_F77='+b $libdir'
+         hardcode_direct_F77=no
+         hardcode_shlibpath_var_F77=no
+         ;;
+       *)
+         hardcode_direct_F77=yes
+         export_dynamic_flag_spec_F77='${wl}-E'
+
+         # hardcode_minus_L: Not really in the search PATH,
+         # but as the default location of the library.
+         hardcode_minus_L_F77=yes
+         ;;
+       esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+       archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+       archive_cmds_F77='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+       hardcode_libdir_flag_spec_ld_F77='-rpath $libdir'
+      fi
+      hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_F77=:
+      link_all_deplibs_F77=yes
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+       archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+       archive_cmds_F77='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      hardcode_libdir_flag_spec_F77='-R$libdir'
+      hardcode_direct_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    newsos6)
+      archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct_F77=yes
+      hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_F77=:
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    openbsd*)
+      hardcode_direct_F77=yes
+      hardcode_shlibpath_var_F77=no
+      if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+       archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+       hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
+       export_dynamic_flag_spec_F77='${wl}-E'
+      else
+       case $host_os in
+        openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+          archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+          hardcode_libdir_flag_spec_F77='-R$libdir'
+          ;;
+        *)
+          archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+          hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir'
+          ;;
+       esac
+      fi
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_minus_L_F77=yes
+      allow_undefined_flag_F77=unsupported
+      archive_cmds_F77='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_From_new_cmds_F77='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+       allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*'
+       archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+       allow_undefined_flag_F77=' -expect_unresolved \*'
+       archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_F77=:
+      ;;
+
+    osf4* | osf5*)     # as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+       allow_undefined_flag_F77=' ${wl}-expect_unresolved ${wl}\*'
+       archive_cmds_F77='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+       hardcode_libdir_flag_spec_F77='${wl}-rpath ${wl}$libdir'
+      else
+       allow_undefined_flag_F77=' -expect_unresolved \*'
+       archive_cmds_F77='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+       archive_expsym_cmds_F77='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+       $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp'
+
+       # Both c and cxx compiler support -rpath directly
+       hardcode_libdir_flag_spec_F77='-rpath $libdir'
+      fi
+      hardcode_libdir_separator_F77=:
+      ;;
+
+    solaris*)
+      no_undefined_flag_F77=' -z text'
+      if test "$GCC" = yes; then
+       wlarc='${wl}'
+       archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+         $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
+      else
+       wlarc=''
+       archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+       archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+       $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      fi
+      hardcode_libdir_flag_spec_F77='-R$libdir'
+      hardcode_shlibpath_var_F77=no
+      case $host_os in
+      solaris2.[0-5] | solaris2.[0-5].*) ;;
+      *)
+       # The compiler driver will combine linker options so we
+       # cannot just pass the convience library names through
+       # without $wl, iff we do not link with $LD.
+       # Luckily, gcc supports the same syntax we need for Sun Studio.
+       # Supported since Solaris 2.6 (maybe 2.5.1?)
+       case $wlarc in
+       '')
+         whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' ;;
+       *)
+         whole_archive_flag_spec_F77='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;;
+       esac ;;
+      esac
+      link_all_deplibs_F77=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+       # Use $CC to link under sequent, because it throws in some extra .o
+       # files that make .init and .fini sections work.
+       archive_cmds_F77='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       archive_cmds_F77='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_direct_F77=yes
+      hardcode_minus_L_F77=yes
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+       sni)
+         archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+         hardcode_direct_F77=yes # is this really true???
+       ;;
+       siemens)
+         ## LD is ld it makes a PLAMLIB
+         ## CC just makes a GrossModule.
+         archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+         reload_cmds_F77='$CC -r -o $output$reload_objs'
+         hardcode_direct_F77=no
+        ;;
+       motorola)
+         archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+         hardcode_direct_F77=no #Motorola manual says yes, but my tests say they lie
+       ;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    sysv4.3*)
+      archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var_F77=no
+      export_dynamic_flag_spec_F77='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+       hardcode_shlibpath_var_F77=no
+       runpath_var=LD_RUN_PATH
+       hardcode_runpath_var=yes
+       ld_shlibs_F77=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*)
+      no_undefined_flag_F77='${wl}-z,text'
+      archive_cmds_need_lc_F77=no
+      hardcode_shlibpath_var_F77=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+       archive_cmds_F77='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       archive_cmds_F77='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      no_undefined_flag_F77='${wl}-z,text'
+      allow_undefined_flag_F77='${wl}-z,nodefs'
+      archive_cmds_need_lc_F77=no
+      hardcode_shlibpath_var_F77=no
+      hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+      hardcode_libdir_separator_F77=':'
+      link_all_deplibs_F77=yes
+      export_dynamic_flag_spec_F77='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+       archive_cmds_F77='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       archive_cmds_F77='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec_F77='-L$libdir'
+      hardcode_shlibpath_var_F77=no
+      ;;
+
+    *)
+      ld_shlibs_F77=no
+      ;;
+    esac
+  fi
+
+echo "$as_me:$LINENO: result: $ld_shlibs_F77" >&5
+echo "${ECHO_T}$ld_shlibs_F77" >&6
+test "$ld_shlibs_F77" = no && can_build_shared=no
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_F77" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc_F77=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds_F77 in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6
+      $rm conftest*
+      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      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); } 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$lt_prog_compiler_wl_F77
+       pic_flag=$lt_prog_compiler_pic_F77
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$allow_undefined_flag_F77
+        allow_undefined_flag_F77=
+        if { (eval echo "$as_me:$LINENO: \"$archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
+  (eval $archive_cmds_F77 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+        then
+         archive_cmds_need_lc_F77=no
+        else
+         archive_cmds_need_lc_F77=yes
+        fi
+        allow_undefined_flag_F77=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $rm conftest*
+      echo "$as_me:$LINENO: result: $archive_cmds_need_lc_F77" >&5
+echo "${ECHO_T}$archive_cmds_need_lc_F77" >&6
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+if test "$GCC" = yes; then
+  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix4* | aix5*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+          echo ' yes '
+          echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+       :
+      else
+       can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $rm \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  linux*)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      supports_anon_versioning=no
+      case `$LD -v 2>/dev/null` in
+        *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+        *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+        *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+        *\ 2.11.*) ;; # other 2.11 versions
+        *) supports_anon_versioning=yes ;;
+      esac
+      if test $supports_anon_versioning = yes; then
+        archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~
+cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+$echo "local: *; };" >> $output_objdir/$libname.ver~
+        $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+      else
+        $archive_expsym_cmds="$archive_cmds"
+      fi
+    else
+      ld_shlibs=no
+    fi
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
+  if test "$GCC" = yes; then
+    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+  else
+    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
+  fi
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+kfreebsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[123]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  # Handle Gentoo/FreeBSD as it was Linux
+  case $host_vendor in
+    gentoo)
+      version_type=linux ;;
+    *)
+      version_type=freebsd-$objformat ;;
+  esac
+
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+    linux)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+      soname_spec='${libname}${release}${shared_ext}$major'
+      need_lib_prefix=no
+      need_version=no
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  freebsd*) # from 4.6 on
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+   hppa*64*)
+     shrext_cmds='.sl'
+     hardcode_into_libs=yes
+     dynamic_linker="$host_os dld.sl"
+     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+     library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+     soname_spec='${libname}${release}${shared_ext}$major'
+     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+     ;;
+   *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+interix3*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+       if test "$lt_cv_prog_gnu_ld" = yes; then
+               version_type=linux
+       else
+               version_type=irix
+       fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,       ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+knetbsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+nto-qnx*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+    *)                         need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+       shlibpath_overrides_runpath=no
+       ;;
+      *)
+       shlibpath_overrides_runpath=yes
+       ;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      export_dynamic_flag_spec='${wl}-Blargedynsym'
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+    shlibpath_overrides_runpath=no
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    shlibpath_overrides_runpath=yes
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+       ;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+echo "${ECHO_T}$dynamic_linker" >&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
+hardcode_action_F77=
+if test -n "$hardcode_libdir_flag_spec_F77" || \
+   test -n "$runpath_var_F77" || \
+   test "X$hardcode_automatic_F77" = "Xyes" ; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct_F77" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, F77)" != no &&
+     test "$hardcode_minus_L_F77" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action_F77=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action_F77=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action_F77=unsupported
+fi
+echo "$as_me:$LINENO: result: $hardcode_action_F77" >&5
+echo "${ECHO_T}$hardcode_action_F77" >&6
+
+if test "$hardcode_action_F77" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+
+# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    compiler_F77 \
+    CC_F77 \
+    LD_F77 \
+    lt_prog_compiler_wl_F77 \
+    lt_prog_compiler_pic_F77 \
+    lt_prog_compiler_static_F77 \
+    lt_prog_compiler_no_builtin_flag_F77 \
+    export_dynamic_flag_spec_F77 \
+    thread_safe_flag_spec_F77 \
+    whole_archive_flag_spec_F77 \
+    enable_shared_with_static_runtimes_F77 \
+    old_archive_cmds_F77 \
+    old_archive_from_new_cmds_F77 \
+    predep_objects_F77 \
+    postdep_objects_F77 \
+    predeps_F77 \
+    postdeps_F77 \
+    compiler_lib_search_path_F77 \
+    archive_cmds_F77 \
+    archive_expsym_cmds_F77 \
+    postinstall_cmds_F77 \
+    postuninstall_cmds_F77 \
+    old_archive_from_expsyms_cmds_F77 \
+    allow_undefined_flag_F77 \
+    no_undefined_flag_F77 \
+    export_symbols_cmds_F77 \
+    hardcode_libdir_flag_spec_F77 \
+    hardcode_libdir_flag_spec_ld_F77 \
+    hardcode_libdir_separator_F77 \
+    hardcode_automatic_F77 \
+    module_cmds_F77 \
+    module_expsym_cmds_F77 \
+    lt_cv_prog_compiler_c_o_F77 \
+    exclude_expsyms_F77 \
+    include_expsyms_F77; do
+
+    case $var in
+    old_archive_cmds_F77 | \
+    old_archive_from_new_cmds_F77 | \
+    archive_cmds_F77 | \
+    archive_expsym_cmds_F77 | \
+    module_cmds_F77 | \
+    module_expsym_cmds_F77 | \
+    old_archive_from_expsyms_cmds_F77 | \
+    export_symbols_cmds_F77 | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\$0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+cfgfile="$ofile"
+
+  cat <<__EOF__ >> "$cfgfile"
+# ### BEGIN LIBTOOL TAG CONFIG: $tagname
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_F77
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_F77
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
+# A language-specific compiler.
+CC=$lt_compiler_F77
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC_F77
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_LD_F77
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_F77
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_F77
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_F77
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_F77
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_F77
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_F77
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_F77
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec_F77
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds_F77
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_F77
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_F77
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds_F77
+archive_expsym_cmds=$lt_archive_expsym_cmds_F77
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_module_cmds_F77
+module_expsym_cmds=$lt_module_expsym_cmds_F77
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_predep_objects_F77
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_postdep_objects_F77
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_predeps_F77
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_postdeps_F77
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_F77
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_F77
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_F77
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_F77
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_F77
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_F77
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_F77
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct_F77
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L_F77
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_F77
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$hardcode_automatic_F77
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_F77
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path_F77"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols_F77
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_F77
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_F77
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_F77
+
+# ### END LIBTOOL TAG CONFIG: $tagname
+
+__EOF__
+
+
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+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
+
+CC="$lt_save_CC"
+
+       else
+         tagname=""
+       fi
+       ;;
+
+      GCJ)
+       if test -n "$GCJ" && test "X$GCJ" != "Xno"; then
+
+
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+objext_GCJ=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}\n"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }\n'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$rm conftest*
+
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$rm conftest*
+
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${GCJ-"gcj"}
+compiler=$CC
+compiler_GCJ=$CC
+for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+archive_cmds_need_lc_GCJ=no
+
+old_archive_cmds_GCJ=$old_archive_cmds
+
+
+lt_prog_compiler_no_builtin_flag_GCJ=
+
+if test "$GCC" = yes; then
+  lt_prog_compiler_no_builtin_flag_GCJ=' -fno-builtin'
+
+
+echo "$as_me:$LINENO: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+echo $ECHO_N "checking if $compiler supports -fno-rtti -fno-exceptions... $ECHO_C" >&6
+if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_prog_compiler_rtti_exceptions=no
+  ac_outfile=conftest.$ac_objext
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="-fno-rtti -fno-exceptions"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:15282: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:15286: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_rtti_exceptions=yes
+     fi
+   fi
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_rtti_exceptions" >&6
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+    lt_prog_compiler_no_builtin_flag_GCJ="$lt_prog_compiler_no_builtin_flag_GCJ -fno-rtti -fno-exceptions"
+else
+    :
+fi
+
+fi
+
+lt_prog_compiler_wl_GCJ=
+lt_prog_compiler_pic_GCJ=
+lt_prog_compiler_static_GCJ=
+
+echo "$as_me:$LINENO: checking for $compiler option to produce PIC" >&5
+echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6
+
+  if test "$GCC" = yes; then
+    lt_prog_compiler_wl_GCJ='-Wl,'
+    lt_prog_compiler_static_GCJ='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       lt_prog_compiler_static_GCJ='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      # FIXME: we need at least 68020 code to build shared libraries, but
+      # adding the `-m68020' flag to GCC prevents building anything better,
+      # like `-m68040'.
+      lt_prog_compiler_pic_GCJ='-m68020 -resident32 -malways-restore-a4'
+      ;;
+
+    beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic_GCJ='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic_GCJ='-fno-common'
+      ;;
+
+    interix3*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      lt_prog_compiler_can_build_shared_GCJ=no
+      enable_shared=no
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       lt_prog_compiler_pic_GCJ=-Kconform_pic
+      fi
+      ;;
+
+    hpux*)
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+       # +Z the default
+       ;;
+      *)
+       lt_prog_compiler_pic_GCJ='-fPIC'
+       ;;
+      esac
+      ;;
+
+    *)
+      lt_prog_compiler_pic_GCJ='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      if test "$host_cpu" = ia64; then
+       # AIX 5 now supports IA64 processor
+       lt_prog_compiler_static_GCJ='-Bstatic'
+      else
+       lt_prog_compiler_static_GCJ='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+      darwin*)
+        # PIC is the default on this platform
+        # Common symbols not allowed in MH_DYLIB files
+       case $cc_basename in
+         xlc*)
+         lt_prog_compiler_pic_GCJ='-qnocommon'
+         lt_prog_compiler_wl_GCJ='-Wl,'
+         ;;
+       esac
+       ;;
+
+    mingw* | pw32* | os2*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic_GCJ='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+       # +Z the default
+       ;;
+      *)
+       lt_prog_compiler_pic_GCJ='+Z'
+       ;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      lt_prog_compiler_static_GCJ='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      # PIC (with -KPIC) is the default.
+      lt_prog_compiler_static_GCJ='-non_shared'
+      ;;
+
+    newsos6)
+      lt_prog_compiler_pic_GCJ='-KPIC'
+      lt_prog_compiler_static_GCJ='-Bstatic'
+      ;;
+
+    linux*)
+      case $cc_basename in
+      icc* | ecc*)
+       lt_prog_compiler_wl_GCJ='-Wl,'
+       lt_prog_compiler_pic_GCJ='-KPIC'
+       lt_prog_compiler_static_GCJ='-static'
+        ;;
+      pgcc* | pgf77* | pgf90* | pgf95*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+       # which looks to be a dead project)
+       lt_prog_compiler_wl_GCJ='-Wl,'
+       lt_prog_compiler_pic_GCJ='-fpic'
+       lt_prog_compiler_static_GCJ='-Bstatic'
+        ;;
+      ccc*)
+        lt_prog_compiler_wl_GCJ='-Wl,'
+        # All Alpha code is PIC.
+        lt_prog_compiler_static_GCJ='-non_shared'
+        ;;
+      esac
+      ;;
+
+    osf3* | osf4* | osf5*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      # All OSF/1 code is PIC.
+      lt_prog_compiler_static_GCJ='-non_shared'
+      ;;
+
+    solaris*)
+      lt_prog_compiler_pic_GCJ='-KPIC'
+      lt_prog_compiler_static_GCJ='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95*)
+       lt_prog_compiler_wl_GCJ='-Qoption ld ';;
+      *)
+       lt_prog_compiler_wl_GCJ='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      lt_prog_compiler_wl_GCJ='-Qoption ld '
+      lt_prog_compiler_pic_GCJ='-PIC'
+      lt_prog_compiler_static_GCJ='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      lt_prog_compiler_pic_GCJ='-KPIC'
+      lt_prog_compiler_static_GCJ='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+       lt_prog_compiler_pic_GCJ='-Kconform_pic'
+       lt_prog_compiler_static_GCJ='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      lt_prog_compiler_pic_GCJ='-KPIC'
+      lt_prog_compiler_static_GCJ='-Bstatic'
+      ;;
+
+    unicos*)
+      lt_prog_compiler_wl_GCJ='-Wl,'
+      lt_prog_compiler_can_build_shared_GCJ=no
+      ;;
+
+    uts4*)
+      lt_prog_compiler_pic_GCJ='-pic'
+      lt_prog_compiler_static_GCJ='-Bstatic'
+      ;;
+
+    *)
+      lt_prog_compiler_can_build_shared_GCJ=no
+      ;;
+    esac
+  fi
+
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_GCJ" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_GCJ" >&6
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_GCJ"; then
+
+echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works" >&5
+echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works... $ECHO_C" >&6
+if test "${lt_prog_compiler_pic_works_GCJ+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_pic_works_GCJ=no
+  ac_outfile=conftest.$ac_objext
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic_GCJ"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:15550: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:15554: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_prog_compiler_pic_works_GCJ=yes
+     fi
+   fi
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_GCJ" >&5
+echo "${ECHO_T}$lt_prog_compiler_pic_works_GCJ" >&6
+
+if test x"$lt_prog_compiler_pic_works_GCJ" = xyes; then
+    case $lt_prog_compiler_pic_GCJ in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic_GCJ=" $lt_prog_compiler_pic_GCJ" ;;
+     esac
+else
+    lt_prog_compiler_pic_GCJ=
+     lt_prog_compiler_can_build_shared_GCJ=no
+fi
+
+fi
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic_GCJ=
+    ;;
+  *)
+    lt_prog_compiler_pic_GCJ="$lt_prog_compiler_pic_GCJ"
+    ;;
+esac
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_GCJ eval lt_tmp_static_flag=\"$lt_prog_compiler_static_GCJ\"
+echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6
+if test "${lt_prog_compiler_static_works_GCJ+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_prog_compiler_static_works_GCJ=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   printf "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_prog_compiler_static_works_GCJ=yes
+       fi
+     else
+       lt_prog_compiler_static_works_GCJ=yes
+     fi
+   fi
+   $rm conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works_GCJ" >&5
+echo "${ECHO_T}$lt_prog_compiler_static_works_GCJ" >&6
+
+if test x"$lt_prog_compiler_static_works_GCJ" = xyes; then
+    :
+else
+    lt_prog_compiler_static_GCJ=
+fi
+
+
+echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5
+echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6
+if test "${lt_cv_prog_compiler_c_o_GCJ+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  lt_cv_prog_compiler_c_o_GCJ=no
+   $rm -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:15654: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:15658: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o_GCJ=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $rm conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files
+   $rm out/* && rmdir out
+   cd ..
+   rmdir conftest
+   $rm conftest*
+
+fi
+echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_c_o_GCJ" >&5
+echo "${ECHO_T}$lt_cv_prog_compiler_c_o_GCJ" >&6
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_GCJ" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  echo "$as_me:$LINENO: checking if we can lock with hard links" >&5
+echo $ECHO_N "checking if we can lock with hard links... $ECHO_C" >&6
+  hard_links=yes
+  $rm conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  echo "$as_me:$LINENO: result: $hard_links" >&5
+echo "${ECHO_T}$hard_links" >&6
+  if test "$hard_links" = no; then
+    { echo "$as_me:$LINENO: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+echo "$as_me:$LINENO: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared libraries... $ECHO_C" >&6
+
+  runpath_var=
+  allow_undefined_flag_GCJ=
+  enable_shared_with_static_runtimes_GCJ=no
+  archive_cmds_GCJ=
+  archive_expsym_cmds_GCJ=
+  old_archive_From_new_cmds_GCJ=
+  old_archive_from_expsyms_cmds_GCJ=
+  export_dynamic_flag_spec_GCJ=
+  whole_archive_flag_spec_GCJ=
+  thread_safe_flag_spec_GCJ=
+  hardcode_libdir_flag_spec_GCJ=
+  hardcode_libdir_flag_spec_ld_GCJ=
+  hardcode_libdir_separator_GCJ=
+  hardcode_direct_GCJ=no
+  hardcode_minus_L_GCJ=no
+  hardcode_shlibpath_var_GCJ=unsupported
+  link_all_deplibs_GCJ=unknown
+  hardcode_automatic_GCJ=no
+  module_cmds_GCJ=
+  module_expsym_cmds_GCJ=
+  always_export_symbols_GCJ=no
+  export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  include_expsyms_GCJ=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  exclude_expsyms_GCJ="_GLOBAL_OFFSET_TABLE_"
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  extract_expsyms_cmds=
+  # Just being paranoid about ensuring that cc_basename is set.
+  for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+  case $host_os in
+  cygwin* | mingw* | pw32*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  esac
+
+  ld_shlibs_GCJ=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec_GCJ='${wl}--rpath ${wl}$libdir'
+    export_dynamic_flag_spec_GCJ='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then
+       whole_archive_flag_spec_GCJ="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+      else
+       whole_archive_flag_spec_GCJ=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>/dev/null` in
+      *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix3* | aix4* | aix5*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+       ld_shlibs_GCJ=no
+       cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+      fi
+      ;;
+
+    amigaos*)
+      archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      hardcode_minus_L_GCJ=yes
+
+      # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+      # that the semantics of dynamic libraries on AmigaOS, at least up
+      # to version 4, is to share data among multiple programs linked
+      # with the same dynamic library.  Since this doesn't match the
+      # behavior of shared libraries on other platforms, we can't use
+      # them.
+      ld_shlibs_GCJ=no
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       allow_undefined_flag_GCJ=unsupported
+       # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+       # support --undefined.  This deserves some investigation.  FIXME
+       archive_cmds_GCJ='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+       ld_shlibs_GCJ=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, GCJ) is actually meaningless,
+      # as there is no search path for DLLs.
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      allow_undefined_flag_GCJ=unsupported
+      always_export_symbols_GCJ=no
+      enable_shared_with_static_runtimes_GCJ=yes
+      export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+        archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+       # If the export-symbols file already is a .def file (1st line
+       # is EXPORTS), use it as is; otherwise, prepend...
+       archive_expsym_cmds_GCJ='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+         cp $export_symbols $output_objdir/$soname.def;
+       else
+         echo EXPORTS > $output_objdir/$soname.def;
+         cat $export_symbols >> $output_objdir/$soname.def;
+       fi~
+       $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+       ld_shlibs_GCJ=no
+      fi
+      ;;
+
+    interix3*)
+      hardcode_direct_GCJ=no
+      hardcode_shlibpath_var_GCJ=no
+      hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec_GCJ='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      archive_cmds_GCJ='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_expsym_cmds_GCJ='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    linux*)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       tmp_addflag=
+       case $cc_basename,$host_cpu in
+       pgcc*)                          # Portland Group C compiler
+         whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+         tmp_addflag=' $pic_flag'
+         ;;
+       pgf77* | pgf90* | pgf95*)       # Portland Group f77 and f90 compilers
+         whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive'
+         tmp_addflag=' $pic_flag -Mnomain' ;;
+       ecc*,ia64* | icc*,ia64*)                # Intel C compiler on ia64
+         tmp_addflag=' -i_dynamic' ;;
+       efc*,ia64* | ifort*,ia64*)      # Intel Fortran compiler on ia64
+         tmp_addflag=' -i_dynamic -nofor_main' ;;
+       ifc* | ifort*)                  # Intel Fortran compiler
+         tmp_addflag=' -nofor_main' ;;
+       esac
+       archive_cmds_GCJ='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+       if test $supports_anon_versioning = yes; then
+         archive_expsym_cmds_GCJ='$echo "{ global:" > $output_objdir/$libname.ver~
+  cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+  $echo "local: *; };" >> $output_objdir/$libname.ver~
+         $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+       fi
+      else
+       ld_shlibs_GCJ=no
+      fi
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+       archive_cmds_GCJ='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+       wlarc=
+      else
+       archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+       ld_shlibs_GCJ=no
+       cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+       ld_shlibs_GCJ=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+       ld_shlibs_GCJ=no
+       cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+       ;;
+       *)
+         if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+           hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
+           archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib'
+           archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib'
+         else
+           ld_shlibs_GCJ=no
+         fi
+       ;;
+      esac
+      ;;
+
+    sunos4*)
+      archive_cmds_GCJ='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      hardcode_direct_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
+       archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+       ld_shlibs_GCJ=no
+      fi
+      ;;
+    esac
+
+    if test "$ld_shlibs_GCJ" = no; then
+      runpath_var=
+      hardcode_libdir_flag_spec_GCJ=
+      export_dynamic_flag_spec_GCJ=
+      whole_archive_flag_spec_GCJ=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      allow_undefined_flag_GCJ=unsupported
+      always_export_symbols_GCJ=yes
+      archive_expsym_cmds_GCJ='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L_GCJ=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+       # Neither direct hardcoding nor static linking is supported with a
+       # broken collect2.
+       hardcode_direct_GCJ=unsupported
+      fi
+      ;;
+
+    aix4* | aix5*)
+      if test "$host_cpu" = ia64; then
+       # On IA64, the linker does run time linking by default, so we don't
+       # have to do anything special.
+       aix_use_runtimelinking=no
+       exp_sym_flag='-Bexport'
+       no_entry_flag=""
+      else
+       # If we're using GNU nm, then we don't want the "-C" option.
+       # -C means demangle to AIX nm, but means don't demangle with GNU nm
+       if $NM -V 2>&1 | grep 'GNU' > /dev/null; then
+         export_symbols_cmds_GCJ='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+       else
+         export_symbols_cmds_GCJ='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$2 == "T") || (\$2 == "D") || (\$2 == "B")) && (substr(\$3,1,1) != ".")) { print \$3 } }'\'' | sort -u > $export_symbols'
+       fi
+       aix_use_runtimelinking=no
+
+       # Test if we are trying to use run time linking or normal
+       # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+       # need to do runtime linking.
+       case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+         for ld_flag in $LDFLAGS; do
+         if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+           aix_use_runtimelinking=yes
+           break
+         fi
+         done
+         ;;
+       esac
+
+       exp_sym_flag='-bexport'
+       no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      archive_cmds_GCJ=''
+      hardcode_direct_GCJ=yes
+      hardcode_libdir_separator_GCJ=':'
+      link_all_deplibs_GCJ=yes
+
+      if test "$GCC" = yes; then
+       case $host_os in aix4.[012]|aix4.[012].*)
+       # We only want to do this on AIX 4.2 and lower, the check
+       # below for broken collect2 doesn't work under 4.3+
+         collect2name=`${CC} -print-prog-name=collect2`
+         if test -f "$collect2name" && \
+          strings "$collect2name" | grep resolve_lib_name >/dev/null
+         then
+         # We have reworked collect2
+         hardcode_direct_GCJ=yes
+         else
+         # We have old collect2
+         hardcode_direct_GCJ=unsupported
+         # It fails to find uninstalled libraries when the uninstalled
+         # path is not listed in the libpath.  Setting hardcode_minus_L
+         # to unsupported forces relinking
+         hardcode_minus_L_GCJ=yes
+         hardcode_libdir_flag_spec_GCJ='-L$libdir'
+         hardcode_libdir_separator_GCJ=
+         fi
+         ;;
+       esac
+       shared_flag='-shared'
+       if test "$aix_use_runtimelinking" = yes; then
+         shared_flag="$shared_flag "'${wl}-G'
+       fi
+      else
+       # not using gcc
+       if test "$host_cpu" = ia64; then
+       # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+       # chokes on -Wl,-G. The following line is correct:
+         shared_flag='-G'
+       else
+         if test "$aix_use_runtimelinking" = yes; then
+           shared_flag='${wl}-G'
+         else
+           shared_flag='${wl}-bM:SRE'
+         fi
+       fi
+      fi
+
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      always_export_symbols_GCJ=yes
+      if test "$aix_use_runtimelinking" = yes; then
+       # Warning - without using the other runtime loading flags (-brtl),
+       # -berok will link without error, but may produce a broken library.
+       allow_undefined_flag_GCJ='-berok'
+       # Determine the default libpath from the value encoded in an empty executable.
+       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
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; 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_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+       hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath"
+       archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+       else
+       if test "$host_cpu" = ia64; then
+         hardcode_libdir_flag_spec_GCJ='${wl}-R $libdir:/usr/lib:/lib'
+         allow_undefined_flag_GCJ="-z nodefs"
+         archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+       else
+        # Determine the default libpath from the value encoded in an empty executable.
+        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
+
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
+}'`; 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_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+        hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath"
+         # Warning - without using the other run time loading flags,
+         # -berok will link without error, but may produce a broken library.
+         no_undefined_flag_GCJ=' ${wl}-bernotok'
+         allow_undefined_flag_GCJ=' ${wl}-berok'
+         # Exported symbols can be pulled into shared objects from archives
+         whole_archive_flag_spec_GCJ='$convenience'
+         archive_cmds_need_lc_GCJ=yes
+         # This is similar to how AIX traditionally builds its shared libraries.
+         archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+       fi
+      fi
+      ;;
+
+    amigaos*)
+      archive_cmds_GCJ='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      hardcode_minus_L_GCJ=yes
+      # see comment about different semantics on the GNU ld section
+      ld_shlibs_GCJ=no
+      ;;
+
+    bsdi[45]*)
+      export_dynamic_flag_spec_GCJ=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      hardcode_libdir_flag_spec_GCJ=' '
+      allow_undefined_flag_GCJ=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      archive_cmds_GCJ='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      old_archive_From_new_cmds_GCJ='true'
+      # FIXME: Should let the user specify the lib program.
+      old_archive_cmds_GCJ='lib /OUT:$oldlib$oldobjs$old_deplibs'
+      fix_srcfile_path_GCJ='`cygpath -w "$srcfile"`'
+      enable_shared_with_static_runtimes_GCJ=yes
+      ;;
+
+    darwin* | rhapsody*)
+      case $host_os in
+        rhapsody* | darwin1.[012])
+         allow_undefined_flag_GCJ='${wl}-undefined ${wl}suppress'
+         ;;
+       *) # Darwin 1.3 on
+         if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then
+           allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+         else
+           case ${MACOSX_DEPLOYMENT_TARGET} in
+             10.[012])
+               allow_undefined_flag_GCJ='${wl}-flat_namespace ${wl}-undefined ${wl}suppress'
+               ;;
+             10.*)
+               allow_undefined_flag_GCJ='${wl}-undefined ${wl}dynamic_lookup'
+               ;;
+           esac
+         fi
+         ;;
+      esac
+      archive_cmds_need_lc_GCJ=no
+      hardcode_direct_GCJ=no
+      hardcode_automatic_GCJ=yes
+      hardcode_shlibpath_var_GCJ=unsupported
+      whole_archive_flag_spec_GCJ=''
+      link_all_deplibs_GCJ=yes
+    if test "$GCC" = yes ; then
+       output_verbose_link_cmd='echo'
+        archive_cmds_GCJ='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'
+      module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+      # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+      archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+      module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    else
+      case $cc_basename in
+        xlc*)
+         output_verbose_link_cmd='echo'
+         archive_cmds_GCJ='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring'
+         module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags'
+          # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds
+         archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[    ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag  -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}'
+          ;;
+       *)
+         ld_shlibs_GCJ=no
+          ;;
+      esac
+    fi
+      ;;
+
+    dgux*)
+      archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    freebsd1*)
+      ld_shlibs_GCJ=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      hardcode_libdir_flag_spec_GCJ='-R$libdir'
+      hardcode_direct_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct_GCJ=yes
+      hardcode_minus_L_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | kfreebsd*-gnu | dragonfly*)
+      archive_cmds_GCJ='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      hardcode_libdir_flag_spec_GCJ='-R$libdir'
+      hardcode_direct_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+       archive_cmds_GCJ='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+       archive_cmds_GCJ='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator_GCJ=:
+      hardcode_direct_GCJ=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L_GCJ=yes
+      export_dynamic_flag_spec_GCJ='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+       archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+       hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
+       hardcode_libdir_separator_GCJ=:
+
+       hardcode_direct_GCJ=yes
+       export_dynamic_flag_spec_GCJ='${wl}-E'
+
+       # hardcode_minus_L: Not really in the search PATH,
+       # but as the default location of the library.
+       hardcode_minus_L_GCJ=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+       case $host_cpu in
+       hppa*64*)
+         archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       ia64*)
+         archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       *)
+         archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       esac
+      else
+       case $host_cpu in
+       hppa*64*)
+         archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       ia64*)
+         archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       *)
+         archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+         ;;
+       esac
+      fi
+      if test "$with_gnu_ld" = no; then
+       hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir'
+       hardcode_libdir_separator_GCJ=:
+
+       case $host_cpu in
+       hppa*64*|ia64*)
+         hardcode_libdir_flag_spec_ld_GCJ='+b $libdir'
+         hardcode_direct_GCJ=no
+         hardcode_shlibpath_var_GCJ=no
+         ;;
+       *)
+         hardcode_direct_GCJ=yes
+         export_dynamic_flag_spec_GCJ='${wl}-E'
+
+         # hardcode_minus_L: Not really in the search PATH,
+         # but as the default location of the library.
+         hardcode_minus_L_GCJ=yes
+         ;;
+       esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+       archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+       archive_cmds_GCJ='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+       hardcode_libdir_flag_spec_ld_GCJ='-rpath $libdir'
+      fi
+      hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_GCJ=:
+      link_all_deplibs_GCJ=yes
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+       archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+       archive_cmds_GCJ='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      hardcode_libdir_flag_spec_GCJ='-R$libdir'
+      hardcode_direct_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    newsos6)
+      archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct_GCJ=yes
+      hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_GCJ=:
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    openbsd*)
+      hardcode_direct_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+       archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+       hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir'
+       export_dynamic_flag_spec_GCJ='${wl}-E'
+      else
+       case $host_os in
+        openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+          archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+          hardcode_libdir_flag_spec_GCJ='-R$libdir'
+          ;;
+        *)
+          archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+          hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir'
+          ;;
+       esac
+      fi
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      hardcode_minus_L_GCJ=yes
+      allow_undefined_flag_GCJ=unsupported
+      archive_cmds_GCJ='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_From_new_cmds_GCJ='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+       allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*'
+       archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+       allow_undefined_flag_GCJ=' -expect_unresolved \*'
+       archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator_GCJ=:
+      ;;
+
+    osf4* | osf5*)     # as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+       allow_undefined_flag_GCJ=' ${wl}-expect_unresolved ${wl}\*'
+       archive_cmds_GCJ='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+       hardcode_libdir_flag_spec_GCJ='${wl}-rpath ${wl}$libdir'
+      else
+       allow_undefined_flag_GCJ=' -expect_unresolved \*'
+       archive_cmds_GCJ='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+       archive_expsym_cmds_GCJ='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+       $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp'
+
+       # Both c and cxx compiler support -rpath directly
+       hardcode_libdir_flag_spec_GCJ='-rpath $libdir'
+      fi
+      hardcode_libdir_separator_GCJ=:
+      ;;
+
+    solaris*)
+      no_undefined_flag_GCJ=' -z text'
+      if test "$GCC" = yes; then
+       wlarc='${wl}'
+       archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+         $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp'
+      else
+       wlarc=''
+       archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+       archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+       $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+      fi
+      hardcode_libdir_flag_spec_GCJ='-R$libdir'
+      hardcode_shlibpath_var_GCJ=no
+      case $host_os in
+      solaris2.[0-5] | solaris2.[0-5].*) ;;
+      *)
+       # The compiler driver will combine linker options so we
+       # cannot just pass the convience library names through
+       # without $wl, iff we do not link with $LD.
+       # Luckily, gcc supports the same syntax we need for Sun Studio.
+       # Supported since Solaris 2.6 (maybe 2.5.1?)
+       case $wlarc in
+       '')
+         whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract' ;;
+       *)
+         whole_archive_flag_spec_GCJ='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;;
+       esac ;;
+      esac
+      link_all_deplibs_GCJ=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+       # Use $CC to link under sequent, because it throws in some extra .o
+       # files that make .init and .fini sections work.
+       archive_cmds_GCJ='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       archive_cmds_GCJ='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      hardcode_direct_GCJ=yes
+      hardcode_minus_L_GCJ=yes
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+       sni)
+         archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+         hardcode_direct_GCJ=yes # is this really true???
+       ;;
+       siemens)
+         ## LD is ld it makes a PLAMLIB
+         ## CC just makes a GrossModule.
+         archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+         reload_cmds_GCJ='$CC -r -o $output$reload_objs'
+         hardcode_direct_GCJ=no
+        ;;
+       motorola)
+         archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+         hardcode_direct_GCJ=no #Motorola manual says yes, but my tests say they lie
+       ;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    sysv4.3*)
+      archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var_GCJ=no
+      export_dynamic_flag_spec_GCJ='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+       archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+       hardcode_shlibpath_var_GCJ=no
+       runpath_var=LD_RUN_PATH
+       hardcode_runpath_var=yes
+       ld_shlibs_GCJ=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*)
+      no_undefined_flag_GCJ='${wl}-z,text'
+      archive_cmds_need_lc_GCJ=no
+      hardcode_shlibpath_var_GCJ=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+       archive_cmds_GCJ='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       archive_cmds_GCJ='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      no_undefined_flag_GCJ='${wl}-z,text'
+      allow_undefined_flag_GCJ='${wl}-z,nodefs'
+      archive_cmds_need_lc_GCJ=no
+      hardcode_shlibpath_var_GCJ=no
+      hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
+      hardcode_libdir_separator_GCJ=':'
+      link_all_deplibs_GCJ=yes
+      export_dynamic_flag_spec_GCJ='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+       archive_cmds_GCJ='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+       archive_cmds_GCJ='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec_GCJ='-L$libdir'
+      hardcode_shlibpath_var_GCJ=no
+      ;;
+
+    *)
+      ld_shlibs_GCJ=no
+      ;;
+    esac
+  fi
+
+echo "$as_me:$LINENO: result: $ld_shlibs_GCJ" >&5
+echo "${ECHO_T}$ld_shlibs_GCJ" >&6
+test "$ld_shlibs_GCJ" = no && can_build_shared=no
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_GCJ" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc_GCJ=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds_GCJ in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5
+echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6
+      $rm conftest*
+      printf "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      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); } 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$lt_prog_compiler_wl_GCJ
+       pic_flag=$lt_prog_compiler_pic_GCJ
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$allow_undefined_flag_GCJ
+        allow_undefined_flag_GCJ=
+        if { (eval echo "$as_me:$LINENO: \"$archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\"") >&5
+  (eval $archive_cmds_GCJ 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+        then
+         archive_cmds_need_lc_GCJ=no
+        else
+         archive_cmds_need_lc_GCJ=yes
+        fi
+        allow_undefined_flag_GCJ=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $rm conftest*
+      echo "$as_me:$LINENO: result: $archive_cmds_need_lc_GCJ" >&5
+echo "${ECHO_T}$archive_cmds_need_lc_GCJ" >&6
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+echo "$as_me:$LINENO: checking dynamic linker characteristics" >&5
+echo $ECHO_N "checking dynamic linker characteristics... $ECHO_C" >&6
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+if test "$GCC" = yes; then
+  sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix4* | aix5*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+          echo ' yes '
+          echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+       :
+      else
+       can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  library_names_spec='$libname.ixlibrary $libname.a'
+  # Create ${libname}_ixlibrary.a entries in /sys/libs.
+  finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $rm \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if echo "$sys_lib_search_path_spec" | grep ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  linux*)
+    if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      supports_anon_versioning=no
+      case `$LD -v 2>/dev/null` in
+        *\ 01.* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+        *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+        *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+        *\ 2.11.*) ;; # other 2.11 versions
+        *) supports_anon_versioning=yes ;;
+      esac
+      if test $supports_anon_versioning = yes; then
+        archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~
+cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+$echo "local: *; };" >> $output_objdir/$libname.ver~
+        $CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+      else
+        $archive_expsym_cmds="$archive_cmds"
+      fi
+    else
+      ld_shlibs=no
+    fi
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+  # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same.
+  if test "$GCC" = yes; then
+    sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"`
+  else
+    sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib'
+  fi
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+kfreebsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[123]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  # Handle Gentoo/FreeBSD as it was Linux
+  case $host_vendor in
+    gentoo)
+      version_type=linux ;;
+    *)
+      version_type=freebsd-$objformat ;;
+  esac
+
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+    linux)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+      soname_spec='${libname}${release}${shared_ext}$major'
+      need_lib_prefix=no
+      need_version=no
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  freebsd*) # from 4.6 on
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+   hppa*64*)
+     shrext_cmds='.sl'
+     hardcode_into_libs=yes
+     dynamic_linker="$host_os dld.sl"
+     shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+     shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+     library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+     soname_spec='${libname}${release}${shared_ext}$major'
+     sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+     sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+     ;;
+   *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+interix3*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+       if test "$lt_cv_prog_gnu_ld" = yes; then
+               version_type=linux
+       else
+               version_type=irix
+       fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,       ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+knetbsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='GNU ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+nto-qnx*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+    *)                         need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+       shlibpath_overrides_runpath=no
+       ;;
+      *)
+       shlibpath_overrides_runpath=yes
+       ;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      export_dynamic_flag_spec='${wl}-Blargedynsym'
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+    shlibpath_overrides_runpath=no
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    shlibpath_overrides_runpath=yes
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+       ;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+echo "$as_me:$LINENO: result: $dynamic_linker" >&5
+echo "${ECHO_T}$dynamic_linker" >&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5
+echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6
+hardcode_action_GCJ=
+if test -n "$hardcode_libdir_flag_spec_GCJ" || \
+   test -n "$runpath_var_GCJ" || \
+   test "X$hardcode_automatic_GCJ" = "Xyes" ; then
+
+  # We can hardcode non-existant directories.
+  if test "$hardcode_direct_GCJ" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, GCJ)" != no &&
+     test "$hardcode_minus_L_GCJ" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action_GCJ=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action_GCJ=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action_GCJ=unsupported
+fi
+echo "$as_me:$LINENO: result: $hardcode_action_GCJ" >&5
+echo "${ECHO_T}$hardcode_action_GCJ" >&6
+
+if test "$hardcode_action_GCJ" = relink; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+
+# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    compiler_GCJ \
+    CC_GCJ \
+    LD_GCJ \
+    lt_prog_compiler_wl_GCJ \
+    lt_prog_compiler_pic_GCJ \
+    lt_prog_compiler_static_GCJ \
+    lt_prog_compiler_no_builtin_flag_GCJ \
+    export_dynamic_flag_spec_GCJ \
+    thread_safe_flag_spec_GCJ \
+    whole_archive_flag_spec_GCJ \
+    enable_shared_with_static_runtimes_GCJ \
+    old_archive_cmds_GCJ \
+    old_archive_from_new_cmds_GCJ \
+    predep_objects_GCJ \
+    postdep_objects_GCJ \
+    predeps_GCJ \
+    postdeps_GCJ \
+    compiler_lib_search_path_GCJ \
+    archive_cmds_GCJ \
+    archive_expsym_cmds_GCJ \
+    postinstall_cmds_GCJ \
+    postuninstall_cmds_GCJ \
+    old_archive_from_expsyms_cmds_GCJ \
+    allow_undefined_flag_GCJ \
+    no_undefined_flag_GCJ \
+    export_symbols_cmds_GCJ \
+    hardcode_libdir_flag_spec_GCJ \
+    hardcode_libdir_flag_spec_ld_GCJ \
+    hardcode_libdir_separator_GCJ \
+    hardcode_automatic_GCJ \
+    module_cmds_GCJ \
+    module_expsym_cmds_GCJ \
+    lt_cv_prog_compiler_c_o_GCJ \
+    exclude_expsyms_GCJ \
+    include_expsyms_GCJ; do
+
+    case $var in
+    old_archive_cmds_GCJ | \
+    old_archive_from_new_cmds_GCJ | \
+    archive_cmds_GCJ | \
+    archive_expsym_cmds_GCJ | \
+    module_cmds_GCJ | \
+    module_expsym_cmds_GCJ | \
+    old_archive_from_expsyms_cmds_GCJ | \
+    export_symbols_cmds_GCJ | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\$0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+cfgfile="$ofile"
+
+  cat <<__EOF__ >> "$cfgfile"
+# ### BEGIN LIBTOOL TAG CONFIG: $tagname
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_GCJ
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_GCJ
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
+# A language-specific compiler.
+CC=$lt_compiler_GCJ
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC_GCJ
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_LD_GCJ
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_GCJ
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_GCJ
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_GCJ
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_GCJ
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_GCJ
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_GCJ
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_GCJ
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec_GCJ
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds_GCJ
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_GCJ
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_GCJ
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds_GCJ
+archive_expsym_cmds=$lt_archive_expsym_cmds_GCJ
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_module_cmds_GCJ
+module_expsym_cmds=$lt_module_expsym_cmds_GCJ
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_predep_objects_GCJ
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_postdep_objects_GCJ
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_predeps_GCJ
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_postdeps_GCJ
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_GCJ
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_GCJ
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_GCJ
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_GCJ
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_GCJ
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_GCJ
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_GCJ
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct_GCJ
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L_GCJ
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_GCJ
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$hardcode_automatic_GCJ
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_GCJ
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path_GCJ"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols_GCJ
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_GCJ
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_GCJ
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_GCJ
+
+# ### END LIBTOOL TAG CONFIG: $tagname
+
+__EOF__
+
+
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+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
+
+CC="$lt_save_CC"
+
+       else
+         tagname=""
+       fi
+       ;;
+
+      RC)
+
+
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+objext_RC=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$rm conftest*
+
+ac_outfile=conftest.$ac_objext
+printf "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$rm conftest*
+
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+CC=${RC-"windres"}
+compiler=$CC
+compiler_RC=$CC
+for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+lt_cv_prog_compiler_c_o_RC=yes
+
+# The else clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+  # See if we are running on zsh, and set the options which allow our commands through
+  # without removal of \ escapes.
+  if test -n "${ZSH_VERSION+set}" ; then
+    setopt NO_GLOB_SUBST
+  fi
+  # Now quote all the things that may contain metacharacters while being
+  # careful not to overquote the AC_SUBSTed values.  We take copies of the
+  # variables and quote the copies for generation of the libtool script.
+  for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \
+    SED SHELL STRIP \
+    libname_spec library_names_spec soname_spec extract_expsyms_cmds \
+    old_striplib striplib file_magic_cmd finish_cmds finish_eval \
+    deplibs_check_method reload_flag reload_cmds need_locks \
+    lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \
+    lt_cv_sys_global_symbol_to_c_name_address \
+    sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+    old_postinstall_cmds old_postuninstall_cmds \
+    compiler_RC \
+    CC_RC \
+    LD_RC \
+    lt_prog_compiler_wl_RC \
+    lt_prog_compiler_pic_RC \
+    lt_prog_compiler_static_RC \
+    lt_prog_compiler_no_builtin_flag_RC \
+    export_dynamic_flag_spec_RC \
+    thread_safe_flag_spec_RC \
+    whole_archive_flag_spec_RC \
+    enable_shared_with_static_runtimes_RC \
+    old_archive_cmds_RC \
+    old_archive_from_new_cmds_RC \
+    predep_objects_RC \
+    postdep_objects_RC \
+    predeps_RC \
+    postdeps_RC \
+    compiler_lib_search_path_RC \
+    archive_cmds_RC \
+    archive_expsym_cmds_RC \
+    postinstall_cmds_RC \
+    postuninstall_cmds_RC \
+    old_archive_from_expsyms_cmds_RC \
+    allow_undefined_flag_RC \
+    no_undefined_flag_RC \
+    export_symbols_cmds_RC \
+    hardcode_libdir_flag_spec_RC \
+    hardcode_libdir_flag_spec_ld_RC \
+    hardcode_libdir_separator_RC \
+    hardcode_automatic_RC \
+    module_cmds_RC \
+    module_expsym_cmds_RC \
+    lt_cv_prog_compiler_c_o_RC \
+    exclude_expsyms_RC \
+    include_expsyms_RC; do
+
+    case $var in
+    old_archive_cmds_RC | \
+    old_archive_from_new_cmds_RC | \
+    archive_cmds_RC | \
+    archive_expsym_cmds_RC | \
+    module_cmds_RC | \
+    module_expsym_cmds_RC | \
+    old_archive_from_expsyms_cmds_RC | \
+    export_symbols_cmds_RC | \
+    extract_expsyms_cmds | reload_cmds | finish_cmds | \
+    postinstall_cmds | postuninstall_cmds | \
+    old_postinstall_cmds | old_postuninstall_cmds | \
+    sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+      # Double-quote double-evaled strings.
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+      ;;
+    *)
+      eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+      ;;
+    esac
+  done
+
+  case $lt_echo in
+  *'\$0 --fallback-echo"')
+    lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+    ;;
+  esac
+
+cfgfile="$ofile"
+
+  cat <<__EOF__ >> "$cfgfile"
+# ### BEGIN LIBTOOL TAG CONFIG: $tagname
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_RC
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_RC
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A C compiler.
+LTCC=$lt_LTCC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_LTCFLAGS
+
+# A language-specific compiler.
+CC=$lt_compiler_RC
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC_RC
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# The linker used to build libraries.
+LD=$lt_LD_RC
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$lt_STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_RC
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='$shrext_cmds'
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_RC
+pic_mode=$pic_mode
+
+# What is the maximum length of a command?
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_RC
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_RC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_RC
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_RC
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_RC
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec_RC
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds_RC
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_RC
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_RC
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds_RC
+archive_expsym_cmds=$lt_archive_expsym_cmds_RC
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=$lt_module_cmds_RC
+module_expsym_cmds=$lt_module_expsym_cmds_RC
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=$lt_predep_objects_RC
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=$lt_postdep_objects_RC
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=$lt_predeps_RC
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=$lt_postdeps_RC
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_RC
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_RC
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_RC
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_RC
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC
+
+# If ld is used when linking, flag to hardcode \$libdir into
+# a binary during linking. This must work even if \$libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_RC
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_RC
+
+# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct_RC
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L_RC
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_RC
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=$hardcode_automatic_RC
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_RC
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path_RC"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols_RC
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_RC
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_RC
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_RC
+
+# ### END LIBTOOL TAG CONFIG: $tagname
+
+__EOF__
+
+
+else
+  # If there is no Makefile yet, we rely on a make rule to execute
+  # `config.status --recheck' to rerun these tests and create the
+  # libtool script then.
+  ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'`
+  if test -f "$ltmain_in"; then
+    test -f Makefile && make "$ltmain"
+  fi
+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
+
+CC="$lt_save_CC"
+
+       ;;
+
+      *)
+       { { echo "$as_me:$LINENO: error: Unsupported tag name: $tagname" >&5
+echo "$as_me: error: Unsupported tag name: $tagname" >&2;}
+   { (exit 1); exit 1; }; }
+       ;;
+      esac
+
+      # Append the new tag name to the list of available tags.
+      if test -n "$tagname" ; then
+      available_tags="$available_tags $tagname"
+    fi
+    fi
+  done
+  IFS="$lt_save_ifs"
+
+  # Now substitute the updated list of available tags.
+  if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then
+    mv "${ofile}T" "$ofile"
+    chmod +x "$ofile"
+  else
+    rm -f "${ofile}T"
+    { { echo "$as_me:$LINENO: error: unable to update list of available tagged configurations." >&5
+echo "$as_me: error: unable to update list of available tagged configurations." >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+fi
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Prevent multiple expansion
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# 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
+
+# Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; 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_AR+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $AR in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_AR="$AR" # 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_AR="$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_AR" && ac_cv_path_AR="no"
+  ;;
+esac
+fi
+AR=$ac_cv_path_AR
+
+if test -n "$AR"; then
+  echo "$as_me:$LINENO: result: $AR" >&5
+echo "${ECHO_T}$AR" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+if [ $AR = "no" ] ; then
+    { { echo "$as_me:$LINENO: error: \"Could not find ar - needed to create a library\"" >&5
+echo "$as_me: error: \"Could not find ar - needed to create a library\"" >&2;}
+   { (exit 1); exit 1; }; };
+fi
+
+echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
+echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
+if test "${ac_cv_c_bigendian+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # See if sys/param.h defines the BYTE_ORDER macro.
+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>
+
+int
+main ()
+{
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#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
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+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>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#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_c_bigendian=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_bigendian=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+# It does not; compile a test program.
+if test "$cross_compiling" = yes; then
+  # try to guess the endianness by grepping values into an object file
+  ac_cv_c_bigendian=unknown
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
+short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
+int
+main ()
+{
+ _ascii (); _ebcdic ();
+  ;
+  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
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
+  ac_cv_c_bigendian=yes
+fi
+if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+  if test "$ac_cv_c_bigendian" = unknown; then
+    ac_cv_c_bigendian=no
+  else
+    # finding both strings is unlikely to happen, but who knows?
+    ac_cv_c_bigendian=unknown
+  fi
+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
+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 ()
+{
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+  u.l = 1;
+  exit (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
+  ac_cv_c_bigendian=no
+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_bigendian=yes
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
+echo "${ECHO_T}$ac_cv_c_bigendian" >&6
+case $ac_cv_c_bigendian in
+  yes)
+
+cat >>confdefs.h <<\_ACEOF
+#define WORDS_BIGENDIAN 1
+_ACEOF
+ ;;
+  no)
+     ;;
+  *)
+    { { echo "$as_me:$LINENO: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&5
+echo "$as_me: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+
+
+
+echo "$as_me:$LINENO: checking for snd_pcm_open in -lasound" >&5
+echo $ECHO_N "checking for snd_pcm_open in -lasound... $ECHO_C" >&6
+if test "${ac_cv_lib_asound_snd_pcm_open+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lasound  $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 snd_pcm_open ();
+int
+main ()
+{
+snd_pcm_open ();
+  ;
+  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_asound_snd_pcm_open=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_asound_snd_pcm_open=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_asound_snd_pcm_open" >&5
+echo "${ECHO_T}$ac_cv_lib_asound_snd_pcm_open" >&6
+if test $ac_cv_lib_asound_snd_pcm_open = yes; then
+  have_alsa=yes
+else
+  have_alsa=no
+fi
+
+
+
+
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+       if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}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
+
+  ;;
+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 -z "$ac_cv_path_PKG_CONFIG"; then
+  ac_pt_PKG_CONFIG=$PKG_CONFIG
+  # 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_ac_pt_PKG_CONFIG+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $ac_pt_PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_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_ac_pt_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
+
+  ;;
+esac
+fi
+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
+
+if test -n "$ac_pt_PKG_CONFIG"; then
+  echo "$as_me:$LINENO: result: $ac_pt_PKG_CONFIG" >&5
+echo "${ECHO_T}$ac_pt_PKG_CONFIG" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  PKG_CONFIG=$ac_pt_PKG_CONFIG
+else
+  PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
+fi
+
+fi
+if test -n "$PKG_CONFIG"; then
+       _pkg_min_version=0.9.0
+       echo "$as_me:$LINENO: checking pkg-config is at least version $_pkg_min_version" >&5
+echo $ECHO_N "checking pkg-config is at least version $_pkg_min_version... $ECHO_C" >&6
+       if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+               echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+       else
+               echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+               PKG_CONFIG=""
+       fi
+
+fi
+
+pkg_failed=no
+echo "$as_me:$LINENO: checking for JACK" >&5
+echo $ECHO_N "checking for JACK... $ECHO_C" >&6
+
+if test -n "$PKG_CONFIG"; then
+    if test -n "$JACK_CFLAGS"; then
+        pkg_cv_JACK_CFLAGS="$JACK_CFLAGS"
+    else
+        if test -n "$PKG_CONFIG" && \
+    { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"jack\"") >&5
+  ($PKG_CONFIG --exists --print-errors "jack") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  pkg_cv_JACK_CFLAGS=`$PKG_CONFIG --cflags "jack" 2>/dev/null`
+else
+  pkg_failed=yes
+fi
+    fi
+else
+       pkg_failed=untried
+fi
+if test -n "$PKG_CONFIG"; then
+    if test -n "$JACK_LIBS"; then
+        pkg_cv_JACK_LIBS="$JACK_LIBS"
+    else
+        if test -n "$PKG_CONFIG" && \
+    { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"jack\"") >&5
+  ($PKG_CONFIG --exists --print-errors "jack") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  pkg_cv_JACK_LIBS=`$PKG_CONFIG --libs "jack" 2>/dev/null`
+else
+  pkg_failed=yes
+fi
+    fi
+else
+       pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+               JACK_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "jack"`
+        else
+               JACK_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "jack"`
+        fi
+       # Put the nasty error message in config.log where it belongs
+       echo "$JACK_PKG_ERRORS" >&5
+
+       have_jack=no
+elif test $pkg_failed = untried; then
+       have_jack=no
+else
+       JACK_CFLAGS=$pkg_cv_JACK_CFLAGS
+       JACK_LIBS=$pkg_cv_JACK_LIBS
+        echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+       have_jack=yes
+fi
+
+
+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
+
+
+
+save_LIBS="${LIBS}"
+echo "$as_me:$LINENO: checking for clock_gettime in -lrt" >&5
+echo $ECHO_N "checking for clock_gettime in -lrt... $ECHO_C" >&6
+if test "${ac_cv_lib_rt_clock_gettime+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrt  $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 clock_gettime ();
+int
+main ()
+{
+clock_gettime ();
+  ;
+  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_rt_clock_gettime=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_rt_clock_gettime=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_rt_clock_gettime" >&5
+echo "${ECHO_T}$ac_cv_lib_rt_clock_gettime" >&6
+if test $ac_cv_lib_rt_clock_gettime = yes; then
+  rt_libs=" -lrt"
+fi
+
+LIBS="${LIBS}${rt_libs}"
+DLL_LIBS="${DLL_LIBS}${rt_libs}"
+
+
+for ac_func in clock_gettime nanosleep
+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
+
+LIBS="${save_LIBS}"
+
+LT_CURRENT=2
+LT_REVISION=0
+LT_AGE=0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+CFLAGS=${CFLAGS:-"-g -O2 -Wall -pedantic -pipe -fPIC"}
+
+if [ $ac_cv_c_bigendian = "yes" ] ; then
+   CFLAGS="$CFLAGS -DPA_BIG_ENDIAN"
+else
+   CFLAGS="$CFLAGS -DPA_LITTLE_ENDIAN"
+fi
+
+case "${host_os}" in
+  darwin* )
+
+       cat >>confdefs.h <<\_ACEOF
+#define PA_USE_COREAUDIO 1
+_ACEOF
+
+       OTHER_OBJS="src/os/mac_osx/pa_mac_hostapis.o src/os/unix/pa_unix_util.o src/hostapi/coreaudio/pa_mac_core.o src/hostapi/coreaudio/ringbuffer.o src/hostapi/coreaudio/pa_mac_core_utilities.o src/hostapi/coreaudio/pa_mac_core_blocking.o";
+       LIBS="-framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon";
+       PADLL="libportaudio.dylib";
+       SHARED_FLAGS="-framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon -dynamiclib";
+        if [ $with_macapi = "asio" ] ; then
+            if [ $with_asiodir ] ; then
+              ASIODIR="$with_asiodir";
+            else
+              ASIODIR="/usr/local/asiosdk2";
+            fi
+            echo "ASIODIR: $ASIODIR";
+
+            OTHER_OBJS="$CFLAGS pa_asio/iasiothiscallresolver.o $ASIODIR/host/asiodrivers.o $ASIODIR/common/asio.o $ASIODIR/host/mac/asioshlib.o";
+            CFLAGS="$CFLAGS -I\$(top_srcdir)/pa_asio -I$ASIDIR/host/mac -I$ASIODIR/common";
+            CXXFLAGS="$CFLAGS";
+        fi
+       ;;
+
+  mingw* )
+
+        echo "WINAPI: $with_winapi"
+        if [ $with_winapi = "directx" ] ; then
+            if [ $with_dxdir ] ; then
+              DXDIR="$with_dxdir";
+            else
+              DXDIR="/usr/local/dx7sdk";
+            fi
+            echo "DXDIR: $DXDIR"
+            OTHER_OBJS="src/hostapi/dsound/pa_win_ds.o src/hostapi/dsound/dsound_wrapper.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o";
+            LIBS="-lwinmm -lm -ldsound -lole32";
+            PADLL="portaudio.dll";
+           THREAD_CFLAGS="-mthreads"
+            SHARED_FLAGS="-shared";
+            DLL_LIBS="${DLL_LIBS} -lwinmm -lm -L./dx7sdk/lib -ldsound -lole32";
+            #VC98="\"/c/Program Files/Microsoft Visual Studio/VC98/Include\"";
+            #CFLAGS="$CFLAGS -I$VC98 -DPA_NO_WMME -DPA_NO_ASIO";
+            CFLAGS="$CFLAGS -I\$(top_srcdir)/include -I$DXDIR/include -DPA_NO_WMME -DPA_NO_ASIO" -DPA_NO_WDMKS;
+        elif [ $with_winapi = "asio" ] ; then
+            if [ $with_asiodir ] ; then
+              ASIODIR="$with_asiodir";
+            else
+              ASIODIR="/usr/local/asiosdk2";
+            fi
+            echo "ASIODIR: $ASIODIR"
+
+            OTHER_OBJS="pa_asio/pa_asio.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o pa_asio/iasiothiscallresolver.o $ASIODIR/common/asio.o $ASIODIR/host/asiodrivers.o $ASIODIR/host/pc/asiolist.o";
+            LIBS="-lwinmm -lm -lstdc++ -lole32 -luuid";
+            PADLL="portaudio.dll";
+           THREAD_CFLAGS="-mthreads"
+            SHARED_FLAGS="-shared";
+            DLL_LIBS="${DLL_LIBS} -lwinmm -lm -lstdc++ -lole32 -luuid";
+            CFLAGS="$CFLAGS -ffast-math -fomit-frame-pointer -I\$(top_srcdir)/src/common -I\$(top_srcdir)/pa_asio -I$ASIODIR/host/pc -I$ASIODIR/common -I$ASIODIR/host -DPA_NO_WMME -DPA_NO_DS -DPA_NO_WDMKS -DWINDOWS";
+            CXXFLAGS="$CFLAGS";
+        elif [ $with_winapi = "wdmks" ] ; then
+            if [ $with_dxdir ] ; then
+              DXDIR="$with_dxdir";
+            else
+              DXDIR="/usr/local/dx7sdk";
+            fi
+            echo "DXDIR: $DXDIR"
+            OTHER_OBJS="src/hostapi/wdmks/pa_win_wdmks.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o";
+            LIBS="-lwinmm -lm -luuid -lsetupapi -lole32";
+            PADLL="portaudio.dll";
+           THREAD_CFLAGS="-mthreads"
+            SHARED_FLAGS="-shared";
+            DLL_LIBS="${DLL_LIBS} -lwinmm -lm -L./dx7sdk/lib -luuid -lsetupapi -lole32";
+            #VC98="\"/c/Program Files/Microsoft Visual Studio/VC98/Include\"";
+            #CFLAGS="$CFLAGS -I$VC98 -DPA_NO_WMME -DPA_NO_ASIO";
+            CFLAGS="$CFLAGS -I\$(top_srcdir)/src/common -I$DXDIR/include -DPA_NO_WMME -DPA_NO_DS -DPA_NO_ASIO";
+        else   # WMME default
+            OTHER_OBJS="src/hostapi/wmme/pa_win_wmme.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o";
+            LIBS="-lwinmm -lm -lstdc++ -lole32 -luuid";
+            PADLL="portaudio.dll";
+           THREAD_CFLAGS="-mthreads"
+            SHARED_FLAGS="-shared";
+            DLL_LIBS="${DLL_LIBS} -lwinmm";
+            CFLAGS="$CFLAGS -I\$(top_srcdir)/src/common -DPA_NO_DS -DPA_NO_ASIO -DPA_NO_WDMKS";
+        fi
+        ;;
+
+  cygwin* )
+
+       OTHER_OBJS="src/hostapi/wmme/pa_win_wmme.o";
+       LIBS="-lwinmm -lm";
+       PADLL="portaudio.dll";
+       THREAD_CFLAGS="-mthreads"
+       SHARED_FLAGS="-shared";
+       DLL_LIBS="${DLL_LIBS} -lwinmm";
+       ;;
+
+  irix* )
+
+echo "$as_me:$LINENO: checking for pthread_create in -lpthread" >&5
+echo $ECHO_N "checking for pthread_create in -lpthread... $ECHO_C" >&6
+if test "${ac_cv_lib_pthread_pthread_create+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread  $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 pthread_create ();
+int
+main ()
+{
+pthread_create ();
+  ;
+  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_pthread_pthread_create=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_pthread_pthread_create=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_pthread_pthread_create" >&5
+echo "${ECHO_T}$ac_cv_lib_pthread_pthread_create" >&6
+if test $ac_cv_lib_pthread_pthread_create = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBPTHREAD 1
+_ACEOF
+
+  LIBS="-lpthread $LIBS"
+
+else
+  { { echo "$as_me:$LINENO: error: IRIX posix thread library not found!" >&5
+echo "$as_me: error: IRIX posix thread library not found!" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+echo "$as_me:$LINENO: checking for alOpenPort in -laudio" >&5
+echo $ECHO_N "checking for alOpenPort in -laudio... $ECHO_C" >&6
+if test "${ac_cv_lib_audio_alOpenPort+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-laudio  $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 alOpenPort ();
+int
+main ()
+{
+alOpenPort ();
+  ;
+  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_audio_alOpenPort=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_audio_alOpenPort=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_audio_alOpenPort" >&5
+echo "${ECHO_T}$ac_cv_lib_audio_alOpenPort" >&6
+if test $ac_cv_lib_audio_alOpenPort = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBAUDIO 1
+_ACEOF
+
+  LIBS="-laudio $LIBS"
+
+else
+  { { echo "$as_me:$LINENO: error: IRIX audio library not found!" >&5
+echo "$as_me: error: IRIX audio library not found!" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+echo "$as_me:$LINENO: checking for dmGetUST in -ldmedia" >&5
+echo $ECHO_N "checking for dmGetUST in -ldmedia... $ECHO_C" >&6
+if test "${ac_cv_lib_dmedia_dmGetUST+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldmedia  $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 dmGetUST ();
+int
+main ()
+{
+dmGetUST ();
+  ;
+  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_dmedia_dmGetUST=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_dmedia_dmGetUST=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_dmedia_dmGetUST" >&5
+echo "${ECHO_T}$ac_cv_lib_dmedia_dmGetUST" >&6
+if test $ac_cv_lib_dmedia_dmGetUST = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBDMEDIA 1
+_ACEOF
+
+  LIBS="-ldmedia $LIBS"
+
+else
+  { { echo "$as_me:$LINENO: error: IRIX digital media library not found!" >&5
+echo "$as_me: error: IRIX digital media library not found!" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+                               cat >>confdefs.h <<\_ACEOF
+#define PA_USE_SGI 1
+_ACEOF
+
+
+                       THREAD_CFLAGS="-D_REENTRANT"
+
+       OTHER_OBJS="pa_sgi/pa_sgi.o src/os/unix/pa_unix_hostapis.o src/os/unix/pa_unix_util.o";
+
+                       LIBS="-lm -ldmedia -laudio -lpthread";
+       PADLL="libportaudio.so";
+       SHARED_FLAGS="";
+       ;;
+
+  *)
+
+   echo "$as_me:$LINENO: checking for pthread_create in -lpthread" >&5
+echo $ECHO_N "checking for pthread_create in -lpthread... $ECHO_C" >&6
+if test "${ac_cv_lib_pthread_pthread_create+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread  $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 pthread_create ();
+int
+main ()
+{
+pthread_create ();
+  ;
+  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_pthread_pthread_create=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_pthread_pthread_create=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_pthread_pthread_create" >&5
+echo "${ECHO_T}$ac_cv_lib_pthread_pthread_create" >&6
+if test $ac_cv_lib_pthread_pthread_create = yes; then
+  have_pthread="yes"
+
+else
+  { { echo "$as_me:$LINENO: error: libpthread not found!" >&5
+echo "$as_me: error: libpthread not found!" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+       if [ $have_alsa = "yes" ] && [ $with_alsa != "no" ] ; then
+               DLL_LIBS="$DLL_LIBS -lasound"
+               OTHER_OBJS="$OTHER_OBJS src/hostapi/alsa/pa_linux_alsa.o"
+                cat >>confdefs.h <<\_ACEOF
+#define PA_USE_ALSA 1
+_ACEOF
+
+       fi
+
+       if [ $have_jack = "yes" ] && [ $with_jack != "no" ] ; then
+               DLL_LIBS="$DLL_LIBS $JACK_LIBS"
+               CFLAGS="$CFLAGS $JACK_CFLAGS"
+               OTHER_OBJS="$OTHER_OBJS src/hostapi/jack/pa_jack.o"
+                cat >>confdefs.h <<\_ACEOF
+#define PA_USE_JACK 1
+_ACEOF
+
+       fi
+
+       if [ $with_oss != "no" ] ; then
+               OTHER_OBJS="$OTHER_OBJS src/hostapi/oss/pa_unix_oss.o"
+               cat >>confdefs.h <<\_ACEOF
+#define PA_USE_OSS 1
+_ACEOF
+
+       fi
+       THREAD_CFLAGS="-pthread"
+       DLL_LIBS="$DLL_LIBS -lm -lpthread";
+       LIBS="$LIBS -lm -lpthread";
+       PADLL="libportaudio.so";
+       SHARED_FLAGS="-shared -fPIC";
+
+        OTHER_OBJS="$OTHER_OBJS src/os/unix/pa_unix_hostapis.o src/os/unix/pa_unix_util.o"
+esac
+CFLAGS="$CFLAGS $THREAD_CFLAGS"
+
+                    ac_config_files="$ac_config_files Makefile portaudio-2.0.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
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then we branch to the quote section.  Otherwise,
+# look for a macro that doesn't take arguments.
+cat >confdef2opt.sed <<\_ACEOF
+t clear
+: clear
+s,^[    ]*#[    ]*define[       ][      ]*\([^  (][^    (]*([^)]*)\)[   ]*\(.*\),-D\1=\2,g
+t quote
+s,^[    ]*#[    ]*define[       ][      ]*\([^  ][^     ]*\)[   ]*\(.*\),-D\1=\2,g
+t quote
+d
+: quote
+s,[     `~#$^&*(){}\\|;'"<>?],\\&,g
+s,\[,\\&,g
+s,\],\\&,g
+s,\$,$$,g
+p
+_ACEOF
+# We use echo to avoid assuming a particular line-breaking character.
+# The extra dot is to prevent the shell from consuming trailing
+# line-breaks from the sub-command output.  A line-break within
+# single-quotes doesn't work because, if this script is created in a
+# platform that uses two characters for line-breaks (e.g., DOS), tr
+# would break.
+ac_LF_and_DOT=`echo; echo .`
+DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
+rm -f confdef2opt.sed
+
+
+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 $as_me, 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
+
+Configuration files:
+$config_files
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+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.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "portaudio-2.0.pc" ) CONFIG_FILES="$CONFIG_FILES portaudio-2.0.pc" ;;
+  *) { { 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
+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,@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,@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,@EGREP@,$EGREP,;t t
+s,@LN_S@,$LN_S,;t t
+s,@ECHO@,$ECHO,;t t
+s,@AR@,$AR,;t t
+s,@ac_ct_AR@,$ac_ct_AR,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@STRIP@,$STRIP,;t t
+s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t
+s,@DLLTOOL@,$DLLTOOL,;t t
+s,@ac_ct_DLLTOOL@,$ac_ct_DLLTOOL,;t t
+s,@AS@,$AS,;t t
+s,@ac_ct_AS@,$ac_ct_AS,;t t
+s,@OBJDUMP@,$OBJDUMP,;t t
+s,@ac_ct_OBJDUMP@,$ac_ct_OBJDUMP,;t t
+s,@CPP@,$CPP,;t t
+s,@CXX@,$CXX,;t t
+s,@CXXFLAGS@,$CXXFLAGS,;t t
+s,@ac_ct_CXX@,$ac_ct_CXX,;t t
+s,@CXXCPP@,$CXXCPP,;t t
+s,@F77@,$F77,;t t
+s,@FFLAGS@,$FFLAGS,;t t
+s,@ac_ct_F77@,$ac_ct_F77,;t t
+s,@LIBTOOL@,$LIBTOOL,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@PKG_CONFIG@,$PKG_CONFIG,;t t
+s,@ac_pt_PKG_CONFIG@,$ac_pt_PKG_CONFIG,;t t
+s,@JACK_CFLAGS@,$JACK_CFLAGS,;t t
+s,@JACK_LIBS@,$JACK_LIBS,;t t
+s,@LT_CURRENT@,$LT_CURRENT,;t t
+s,@LT_REVISION@,$LT_REVISION,;t t
+s,@LT_AGE@,$LT_AGE,;t t
+s,@OTHER_OBJS@,$OTHER_OBJS,;t t
+s,@PADLL@,$PADLL,;t t
+s,@SHARED_FLAGS@,$SHARED_FLAGS,;t t
+s,@THREAD_CFLAGS@,$THREAD_CFLAGS,;t t
+s,@DLL_LIBS@,$DLL_LIBS,;t t
+s,@NASM@,$NASM,;t t
+s,@NASMOPT@,$NASMOPT,;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
+
+{ (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
+
diff --git a/utils/iaxclient/lib/portaudio/configure.in b/utils/iaxclient/lib/portaudio/configure.in
new file mode 100644 (file)
index 0000000..42056ba
--- /dev/null
@@ -0,0 +1,282 @@
+dnl
+dnl portaudio V19 configure.in script
+dnl
+dnl Dominic Mazzoni, Arve Knudsen
+dnl
+
+dnl Require autoconf >= 2.13
+AC_PREREQ(2.13)
+
+dnl Init autoconf and make sure configure is being called
+dnl from the right directory
+AC_INIT([include/portaudio.h])
+
+dnl Specify options
+
+AC_ARG_WITH(alsa, 
+            [  --with-alsa (default=yes)],
+            with_alsa=$withval, with_alsa="yes")
+
+AC_ARG_WITH(jack, 
+            [  --with-jack (default=yes)],
+            with_jack=$withval, with_jack="yes")
+
+AC_ARG_WITH(oss, 
+            [  --with-oss (default=yes)],
+            with_oss=$withval, with_oss="yes")
+
+AC_ARG_WITH(host_os, 
+            [  --with-host_os (no default)],
+            host_os=$withval)
+
+AC_ARG_WITH(winapi,
+            [  --with-winapi ((wmme/directx/asio) default=wmme)],
+            with_winapi=$withval, with_winapi="wmme")
+
+dnl Mac API added for ASIO, can have other api's listed
+AC_ARG_WITH(macapi,
+            [  --with-macapi ((asio/core/sm) default=core)],
+            with_macapi=$withval, with_macapi="core")
+
+AC_ARG_WITH(asiodir,
+            [  --with-asiodir (default=/usr/local/asiosdk2)],
+            with_asiodir=$withval, with_asiodir="/usr/local/asiosdk2")
+
+AC_ARG_WITH(dxdir,
+            [  --with-dxdir (default=/usr/local/dx7sdk)],
+            with_dxdir=$withval, with_dxdir="/usr/local/dx7sdk")
+
+AC_ARG_ENABLE(debug-output,
+       [  --enable-debug-output],
+        [if test x$enableval != xno ; then
+            AC_DEFINE(PA_ENABLE_DEBUG_OUTPUT,,[Enable debugging messages])
+          fi
+        ])
+
+dnl Checks for programs.
+
+AC_PROG_CC
+AC_LIBTOOL_WIN32_DLL
+AC_PROG_LIBTOOL
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PATH_PROG(AR, ar, no)
+if [[ $AR = "no" ]] ; then
+    AC_MSG_ERROR("Could not find ar - needed to create a library");
+fi
+
+dnl This must be one of the first tests we do or it will fail...
+AC_C_BIGENDIAN
+
+dnl checks for various host APIs and arguments to configure that
+dnl turn them on or off
+
+AC_CHECK_LIB(asound, snd_pcm_open, have_alsa=yes, have_alsa=no)
+
+dnl Determine the host description for the subsequent test.
+dnl PKG_CHECK_MODULES seems to check and set the host variable also, but
+dnl that then requires pkg-config availability which is not standard on
+dnl MinGW systems and can be a pain to install.
+dnl AC_CANONICAL_HOST
+
+PKG_CHECK_MODULES(JACK, jack, have_jack=yes, have_jack=no)
+
+dnl sizeof checks: we will need a 16-bit and a 32-bit type
+
+AC_CHECK_SIZEOF(short)
+AC_CHECK_SIZEOF(int)
+AC_CHECK_SIZEOF(long)
+
+save_LIBS="${LIBS}"
+AC_CHECK_LIB(rt, clock_gettime, [rt_libs=" -lrt"])
+LIBS="${LIBS}${rt_libs}"
+DLL_LIBS="${DLL_LIBS}${rt_libs}"
+AC_CHECK_FUNCS([clock_gettime nanosleep])
+LIBS="${save_LIBS}"
+
+dnl LT_RELEASE=19
+LT_CURRENT=2
+LT_REVISION=0
+LT_AGE=0
+
+dnl AC_SUBST(LT_RELEASE)
+AC_SUBST(LT_CURRENT)
+AC_SUBST(LT_REVISION)
+AC_SUBST(LT_AGE)
+
+dnl extra variables
+AC_SUBST(OTHER_OBJS)
+AC_SUBST(PADLL)
+AC_SUBST(SHARED_FLAGS)
+AC_SUBST(THREAD_CFLAGS)
+AC_SUBST(DLL_LIBS)
+AC_SUBST(CXXFLAGS)
+AC_SUBST(NASM)
+AC_SUBST(NASMOPT)
+
+CFLAGS=${CFLAGS:-"-g -O2 -Wall -pedantic -pipe -fPIC"}
+
+if [[ $ac_cv_c_bigendian = "yes" ]] ; then
+   CFLAGS="$CFLAGS -DPA_BIG_ENDIAN"
+else
+   CFLAGS="$CFLAGS -DPA_LITTLE_ENDIAN"
+fi
+
+case "${host_os}" in
+  darwin* )
+       dnl Mac OS X configuration
+
+       AC_DEFINE(PA_USE_COREAUDIO)
+       OTHER_OBJS="src/os/mac_osx/pa_mac_hostapis.o src/os/unix/pa_unix_util.o src/hostapi/coreaudio/pa_mac_core.o src/hostapi/coreaudio/ringbuffer.o src/hostapi/coreaudio/pa_mac_core_utilities.o src/hostapi/coreaudio/pa_mac_core_blocking.o";
+       LIBS="-framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon";
+       PADLL="libportaudio.dylib";
+       SHARED_FLAGS="-framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework Carbon -dynamiclib";
+        if [[ $with_macapi = "asio" ]] ; then
+            if [[ $with_asiodir ]] ; then
+              ASIODIR="$with_asiodir";
+            else
+              ASIODIR="/usr/local/asiosdk2";
+            fi
+            echo "ASIODIR: $ASIODIR";
+
+            OTHER_OBJS="$CFLAGS pa_asio/iasiothiscallresolver.o $ASIODIR/host/asiodrivers.o $ASIODIR/common/asio.o $ASIODIR/host/mac/asioshlib.o";
+            CFLAGS="$CFLAGS -I\$(top_srcdir)/pa_asio -I$ASIDIR/host/mac -I$ASIODIR/common";
+            CXXFLAGS="$CFLAGS";
+        fi
+       ;;
+
+  mingw* )
+        dnl MingW configuration
+
+        echo "WINAPI: $with_winapi"
+        if [[ $with_winapi = "directx" ]] ; then
+            if [[ $with_dxdir ]] ; then
+              DXDIR="$with_dxdir";
+            else
+              DXDIR="/usr/local/dx7sdk";
+            fi
+            echo "DXDIR: $DXDIR"
+            OTHER_OBJS="src/hostapi/dsound/pa_win_ds.o src/hostapi/dsound/dsound_wrapper.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o";
+            LIBS="-lwinmm -lm -ldsound -lole32";
+            PADLL="portaudio.dll";
+           THREAD_CFLAGS="-mthreads"
+            SHARED_FLAGS="-shared";
+            DLL_LIBS="${DLL_LIBS} -lwinmm -lm -L./dx7sdk/lib -ldsound -lole32";
+            #VC98="\"/c/Program Files/Microsoft Visual Studio/VC98/Include\"";
+            #CFLAGS="$CFLAGS -I$VC98 -DPA_NO_WMME -DPA_NO_ASIO";
+            CFLAGS="$CFLAGS -I\$(top_srcdir)/include -I$DXDIR/include -DPA_NO_WMME -DPA_NO_ASIO" -DPA_NO_WDMKS;
+        elif [[ $with_winapi = "asio" ]] ; then
+            if [[ $with_asiodir ]] ; then
+              ASIODIR="$with_asiodir";
+            else
+              ASIODIR="/usr/local/asiosdk2";
+            fi
+            echo "ASIODIR: $ASIODIR"
+
+            OTHER_OBJS="pa_asio/pa_asio.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o pa_asio/iasiothiscallresolver.o $ASIODIR/common/asio.o $ASIODIR/host/asiodrivers.o $ASIODIR/host/pc/asiolist.o";
+            LIBS="-lwinmm -lm -lstdc++ -lole32 -luuid";
+            PADLL="portaudio.dll";
+           THREAD_CFLAGS="-mthreads"
+            SHARED_FLAGS="-shared";
+            DLL_LIBS="${DLL_LIBS} -lwinmm -lm -lstdc++ -lole32 -luuid";
+            CFLAGS="$CFLAGS -ffast-math -fomit-frame-pointer -I\$(top_srcdir)/src/common -I\$(top_srcdir)/pa_asio -I$ASIODIR/host/pc -I$ASIODIR/common -I$ASIODIR/host -DPA_NO_WMME -DPA_NO_DS -DPA_NO_WDMKS -DWINDOWS";
+            CXXFLAGS="$CFLAGS";
+        elif [[ $with_winapi = "wdmks" ]] ; then
+            if [[ $with_dxdir ]] ; then
+              DXDIR="$with_dxdir";
+            else
+              DXDIR="/usr/local/dx7sdk";
+            fi
+            echo "DXDIR: $DXDIR"
+            OTHER_OBJS="src/hostapi/wdmks/pa_win_wdmks.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o";
+            LIBS="-lwinmm -lm -luuid -lsetupapi -lole32";
+            PADLL="portaudio.dll";
+           THREAD_CFLAGS="-mthreads"
+            SHARED_FLAGS="-shared";
+            DLL_LIBS="${DLL_LIBS} -lwinmm -lm -L./dx7sdk/lib -luuid -lsetupapi -lole32";
+            #VC98="\"/c/Program Files/Microsoft Visual Studio/VC98/Include\"";
+            #CFLAGS="$CFLAGS -I$VC98 -DPA_NO_WMME -DPA_NO_ASIO";
+            CFLAGS="$CFLAGS -I\$(top_srcdir)/src/common -I$DXDIR/include -DPA_NO_WMME -DPA_NO_DS -DPA_NO_ASIO";
+        else   # WMME default
+            OTHER_OBJS="src/hostapi/wmme/pa_win_wmme.o src/os/win/pa_win_hostapis.o src/os/win/pa_win_util.o";
+            LIBS="-lwinmm -lm -lstdc++ -lole32 -luuid";
+            PADLL="portaudio.dll";
+           THREAD_CFLAGS="-mthreads"
+            SHARED_FLAGS="-shared";
+            DLL_LIBS="${DLL_LIBS} -lwinmm";
+            CFLAGS="$CFLAGS -I\$(top_srcdir)/src/common -DPA_NO_DS -DPA_NO_ASIO -DPA_NO_WDMKS";
+        fi
+        ;;
+
+  cygwin* )
+       dnl Cygwin configuration
+
+       OTHER_OBJS="src/hostapi/wmme/pa_win_wmme.o";
+       LIBS="-lwinmm -lm";
+       PADLL="portaudio.dll";
+       THREAD_CFLAGS="-mthreads"
+       SHARED_FLAGS="-shared";
+       DLL_LIBS="${DLL_LIBS} -lwinmm";
+       ;;
+
+  irix* )
+       dnl SGI IRIX audio library (AL) configuration (Pieter, oct 2-13, 2003).
+       dnl The 'dmedia' library is needed to read the Unadjusted System Time (UST).
+    dnl
+       AC_CHECK_LIB(pthread, pthread_create, , AC_MSG_ERROR([IRIX posix thread library not found!]))
+       AC_CHECK_LIB(audio,   alOpenPort,     , AC_MSG_ERROR([IRIX audio library not found!]))
+       AC_CHECK_LIB(dmedia,  dmGetUST,       , AC_MSG_ERROR([IRIX digital media library not found!]))
+
+       dnl See the '#ifdef PA_USE_SGI' in file pa_unix/pa_unix_hostapis.c
+       dnl which selects the appropriate PaXXX_Initialize() function.
+       dnl
+       AC_DEFINE(PA_USE_SGI)
+
+       dnl The _REENTRANT option for pthread safety. Perhaps not necessary but it 'll do no harm.
+       dnl
+       THREAD_CFLAGS="-D_REENTRANT"
+    
+       OTHER_OBJS="pa_sgi/pa_sgi.o src/os/unix/pa_unix_hostapis.o src/os/unix/pa_unix_util.o";
+       
+       dnl SGI books say -lpthread should be the last of the libs mentioned.
+       dnl
+       LIBS="-lm -ldmedia -laudio -lpthread";
+       PADLL="libportaudio.so";
+       SHARED_FLAGS="";
+       ;;
+
+  *)
+       dnl Unix configuration
+
+   AC_CHECK_LIB(pthread, pthread_create,[have_pthread="yes"]
+                ,
+                AC_MSG_ERROR([libpthread not found!]))
+
+       if [[ $have_alsa = "yes" ] && [ $with_alsa != "no" ]] ; then
+               DLL_LIBS="$DLL_LIBS -lasound"
+               OTHER_OBJS="$OTHER_OBJS src/hostapi/alsa/pa_linux_alsa.o"
+                AC_DEFINE(PA_USE_ALSA)
+       fi
+
+       if [[ $have_jack = "yes" ] && [ $with_jack != "no" ]] ; then
+               DLL_LIBS="$DLL_LIBS $JACK_LIBS"
+               CFLAGS="$CFLAGS $JACK_CFLAGS"
+               OTHER_OBJS="$OTHER_OBJS src/hostapi/jack/pa_jack.o"
+                AC_DEFINE(PA_USE_JACK)
+       fi
+
+       if [[ $with_oss != "no" ]] ; then
+               OTHER_OBJS="$OTHER_OBJS src/hostapi/oss/pa_unix_oss.o"
+               AC_DEFINE(PA_USE_OSS)
+       fi
+       THREAD_CFLAGS="-pthread"
+       DLL_LIBS="$DLL_LIBS -lm -lpthread";
+       LIBS="$LIBS -lm -lpthread";
+       PADLL="libportaudio.so";
+       SHARED_FLAGS="-shared -fPIC";
+
+        OTHER_OBJS="$OTHER_OBJS src/os/unix/pa_unix_hostapis.o src/os/unix/pa_unix_util.o"
+esac
+CFLAGS="$CFLAGS $THREAD_CFLAGS"
+
+AC_OUTPUT([Makefile portaudio-2.0.pc])
diff --git a/utils/iaxclient/lib/portaudio/docs/index.html b/utils/iaxclient/lib/portaudio/docs/index.html
new file mode 100644 (file)
index 0000000..7d9b248
--- /dev/null
@@ -0,0 +1,60 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
+   <meta name="Author" content="Phil Burk">
+   <meta name="Description" content="PortAudio Docs, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
+   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
+   <title>PortAudio Docs</title>
+</head>
+<body>
+&nbsp;
+<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
+<tr>
+<td>
+<center>
+<h1>
+PortAudio Documentation</h1></center>
+</td>
+</tr>
+</table></center>
+
+<p>Copyright 2000 Phil Burk and Ross Bencina
+<br>&nbsp;
+<h3>
+<a href="portaudio_h.txt">API Reference</a></h3>
+
+<blockquote>The Application Programmer Interface is documented in "portaudio.h".</blockquote>
+
+<h3>
+<a href="pa_tutorial.html">Tutorial</a></h3>
+
+<blockquote>Describes how to write audio programs using the PortAudio API.</blockquote>
+
+<h3>
+<a href="pa_impl_guide.html">Implementation Guide</a></h3>
+
+<blockquote>Describes how to write an implementation of PortAudio for a
+new computer platform.</blockquote>
+
+<h3>
+<a href="portaudio_icmc2001.pdf">Paper Presented at ICMC2001</a> (PDF)</h3>
+
+<blockquote>Describes the PortAudio API and discusses implementation issues.
+Written July 2001.</blockquote>
+
+<h3>
+<a href="latency.html">Improving Latency</a></h3>
+
+<blockquote>How to tune your computer to achieve the lowest possible audio
+delay.</blockquote>
+
+<h3>
+<a href="proposals.html">Proposed Changes</a></h3>
+
+<blockquote>Describes API changes being considered by the developer community.
+Feedback welcome.</blockquote>
+<a href="http://www.portaudio.com/">Return to PortAudio Home Page</a>
+</body>
+</html>
diff --git a/utils/iaxclient/lib/portaudio/docs/latency.html b/utils/iaxclient/lib/portaudio/docs/latency.html
new file mode 100644 (file)
index 0000000..87f1d12
--- /dev/null
@@ -0,0 +1,192 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
+   <meta name="Author" content="Phil Burk">
+   <meta name="Description" content="Internal docs. How a stream is started or stopped.">
+   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
+   <title>PortAudio Implementation - Start/Stop</title>
+</head>
+<body>
+&nbsp;
+<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
+<tr>
+<td>
+<center>
+<h1>
+<a href="http://www.portaudio.com">PortAudio</a> Latency</h1></center>
+</td>
+</tr>
+</table></center>
+
+<p>This page discusses the issues of audio latency for <a href="http://www.portaudio.com">PortAudio</a>
+. It offers suggestions on how to lower latency to improve the responsiveness
+of applications.
+<blockquote><b><a href="#what">What is Latency?</a></b>
+<br><b><a href="#portaudio">PortAudio and Latency</a></b>
+<br><b><a href="#macintosh">Macintosh</a></b>
+<br><b><a href="#unix">Unix</a></b>
+<br><b><a href="#windows">WIndows</a></b></blockquote>
+By Phil Burk, Copyright 2002 Phil Burk and Ross Bencina
+<h2>
+<a NAME="what"></a>What is Latency?</h2>
+Latency is basically longest time that you have to wait before you obtain
+a desired result. For digital audio output it is the time between making
+a sound in software and finally hearing it.
+<p>Consider the example of pressing a key on the ASCII keyboard to play
+a note. There are several stages in this process which each contribute
+their own latency. First the operating system must respond to the keypress.
+Then the audio signal generated must work its way through the PortAudio
+buffers. Then it must work its way through the audio card hardware. Then
+it must go through the audio amplifier which is very quick and then travel
+through the air. Sound travels at abous one foot per millisecond through
+air so placing speakers across the room can add 5-20 msec of delay.
+<p>The reverse process occurs when recording or responding to audio input.
+If you are processing audio, for example if you implement a software guitar
+fuzz box, then you have both the audio input and audio output latencies
+added together.
+<p>The audio buffers are used to prevent glitches in the audio stream.
+The user software writes audio into the output buffers. That audio is read
+by the low level audio driver or by DMA and sent to the DAC. If the computer
+gets busy doing something like reading the disk or redrawing the screen,
+then it may not have time to fill the audio buffer. The audio hardware
+then runs out of audio data, which causes a glitch. By using a large enough
+buffer we can ensure that there is always enough audio data for the audio
+hardware to play. But if the buffer is too large then the latency is high
+and the system feels sluggish. If you play notes on the keyboard then the
+"instrument" will feel unresponsive. So you want the buffers to be as small
+as possible without glitching.
+<h2>
+<a NAME="portaudio"></a>PortAudio and Latency</h2>
+The only delay that PortAudio can control is the total length of its buffers.
+The Pa_OpenStream() call takes two parameters: numBuffers and framesPerBuffer.
+The latency is also affected by the sample rate which we will call framesPerSecond.
+A frame is a set of samples that occur simultaneously. For a stereo stream,
+a frame is two samples.
+<p>The latency in milliseconds due to this buffering&nbsp; is:
+<blockquote><tt>latency_msec = 1000 * numBuffers * framesPerBuffer / framesPerSecond</tt></blockquote>
+This is not the total latency, as we have seen, but it is the part we can
+control.
+<p>If you call Pa_OpenStream() with numBuffers equal to zero, then PortAudio
+will select a conservative number that will prevent audio glitches. If
+you still get glitches, then you can pass a larger value for numBuffers
+until the glitching stops. if you try to pass a numBuffers value that is
+too small, then PortAudio will use its own idea of the minimum value.
+<p>PortAudio decides on the minimum number of buffers in a conservative
+way based on the frameRate, operating system and other variables. You can
+query the value that PortAudio will use by calling:
+<blockquote><tt>int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate
+);</tt></blockquote>
+On some systems you can override the PortAudio minimum if you know your
+system can handle a lower value. You do this by setting an environment
+variable called PA_MIN_LATENCY_MSEC which is read by PortAudio when it
+starts up. This is supported on the PortAudio implementations for Windows
+MME, Windows DirectSound, and Unix OSS.
+<h2>
+<a NAME="macintosh"></a>Macintosh</h2>
+The best thing you can do to improve latency on Mac OS 8 and 9 is to turn
+off Virtual Memory. PortAudio V18 will detect that Virtual Memory is turned
+off and use a very low latency.
+<p>For Mac OS X the latency is very low because Apple Core Audio is so
+well written. You can set the PA_MIN_LATENCY_MSEC variable using:
+<blockquote><tt>setenv PA_MIN_LATENCY_MSEC 4</tt></blockquote>
+
+<h2>
+<a NAME="unix"></a>Unix</h2>
+PortAudio under Unix currently uses a backgroud thread that reads and writes
+to OSS. This gives you decent but not great latency. But if you raise the
+priority of the background thread to a very priority then you can get under
+10 milliseconds latency. In order to raise your priority you must run the
+PortAudio program as root! You must also set PA_MIN_LATENCY_MSEC using
+the appropriate command for your shell.
+<h2>
+<a NAME="windows"></a>Windows</h2>
+Latency under Windows is a complex issue because of all the alternative
+operating system versions and device drivers. I have seen latency range
+from 8 milliseconds to 400 milliseconds. The worst case is when using Windows
+NT. Windows 98 is a little better, and Windows XP can be quite good if
+properly tuned.
+<p>The underlying audio API also makes a lot of difference. If the audio
+device has its own DirectSound driver then DirectSound can often provide
+better latency than WMME. But if a real DirectSound driver is not available
+for your device then it is emulated using WMME and the latency can be very
+high. That's where I saw the 400 millisecond latency. The ASIO implementation
+is generally very good and will give the lowest latency if available.
+<p>You can set the PA_MIN_LATENCY_MSEC variable to 50, for example, by
+entering in MS-DOS:
+<blockquote><tt>set PA_MIN_LATENCY_MSEC=50</tt></blockquote>
+If you enter this in a DOS window then you must run the PortAudio program
+from that same window for the variable to have an effect. You can add that
+line to your C:\AUTOEXEC.BAT file and reboot if you want it to affect any
+PortAudio based program.
+<p>For Windows XP, you can set environment variables as follows:
+<ol>
+<li>
+Select "Control Panel" from the "Start Menu".</li>
+
+<li>
+Launch the "System" Control Panel</li>
+
+<li>
+Click on the "Advanced" tab.</li>
+
+<li>
+Click on the "Environment Variables" button.</li>
+
+<li>
+Click "New" button under&nbsp; User Variables.</li>
+
+<li>
+Enter PA_MIN_LATENCY_MSEC for the name and some optimistic number for the
+value.</li>
+
+<li>
+Click OK, OK, OK.</li>
+</ol>
+
+<h3>
+Improving Latency on Windows</h3>
+There are several steps you can take to improve latency under windows.
+<ol>
+<li>
+Avoid reading or writng to disk when doing audio.</li>
+
+<li>
+Turn off all automated background tasks such as email clients, virus scanners,
+backup programs, FTP servers, web servers, etc. when doing audio.</li>
+
+<li>
+Disconnect from the network to prevent network traffic from interrupting
+your CPU.</li>
+</ol>
+<b>Important: </b>Windows XP users can also tune the OS to favor background
+tasks, such as audio, over foreground tasks, such as word processing. I
+lowered my latency from 40 to 10 milliseconds using this simple technique.
+<ol>
+<li>
+Select "Control Panel" from the "Start Menu".</li>
+
+<li>
+Launch the "System" Control Panel</li>
+
+<li>
+Click on the "Advanced" tab.</li>
+
+<li>
+Click on the "Settings" button in the Performance area.</li>
+
+<li>
+Click on the "Advanced" tab.</li>
+
+<li>
+Select "Background services" in the Processor Scheduling area.</li>
+
+<li>
+Click OK, OK.</li>
+</ol>
+Please let us know if you have others sugestions for lowering latency.
+<br>&nbsp;
+<br>&nbsp;
+</body>
+</html>
diff --git a/utils/iaxclient/lib/portaudio/docs/pa_impl_guide.html b/utils/iaxclient/lib/portaudio/docs/pa_impl_guide.html
new file mode 100644 (file)
index 0000000..50abc30
--- /dev/null
@@ -0,0 +1,197 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
+   <meta name="Author" content="Phil Burk">
+   <meta name="Description" content="Internal docs. How a stream is started or stopped.">
+   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
+   <title>PortAudio Implementation - Start/Stop</title>
+</head>
+<body>
+&nbsp;
+<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
+<tr>
+<td>
+<center>
+<h1>
+<a href="http://www.portaudio.com">PortAudio</a> Implementation Guide</h1></center>
+</td>
+</tr>
+</table></center>
+
+<p>This document describes how to implement the PortAudio API on a new
+computer platform. Implementing PortAudio on a new platform, makes it possible
+to port many existing audio applications to that platform.
+<p>By Phil Burk
+<br>Copyright 2000 Phil Burk and Ross Bencina
+<p>Note that the license says: <b>"Any person wishing to distribute modifications
+to the Software is requested to send the modifications to the original
+developer so that they can be incorporated into the canonical version."</b>.
+So when you have finished a new implementation, please send it back to
+us at&nbsp; "<a href="http://www.portaudio.com">http://www.portaudio.com</a>"
+so that we can make it available for other users. Thank you!
+<h2>
+Download the Latest PortAudio Implementation</h2>
+Always start with the latest implementation available at "<a href="http://www.portaudio.com">http://www.portaudio.com</a>".
+Look for the nightly snapshot under the CVS section.
+<h2>
+Select an Existing Implementation as a Basis</h2>
+The fastest way to get started is to take an existing implementation and
+translate it for your new platform. Choose an implementation whose architecture
+is as close as possible to your target.
+<ul>
+<li>
+DirectSound Implementation - pa_win_ds - Uses a timer callback for the
+background "thread". Polls a circular buffer and writes blocks of data
+to keep it full.</li>
+
+<li>
+Windows MME - pa_win_wmme - Spawns an actual Win32 thread. Writes blocks
+of data to the HW device and waits for events that signal buffer completion.</li>
+
+<li>
+Linux OSS - pa_linux - Spawns a real thread that writes to the "/dev/dsp"
+stream using blocking I/O calls.</li>
+</ul>
+When you write a new implementation, you will be using some code that is
+in common with all implementations. This code is in the folder "pa_common".
+It provides various functions such as parameter checking, error code to
+text conversion, sample format conversion, clipping and dithering, etc.
+<p>The code that you write will go into a separate folder called "pa_{os}_{api}".
+For example, code specific to the DirectSound interface for Windows goes
+in "pa_win_ds".
+<h2>
+Read Docs and Code</h2>
+Famialiarize yourself with the system by reading the documentation provided.
+here is a suggested order:
+<ol>
+<li>
+User Programming <a href="pa_tutorial.html">Tutorial</a></li>
+
+<li>
+Header file "pa_common/portaudio.h" which defines API.</li>
+
+<li>
+Header file "pa_common/pa_host.h" for host dependant code. This definces
+the routine you will need to provide.</li>
+
+<li>
+Shared code in "pa_common/pa_lib.c".</li>
+
+<li>
+Docs on Implementation of <a href="pa_impl_startstop.html">Start/Stop</a>
+code.</li>
+</ol>
+
+<h2>
+Implement&nbsp; Output to Default Device</h2>
+Now we are ready to crank some code. For instant gratification, let's try
+to play a sine wave.
+<ol>
+<li>
+Link the test program "pa_tests/patest_sine.c" with the file "pa_lib.c"
+and the implementation specific file you are creating.</li>
+
+<li>
+For now, just stub out the device query code and the audio input code.</li>
+
+<li>
+Modify PaHost_OpenStream() to open your default target device and get everything
+setup.</li>
+
+<li>
+Modify PaHost_StartOutput() to start playing audio.</li>
+
+<li>
+Modify PaHost_StopOutput() to stop audio.</li>
+
+<li>
+Modify PaHost_CloseStream() to clean up. Free all memory that you allocated
+in PaHost_OpenStream().</li>
+
+<li>
+Keep cranking until you can play a sine wave using "patest_sine.c".</li>
+
+<li>
+Once that works, try "patest_pink.c", "patest_clip.c", "patest_sine8.c".</li>
+
+<li>
+To test your Open and Close code, try "patest_many.c".</li>
+
+<li>
+Now test to make sure that the three modes of stopping are properly supported
+by running "patest_stop.c".</li>
+
+<li>
+Test your implementation of time stamping with "patest_sync.c".</li>
+</ol>
+
+<h2>
+Implement Device Queries</h2>
+Now that output is working, lets implement the code for querying what devices
+are available to the user. Run "pa_tests/pa_devs.c". It should print all
+of the devices available and their characteristics.
+<h2>
+Implement Input</h2>
+Implement audio input and test it with:
+<ol>
+<li>
+patest_record.c - record in half duplex, play back as recorded.</li>
+
+<li>
+patest_wire.c - full duplex, copies input to output. Note that some HW
+may not support full duplex.</li>
+
+<li>
+patest_fuzz.c - plug in your guitar and get a feel for why latency is an
+important issue in computer music.</li>
+
+<li>
+paqa_devs.c - try to open every device and use it with every possible format</li>
+</ol>
+
+<h2>
+Debugging Tools</h2>
+You generally cannot use printf() calls to debug real-time processes because
+they disturb the timing. Also calling printf() from your background thread
+or interrupt could crash the machine. So PA includes a tool for capturing
+events and storing the information while it is running. It then prints
+the events when Pa_Terminate() is called.
+<ol>
+<li>
+To enable trace mode, change TRACE_REALTIME_EVENTS in "pa_common/pa_trace.h"
+from a (0) to a (1).</li>
+
+<li>
+Link with "pa_common/pa_trace.c".</li>
+
+<li>
+Add trace messages to your code by calling:</li>
+
+<br><tt>&nbsp;&nbsp; void AddTraceMessage( char *msg, int data );</tt>
+<br><tt>for example</tt>
+<br><tt>&nbsp;&nbsp; AddTraceMessage("Pa_TimeSlice: past_NumCallbacks ",
+past->past_NumCallbacks );</tt>
+<li>
+Run your program. You will get a dump of events at the end.</li>
+
+<li>
+You can leave the trace messages in your code. They will turn to NOOPs
+when you change TRACE_REALTIME_EVENTS back to (0).</li>
+</ol>
+
+<h2>
+Delivery</h2>
+Please send your new code along with notes on the implementation back to
+us at "<a href="http://www.portaudio.com">http://www.portaudio.com</a>".
+We will review the implementation and post it with your name. If you had
+to make any modifications to the code in "pa_common" or "pa_tests" <b>please</b>
+send us those modifications and your notes. We will try to merge your changes
+so that the "pa_common" code works with <b>all</b> implementations.
+<p>If you have suggestions for how to make future implementations easier,
+please let us know.
+<br>THANKS!
+<br>&nbsp;
+</body>
+</html>
diff --git a/utils/iaxclient/lib/portaudio/docs/pa_impl_startstop.html b/utils/iaxclient/lib/portaudio/docs/pa_impl_startstop.html
new file mode 100644 (file)
index 0000000..0f2d0ce
--- /dev/null
@@ -0,0 +1,190 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.75 [en]C-gatewaynet  (Win98; U) [Netscape]">
+   <meta name="Author" content="Phil Burk">
+   <meta name="Description" content="Internal docs. How a stream is started or stopped.">
+   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
+   <title>PortAudio Implementation - Start/Stop</title>
+</head>
+<body>
+&nbsp;
+<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
+<tr>
+<td>
+<center>
+<h1>
+PortAudio Implementation</h1></center>
+</td>
+</tr>
+</table></center>
+
+<h2>
+Starting and Stopping Streams</h2>
+PortAudio is generally executed in two "threads". The foreground thread
+is the application thread. The background "thread" may be implemented as
+an actual thread, an interrupt handler, or a callback from a timer thread.
+<p>There are three ways that PortAudio can stop a stream. In each case
+we look at the sequence of events and the messages sent between the two
+threads. The following variables are contained in the internalPortAudioStream.
+<blockquote><tt>int&nbsp;&nbsp; past_IsActive;&nbsp;&nbsp;&nbsp;&nbsp;
+/* Background is still playing. */</tt>
+<br><tt>int&nbsp;&nbsp; past_StopSoon;&nbsp;&nbsp;&nbsp;&nbsp; /* Stop
+when last buffer done. */</tt>
+<br><tt>int&nbsp;&nbsp; past_StopNow;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*
+Stop IMMEDIATELY. */</tt></blockquote>
+
+<h3>
+Pa_AbortStream()</h3>
+This function causes the background thread to terminate as soon as possible
+and audio I/O to stop abruptly.
+<br>&nbsp;
+<table BORDER COLS=2 WIDTH="60%" >
+<tr>
+<td><b>Foreground Thread</b></td>
+
+<td><b>Background Thread</b></td>
+</tr>
+
+<tr>
+<td>sets <tt>StopNow</tt></td>
+
+<td></td>
+</tr>
+
+<tr>
+<td></td>
+
+<td>sees <tt>StopNow</tt>,&nbsp;</td>
+</tr>
+
+<tr>
+<td></td>
+
+<td>clears IsActive, stops thread</td>
+</tr>
+
+<tr>
+<td>waits for thread to exit</td>
+
+<td></td>
+</tr>
+
+<tr>
+<td>turns off audio I/O</td>
+
+<td></td>
+</tr>
+</table>
+
+<h3>
+Pa_StopStream()</h3>
+This function stops the user callback function from being called and then
+waits for all audio data written to the output buffer to be played. In
+a system with very low latency, you may not hear any difference between
+<br>&nbsp;
+<table BORDER COLS=2 WIDTH="60%" >
+<tr>
+<td><b>Foreground Thread</b></td>
+
+<td><b>Background Thread</b></td>
+</tr>
+
+<tr>
+<td>sets StopSoon</td>
+
+<td></td>
+</tr>
+
+<tr>
+<td></td>
+
+<td>stops calling user callback</td>
+</tr>
+
+<tr>
+<td></td>
+
+<td>continues until output buffer empty</td>
+</tr>
+
+<tr>
+<td></td>
+
+<td>clears IsActive, stops thread</td>
+</tr>
+
+<tr>
+<td>waits for thread to exit</td>
+
+<td></td>
+</tr>
+
+<tr>
+<td>turns off audio I/O</td>
+
+<td></td>
+</tr>
+</table>
+
+<h3>
+User callback returns one.</h3>
+If the user callback returns one then the user callback function will no
+longer be called. Audio output will continue until all audio data written
+to the output buffer has been played. Then the audio I/O is stopped, the
+background thread terminates, and the stream becomes inactive.
+<br>&nbsp;
+<table BORDER COLS=2 WIDTH="60%" >
+<tr>
+<td><b>Foreground Thread</b></td>
+
+<td><b>Background Thread</b></td>
+</tr>
+
+<tr>
+<td></td>
+
+<td>callback returns 1</td>
+</tr>
+
+<tr>
+<td></td>
+
+<td>sets StopSoon</td>
+</tr>
+
+<tr>
+<td></td>
+
+<td>stops calling user callback</td>
+</tr>
+
+<tr>
+<td></td>
+
+<td>continues until output buffer empty</td>
+</tr>
+
+<tr>
+<td></td>
+
+<td>clears IsActive, stops thread</td>
+</tr>
+
+<tr>
+<td>waits for thread to exit</td>
+
+<td></td>
+</tr>
+
+<tr>
+<td>turns off audio I/O</td>
+
+<td></td>
+</tr>
+</table>
+
+<br>&nbsp;
+</body>
+</html>
diff --git a/utils/iaxclient/lib/portaudio/docs/pa_tut_asio.html b/utils/iaxclient/lib/portaudio/docs/pa_tut_asio.html
new file mode 100644 (file)
index 0000000..1c3e5bf
--- /dev/null
@@ -0,0 +1,55 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.77 [en]C-gatewaynet  (Win98; U) [Netscape]">
+   <meta name="Author" content="Phil Burk">
+   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
+   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
+   <title>PortAudio Tutorial</title>
+</head>
+<body>
+&nbsp;
+<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
+<tr>
+<td>
+<center>
+<h1>
+PortAudio Tutorial</h1></center>
+</td>
+</tr>
+</table></center>
+
+<h2>
+Compiling for ASIO (Windows or Macintosh)</h2>
+
+<blockquote>ASIO is a low latency audio API from Steinberg. To compile
+an ASIO application, you must first <a href="http://www.steinberg.net/developers/ASIO2SDKAbout.phtml">download
+the ASIO SDK</a> from Steinberg. You also need to obtain ASIO drivers for
+your audio device.
+<p>Note: I am using '/' as a file separator below. On Macintosh replace
+'/' with ':'. On Windows, replace '/' with '\'.
+<p>&nbsp;To use ASIO with the PortAudio library add the following source
+files to your project:
+<blockquote>
+<pre>pa_asio/pa_asio.cpp</pre>
+</blockquote>
+and also these files from the ASIO SDK:
+<blockquote>
+<pre>common/asio.cpp
+host/asiodrivers.cpp
+host/asiolist.cpp</pre>
+</blockquote>
+and add these directories to the path for include files
+<blockquote>
+<pre>asiosdk2/host/pc&nbsp;&nbsp; (for Windows)
+asiosdk2/common
+asiosdk2/host</pre>
+</blockquote>
+You may try compiling the "pa_tests/patest_saw.c" file first because it
+is the simplest.</blockquote>
+<font size=+2><a href="http://www.portaudio.com/">home</a> |
+<a href="pa_tutorial.html">contents</a>
+| <a href="pa_tut_over.html">previous</a> |&nbsp; <a href="pa_tut_callback.html">next</a></font>
+</body>
+</html>
diff --git a/utils/iaxclient/lib/portaudio/docs/pa_tut_callback.html b/utils/iaxclient/lib/portaudio/docs/pa_tut_callback.html
new file mode 100644 (file)
index 0000000..f5ccaf0
--- /dev/null
@@ -0,0 +1,91 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.77 [en]C-gatewaynet  (Win98; U) [Netscape]">
+   <meta name="Author" content="Phil Burk">
+   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
+   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
+   <title>PortAudio Tutorial</title>
+</head>
+<body>
+&nbsp;
+<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
+<tr>
+<td>
+<center>
+<h1>
+PortAudio Tutorial</h1></center>
+</td>
+</tr>
+</table></center>
+
+<h2>
+Writing a Callback Function</h2>
+
+<blockquote>To write a program using PortAudio, you must include the "portaudio.h"
+include file. You may wish to read "<a href="portaudio_h.txt">portaudio.h</a>"
+because it contains a complete description of the PortAudio functions and
+constants.
+<blockquote>
+<pre>#include "portaudio.h"</pre>
+</blockquote>
+The next task is to write your custom callback function. It is a function
+that is called by the PortAudio engine whenever it has captured audio data,
+or when it needs more audio data for output.
+<p>Your callback function is often called by an interrupt, or low level
+process so you should not do any complex system activities like allocating
+memory, or reading or writing files, or printf(). Just crunch numbers and
+generate audio signals. What is safe or not safe will vary from platform
+to platform. On the Macintosh, for example, you can only call "interrupt
+safe" routines. Also do not call any PortAudio functions in the callback
+except for Pa_StreamTime() and Pa_GetCPULoad().
+<p>Your callback function must return an int and accept the exact parameters
+specified in this typedef:
+<blockquote>
+<pre>typedef int (PortAudioCallback)(
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void *inputBuffer, void *outputBuffer,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long framesPerBuffer,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PaTimestamp outTime, void *userData );</pre>
+</blockquote>
+Here is an example callback function from the test file "patests/patest_saw.c".
+It calculates a simple left and right sawtooth signal and writes it to
+the output buffer. Notice that in this example, the signals are of <tt>float</tt>
+data type. The signals must be between -1.0 and +1.0. You can also use
+16 bit integers or other formats which are specified during setup. You
+can pass a pointer to your data structure through PortAudio which will
+appear as <tt>userData</tt>.
+<blockquote>
+<pre>int patestCallback(&nbsp; void *inputBuffer, void *outputBuffer,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long framesPerBuffer,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PaTimestamp outTime, void *userData )
+{
+&nbsp;&nbsp;&nbsp; unsigned int i;
+/* Cast data passed through stream to our structure type. */
+&nbsp;&nbsp;&nbsp; paTestData *data = (paTestData*)userData;
+&nbsp;&nbsp;&nbsp; float *out = (float*)outputBuffer;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+&nbsp;&nbsp;&nbsp; for( i=0; i&lt;framesPerBuffer; i++ )
+&nbsp;&nbsp;&nbsp; {
+&nbsp;&nbsp;&nbsp; /* Stereo channels are interleaved. */
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *out++ = data->left_phase;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* left */
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *out++ = data->right_phase;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* right */
+
+&nbsp;&nbsp;&nbsp; /* Generate simple sawtooth phaser that ranges between -1.0 and 1.0. */
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data->left_phase += 0.01f;
+&nbsp;&nbsp;&nbsp; /* When signal reaches top, drop back down. */
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( data->left_phase >= 1.0f ) data->left_phase -= 2.0f;
+
+&nbsp;&nbsp;&nbsp; /* higher pitch so we can distinguish left and right. */
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data->right_phase += 0.03f;&nbsp;
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( data->right_phase >= 1.0f ) data->right_phase -= 2.0f;
+&nbsp;&nbsp;&nbsp; }
+&nbsp;&nbsp;&nbsp; return 0;
+}</pre>
+</blockquote>
+</blockquote>
+<font size=+2><a href="http://www.portaudio.com/">home</a> |
+<a href="pa_tutorial.html">contents</a>
+| <a href="pa_tut_over.html">previous</a> |&nbsp; <a href="pa_tut_init.html">next</a></font>
+</body>
+</html>
diff --git a/utils/iaxclient/lib/portaudio/docs/pa_tut_devs.html b/utils/iaxclient/lib/portaudio/docs/pa_tut_devs.html
new file mode 100644 (file)
index 0000000..1756992
--- /dev/null
@@ -0,0 +1,65 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.75 [en]C-gatewaynet  (Win98; U) [Netscape]">
+   <meta name="Author" content="Phil Burk">
+   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
+   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
+   <title>PortAudio Tutorial</title>
+</head>
+<body>
+&nbsp;
+<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
+<tr>
+<td>
+<center>
+<h1>
+PortAudio Tutorial</h1></center>
+</td>
+</tr>
+</table></center>
+
+<h2>
+Querying for Available Devices</h2>
+
+<blockquote>There are often several different audio devices available in
+a computer with different capabilities. They can differ in the sample rates
+supported, bit widths, etc. PortAudio provides a simple way to query for
+the available devices, and then pass the selected device to Pa_OpenStream().
+For an example, see the file "pa_tests/pa_devs.c".
+<p>To determine the number of devices:
+<blockquote>
+<pre>numDevices = Pa_CountDevices();</pre>
+</blockquote>
+You can then query each device in turn by calling Pa_GetDeviceInfo() with
+an index.
+<blockquote>
+<pre>for( i=0; i&lt;numDevices; i++ ) {
+&nbsp;&nbsp;&nbsp;&nbsp; pdi = Pa_GetDeviceInfo( i );</pre>
+</blockquote>
+It will return a pointer to a <tt>PaDeviceInfo</tt> structure which is
+defined as:
+<blockquote>
+<pre>typedef struct{
+&nbsp;&nbsp;&nbsp; int structVersion;&nbsp;
+&nbsp;&nbsp;&nbsp; const char *name;
+&nbsp;&nbsp;&nbsp; int maxInputChannels;
+&nbsp;&nbsp;&nbsp; int maxOutputChannels;
+/* Number of discrete rates, or -1 if range supported. */
+&nbsp;&nbsp;&nbsp; int numSampleRates;
+/* Array of supported sample rates, or {min,max} if range supported. */
+&nbsp;&nbsp;&nbsp; const double *sampleRates;
+&nbsp;&nbsp;&nbsp; PaSampleFormat nativeSampleFormat;
+}PaDeviceInfo;</pre>
+</blockquote>
+If the device supports a continuous range of sample rates, then numSampleRates
+will equal -1, and the sampleRates array will have two values, the minimum&nbsp;
+and maximum rate.
+<p>The device information is allocated by Pa_Initialize() and freed by
+Pa_Terminate() so you do not have to free() the structure returned by Pa_GetDeviceInfo().</blockquote>
+<font size=+2><a href="http://www.portaudio.com/">home</a> |
+<a href="pa_tutorial.html">contents</a>
+| <a href="pa_tut_util.html">previous</a> |&nbsp; <a href="pa_tut_rw.html">next</a></font>
+</body>
+</html>
diff --git a/utils/iaxclient/lib/portaudio/docs/pa_tut_explore.html b/utils/iaxclient/lib/portaudio/docs/pa_tut_explore.html
new file mode 100644 (file)
index 0000000..91c08a5
--- /dev/null
@@ -0,0 +1,42 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.73 [en]C-gatewaynet  (Win98; U) [Netscape]">
+   <meta name="Author" content="Phil Burk">
+   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
+   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
+   <title>PortAudio Tutorial</title>
+</head>
+<body>
+&nbsp;
+<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
+<tr>
+<td>
+<center>
+<h1>
+PortAudio Tutorial</h1></center>
+</td>
+</tr>
+</table></center>
+
+<h2>
+Exploring PortAudio</h2>
+
+<blockquote>Now that you have a good idea of how PortAudio works, you can
+try out the test programs.
+<ul>
+<li>
+For an example of playing a sine wave, see "pa_tests/patest_sine.c".</li>
+
+<li>
+For an example of recording and playing back a sound, see&nbsp; "pa_tests/patest_record.c".</li>
+</ul>
+I also encourage you to examine the source for the PortAudio libraries.
+If you have suggestions on ways to improve them, please let us know. if
+you want to implement PortAudio on a new platform, please let us know as
+well so we can coordinate people's efforts.</blockquote>
+<font size=+2><a href="http://www.portaudio.com/">home</a> | <a href="pa_tutorial.html">contents</a>
+| <a href="pa_tut_rw.html">previous</a> |&nbsp; next</font>
+</body>
+</html>
diff --git a/utils/iaxclient/lib/portaudio/docs/pa_tut_init.html b/utils/iaxclient/lib/portaudio/docs/pa_tut_init.html
new file mode 100644 (file)
index 0000000..91bfa8d
--- /dev/null
@@ -0,0 +1,43 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.73 [en]C-gatewaynet  (Win98; U) [Netscape]">
+   <meta name="Author" content="Phil Burk">
+   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
+   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
+   <title>PortAudio Tutorial</title>
+</head>
+<body>
+&nbsp;
+<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
+<tr>
+<td>
+<center>
+<h1>
+PortAudio Tutorial</h1></center>
+</td>
+</tr>
+</table></center>
+
+<h2>
+Initializing PortAudio</h2>
+
+<blockquote>Before making any other calls to PortAudio, you must call <tt>Pa_Initialize</tt>().
+This will trigger a scan of available devices which can be queried later.
+Like most PA functions, it will return a result of type <tt>paError</tt>.
+If the result is not <tt>paNoError</tt>, then an error has occurred.
+<blockquote>
+<pre>err = Pa_Initialize();
+if( err != paNoError ) goto error;</pre>
+</blockquote>
+You can get a text message that explains the error message by passing it
+to
+<blockquote>
+<pre>printf(&nbsp; "PortAudio error: %s\n", Pa_GetErrorText( err ) );</pre>
+</blockquote>
+</blockquote>
+<font size=+2><a href="http://www.portaudio.com/">home</a> | <a href="pa_tutorial.html">contents</a>
+| <a href="pa_tut_callback.html">previous</a> |&nbsp; <a href="pa_tut_open.html">next</a></font>
+</body>
+</html>
diff --git a/utils/iaxclient/lib/portaudio/docs/pa_tut_mac.html b/utils/iaxclient/lib/portaudio/docs/pa_tut_mac.html
new file mode 100644 (file)
index 0000000..bf3dafd
--- /dev/null
@@ -0,0 +1,41 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.77 [en]C-gatewaynet  (Win98; U) [Netscape]">
+   <meta name="Author" content="Phil Burk">
+   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
+   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
+   <title>PortAudio Tutorial</title>
+</head>
+<body>
+&nbsp;
+<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
+<tr>
+<td>
+<center>
+<h1>
+PortAudio Tutorial</h1></center>
+</td>
+</tr>
+</table></center>
+
+<h2>
+Compiling for Macintosh</h2>
+
+<blockquote>To compile a Macintosh application with the PortAudio library,
+add the following source files to your project:
+<blockquote>
+<pre>pa_mac:pa_mac.c
+pa_common:pa_lib.c
+pa_common:portaudio.h
+pa_common:pa_host.h</pre>
+</blockquote>
+Also add the Apple <b>SoundLib</b> to your project.
+<p>You may try compiling the "pa_tests:patest_saw.c" file first because
+it is the simplest.</blockquote>
+<font size=+2><a href="http://www.portaudio.com/">home</a> |
+<a href="pa_tutorial.html">contents</a>
+| <a href="pa_tut_over.html">previous</a> |&nbsp; <a href="pa_tut_callback.html">next</a></font>
+</body>
+</html>
diff --git a/utils/iaxclient/lib/portaudio/docs/pa_tut_mac_osx.html b/utils/iaxclient/lib/portaudio/docs/pa_tut_mac_osx.html
new file mode 100644 (file)
index 0000000..3af8c14
--- /dev/null
@@ -0,0 +1,46 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
+   <meta name="Author" content="Phil Burk">
+   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
+   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
+   <title>PortAudio Tutorial</title>
+</head>
+<body>
+&nbsp;
+<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
+<tr>
+<td>
+<center>
+<h1>
+PortAudio Tutorial</h1></center>
+</td>
+</tr>
+</table></center>
+
+<h2>
+Compiling for Macintosh OS X</h2>
+
+<blockquote>To compile a Macintosh OS X CoreAudio application with the
+PortAudio library:
+<p>Create a new ProjectBuilder project. You can use a "Tool" project to
+run the PortAudio examples.
+<p>Add the following source files to your Project:
+<blockquote>
+<pre>pa_mac_core/pa_mac_core.c
+pa_common/pa_lib.c
+pa_common/portaudio.h
+pa_common/pa_host.h
+pa_common/pa_convert.c</pre>
+</blockquote>
+Add the Apple CoreAudio.framework to your project by selecting "Add FrameWorks..."
+from the Project menu.
+<p>Compile and run the "pa_tests:patest_saw.c" file first because it is
+the simplest.</blockquote>
+<font size=+2><a href="http://www.portaudio.com/">home</a> |
+<a href="pa_tutorial.html">contents</a>
+| <a href="pa_tut_over.html">previous</a> |&nbsp; <a href="pa_tut_callback.html">next</a></font>
+</body>
+</html>
diff --git a/utils/iaxclient/lib/portaudio/docs/pa_tut_open.html b/utils/iaxclient/lib/portaudio/docs/pa_tut_open.html
new file mode 100644 (file)
index 0000000..1621ef3
--- /dev/null
@@ -0,0 +1,52 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.73 [en]C-gatewaynet  (Win98; U) [Netscape]">
+   <meta name="Author" content="Phil Burk">
+   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
+   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
+   <title>PortAudio Tutorial</title>
+</head>
+<body>
+&nbsp;
+<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
+<tr>
+<td>
+<center>
+<h1>
+PortAudio Tutorial</h1></center>
+</td>
+</tr>
+</table></center>
+
+<h2>
+Opening a Stream using Defaults</h2>
+
+<blockquote>The next step is to open a stream which is similar to opening
+a file. You can specify whether you want audio input and/or output, how
+many channels, the data format, sample rate, etc. There are two calls for
+opening streams, <tt>Pa_OpenStream</tt>() and <tt>Pa_OpenDefaultStream</tt>().
+<p><tt>Pa_OpenStream()</tt> takes extra&nbsp; parameters which give you
+more control. You can normally just use <tt>Pa_OpenDefaultStream</tt>()
+which just calls <tt>Pa_OpenStream()</tt> <tt>with</tt> some reasonable
+default values.&nbsp; Let's open a stream for stereo output, using floating
+point data, at 44100 Hz.
+<blockquote>
+<pre>err = Pa_OpenDefaultStream(
+&nbsp;&nbsp;&nbsp; &amp;stream,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* passes back stream pointer */
+&nbsp;&nbsp;&nbsp; 0,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* no input channels */
+&nbsp;&nbsp;&nbsp; 2,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* stereo output */
+&nbsp;&nbsp;&nbsp; paFloat32,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 32 bit floating point output */
+&nbsp;&nbsp;&nbsp; 44100,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* sample rate */
+&nbsp;&nbsp;&nbsp; 256,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* frames per buffer */
+&nbsp;&nbsp;&nbsp; 0,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* number of buffers, if zero then use default minimum */
+&nbsp;&nbsp;&nbsp; patestCallback, /* specify our custom callback */
+&nbsp;&nbsp;&nbsp; &amp;data );&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* pass our data through to callback */</pre>
+</blockquote>
+If you want to use 16 bit integer data, pass <tt>paInt16</tt> instead of
+<tt>paFloat32</tt>.</blockquote>
+<font size=+2><a href="http://www.portaudio.com/">home</a> | <a href="pa_tutorial.html">contents</a>
+| <a href="pa_tut_init.html">previous</a> |&nbsp; <a href="pa_tut_run.html">next</a></font>
+</body>
+</html>
diff --git a/utils/iaxclient/lib/portaudio/docs/pa_tut_oss.html b/utils/iaxclient/lib/portaudio/docs/pa_tut_oss.html
new file mode 100644 (file)
index 0000000..1bb76f2
--- /dev/null
@@ -0,0 +1,46 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.77 [en]C-gatewaynet  (Win98; U) [Netscape]">
+   <meta name="Author" content="Phil Burk">
+   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
+   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
+   <title>PortAudio Tutorial</title>
+</head>
+<body>
+&nbsp;
+<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
+<tr>
+<td>
+<center>
+<h1>
+PortAudio Tutorial</h1></center>
+</td>
+</tr>
+</table></center>
+
+<h2>
+Compiling for Unix OSS</h2>
+
+<blockquote>[Skip this page if you are not using Unix and OSS]
+<p>We currently support the <a href="http://www.opensound.com/">OSS</a>
+audio drivers for Linux, Solaris, and FreeBSD. We hope to someday support
+the newer ALSA drivers.
+<ol>
+<li>
+cd to pa_unix_oss directory</li>
+
+<li>
+Edit the Makefile and uncomment one of the tests. You may try compiling
+the "patest_sine.c" file first because it is very simple.</li>
+
+<li>
+gmake run</li>
+</ol>
+</blockquote>
+<font size=+2><a href="http://www.portaudio.com/">home</a> |
+<a href="pa_tutorial.html">contents</a>
+| <a href="pa_tut_pc.html">previous</a> |&nbsp; <a href="pa_tut_callback.html">next</a></font>
+</body>
+</html>
diff --git a/utils/iaxclient/lib/portaudio/docs/pa_tut_over.html b/utils/iaxclient/lib/portaudio/docs/pa_tut_over.html
new file mode 100644 (file)
index 0000000..baa9920
--- /dev/null
@@ -0,0 +1,92 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
+   <meta name="Author" content="Phil Burk">
+   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
+   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
+   <title>PortAudio Tutorial</title>
+</head>
+<body>
+&nbsp;
+<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
+<tr>
+<td>
+<center>
+<h1>
+PortAudio Tutorial</h1></center>
+</td>
+</tr>
+</table></center>
+
+<h2>
+Overview of PortAudio</h2>
+
+<blockquote>PortAudio is a library that provides streaming audio input
+and output. It is a cross-platform API (Application Programming Interface)
+that works on Windows, Macintosh, Unix running OSS, SGI, BeOS, and perhaps
+other platforms by the time you read this. This means that you can write
+a simple 'C' program to process or generate an audio signal, and that program
+can run on several different types of computer just by recompiling the
+source code.
+<p>Here are the steps to writing a PortAudio application:
+<ol>
+<li>
+Write a callback function that will be called by PortAudio when audio processing
+is needed.</li>
+
+<li>
+Initialize the PA library and open a stream for audio I/O.</li>
+
+<li>
+Start the stream. Your callback function will be now be called repeatedly
+by PA in the background.</li>
+
+<li>
+In your callback you can read audio data from the inputBuffer and/or write
+data to the outputBuffer.</li>
+
+<li>
+Stop the stream by returning 1 from your callback, or by calling a stop
+function.</li>
+
+<li>
+Close the stream and terminate the library.</li>
+</ol>
+</blockquote>
+
+<blockquote>There is also <a href="pa_tut_rw.html">another interface</a>
+provided that allows you to generate audio in the foreground. You then
+simply write data to the stream and the tool will not return until it is
+ready to accept more data. This interface is simpler to use but is usually
+not preferred for large applications because it requires that you launch
+a thread to perform the synthesis. Launching a thread may be difficult
+on non-multi-tasking systems such as the Macintosh prior to MacOS X.
+<p>Let's continue by building a simple application that will play a sawtooth
+wave.
+<p>Please select the page for the specific implementation you would like
+to use:
+<ul>
+<li>
+<a href="pa_tut_pc.html">Windows (WMME or DirectSound)</a></li>
+
+<li>
+<a href="pa_tut_mac.html">Macintosh SoundManager for OS 7,8,9</a></li>
+
+<li>
+<a href="pa_tut_mac_osx.html">Macintosh CoreAudio for OS X</a></li>
+
+<li>
+<a href="pa_tut_asio.html">ASIO on Windows or Macintosh</a></li>
+
+<li>
+<a href="pa_tut_oss.html">Unix OSS</a></li>
+</ul>
+or continue with the <a href="pa_tut_callback.html">next page of the programming
+tutorial</a>.</blockquote>
+<font size=+2><a href="http://www.portaudio.com/">home</a> |
+<a href="pa_tutorial.html">contents</a>
+| <a href="pa_tutorial.html">previous</a></font>
+</body>
+</html>
diff --git a/utils/iaxclient/lib/portaudio/docs/pa_tut_pc.html b/utils/iaxclient/lib/portaudio/docs/pa_tut_pc.html
new file mode 100644 (file)
index 0000000..87e5f9a
--- /dev/null
@@ -0,0 +1,78 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.77 [en]C-gatewaynet  (Win98; U) [Netscape]">
+   <meta name="Author" content="Phil Burk">
+   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
+   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
+   <title>PortAudio Tutorial</title>
+</head>
+<body>
+&nbsp;
+<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
+<tr>
+<td>
+<center>
+<h1>
+PortAudio Tutorial</h1></center>
+</td>
+</tr>
+</table></center>
+
+<h2>
+Compiling for Windows (WMME or DirectSound)</h2>
+
+<blockquote>To compile PortAudio for Windows, you can choose between two
+options. One implementation uses the DirectSound API. The other uses the
+Windows MultiMedia Extensions API (aka WMME or WAVE).
+<p>Some advantages of using DirectSound are that DirectSound may have lower
+latency than WMME, and supports effects processing plugins. But one disadvantage
+is that DirectSound is not installed on all PCs, and is not well supported
+under Windows NT. So WMME is the best choice for most projects.
+<p>For either implementation add the following source files to your project:
+<blockquote>
+<pre><b>pa_common\pa_lib.c
+pa_common\portaudio.h
+pa_common\pa_host.h</b></pre>
+</blockquote>
+Link with the system library "<b>winmm.lib</b>". For Visual C++:
+<ol>
+<li>
+select "Settings..." from the "Project" menu,</li>
+
+<li>
+select the project name in the tree on the left,</li>
+
+<li>
+choose "All Configurations" in the popup menu above the tree,</li>
+
+<li>
+select the "Link" tab,</li>
+
+<li>
+enter "winmm.lib", without quotes, as the first item in the "Object/library
+modules:" field.</li>
+</ol>
+<b>WMME</b> - To use the WMME implementation, add the following source
+files to your project:
+<blockquote><b><tt>pa_win_wmme/pa_win_wmme.c</tt></b></blockquote>
+<b>DirectSound</b> - If you want to use the DirectSound implementation
+of PortAudio then you must have a recent copy of the free
+<a href="http://www.microsoft.com/directx/download.asp">DirectX</a>
+SDK for Developers from Microsoft installed on your computer. To compile
+an application add the following source files to your project:
+<blockquote>
+<pre><b>pa_win_ds\dsound_wrapper.c
+pa_win_ds\pa_dsound.c</b></pre>
+</blockquote>
+Link with the system library "<b>dsound.lib</b>" using the procedure described
+above for "winmm.lib".</blockquote>
+
+<blockquote>You might try compiling the "pa_tests\patest_saw.c" file first
+because it is the simplest.</blockquote>
+<font size=+2><a href="http://www.portaudio.com/">home</a> |
+<a href="pa_tutorial.html">contents</a>
+| <a href="pa_tut_over.html">previous</a> |&nbsp; <a href="pa_tut_callback.html">next</a></font>
+</body>
+</html>
diff --git a/utils/iaxclient/lib/portaudio/docs/pa_tut_run.html b/utils/iaxclient/lib/portaudio/docs/pa_tut_run.html
new file mode 100644 (file)
index 0000000..5c70d08
--- /dev/null
@@ -0,0 +1,56 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.73 [en]C-gatewaynet  (Win98; U) [Netscape]">
+   <meta name="Author" content="Phil Burk">
+   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
+   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
+   <title>PortAudio Tutorial</title>
+</head>
+<body>
+&nbsp;
+<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
+<tr>
+<td>
+<center>
+<h1>
+PortAudio Tutorial</h1></center>
+</td>
+</tr>
+</table></center>
+
+<h2>
+Starting and Stopping a Stream</h2>
+
+<blockquote>The stream will not start running until you call Pa_StartStream().
+Then it will start calling your callback function to perform the audio
+processing.
+<blockquote>
+<pre>err = Pa_StartStream( stream );
+if( err != paNoError ) goto error;</pre>
+</blockquote>
+At this point, audio is being generated. You can communicate to your callback
+routine through the data structure you passed in on the open call, or through
+global variables, or using other interprocess communication techniques.
+Please be aware that your callback function may be called at interrupt
+time when your foreground process is least expecting it. So avoid sharing
+complex data structures that are easily corrupted like double linked lists.
+<p>In many of the tests we simply sleep for a few seconds so we can hear
+the sound. This is easy to do with Pa_Sleep() which will sleep for some
+number of milliseconds. Do not rely on this function for accurate scheduling.
+it is mostly for writing examples.
+<blockquote>
+<pre>/* Sleep for several seconds. */
+Pa_Sleep(NUM_SECONDS*1000);</pre>
+</blockquote>
+When you are through, you can stop the stream from the foreground.
+<blockquote>
+<pre>err = Pa_StopStream( stream );
+if( err != paNoError ) goto error;</pre>
+</blockquote>
+You can also stop the stream by returning 1 from your custom callback function.</blockquote>
+<font size=+2><a href="http://www.portaudio.com/">home</a> | <a href="pa_tutorial.html">contents</a>
+| <a href="pa_tut_open.html">previous</a> |&nbsp; <a href="pa_tut_term.html">next</a></font>
+</body>
+</html>
diff --git a/utils/iaxclient/lib/portaudio/docs/pa_tut_rw.html b/utils/iaxclient/lib/portaudio/docs/pa_tut_rw.html
new file mode 100644 (file)
index 0000000..93c7b8b
--- /dev/null
@@ -0,0 +1,79 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.77 [en]C-gatewaynet  (Win98; U) [Netscape]">
+   <meta name="Author" content="Phil Burk">
+   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
+   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
+   <title>PortAudio Tutorial</title>
+</head>
+<body>
+&nbsp;
+<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
+<tr>
+<td>
+<center>
+<h1>
+PortAudio Tutorial</h1></center>
+</td>
+</tr>
+</table></center>
+
+<h2>
+Blocking Read/Write Functions</h2>
+
+<blockquote>[Note: These functions are not part of the official PortAudio
+API. They are simply built on top of PortAudio as an extra utility. Also
+note that they are under evaluation and their definition may change.]
+<p>There are two fundamentally different ways to design an audio API. One
+is to use callback functions the way we have already shown. The callback
+function operates under an interrupt or background thread This leaves the
+foreground application free to do other things while the audio just runs
+in the background. But this can sometimes be awkward.
+<p>So we have provided an alternative technique that lets a program generate
+audio in the foreground and then just write it to the audio stream as if
+it was a file. If there is not enough room in the audio buffer for more
+data, then the write function will just block until more room is available.
+This can make it very easy to write an audio example. To use this tool,
+you must add the files "pablio/pablio.c" and "pablio/ringbuffer.c" to your
+project. You must also:
+<blockquote>
+<pre>#include "pablio.h"</pre>
+</blockquote>
+Here is a short excerpt of a program that opens a stream for input and
+output. It then reads a block of samples from input, and writes them to
+output, in a loop.&nbsp; The complete example can be found in "pablio/test_rw.c".
+<blockquote>
+<pre>&nbsp;&nbsp;&nbsp; #define SAMPLES_PER_FRAME&nbsp;&nbsp;&nbsp;&nbsp; (2)
+&nbsp;&nbsp;&nbsp; #define FRAMES_PER_BLOCK&nbsp;&nbsp;&nbsp; (1024)
+&nbsp;&nbsp;&nbsp; SAMPLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; samples[SAMPLES_PER_FRAME * FRAMES_PER_BLOCK];
+&nbsp;&nbsp;&nbsp; PaError&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; err;
+&nbsp;&nbsp;&nbsp; PABLIO_Stream&nbsp; *aStream;
+
+/* Open simplified blocking I/O layer on top of PortAudio. */
+&nbsp;&nbsp;&nbsp; err = OpenAudioStream( &amp;rwbl, SAMPLE_RATE, paFloat32,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (PABLIO_READ_WRITE | PABLIO_STEREO) );
+&nbsp;&nbsp;&nbsp; if( err != paNoError ) goto error;
+
+/* Process samples in the foreground. */
+&nbsp;&nbsp;&nbsp; for( i=0; i&lt;(NUM_SECONDS * SAMPLE_RATE); i++ )
+&nbsp;&nbsp;&nbsp; {
+&nbsp;&nbsp;&nbsp; /* Read one block of data into sample array from audio input. */
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ReadAudioStream( aStream, samples, FRAMES_PER_BLOCK );
+&nbsp;&nbsp;&nbsp; /*
+&nbsp;&nbsp;&nbsp; ** At this point you could process the data in samples array,
+&nbsp;&nbsp;&nbsp; ** and write the result back to the same samples array.
+&nbsp;&nbsp;&nbsp; */
+&nbsp;&nbsp;&nbsp; /* Write that same frame of data to output. */
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WriteAudioStream( aStream, samples, FRAMES_PER_BLOCK );
+&nbsp;&nbsp;&nbsp; }
+
+&nbsp;&nbsp;&nbsp; CloseAudioStream( aStream );</pre>
+</blockquote>
+</blockquote>
+<font size=+2><a href="http://www.portaudio.com/">home</a> |
+<a href="pa_tutorial.html">contents</a>
+| <a href="pa_tut_devs.html">previous</a> |&nbsp; <a href="pa_tut_explore.html">next</a></font>
+</body>
+</html>
diff --git a/utils/iaxclient/lib/portaudio/docs/pa_tut_term.html b/utils/iaxclient/lib/portaudio/docs/pa_tut_term.html
new file mode 100644 (file)
index 0000000..1c72209
--- /dev/null
@@ -0,0 +1,47 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.73 [en]C-gatewaynet  (Win98; U) [Netscape]">
+   <meta name="Author" content="Phil Burk">
+   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
+   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
+   <title>PortAudio Tutorial</title>
+</head>
+<body>
+&nbsp;
+<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
+<tr>
+<td>
+<center>
+<h1>
+PortAudio Tutorial</h1></center>
+</td>
+</tr>
+</table></center>
+
+<h2>
+Terminating PortAudio</h2>
+
+<blockquote>You can start and stop a stream as many times as you like.
+But when you are done using it, you should close it by calling:</blockquote>
+
+<blockquote>
+<blockquote>
+<pre>err = Pa_CloseStream( stream );
+if( err != paNoError ) goto error;</pre>
+</blockquote>
+Then when you are done using PortAudio, you should terminate the whole
+system by calling:
+<blockquote>
+<pre>Pa_Terminate();</pre>
+</blockquote>
+That's basically it. You can now write an audio program in 'C' that will
+run on multiple platforms, for example PCs and Macintosh.
+<p>In the rest of the tutorial we will look at some additional utility
+functions, and a different way of using PortAudio that does not require
+the use of a callback function.</blockquote>
+<font size=+2><a href="http://www.portaudio.com/">home</a> | <a href="pa_tutorial.html">contents</a>
+| <a href="pa_tut_run.html">previous</a> |&nbsp; <a href="pa_tut_util.html">next</a></font>
+</body>
+</html>
diff --git a/utils/iaxclient/lib/portaudio/docs/pa_tut_util.html b/utils/iaxclient/lib/portaudio/docs/pa_tut_util.html
new file mode 100644 (file)
index 0000000..f4b5475
--- /dev/null
@@ -0,0 +1,55 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.75 [en]C-gatewaynet  (Win98; U) [Netscape]">
+   <meta name="Author" content="Phil Burk">
+   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
+   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
+   <title>PortAudio Tutorial</title>
+</head>
+<body>
+&nbsp;
+<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
+<tr>
+<td>
+<center>
+<h1>
+PortAudio Tutorial</h1></center>
+</td>
+</tr>
+</table></center>
+
+<h2>
+Utility Functions</h2>
+
+<blockquote>Here are several more functions that are not critical, but
+may be handy when using PortAudio.
+<p>Pa_StreamActive() returns one when the stream in playing audio, zero
+when not playing, or a negative error number if the stream is invalid.
+The stream is active between calls to Pa_StartStream() and Pa_StopStream(),
+but may also become inactive if the callback returns a non-zero value.
+In the latter case, the stream is considered inactive after the last buffer
+has finished playing.
+<blockquote>
+<pre>PaError Pa_StreamActive( PortAudioStream *stream );</pre>
+</blockquote>
+Pa_StreamTime() returns the number of samples that have been generated.
+PaTimeStamp is a double precision number which is a convenient way to pass
+big numbers around even though we only need integers.
+<blockquote>
+<pre>PaTimestamp Pa_StreamTime( PortAudioStream *stream );</pre>
+</blockquote>
+The "CPU Load" is a fraction of total CPU time consumed by the stream's
+audio processing. A value of 0.5 would imply that PortAudio and the sound
+generating callback was consuming roughly 50% of the available CPU time.
+This function may be called from the callback function or the application.
+<blockquote>
+<pre>double Pa_GetCPULoad( PortAudioStream* stream );</pre>
+</blockquote>
+</blockquote>
+<font size=+2><a href="http://www.portaudio.com/">home</a> |
+<a href="pa_tutorial.html">contents</a> | <a href="pa_tut_term.html">previous</a>
+|&nbsp; <a href="pa_tut_devs.html">next</a></font>
+</body>
+</html>
diff --git a/utils/iaxclient/lib/portaudio/docs/pa_tutorial.html b/utils/iaxclient/lib/portaudio/docs/pa_tutorial.html
new file mode 100644 (file)
index 0000000..1371c44
--- /dev/null
@@ -0,0 +1,46 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
+   <meta name="Author" content="Phil Burk">
+   <meta name="Description" content="Tutorial for PortAudio, a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
+   <meta name="KeyWords" content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
+   <title>PortAudio Tutorial</title>
+</head>
+<body>
+&nbsp;
+<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
+<tr>
+<td>
+<center>
+<h1>
+PortAudio Tutorial</h1></center>
+</td>
+</tr>
+</table></center>
+
+<p>Copyright 2000 Phil Burk and Ross Bencina
+<h2>
+Table of Contents</h2>
+
+<blockquote><a href="pa_tut_over.html">Overview of PortAudio</a>
+<br><a href="pa_tut_mac.html">Compiling for Macintosh OS 7,8,9</a>
+<br><a href="pa_tut_mac_osx.html">Compiling for Macintosh OS X</a>
+<br><a href="pa_tut_pc.html">Compiling for Windows (DirectSound and WMME)</a>
+<br><a href="pa_tut_asio.html">Compiling for ASIO on Windows or Mac OS
+8,9</a>
+<br><a href="pa_tut_oss.html">Compiling for Unix OSS</a>
+<br><a href="pa_tut_callback.html">Writing a Callback Function</a>
+<br><a href="pa_tut_init.html">Initializing PortAudio</a>
+<br><a href="pa_tut_open.html">Opening a Stream using Defaults</a>
+<br><a href="pa_tut_run.html">Starting and Stopping a Stream</a>
+<br><a href="pa_tut_term.html">Cleaning Up</a>
+<br><a href="pa_tut_util.html">Utilities</a>
+<br><a href="pa_tut_devs.html">Querying for Devices</a>
+<br><a href="pa_tut_rw.html">Blocking Read/Write Functions</a>
+<br><a href="pa_tut_explore.html">Exploring the PortAudio Package</a></blockquote>
+<font size=+2><a href="http://www.portaudio.com/">home</a> | contents |
+previous |&nbsp; <a href="pa_tut_over.html">next</a></font>
+</body>
+</html>
diff --git a/utils/iaxclient/lib/portaudio/docs/portaudio_h.txt b/utils/iaxclient/lib/portaudio/docs/portaudio_h.txt
new file mode 100644 (file)
index 0000000..6d60086
--- /dev/null
@@ -0,0 +1,425 @@
+#ifndef PORT_AUDIO_H
+#define PORT_AUDIO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * PortAudio Portable Real-Time Audio Library
+ * PortAudio API Header File
+ * Latest version available at: http://www.audiomulch.com/portaudio/
+ *
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+typedef int PaError;
+typedef enum {
+       paNoError = 0,
+
+       paHostError = -10000,
+       paInvalidChannelCount,
+       paInvalidSampleRate,
+       paInvalidDeviceId,
+       paInvalidFlag,
+       paSampleFormatNotSupported,
+       paBadIODeviceCombination,
+       paInsufficientMemory,
+       paBufferTooBig,
+       paBufferTooSmall,
+       paNullCallback,
+       paBadStreamPtr,
+       paTimedOut,
+       paInternalError
+} PaErrorNum;
+
+/*
+       Pa_Initialize() is the library initialisation function - call this before
+       using the library.
+*/
+
+PaError Pa_Initialize( void );
+
+/*
+       Pa_Terminate() is the library termination function - call this after
+       using the library.
+*/
+
+PaError Pa_Terminate( void );
+
+/*
+       Return host specific error.
+       This can be called after receiving a paHostError.
+*/
+long Pa_GetHostError( void );
+
+/*
+       Translate the error number into a human readable message.
+*/
+const char *Pa_GetErrorText( PaError errnum );
+
+/*
+       Sample formats
+
+       These are formats used to pass sound data between the callback and the
+       stream. Each device has a "native" format which may be used when optimum
+       efficiency or control over conversion is required.
+
+       Formats marked "always available" are supported (emulated) by all devices.
+
+       The floating point representation uses +1.0 and -1.0 as the respective
+       maximum and minimum.
+       
+*/
+
+typedef unsigned long PaSampleFormat;
+#define paFloat32      ((PaSampleFormat) (1<<0))       /*always available*/
+#define paInt16        ((PaSampleFormat) (1<<1))       /*always available*/
+#define paInt32        ((PaSampleFormat) (1<<2))       /*always available*/
+#define paInt24        ((PaSampleFormat) (1<<3))
+#define paPackedInt24  ((PaSampleFormat) (1<<4))
+#define paInt8         ((PaSampleFormat) (1<<5))
+#define paUInt8        ((PaSampleFormat) (1<<6))    /* unsigned 8 bit, 128 is "ground" */
+#define paCustomFormat ((PaSampleFormat) (1<<16))
+
+/*
+       Device enumeration mechanism.
+
+       Device ids range from 0 to Pa_CountDevices()-1.
+
+       Devices may support input, output or both. Device 0 is always the "default"
+       device and should support at least stereo in and out if that is available
+       on the taget platform _even_ if this involves kludging an input/output
+       device on platforms that usually separate input from output. Other platform
+       specific devices are specified by positive device ids.
+*/
+
+typedef int PaDeviceID;
+#define paNoDevice -1
+
+typedef struct{
+       int structVersion; 
+       const char *name;
+       int maxInputChannels;
+       int maxOutputChannels;
+/* Number of discrete rates, or -1 if range supported. */
+       int numSampleRates;
+/* Array of supported sample rates, or {min,max} if range supported. */
+       const double *sampleRates;
+       PaSampleFormat nativeSampleFormats;
+} PaDeviceInfo;
+
+
+int Pa_CountDevices();
+/*
+       Pa_GetDefaultInputDeviceID(), Pa_GetDefaultOutputDeviceID()
+
+       Return the default device ID or paNoDevice if there is no devices.
+       The result can be passed to Pa_OpenStream().
+       
+       On the PC, the user can specify a default device by
+       setting an environment variable. For example, to use device #1.
+
+               set PA_RECOMMENDED_OUTPUT_DEVICE=1
+       
+       The user should first determine the available device ID by using
+       the supplied application "pa_devs".
+*/
+PaDeviceID Pa_GetDefaultInputDeviceID( void );
+PaDeviceID Pa_GetDefaultOutputDeviceID( void );
+
+/*
+       PaTimestamp is used to represent a continuous sample clock with arbitrary
+       start time useful for syncronisation. The type is used in the outTime
+       argument to the callback function and the result of Pa_StreamTime()
+*/
+
+typedef double PaTimestamp;
+
+/*
+       Pa_GetDeviceInfo() returns a pointer to an immutable PaDeviceInfo structure
+       referring to the device specified by id.
+       If id is out of range the function returns NULL.
+
+       The returned structure is owned by the PortAudio implementation and must
+       not be manipulated or freed. The pointer is guaranteed to be valid until
+       between calls to Pa_Initialize() and Pa_Terminate().
+*/
+
+const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID devID );
+
+/*
+       PortAudioCallback is implemented by clients of the portable audio api.
+
+       inputBuffer and outputBuffer are arrays of interleaved samples,
+       the format, packing and number of channels used by the buffers are
+       determined by parameters to Pa_OpenStream() (see below).
+
+       framesPerBuffer is the number of sample frames to be processed by the callback.
+
+       outTime is the time in samples when the buffer(s) processed by
+       this callback will begin being played at the audio output.
+       See also Pa_StreamTime()
+
+       userData is the value of a user supplied pointer passed to Pa_OpenStream()
+       intended for storing synthesis data etc.
+
+       return value:
+       The callback can return a nonzero value to stop the stream. This may be
+       useful in applications such as soundfile players where a specific duration
+       of output is required. However, it is not necessary to utilise this mechanism
+       as StopStream() will also terminate the stream. A callback returning a
+       nonzero value must fill the entire outputBuffer.
+
+       NOTE: None of the other stream functions may be called from within the
+       callback function except for Pa_GetCPULoad().
+
+*/
+
+typedef int (PortAudioCallback)(
+               void *inputBuffer, void *outputBuffer,
+               unsigned long framesPerBuffer,
+               PaTimestamp outTime, void *userData );
+
+
+/*
+       Stream flags
+
+       These flags may be supplied (ored together) in the streamFlags argument to
+       the Pa_OpenStream() function.
+
+       [ suggestions? ]
+*/
+
+#define   paNoFlag      (0)
+#define   paClipOff     (1<<0)   /* disable defult clipping of out of range samples */
+#define   paDitherOff   (1<<1)   /* disable default dithering */
+#define   paPlatformSpecificFlags (0x00010000)
+typedef   unsigned long PaStreamFlags;
+
+/*
+       A single PortAudioStream provides multiple channels of real-time
+       input and output audio streaming to a client application.
+       Pointers to PortAudioStream objects are passed between PortAudio functions.
+*/
+
+typedef void PortAudioStream;
+#define PaStream PortAudioStream
+
+/*
+       Pa_OpenStream() opens a stream for either input, output or both.
+
+       stream is the address of a PortAudioStream pointer which will receive
+       a pointer to the newly opened stream.
+
+       inputDevice is the id of the device used for input (see PaDeviceID above.)
+       inputDevice may be paNoDevice to indicate that an input device is not required.
+
+       numInputChannels is the number of channels of sound to be delivered to the
+       callback. It can range from 1 to the value of maxInputChannels in the
+       device input record for the device specified in the inputDevice parameter.
+       If inputDevice is paNoDevice numInputChannels is ignored.
+
+       inputSampleFormat is the format of inputBuffer provided to the callback
+       function. inputSampleFormat may be any of the formats described by the
+       PaSampleFormat enumeration (see above). PortAudio guarantees support for
+       the sound devices native formats (nativeSampleFormats in the device info
+       record) and additionally 16 and 32 bit integer and 32 bit floating point
+       formats. Support for other formats is implementation defined.
+
+       inputDriverInfo is a pointer to an optional driver specific data structure
+       containing additional information for device setup or stream processing.
+       inputDriverInfo is never required for correct operation. If not used
+       inputDriverInfo should be NULL.
+
+       outputDevice is the id of the device used for output (see PaDeviceID above.)
+       outputDevice may be paNoDevice to indicate that an output device is not required.
+
+       numOutputChannels is the number of channels of sound to be supplied by the
+       callback. See the definition of numInputChannels above for more details.
+
+       outputSampleFormat is the sample format of the outputBuffer filled by the
+       callback function. See the definition of inputSampleFormat above for more
+       details.
+
+       outputDriverInfo is a pointer to an optional driver specific data structure
+       containing additional information for device setup or stream processing.
+       outputDriverInfo is never required for correct operation. If not used
+       outputDriverInfo should be NULL.
+
+       sampleRate is the desired sampleRate for input and output
+
+       framesPerBuffer is the length in sample frames of all internal sample buffers
+       used for communication with platform specific audio routines. Wherever
+       possible this corresponds to the framesPerBuffer parameter passed to the
+       callback function.
+
+       numberOfBuffers is the number of buffers used for multibuffered
+       communication with the platform specific audio routines. This parameter is
+       provided only as a guide - and does not imply that an implementation must
+       use multibuffered i/o when reliable double buffering is available (such as
+       SndPlayDoubleBuffer() on the Macintosh.)
+
+       streamFlags may contain a combination of flags ORed together.
+       These flags modify the behavior of the
+       streaming process. Some flags may only be relevant to certain buffer formats.
+
+       callback is a pointer to a client supplied function that is responsible
+       for processing and filling input and output buffers (see above for details.)
+
+       userData is a client supplied pointer which is passed to the callback
+       function. It could for example, contain a pointer to instance data necessary
+       for processing the audio buffers.
+
+       return value:
+       Apon success Pa_OpenStream() returns PaNoError and places a pointer to a
+       valid PortAudioStream in the stream argument. The stream is inactive (stopped).
+       If a call to Pa_OpenStream() fails a nonzero error code is returned (see
+       PAError above) and the value of stream is invalid.
+
+*/
+
+PaError Pa_OpenStream( PortAudioStream** stream,
+                               PaDeviceID inputDevice,
+                               int numInputChannels,
+                               PaSampleFormat inputSampleFormat,
+                               void *inputDriverInfo,
+                               PaDeviceID outputDevice,
+                               int numOutputChannels,
+                               PaSampleFormat outputSampleFormat,
+                               void *outputDriverInfo,
+                               double sampleRate,
+                               unsigned long framesPerBuffer,
+                               unsigned long numberOfBuffers,
+                               PaStreamFlags streamFlags,
+                               PortAudioCallback *callback,
+                               void *userData );
+
+
+/*
+       Pa_OpenDefaultStream() is a simplified version of Pa_OpenStream() that
+       opens the default input and/or ouput devices. Most parameters have
+       identical meaning to their Pa_OpenStream() counterparts, with the following
+       exceptions:
+
+       If either numInputChannels or numOutputChannels is 0 the respective device
+       is not opened (same as passing paNoDevice in the device arguments to Pa_OpenStream() )
+
+       sampleFormat applies to both the input and output buffers.
+*/
+
+PaError Pa_OpenDefaultStream( PortAudioStream** stream,
+                               int numInputChannels,
+                               int numOutputChannels,
+                               PaSampleFormat sampleFormat,
+                               double sampleRate,
+                               unsigned long framesPerBuffer,
+                               unsigned long numberOfBuffers,
+                               PortAudioCallback *callback,
+                               void *userData );
+          
+/*
+       Pa_CloseStream() closes an audio stream, flushing any pending buffers.
+*/
+
+PaError Pa_CloseStream( PortAudioStream* );
+
+/*
+       Pa_StartStream() and Pa_StopStream() begin and terminate audio processing.
+       Pa_StopStream() waits until all pending audio buffers have been played.
+    Pa_AbortStream() stops playing immediately without waiting for pending
+    buffers to complete.
+*/
+
+PaError Pa_StartStream( PortAudioStream *stream );
+
+PaError Pa_StopStream( PortAudioStream *stream );
+
+PaError Pa_AbortStream( PortAudioStream *stream );
+
+/*
+       Pa_StreamActive() returns one when the stream is playing audio,
+       zero when not playing, or a negative error number if the
+       stream is invalid.
+       The stream is active between calls to Pa_StartStream() and Pa_StopStream(),
+       but may also become inactive if the callback returns a non-zero value.
+       In the latter case, the stream is considered inactive after the last
+       buffer has finished playing.
+*/
+
+PaError Pa_StreamActive( PortAudioStream *stream );
+
+/*
+       Pa_StreamTime() returns the current output time for the stream in samples.
+       This time may be used as a time reference (for example syncronising audio to
+       MIDI).
+*/
+
+PaTimestamp Pa_StreamTime( PortAudioStream *stream );
+
+/*
+       The "CPU Load" is a fraction of total CPU time consumed by the
+       stream's audio processing.
+       A value of 0.5 would imply that PortAudio and the sound generating
+       callback was consuming roughly 50% of the available CPU time.
+       This function may be called from the callback function or the application.
+*/
+double Pa_GetCPULoad( PortAudioStream* stream );
+
+/*
+       Use Pa_GetMinNumBuffers() to determine minimum number of buffers required for
+       the current host based on minimum latency. 
+       On the PC, for the DirectSound implementation, latency can be optionally set
+       by user by setting an environment variable.
+       For example, to set latency to 200 msec, put:
+       
+          set PA_MIN_LATENCY_MSEC=200
+       
+       in the AUTOEXEC.BAT file and reboot.
+       If the environment variable is not set, then the latency will be determined
+       based on the OS. Windows NT has higher latency than Win95.
+*/
+
+int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate );
+
+/*
+       Sleep for at least 'msec' milliseconds.
+       You may sleep longer than the requested time so don't rely
+       on this for accurate musical timing.
+*/
+void Pa_Sleep( long msec );
+
+/*
+       Return size in bytes of a single sample in a given PaSampleFormat
+       or paSampleFormatNotSupported. 
+*/
+PaError Pa_GetSampleSize( PaSampleFormat format );
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* PORT_AUDIO_H */
diff --git a/utils/iaxclient/lib/portaudio/docs/portaudio_icmc2001.pdf b/utils/iaxclient/lib/portaudio/docs/portaudio_icmc2001.pdf
new file mode 100644 (file)
index 0000000..dd074b7
Binary files /dev/null and b/utils/iaxclient/lib/portaudio/docs/portaudio_icmc2001.pdf differ
diff --git a/utils/iaxclient/lib/portaudio/docs/proposals.html b/utils/iaxclient/lib/portaudio/docs/proposals.html
new file mode 100644 (file)
index 0000000..0f9b8cb
--- /dev/null
@@ -0,0 +1,36 @@
+<HTML>
+<HEAD>
+<TITLE>Proposed Changes to PortAudio API</TITLE>
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<META content="Phil Burk, Ross Bencina" name=Author>
+<META content="Changes being discussed by the community of PortAudio deveopers." 
+name=Description>
+<META 
+content="audio, tutorial, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis," 
+name=KeyWords>
+</HEAD>
+<BODY LINK="#0000ff" VLINK="#800080">&nbsp; 
+<CENTER>
+<TABLE bgColor=#fada7a cols=1 width="100%">
+  <TBODY>
+  <TR>
+    <TD>
+      <CENTER>
+      <H1>Proposed Changes to PortAudio API</H1>
+       </CENTER>
+</TD></TR></TBODY></TABLE></CENTER>
+<P><A href="http://www.portaudio.com/">PortAudio Home Page</A></P>
+
+<P>Updated: July 27, 2002 </P>
+<H2>The Proposals Have Moved</H2>
+
+<p>
+All PortAudio Enhancement Proposal documentation has moved. On the web site, it is now located at:
+<A HREF="http://www.portaudio.com/docs/proposals">http://www.portaudio.com/docs/proposals</A>
+
+On the CVS server it is now located in a module named "pa_proposals".
+</p>
+
+
+</BODY>
+</HTML>
diff --git a/utils/iaxclient/lib/portaudio/docs/releases.html b/utils/iaxclient/lib/portaudio/docs/releases.html
new file mode 100644 (file)
index 0000000..aec80a1
--- /dev/null
@@ -0,0 +1,339 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
+   <meta name="Author" content="Phil Burk">
+   <meta name="Description" content="PortAudio is a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
+   <meta name="KeyWords" content="audio, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
+   <title>PortAudio Release Notes</title>
+</head>
+<body>
+&nbsp;
+<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
+<tr>
+<td>
+<center>
+<h1>
+PortAudio - Release Notes</h1></center>
+</td>
+</tr>
+</table></center>
+
+<p>Link to <a href="http://www.portaudio.com">PortAudio Home Page</a>
+<h2>
+<b>V18 - 5/6/02</b></h2>
+
+<blockquote>All source code and documentation now under <a href="http://www.portaudio.com/usingcvs.html">CVS</a>.
+<p>Ran most of the code through <a href="http://astyle.sourceforge.net/">AStyle</a>
+to cleanup ragged indentation caused by using different editors. Used this
+command:
+<br><tt>&nbsp;&nbsp; astyle --style=ansi -c -o --convert-tabs --indent-preprocessor
+*.c</tt></blockquote>
+
+<blockquote>Added "pa_common/pa_convert.c" for Mac OS X. Start of new conversion
+utilities.
+<p><b>ASIO</b>
+<ul>
+<li>
+New Pa_ASIO_Adaptor_Init function to init Callback adpatation variables,</li>
+
+<li>
+Cleanup of Pa_ASIO_Callback_Input</li>
+
+<li>
+Break apart device loading to debug random failure in Pa_ASIO_QueryDeviceInfo</li>
+
+<li>
+Deallocate all resources in PaHost_Term for cases where Pa_CloseStream
+is not called properly</li>
+
+<li>
+New Pa_ASIO_loadDriver that calls CoInitialize on each thread on Windows.
+Allows use by multiple threads.</li>
+
+<li>
+Correct error code management in PaHost_Term, removed various compiler
+warning</li>
+
+<li>
+Add Mac includes for &lt;Devices.h> and &lt;Timer.h></li>
+
+<li>
+Pa_ASIO_QueryDeviceInfo bug correction, memory allocation checking, better
+error handling</li>
+</ul>
+<b>Mac OS X</b>
+<ul>
+<li>
+Major cleanup and improvements.</li>
+
+<li>
+Fixed device queries for numChannels and sampleRates,</li>
+
+<li>
+Audio input works if using same CoreAudio device (some HW devices make
+separate CoreAudio devices).</li>
+
+<li>
+Added paInt16, paInt8, format using new "pa_common/pa_convert.c" file.</li>
+
+<li>
+Return error if opened in mono mode cuz not supported.</li>
+
+<li>
+Check for getenv("PA_MIN_LATEWNCY_MSEC") to set latency externally.</li>
+
+<li>
+Use getrusage() instead of gettimeofday() for CPU Load calculation.</li>
+</ul>
+<b>Windows MME</b>
+<ul>
+<li>
+Fixed bug that caused TIMEOUT in Pa_StopStream(). Added check for past_StopSoon()
+in Pa_TimeSlice(). Thanks Julien Maillard.</li>
+
+<li>
+Detect Win XP versus NT, use lower latency.</li>
+
+<li>
+Fix DBUG typo;</li>
+
+<li>
+removed init of CurrentCount which was not compiling on Borland</li>
+
+<li>
+general cleanup, factored streamData alloc and cpu usage initialization</li>
+
+<li>
+stopped counting WAVE_MAPPER when there were no audio cards plugged in</li>
+</ul>
+<b>Windows DirectSound</b>
+<ul>
+<li>
+Detect Win XP and Win 2K properly when determining latency.</li>
+</ul>
+<b>Unix OSS</b>
+<ul>
+<li>
+Use high real-time priority if app is running with root priveledges. Lowers
+latency.</li>
+
+<li>
+Added watch dog thread that prevents real-time thread from hogging CPU
+and hanging the computer.</li>
+
+<li>
+Check error return from read() and write().</li>
+
+<li>
+Check CPU endianness instead of assuming Little Endian.</li>
+</ul>
+</blockquote>
+
+<h2>
+<b>V17 - 10/15/01</b></h2>
+
+<blockquote><b>Unix OSS</b>
+<ul>
+<li>
+Set num channels back to two after device query for ALSA. This fixed a
+bug in V16 that sometimes caused a failure when querying for the sample
+rates. Thanks Stweart Greenhill.</li>
+</ul>
+</blockquote>
+
+<blockquote>
+<h4>
+<b>Macintosh Sound Manager</b></h4>
+
+<ul>
+<li>
+Use NewSndCallBackUPP() for CARBON compatibility.</li>
+</ul>
+</blockquote>
+
+<h2>
+<b>V16 - 9/27/01</b></h2>
+
+<blockquote><b>Added Alpha implementations for ASIO, SGI, and BeOS!</b>
+<br>&nbsp;
+<li>
+CPULoad is now calculated based on the time spent to generate a known number
+of frames. This is more accurate than a simple percentage of real-time.
+Implemented in pa_unix_oss, pa_win_wmme and pa_win_ds.</li>
+
+<li>
+Fix dither and shift for recording PaUInt8 format data.</li>
+
+<li>
+Added "patest_maxsines.c" which tests <tt>Pa_GetCPULoad().</tt></li>
+</blockquote>
+
+<blockquote>
+<h4>
+Windows WMME</h4>
+
+<ul>
+<li>
+sDevicePtrs now allocated using <tt>GlobalAlloc()</tt>. This prevents a
+crash in Pa_Terminate() on Win2000. Thanks Mike Berry for finding this.
+Thanks Mike Berry.</li>
+
+<li>
+Pass process instead of thread to <tt>SetPriorityClass</tt>(). This fixes
+a bug that caused the priority to not be increased. Thanks to Alberto di
+Bene for spotting this.</li>
+</ul>
+
+<h4>
+Windows DirectSound</h4>
+
+<ul>
+<li>
+Casts for compiling with __MWERKS__ CodeWarrior.</li>
+</ul>
+
+<h4>
+UNIX OSS</h4>
+
+<ul>
+<li>
+Derived from Linux OSS implementation.</li>
+
+<li>
+Numerous patches from Heiko Purnhagen, Stephen Brandon, etc.</li>
+
+<li>
+Improved query mechanism which often bailed out unnecessarily.</li>
+
+<li>
+Removed sNumDevices and potential related bugs,</li>
+
+<li>
+Use <tt>getenv("PA_MIN_LATENCY_MSEC")</tt> in code to set desired latency.
+User can set by entering:</li>
+
+<br>&nbsp;&nbsp;&nbsp; <tt>export PA_MIN_LATENCY_MSEC=40</tt></ul>
+
+<h4>
+Macintosh Sound Manager</h4>
+
+<ul>
+<li>
+Pass unused event to WaitNextEvent instead of NULL to prevent Mac OSX crash.
+Thanks Dominic Mazzoni.</li>
+
+<li>
+Use requested number of input channels.</li>
+
+<br>&nbsp;</ul>
+</blockquote>
+
+<h2>
+<b>V15 - 5/29/01</b></h2>
+
+<blockquote>
+<ul>
+<li>
+<b>New Linux OSS Beta</b></li>
+</ul>
+
+<h4>
+Windows WMME</h4>
+
+<ul>
+<li>
+&nbsp;sDevicePtrs now allocated based on sizeof(pointer). Was allocating
+too much space.</li>
+
+<li>
+&nbsp;Check for excessive numbers of channels. Some drivers reported bogus
+numbers.</li>
+
+<li>
+Apply Mike Berry's changes for CodeWarrior on PC including condition including
+of memory.h, and explicit typecasting on memory allocation.</li>
+</ul>
+
+<h4>
+Macintosh Sound Manager</h4>
+
+<ul>
+<li>
+ScanInputDevices was setting sDefaultOutputDeviceID instead of sDefaultInputDeviceID.</li>
+
+<li>
+Device Scan was crashing for anything other than siBadSoundInDevice, but
+some Macs may return other errors! Caused failure to init on some G4s under
+OS9.</li>
+
+<li>
+Fix TIMEOUT in record mode.</li>
+
+<li>
+Change CARBON_COMPATIBLE to TARGET_API_MAC_CARBON</li>
+</ul>
+</blockquote>
+
+<h2>
+<b>V14 - 2/6/01</b></h2>
+
+<blockquote>
+<ul>
+<li>
+Added implementation for Windows MultiMedia Extensions (WMME) by Ross and
+Phil</li>
+
+<li>
+Changed Pa_StopStream() so that it waits for the buffers to drain.</li>
+
+<li>
+Added Pa_AbortStream() that stops immediately without waiting.</li>
+
+<li>
+Added new test: patest_stop.c to test above two mods.</li>
+
+<li>
+Fixed Pa_StreamTime() so that it returns current play position instead
+of the write position. Added "patest_sync.c" to demo audio/video sync.</li>
+
+<li>
+Improved stability of Macintosh implementation. Added timeouts to prevent
+hangs.</li>
+
+<li>
+Added Pa_GetSampleSize( PaSampleFormat format );</li>
+
+<li>
+Changes some "int"s to "long"s so that PA works properly on Macintosh which
+often compiles using 16 bit ints.</li>
+
+<li>
+Added Implementation Guide</li>
+</ul>
+</blockquote>
+
+<h2>
+<b>V12 - 1/9/01</b></h2>
+
+<blockquote>
+<ul>
+<li>
+Mac now scans for and queries all devices. But it does not yet support
+selecting any other than the default device.</li>
+
+<li>
+Blocking I/O calls renamed to separate them from the PortAudio API.</li>
+
+<li>
+Cleaned up indentation problems with tabs versus spaces.</li>
+
+<li>
+Now attempts to correct bogus sample rate info returned from DirectSound
+device queries.</li>
+</ul>
+</blockquote>
+
+</body>
+</html>
diff --git a/utils/iaxclient/lib/portaudio/fixdir.bat b/utils/iaxclient/lib/portaudio/fixdir.bat
new file mode 100755 (executable)
index 0000000..92d6c74
--- /dev/null
@@ -0,0 +1,19 @@
+rem Use Astyle to fix style in 'C' files
+cd %1%
+
+fixlines -p *.c
+fixlines -p *.cpp
+fixlines -p *.cc
+
+astyle --style=ansi -c -o --convert-tabs --indent-preprocessor *.c
+astyle --style=ansi -c -o --convert-tabs --indent-preprocessor *.cpp
+astyle --style=ansi -c -o --convert-tabs --indent-preprocessor *.cc
+del *.orig
+@rem convert line terminators to Unix style LFs
+fixlines -u *.c
+fixlines -u *.cpp
+fixlines -u *.cc
+fixlines -u *.h
+del *.bak
+
+cd ..\
diff --git a/utils/iaxclient/lib/portaudio/fixfile.bat b/utils/iaxclient/lib/portaudio/fixfile.bat
new file mode 100755 (executable)
index 0000000..48f6fbc
--- /dev/null
@@ -0,0 +1,7 @@
+rem Use Astyle to fix style in a file
+fixlines -p %1%
+astyle --style=ansi -c -o --convert-tabs --indent-preprocessor %1%
+del %1%.orig
+@rem convert line terminators to Unix style LFs
+fixlines -u %1%
+del %1%.bak
diff --git a/utils/iaxclient/lib/portaudio/include/pa_asio.h b/utils/iaxclient/lib/portaudio/include/pa_asio.h
new file mode 100644 (file)
index 0000000..850bdae
--- /dev/null
@@ -0,0 +1,122 @@
+#ifndef PA_ASIO_H
+#define PA_ASIO_H
+/*
+ * $Id: pa_asio.h,v 1.1 2006/06/10 21:30:51 dmazzoni Exp $
+ * PortAudio Portable Real-Time Audio Library
+ * ASIO specific extensions
+ *
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** @file
+ @brief ASIO-specific PortAudio API extension header file.
+*/
+
+
+#include "portaudio.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+
+/** Retrieve legal latency settings for the specificed device, in samples.
+
+ @param device The global index of the device about which the query is being made.
+ @param minLatency A pointer to the location which will recieve the minimum latency value.
+ @param maxLatency A pointer to the location which will recieve the maximum latency value.
+ @param preferredLatency A pointer to the location which will recieve the preferred latency value.
+ @param granularity A pointer to the location which will recieve the granularity. This value 
+ determines which values between minLatency and maxLatency are available. ie the step size,
+ if granularity is -1 then available latency settings are powers of two.
+
+ @see ASIOGetBufferSize in the ASIO SDK.
+
+ @todo This function should have a better name, any suggestions?
+*/
+PaError PaAsio_GetAvailableLatencyValues( PaDeviceIndex device,
+               long *minLatency, long *maxLatency, long *preferredLatency, long *granularity );
+
+        
+/** Display the ASIO control panel for the specified device.
+
+  @param device The global index of the device whose control panel is to be displayed.
+  @param systemSpecific On Windows, the calling application's main window handle,
+  on Macintosh this value should be zero.
+*/
+PaError PaAsio_ShowControlPanel( PaDeviceIndex device, void* systemSpecific );
+
+
+
+
+/** Retrieve a pointer to a string containing the name of the specified
+ input channel. The string is valid until Pa_Terminate is called.
+
+ The string will be no longer than 32 characters including the null terminator.
+*/
+PaError PaAsio_GetInputChannelName( PaDeviceIndex device, int channelIndex,
+        const char** channelName );
+
+        
+/** Retrieve a pointer to a string containing the name of the specified
+ input channel. The string is valid until Pa_Terminate is called.
+
+ The string will be no longer than 32 characters including the null terminator.
+*/
+PaError PaAsio_GetOutputChannelName( PaDeviceIndex device, int channelIndex,
+        const char** channelName );
+
+
+#define paAsioUseChannelSelectors      (0x01)
+
+typedef struct PaAsioStreamInfo{
+    unsigned long size;             /**< sizeof(PaAsioStreamInfo) */
+    PaHostApiTypeId hostApiType;    /**< paASIO */
+    unsigned long version;          /**< 1 */
+
+    unsigned long flags;
+
+    /* Support for opening only specific channels of an ASIO device.
+        If the paAsioUseChannelSelectors flag is set, channelSelectors is a
+        pointer to an array of integers specifying the device channels to use.
+        When used, the length of the channelSelectors array must match the
+        corresponding channelCount parameter to Pa_OpenStream() otherwise a
+        crash may result.
+        The values in the selectors array must specify channels within the
+        range of supported channels for the device or paInvalidChannelCount will
+        result.
+    */
+    int *channelSelectors;
+}PaAsioStreamInfo;
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* PA_ASIO_H */
diff --git a/utils/iaxclient/lib/portaudio/include/pa_linux_alsa.h b/utils/iaxclient/lib/portaudio/include/pa_linux_alsa.h
new file mode 100644 (file)
index 0000000..fe22d6f
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef PA_LINUX_ALSA_H
+#define PA_LINUX_ALSA_H
+
+/*
+ * $Id: pa_linux_alsa.h,v 1.1 2006/06/10 21:30:51 dmazzoni Exp $
+ * PortAudio Portable Real-Time Audio Library
+ * ALSA-specific extensions
+ *
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** @file
+ * ALSA-specific PortAudio API extension header file.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct PaAlsaStreamInfo
+{
+    unsigned long size;
+    PaHostApiTypeId hostApiType;
+    unsigned long version;
+
+    const char *deviceString;
+}
+PaAlsaStreamInfo;
+
+void PaAlsa_InitializeStreamInfo( PaAlsaStreamInfo *info );
+
+void PaAlsa_EnableRealtimeScheduling( PaStream *s, int enable );
+
+void PaAlsa_EnableWatchdog( PaStream *s, int enable );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/utils/iaxclient/lib/portaudio/include/pa_mac_core.h b/utils/iaxclient/lib/portaudio/include/pa_mac_core.h
new file mode 100644 (file)
index 0000000..5994294
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Mac spcific flags for PA.
+ * portaudio.h should be included before this file.
+ */
+
+/*
+ * A pointer to a paMacCoreStreamInfo may be passed as
+ * the hostApiSpecificStreamInfo in the PaStreamParameters struct
+ * when opening a stream. Use NULL, for the defaults. Note that for
+ * duplex streams, both infos should be the same or behaviour
+ * is undefined.
+ */
+typedef struct paMacCoreStreamInfo
+{
+    unsigned long size;         /**size of whole structure including this header */
+    PaHostApiTypeId hostApiType;/**host API for which this data is intended */
+    unsigned long version;      /**structure version */
+    unsigned long flags;        /* flags to modify behaviour */
+} paMacCoreStreamInfo;
+
+/* Use this function to initialize a paMacCoreStreamInfo struct
+   using the requested flags. */
+void paSetupMacCoreStreamInfo( paMacCoreStreamInfo *data, unsigned long flags )
+{
+   bzero( data, sizeof( paMacCoreStreamInfo ) );
+   data->size = sizeof( paMacCoreStreamInfo );
+   data->hostApiType = paCoreAudio;
+   data->version = 0x01;
+   data->flags = flags;
+}
+
+/*
+ * The following flags alter the behaviour of PA on the mac platform.
+ * they can be ORed together. These should work both for opening and
+ * checking a device.
+ */
+/* Allows PortAudio to change things like the device's frame size,
+ * which allows for much lower latency, but might disrupt the device
+ * if other programs are using it. */
+const unsigned long paMacCore_ChangeDeviceParameters      = 0x01;
+
+/* In combination with the above flag,
+ * causes the stream opening to fail, unless the exact sample rates
+ * are supported by the device. */
+const unsigned long paMacCore_FailIfConversionRequired    = 0x02;
+
+/* These flags set the SR conversion quality, if required. The wierd ordering
+ * allows Maximum Quality to be the default.*/
+const unsigned long paMacCore_ConversionQualityMin    = 0x0100;
+const unsigned long paMacCore_ConversionQualityMedium = 0x0200;
+const unsigned long paMacCore_ConversionQualityLow    = 0x0300;
+const unsigned long paMacCore_ConversionQualityHigh   = 0x0400;
+const unsigned long paMacCore_ConversionQualityMax    = 0x0000;
+
+/*
+ * Here are some "preset" combinations of flags (above) to get to some
+ * common configurations. THIS IS OVERKILL, but if more flags are added
+ * it won't be.
+ */
+/*This is the default setting: do as much sample rate conversion as possible
+ * and as little mucking with the device as possible. */
+const unsigned long paMacCorePlayNice = 0x00;
+/*This setting is tuned for pro audio apps. It allows SR conversion on input
+  and output, but it tries to set the appropriate SR on the device.*/
+const unsigned long paMacCorePro      = 0x01;
+/*This is a setting to minimize CPU usage and still play nice.*/
+const unsigned long paMacCoreMinimizeCPUButPlayNice = 0x0100;
+/*This is a setting to minimize CPU usage, even if that means interrupting the device. */
+const unsigned long paMacCoreMinimizeCPU = 0x0101;
diff --git a/utils/iaxclient/lib/portaudio/include/pa_win_wmme.h b/utils/iaxclient/lib/portaudio/include/pa_win_wmme.h
new file mode 100644 (file)
index 0000000..47a0a9e
--- /dev/null
@@ -0,0 +1,160 @@
+#ifndef PA_WIN_WMME_H
+#define PA_WIN_WMME_H
+/*
+ * $Id: pa_win_wmme.h,v 1.1 2006/06/10 21:30:51 dmazzoni Exp $
+ * PortAudio Portable Real-Time Audio Library
+ * MME specific extensions
+ *
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** @file
+ @brief WMME-specific PortAudio API extension header file.
+*/
+
+
+#include "portaudio.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+
+#define paWinMmeUseLowLevelLatencyParameters            (0x01)
+#define paWinMmeUseMultipleDevices                      (0x02)  /* use mme specific multiple device feature */
+
+
+/* By default, the mme implementation drops the processing thread's priority
+    to THREAD_PRIORITY_NORMAL and sleeps the thread if the CPU load exceeds 100%
+    This flag disables any priority throttling. The processing thread will always
+    run at THREAD_PRIORITY_TIME_CRITICAL.
+*/
+#define paWinMmeDontThrottleOverloadedProcessingThread  (0x08)
+
+
+typedef struct PaWinMmeDeviceAndChannelCount{
+    PaDeviceIndex device;
+    int channelCount;
+}PaWinMmeDeviceAndChannelCount;
+
+
+typedef struct PaWinMmeStreamInfo{
+    unsigned long size;             /**< sizeof(PaWinMmeStreamInfo) */
+    PaHostApiTypeId hostApiType;    /**< paMME */
+    unsigned long version;          /**< 1 */
+
+    unsigned long flags;
+
+    /* low-level latency setting support
+        These settings control the number and size of host buffers in order
+        to set latency. They will be used instead of the generic parameters
+        to Pa_OpenStream() if flags contains the PaWinMmeUseLowLevelLatencyParameters
+        flag.
+
+        If PaWinMmeStreamInfo structures with PaWinMmeUseLowLevelLatencyParameters
+        are supplied for both input and output in a full duplex stream, then the
+        input and output framesPerBuffer must be the same, or the larger of the
+        two must be a multiple of the smaller, otherwise a
+        paIncompatibleHostApiSpecificStreamInfo error will be returned from
+        Pa_OpenStream().
+    */
+    unsigned long framesPerBuffer;
+    unsigned long bufferCount;  /* formerly numBuffers */ 
+
+    /* multiple devices per direction support
+        If flags contains the PaWinMmeUseMultipleDevices flag,
+        this functionality will be used, otherwise the device parameter to
+        Pa_OpenStream() will be used instead.
+        If devices are specified here, the corresponding device parameter
+        to Pa_OpenStream() should be set to paUseHostApiSpecificDeviceSpecification,
+        otherwise an paInvalidDevice error will result.
+        The total number of channels accross all specified devices
+        must agree with the corresponding channelCount parameter to
+        Pa_OpenStream() otherwise a paInvalidChannelCount error will result.
+    */
+    PaWinMmeDeviceAndChannelCount *devices;
+    unsigned long deviceCount;
+
+}PaWinMmeStreamInfo;
+
+
+/** Retrieve the number of wave in handles used by a PortAudio WinMME stream.
+ Returns zero if the stream is output only.
+
+ @return A non-negative value indicating the number of wave in handles
+ or, a PaErrorCode (which are always negative) if PortAudio is not initialized
+ or an error is encountered.
+
+ @see PaWinMME_GetStreamInputHandle
+*/
+int PaWinMME_GetStreamInputHandleCount( PaStream* stream );
+
+
+/** Retrieve a wave in handle used by a PortAudio WinMME stream.
+
+ @param stream The stream to query.
+ @param handleIndex The zero based index of the wave in handle to retrieve. This
+    should be in the range [0, PaWinMME_GetStreamInputHandle(stream)-1].
+
+ @return A valid wave in handle, or NULL if an error occurred.
+
+ @see PaWinMME_GetStreamInputHandle
+*/
+HWAVEIN PaWinMME_GetStreamInputHandle( PaStream* stream, int handleIndex );
+
+
+/** Retrieve the number of wave out handles used by a PortAudio WinMME stream.
+ Returns zero if the stream is input only.
+ @return A non-negative value indicating the number of wave out handles
+ or, a PaErrorCode (which are always negative) if PortAudio is not initialized
+ or an error is encountered.
+
+ @see PaWinMME_GetStreamOutputHandle
+*/
+int PaWinMME_GetStreamOutputHandleCount( PaStream* stream );
+
+
+/** Retrieve a wave out handle used by a PortAudio WinMME stream.
+
+ @param stream The stream to query.
+ @param handleIndex The zero based index of the wave out handle to retrieve.
+    This should be in the range [0, PaWinMME_GetStreamOutputHandleCount(stream)-1].
+
+ @return A valid wave out handle, or NULL if an error occurred.
+
+ @see PaWinMME_GetStreamOutputHandleCount
+*/
+HWAVEOUT PaWinMME_GetStreamOutputHandle( PaStream* stream, int handleIndex );
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* PA_WIN_WMME_H */                                  
diff --git a/utils/iaxclient/lib/portaudio/include/portaudio.h b/utils/iaxclient/lib/portaudio/include/portaudio.h
new file mode 100644 (file)
index 0000000..645730e
--- /dev/null
@@ -0,0 +1,1125 @@
+
+#ifndef PORTAUDIO_H
+#define PORTAUDIO_H
+/*
+ * $Id: portaudio.h,v 1.1 2006/06/10 21:30:51 dmazzoni Exp $
+ * PortAudio Portable Real-Time Audio Library
+ * PortAudio API Header File
+ * Latest version available at: http://www.portaudio.com/
+ *
+ * Copyright (c) 1999-2002 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file
+ @brief The PortAudio API.
+*/
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/** Retrieve the release number of the currently running PortAudio build,
+ eg 1900.
+*/
+int Pa_GetVersion( void );
+
+
+/** Retrieve a textual description of the current PortAudio build,
+ eg "PortAudio V19-devel 13 October 2002".
+*/
+const char* Pa_GetVersionText( void );
+
+
+/** Error codes returned by PortAudio functions.
+ Note that with the exception of paNoError, all PaErrorCodes are negative.
+*/
+
+typedef int PaError;
+typedef enum PaErrorCode
+{
+    paNoError = 0,
+
+    paNotInitialized = -10000,
+    paUnanticipatedHostError,
+    paInvalidChannelCount,
+    paInvalidSampleRate,
+    paInvalidDevice,
+    paInvalidFlag,
+    paSampleFormatNotSupported,
+    paBadIODeviceCombination,
+    paInsufficientMemory,
+    paBufferTooBig,
+    paBufferTooSmall,
+    paNullCallback,
+    paBadStreamPtr,
+    paTimedOut,
+    paInternalError,
+    paDeviceUnavailable,
+    paIncompatibleHostApiSpecificStreamInfo,
+    paStreamIsStopped,
+    paStreamIsNotStopped,
+    paInputOverflowed,
+    paOutputUnderflowed,
+    paHostApiNotFound,
+    paInvalidHostApi,
+    paCanNotReadFromACallbackStream,      /**< @todo review error code name */
+    paCanNotWriteToACallbackStream,       /**< @todo review error code name */
+    paCanNotReadFromAnOutputOnlyStream,   /**< @todo review error code name */
+    paCanNotWriteToAnInputOnlyStream,     /**< @todo review error code name */
+    paIncompatibleStreamHostApi,
+    paBadBufferPtr
+} PaErrorCode;
+
+
+/** Translate the supplied PortAudio error code into a human readable
+ message.
+*/
+const char *Pa_GetErrorText( PaError errorCode );
+
+
+/** Library initialization function - call this before using PortAudio.
+ This function initialises internal data structures and prepares underlying
+ host APIs for use. This function MUST be called before using any other
+ PortAudio API functions.
+
+ If Pa_Initialize() is called multiple times, each successful 
+ call must be matched with a corresponding call to Pa_Terminate(). 
+ Pairs of calls to Pa_Initialize()/Pa_Terminate() may overlap, and are not 
+ required to be fully nested.
+
+ Note that if Pa_Initialize() returns an error code, Pa_Terminate() should
+ NOT be called.
+
+ @return paNoError if successful, otherwise an error code indicating the cause
+ of failure.
+
+ @see Pa_Terminate
+*/
+PaError Pa_Initialize( void );
+
+
+/** Library termination function - call this when finished using PortAudio.
+ This function deallocates all resources allocated by PortAudio since it was
+ initializied by a call to Pa_Initialize(). In cases where Pa_Initialise() has
+ been called multiple times, each call must be matched with a corresponding call
+ to Pa_Terminate(). The final matching call to Pa_Terminate() will automatically
+ close any PortAudio streams that are still open.
+
+ Pa_Terminate() MUST be called before exiting a program which uses PortAudio.
+ Failure to do so may result in serious resource leaks, such as audio devices
+ not being available until the next reboot.
+
+ @return paNoError if successful, otherwise an error code indicating the cause
+ of failure.
+ @see Pa_Initialize
+*/
+PaError Pa_Terminate( void );
+
+
+
+/** The type used to refer to audio devices. Values of this type usually
+ range from 0 to (Pa_DeviceCount-1), and may also take on the PaNoDevice
+ and paUseHostApiSpecificDeviceSpecification values.
+
+ @see Pa_DeviceCount, paNoDevice, paUseHostApiSpecificDeviceSpecification
+*/
+typedef int PaDeviceIndex;
+
+
+/** A special PaDeviceIndex value indicating that no device is available,
+ or should be used.
+
+ @see PaDeviceIndex
+*/
+#define paNoDevice ((PaDeviceIndex)-1)
+
+
+/** A special PaDeviceIndex value indicating that the device(s) to be used
+ are specified in the host api specific stream info structure.
+
+ @see PaDeviceIndex
+*/
+#define paUseHostApiSpecificDeviceSpecification ((PaDeviceIndex)-2)
+
+
+/* Host API enumeration mechanism */
+
+/** The type used to enumerate to host APIs at runtime. Values of this type
+ range from 0 to (Pa_GetHostApiCount()-1).
+
+ @see Pa_GetHostApiCount
+*/
+typedef int PaHostApiIndex;
+
+
+/** Retrieve the number of available host APIs. Even if a host API is
+ available it may have no devices available.
+
+ @return A non-negative value indicating the number of available host APIs
+ or, a PaErrorCode (which are always negative) if PortAudio is not initialized
+ or an error is encountered.
+
+ @see PaHostApiIndex
+*/
+PaHostApiIndex Pa_GetHostApiCount( void );
+
+
+/** Retrieve the index of the default host API. The default host API will be
+ the lowest common denominator host API on the current platform and is
+ unlikely to provide the best performance.
+
+ @return A non-negative value ranging from 0 to (Pa_GetHostApiCount()-1)
+ indicating the default host API index or, a PaErrorCode (which are always
+ negative) if PortAudio is not initialized or an error is encountered.
+*/
+PaHostApiIndex Pa_GetDefaultHostApi( void );
+
+
+/** Unchanging unique identifiers for each supported host API. This type
+ is used in the PaHostApiInfo structure. The values are guaranteed to be
+ unique and to never change, thus allowing code to be written that
+ conditionally uses host API specific extensions.
+
+ New type ids will be allocated when support for a host API reaches
+ "public alpha" status, prior to that developers should use the
+ paInDevelopment type id.
+
+ @see PaHostApiInfo
+*/
+typedef enum PaHostApiTypeId
+{
+    paInDevelopment=0, /* use while developing support for a new host API */
+    paDirectSound=1,
+    paMME=2,
+    paASIO=3,
+    paSoundManager=4,
+    paCoreAudio=5,
+    paOSS=7,
+    paALSA=8,
+    paAL=9,
+    paBeOS=10,
+    paWDMKS=11,
+    paJACK=12,
+       paWASAPI=13
+} PaHostApiTypeId;
+
+
+/** A structure containing information about a particular host API. */
+
+typedef struct PaHostApiInfo
+{
+    /** this is struct version 1 */
+    int structVersion;
+    /** The well known unique identifier of this host API @see PaHostApiTypeId */
+    PaHostApiTypeId type;
+    /** A textual description of the host API for display on user interfaces. */
+    const char *name;
+
+    /**  The number of devices belonging to this host API. This field may be
+     used in conjunction with Pa_HostApiDeviceIndexToDeviceIndex() to enumerate
+     all devices for this host API.
+     @see Pa_HostApiDeviceIndexToDeviceIndex
+    */
+    int deviceCount;
+
+    /** The default input device for this host API. The value will be a
+     device index ranging from 0 to (Pa_GetDeviceCount()-1), or paNoDevice
+     if no default input device is available.
+    */
+    PaDeviceIndex defaultInputDevice;
+
+    /** The default output device for this host API. The value will be a
+     device index ranging from 0 to (Pa_GetDeviceCount()-1), or paNoDevice
+     if no default output device is available.
+    */
+    PaDeviceIndex defaultOutputDevice;
+    
+} PaHostApiInfo;
+
+
+/** Retrieve a pointer to a structure containing information about a specific
+ host Api.
+
+ @param hostApi A valid host API index ranging from 0 to (Pa_GetHostApiCount()-1)
+
+ @return A pointer to an immutable PaHostApiInfo structure describing
+ a specific host API. If the hostApi parameter is out of range or an error
+ is encountered, the function returns NULL.
+
+ The returned structure is owned by the PortAudio implementation and must not
+ be manipulated or freed. The pointer is only guaranteed to be valid between
+ calls to Pa_Initialize() and Pa_Terminate().
+*/
+const PaHostApiInfo * Pa_GetHostApiInfo( PaHostApiIndex hostApi );
+
+
+/** Convert a static host API unique identifier, into a runtime
+ host API index.
+
+ @param type A unique host API identifier belonging to the PaHostApiTypeId
+ enumeration.
+
+ @return A valid PaHostApiIndex ranging from 0 to (Pa_GetHostApiCount()-1) or,
+ a PaErrorCode (which are always negative) if PortAudio is not initialized
+ or an error is encountered.
+ The paHostApiNotFound error code indicates that the host API specified by the
+ type parameter is not available.
+
+ @see PaHostApiTypeId
+*/
+PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type );
+
+
+/** Convert a host-API-specific device index to standard PortAudio device index.
+ This function may be used in conjunction with the deviceCount field of
+ PaHostApiInfo to enumerate all devices for the specified host API.
+
+ @param hostApi A valid host API index ranging from 0 to (Pa_GetHostApiCount()-1)
+
+ @param hostApiDeviceIndex A valid per-host device index in the range
+ 0 to (Pa_GetHostApiInfo(hostApi)->deviceCount-1)
+
+ @return A non-negative PaDeviceIndex ranging from 0 to (Pa_GetDeviceCount()-1)
+ or, a PaErrorCode (which are always negative) if PortAudio is not initialized
+ or an error is encountered.
+
+ A paInvalidHostApi error code indicates that the host API index specified by
+ the hostApi parameter is out of range.
+
+ A paInvalidDevice error code indicates that the hostApiDeviceIndex parameter
+ is out of range.
+ @see PaHostApiInfo
+*/
+PaDeviceIndex Pa_HostApiDeviceIndexToDeviceIndex( PaHostApiIndex hostApi,
+        int hostApiDeviceIndex );
+
+
+
+/** Structure used to return information about a host error condition.
+*/
+typedef struct PaHostErrorInfo{
+    PaHostApiTypeId hostApiType;    /**< the host API which returned the error code */
+    long errorCode;                 /**< the error code returned */
+    const char *errorText;          /**< a textual description of the error if available, otherwise a zero-length string */
+}PaHostErrorInfo;
+
+
+/** Return information about the last host error encountered. The error
+ information returned by Pa_GetLastHostErrorInfo() will never be modified
+ asyncronously by errors occurring in other PortAudio owned threads
+ (such as the thread that manages the stream callback.)
+
+ This function is provided as a last resort, primarily to enhance debugging
+ by providing clients with access to all available error information.
+
+ @return A pointer to an immutable structure constaining information about
+ the host error. The values in this structure will only be valid if a
+ PortAudio function has previously returned the paUnanticipatedHostError
+ error code.
+*/
+const PaHostErrorInfo* Pa_GetLastHostErrorInfo( void );
+
+
+
+/* Device enumeration and capabilities */
+
+/** Retrieve the number of available devices. The number of available devices
+ may be zero.
+
+ @return A non-negative value indicating the number of available devices or,
+ a PaErrorCode (which are always negative) if PortAudio is not initialized
+ or an error is encountered.
+*/
+PaDeviceIndex Pa_GetDeviceCount( void );
+
+
+/** Retrieve the index of the default input device. The result can be
+ used in the inputDevice parameter to Pa_OpenStream().
+
+ @return The default input device index for the default host API, or paNoDevice
+ if no default input device is available or an error was encountered.
+*/
+PaDeviceIndex Pa_GetDefaultInputDevice( void );
+
+
+/** Retrieve the index of the default output device. The result can be
+ used in the outputDevice parameter to Pa_OpenStream().
+
+ @return The default output device index for the defualt host API, or paNoDevice
+ if no default output device is available or an error was encountered.
+
+ @note
+ On the PC, the user can specify a default device by
+ setting an environment variable. For example, to use device #1.
+<pre>
+ set PA_RECOMMENDED_OUTPUT_DEVICE=1
+</pre>
+ The user should first determine the available device ids by using
+ the supplied application "pa_devs".
+*/
+PaDeviceIndex Pa_GetDefaultOutputDevice( void );
+
+
+/** The type used to represent monotonic time in seconds that can be used
+ for syncronisation. The type is used for the outTime argument to the
+ PaStreamCallback and as the result of Pa_GetStreamTime().
+     
+ @see PaStreamCallback, Pa_GetStreamTime
+*/
+typedef double PaTime;
+
+
+/** A type used to specify one or more sample formats. Each value indicates
+ a possible format for sound data passed to and from the stream callback,
+ Pa_ReadStream and Pa_WriteStream.
+
+ The standard formats paFloat32, paInt16, paInt32, paInt24, paInt8
+ and aUInt8 are usually implemented by all implementations.
+
+ The floating point representation (paFloat32) uses +1.0 and -1.0 as the
+ maximum and minimum respectively.
+
+ paUInt8 is an unsigned 8 bit format where 128 is considered "ground"
+
+ The paNonInterleaved flag indicates that a multichannel buffer is passed
+ as a set of non-interleaved pointers.
+
+ @see Pa_OpenStream, Pa_OpenDefaultStream, PaDeviceInfo
+ @see paFloat32, paInt16, paInt32, paInt24, paInt8
+ @see paUInt8, paCustomFormat, paNonInterleaved
+*/
+typedef unsigned long PaSampleFormat;
+
+
+#define paFloat32        ((PaSampleFormat) 0x00000001) /**< @see PaSampleFormat */
+#define paInt32          ((PaSampleFormat) 0x00000002) /**< @see PaSampleFormat */
+#define paInt24          ((PaSampleFormat) 0x00000004) /**< Packed 24 bit format. @see PaSampleFormat */
+#define paInt16          ((PaSampleFormat) 0x00000008) /**< @see PaSampleFormat */
+#define paInt8           ((PaSampleFormat) 0x00000010) /**< @see PaSampleFormat */
+#define paUInt8          ((PaSampleFormat) 0x00000020) /**< @see PaSampleFormat */
+#define paCustomFormat   ((PaSampleFormat) 0x00010000)/**< @see PaSampleFormat */
+
+#define paNonInterleaved ((PaSampleFormat) 0x80000000)
+
+/** A structure providing information and capabilities of PortAudio devices.
+ Devices may support input, output or both input and output.
+*/
+typedef struct PaDeviceInfo
+{
+    int structVersion;  /* this is struct version 2 */
+    const char *name;
+    PaHostApiIndex hostApi; /* note this is a host API index, not a type id*/
+    
+    int maxInputChannels;
+    int maxOutputChannels;
+
+    /* Default latency values for interactive performance. */
+    PaTime defaultLowInputLatency;
+    PaTime defaultLowOutputLatency;
+    /* Default latency values for robust non-interactive applications (eg. playing sound files). */
+    PaTime defaultHighInputLatency;
+    PaTime defaultHighOutputLatency;
+
+    double defaultSampleRate;
+} PaDeviceInfo;
+
+
+/** Retrieve a pointer to a PaDeviceInfo structure containing information
+ about the specified device.
+ @return A pointer to an immutable PaDeviceInfo structure. If the device
+ parameter is out of range the function returns NULL.
+
+ @param device A valid device index in the range 0 to (Pa_GetDeviceCount()-1)
+
+ @note PortAudio manages the memory referenced by the returned pointer,
+ the client must not manipulate or free the memory. The pointer is only
+ guaranteed to be valid between calls to Pa_Initialize() and Pa_Terminate().
+
+ @see PaDeviceInfo, PaDeviceIndex
+*/
+const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceIndex device );
+
+
+/** Parameters for one direction (input or output) of a stream.
+*/
+typedef struct PaStreamParameters
+{
+    /** A valid device index in the range 0 to (Pa_GetDeviceCount()-1)
+     specifying the device to be used or the special constant
+     paUseHostApiSpecificDeviceSpecification which indicates that the actual
+     device(s) to use are specified in hostApiSpecificStreamInfo.
+     This field must not be set to paNoDevice.
+    */
+    PaDeviceIndex device;
+    
+    /** The number of channels of sound to be delivered to the
+     stream callback or accessed by Pa_ReadStream() or Pa_WriteStream().
+     It can range from 1 to the value of maxInputChannels in the
+     PaDeviceInfo record for the device specified by the device parameter.
+    */
+    int channelCount;
+
+    /** The sample format of the buffer provided to the stream callback,
+     a_ReadStream() or Pa_WriteStream(). It may be any of the formats described
+     by the PaSampleFormat enumeration.
+    */
+    PaSampleFormat sampleFormat;
+
+    /** The desired latency in seconds. Where practical, implementations should
+     configure their latency based on these parameters, otherwise they may
+     choose the closest viable latency instead. Unless the suggested latency
+     is greater than the absolute upper limit for the device implementations
+     should round the suggestedLatency up to the next practial value - ie to
+     provide an equal or higher latency than suggestedLatency wherever possibe.
+     Actual latency values for an open stream may be retrieved using the
+     inputLatency and outputLatency fields of the PaStreamInfo structure
+     returned by Pa_GetStreamInfo().
+     @see default*Latency in PaDeviceInfo, *Latency in PaStreamInfo
+    */
+    PaTime suggestedLatency;
+
+    /** An optional pointer to a host api specific data structure
+     containing additional information for device setup and/or stream processing.
+     hostApiSpecificStreamInfo is never required for correct operation,
+     if not used it should be set to NULL.
+    */
+    void *hostApiSpecificStreamInfo;
+
+} PaStreamParameters;
+
+
+/** Return code for Pa_IsFormatSupported indicating success. */
+#define paFormatIsSupported (0)
+
+/** Determine whether it would be possible to open a stream with the specified
+ parameters.
+
+ @param inputParameters A structure that describes the input parameters used to
+ open a stream. The suggestedLatency field is ignored. See PaStreamParameters
+ for a description of these parameters. inputParameters must be NULL for
+ output-only streams.
+
+ @param outputParameters A structure that describes the output parameters used
+ to open a stream. The suggestedLatency field is ignored. See PaStreamParameters
+ for a description of these parameters. outputParameters must be NULL for
+ input-only streams.
+
+ @param sampleRate The required sampleRate. For full-duplex streams it is the
+ sample rate for both input and output
+
+ @return Returns 0 if the format is supported, and an error code indicating why
+ the format is not supported otherwise. The constant paFormatIsSupported is
+ provided to compare with the return value for success.
+
+ @see paFormatIsSupported, PaStreamParameters
+*/
+PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters,
+                              const PaStreamParameters *outputParameters,
+                              double sampleRate );
+
+
+
+/* Streaming types and functions */
+
+
+/**
+ A single PaStream can provide multiple channels of real-time
+ streaming audio input and output to a client application. A stream
+ provides access to audio hardware represented by one or more
+ PaDevices. Depending on the underlying Host API, it may be possible 
+ to open multiple streams using the same device, however this behavior 
+ is implementation defined. Portable applications should assume that 
+ a PaDevice may be simultaneously used by at most one PaStream.
+
+ Pointers to PaStream objects are passed between PortAudio functions that
+ operate on streams.
+
+ @see Pa_OpenStream, Pa_OpenDefaultStream, Pa_OpenDefaultStream, Pa_CloseStream,
+ Pa_StartStream, Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive,
+ Pa_GetStreamTime, Pa_GetStreamCpuLoad
+
+*/
+typedef void PaStream;
+
+
+/** Can be passed as the framesPerBuffer parameter to Pa_OpenStream()
+ or Pa_OpenDefaultStream() to indicate that the stream callback will
+ accept buffers of any size.
+*/
+#define paFramesPerBufferUnspecified  (0)
+
+
+/** Flags used to control the behavior of a stream. They are passed as
+ parameters to Pa_OpenStream or Pa_OpenDefaultStream. Multiple flags may be
+ ORed together.
+
+ @see Pa_OpenStream, Pa_OpenDefaultStream
+ @see paNoFlag, paClipOff, paDitherOff, paNeverDropInput,
+  paPrimeOutputBuffersUsingStreamCallback, paPlatformSpecificFlags
+*/
+typedef unsigned long PaStreamFlags;
+
+/** @see PaStreamFlags */
+#define   paNoFlag          ((PaStreamFlags) 0)
+
+/** Disable default clipping of out of range samples.
+ @see PaStreamFlags
+*/
+#define   paClipOff         ((PaStreamFlags) 0x00000001)
+
+/** Disable default dithering.
+ @see PaStreamFlags
+*/
+#define   paDitherOff       ((PaStreamFlags) 0x00000002)
+
+/** Flag requests that where possible a full duplex stream will not discard
+ overflowed input samples without calling the stream callback. This flag is
+ only valid for full duplex callback streams and only when used in combination
+ with the paFramesPerBufferUnspecified (0) framesPerBuffer parameter. Using
+ this flag incorrectly results in a paInvalidFlag error being returned from
+ Pa_OpenStream and Pa_OpenDefaultStream.
+
+ @see PaStreamFlags, paFramesPerBufferUnspecified
+*/
+#define   paNeverDropInput  ((PaStreamFlags) 0x00000004)
+
+/** Call the stream callback to fill initial output buffers, rather than the
+ default behavior of priming the buffers with zeros (silence). This flag has
+ no effect for input-only and blocking read/write streams.
+ @see PaStreamFlags
+*/
+#define   paPrimeOutputBuffersUsingStreamCallback ((PaStreamFlags) 0x00000008)
+
+/** A mask specifying the platform specific bits.
+ @see PaStreamFlags
+*/
+#define   paPlatformSpecificFlags ((PaStreamFlags)0xFFFF0000)
+
+/**
+ Timing information for the buffers passed to the stream callback.
+*/
+typedef struct PaStreamCallbackTimeInfo{
+    PaTime inputBufferAdcTime;
+    PaTime currentTime;
+    PaTime outputBufferDacTime;
+} PaStreamCallbackTimeInfo;
+
+
+/**
+ Flag bit constants for the statusFlags to PaStreamCallback.
+
+ @see paInputUnderflow, paInputOverflow, paOutputUnderflow, paOutputOverflow,
+ paPrimingOutput
+*/
+typedef unsigned long PaStreamCallbackFlags;
+
+/** In a stream opened with paFramesPerBufferUnspecified, indicates that
+ input data is all silence (zeros) because no real data is available. In a
+ stream opened without paFramesPerBufferUnspecified, it indicates that one or
+ more zero samples have been inserted into the input buffer to compensate
+ for an input underflow.
+ @see PaStreamCallbackFlags
+*/
+#define paInputUnderflow   ((PaStreamCallbackFlags) 0x00000001)
+
+/** In a stream opened with paFramesPerBufferUnspecified, indicates that data
+ prior to the first sample of the input buffer was discarded due to an
+ overflow, possibly because the stream callback is using too much CPU time.
+ Otherwise indicates that data prior to one or more samples in the
+ input buffer was discarded.
+ @see PaStreamCallbackFlags
+*/
+#define paInputOverflow    ((PaStreamCallbackFlags) 0x00000002)
+
+/** Indicates that output data (or a gap) was inserted, possibly because the
+ stream callback is using too much CPU time.
+ @see PaStreamCallbackFlags
+*/
+#define paOutputUnderflow  ((PaStreamCallbackFlags) 0x00000004)
+
+/** Indicates that output data will be discarded because no room is available.
+ @see PaStreamCallbackFlags
+*/
+#define paOutputOverflow   ((PaStreamCallbackFlags) 0x00000008)
+
+/** Some of all of the output data will be used to prime the stream, input
+ data may be zero.
+ @see PaStreamCallbackFlags
+*/
+#define paPrimingOutput    ((PaStreamCallbackFlags) 0x00000010)
+
+/**
+ Allowable return values for the PaStreamCallback.
+ @see PaStreamCallback
+*/
+typedef enum PaStreamCallbackResult
+{
+    paContinue=0,
+    paComplete=1,
+    paAbort=2
+} PaStreamCallbackResult;
+
+
+/**
+ Functions of type PaStreamCallback are implemented by PortAudio clients.
+ They consume, process or generate audio in response to requests from an
+ active PortAudio stream.
+     
+ @param input and @param output are arrays of interleaved samples,
+ the format, packing and number of channels used by the buffers are
+ determined by parameters to Pa_OpenStream().
+     
+ @param frameCount The number of sample frames to be processed by
+ the stream callback.
+
+ @param timeInfo The time in seconds when the first sample of the input
+ buffer was received at the audio input, the time in seconds when the first
+ sample of the output buffer will begin being played at the audio output, and
+ the time in seconds when the stream callback was called.
+ See also Pa_GetStreamTime()
+
+ @param statusFlags Flags indicating whether input and/or output buffers
+ have been inserted or will be dropped to overcome underflow or overflow
+ conditions.
+
+ @param userData The value of a user supplied pointer passed to
+ Pa_OpenStream() intended for storing synthesis data etc.
+
+ @return
+ The stream callback should return one of the values in the
+ PaStreamCallbackResult enumeration. To ensure that the callback continues
+ to be called, it should return paContinue (0). Either paComplete or paAbort
+ can be returned to finish stream processing, after either of these values is
+ returned the callback will not be called again. If paAbort is returned the
+ stream will finish as soon as possible. If paComplete is returned, the stream
+ will continue until all buffers generated by the callback have been played.
+ This may be useful in applications such as soundfile players where a specific
+ duration of output is required. However, it is not necessary to utilise this
+ mechanism as Pa_StopStream(), Pa_AbortStream() or Pa_CloseStream() can also
+ be used to stop the stream. The callback must always fill the entire output
+ buffer irrespective of its return value.
+
+ @see Pa_OpenStream, Pa_OpenDefaultStream
+
+ @note With the exception of Pa_GetStreamCpuLoad() it is not permissable to call
+ PortAudio API functions from within the stream callback.
+*/
+typedef int PaStreamCallback(
+    const void *input, void *output,
+    unsigned long frameCount,
+    const PaStreamCallbackTimeInfo* timeInfo,
+    PaStreamCallbackFlags statusFlags,
+    void *userData );
+
+
+/** Opens a stream for either input, output or both.
+     
+ @param stream The address of a PaStream pointer which will receive
+ a pointer to the newly opened stream.
+     
+ @param inputParameters A structure that describes the input parameters used by
+ the opened stream. See PaStreamParameters for a description of these parameters.
+ inputParameters must be NULL for output-only streams.
+
+ @param outputParameters A structure that describes the output parameters used by
+ the opened stream. See PaStreamParameters for a description of these parameters.
+ outputParameters must be NULL for input-only streams.
+ @param sampleRate The desired sampleRate. For full-duplex streams it is the
+ sample rate for both input and output
+     
+ @param framesPerBuffer The number of frames passed to the stream callback
+ function, or the preferred block granularity for a blocking read/write stream.
+ The special value paFramesPerBufferUnspecified (0) may be used to request that
+ the stream callback will recieve an optimal (and possibly varying) number of
+ frames based on host requirements and the requested latency settings.
+ Note: With some host APIs, the use of non-zero framesPerBuffer for a callback
+ stream may introduce an additional layer of buffering which could introduce
+ additional latency. PortAudio guarantees that the additional latency
+ will be kept to the theoretical minimum however, it is strongly recommended
+ that a non-zero framesPerBuffer value only be used when your algorithm
+ requires a fixed number of frames per stream callback.
+ @param streamFlags Flags which modify the behaviour of the streaming process.
+ This parameter may contain a combination of flags ORed together. Some flags may
+ only be relevant to certain buffer formats.
+     
+ @param streamCallback A pointer to a client supplied function that is responsible
+ for processing and filling input and output buffers. If this parameter is NULL
+ the stream will be opened in 'blocking read/write' mode. In blocking mode,
+ the client can receive sample data using Pa_ReadStream and write sample data
+ using Pa_WriteStream, the number of samples that may be read or written
+ without blocking is returned by Pa_GetStreamReadAvailable and
+ Pa_GetStreamWriteAvailable respectively.
+
+ @param userData A client supplied pointer which is passed to the stream callback
+ function. It could for example, contain a pointer to instance data necessary
+ for processing the audio buffers. This parameter is ignored if streamCallback
+ is NULL.
+     
+ @return
+ Upon success Pa_OpenStream() returns paNoError and places a pointer to a
+ valid PaStream in the stream argument. The stream is inactive (stopped).
+ If a call to Pa_OpenStream() fails, a non-zero error code is returned (see
+ PaError for possible error codes) and the value of stream is invalid.
+
+ @see PaStreamParameters, PaStreamCallback, Pa_ReadStream, Pa_WriteStream,
+ Pa_GetStreamReadAvailable, Pa_GetStreamWriteAvailable
+*/
+PaError Pa_OpenStream( PaStream** stream,
+                       const PaStreamParameters *inputParameters,
+                       const PaStreamParameters *outputParameters,
+                       double sampleRate,
+                       unsigned long framesPerBuffer,
+                       PaStreamFlags streamFlags,
+                       PaStreamCallback *streamCallback,
+                       void *userData );
+
+
+/** A simplified version of Pa_OpenStream() that opens the default input
+ and/or output devices.
+
+ @param stream The address of a PaStream pointer which will receive
+ a pointer to the newly opened stream.
+ @param numInputChannels  The number of channels of sound that will be supplied
+ to the stream callback or returned by Pa_ReadStream. It can range from 1 to
+ the value of maxInputChannels in the PaDeviceInfo record for the default input
+ device. If 0 the stream is opened as an output-only stream.
+
+ @param numOutputChannels The number of channels of sound to be delivered to the
+ stream callback or passed to Pa_WriteStream. It can range from 1 to the value
+ of maxOutputChannels in the PaDeviceInfo record for the default output dvice.
+ If 0 the stream is opened as an output-only stream.
+
+ @param sampleFormat The sample format of both the input and output buffers
+ provided to the callback or passed to and from Pa_ReadStream and Pa_WriteStream.
+ sampleFormat may be any of the formats described by the PaSampleFormat
+ enumeration.
+ @param sampleRate Same as Pa_OpenStream parameter of the same name.
+ @param framesPerBuffer Same as Pa_OpenStream parameter of the same name.
+ @param streamCallback Same as Pa_OpenStream parameter of the same name.
+ @param userData Same as Pa_OpenStream parameter of the same name.
+
+ @return As for Pa_OpenStream
+
+ @see Pa_OpenStream, PaStreamCallback
+*/
+PaError Pa_OpenDefaultStream( PaStream** stream,
+                              int numInputChannels,
+                              int numOutputChannels,
+                              PaSampleFormat sampleFormat,
+                              double sampleRate,
+                              unsigned long framesPerBuffer,
+                              PaStreamCallback *streamCallback,
+                              void *userData );
+
+
+/** Closes an audio stream. If the audio stream is active it
+ discards any pending buffers as if Pa_AbortStream() had been called.
+*/
+PaError Pa_CloseStream( PaStream *stream );
+
+
+/** Functions of type PaStreamFinishedCallback are implemented by PortAudio 
+ clients. They can be registered with a stream using the Pa_SetStreamFinishedCallback
+ function. Once registered they are called when the stream becomes inactive
+ (ie once a call to Pa_StopStream() will not block).
+ A stream will become inactive after the stream callback returns non-zero,
+ or when Pa_StopStream or Pa_AbortStream is called. For a stream providing audio
+ output, if the stream callback returns paComplete, or Pa_StopStream is called,
+ the stream finished callback will not be called until all generated sample data
+ has been played.
+ @param userData The userData parameter supplied to Pa_OpenStream()
+
+ @see Pa_SetStreamFinishedCallback
+*/
+typedef void PaStreamFinishedCallback( void *userData );
+
+
+/** Register a stream finished callback function which will be called when the 
+ stream becomes inactive. See the description of PaStreamFinishedCallback for 
+ further details about when the callback will be called.
+
+ @param stream a pointer to a PaStream that is in the stopped state - if the
+ stream is not stopped, the stream's finished callback will remain unchanged 
+ and an error code will be returned.
+
+ @param streamFinishedCallback a pointer to a function with the same signature
+ as PaStreamFinishedCallback, that will be called when the stream becomes
+ inactive. Passing NULL for this parameter will un-register a previously
+ registered stream finished callback function.
+
+ @return on success returns paNoError, otherwise an error code indicating the cause
+ of the error.
+
+ @see PaStreamFinishedCallback
+*/
+PaError Pa_SetStreamFinishedCallback( PaStream *stream, PaStreamFinishedCallback* streamFinishedCallback ); 
+
+
+/** Commences audio processing.
+*/
+PaError Pa_StartStream( PaStream *stream );
+
+
+/** Terminates audio processing. It waits until all pending
+ audio buffers have been played before it returns.
+*/
+PaError Pa_StopStream( PaStream *stream );
+
+
+/** Terminates audio processing immediately without waiting for pending
+ buffers to complete.
+*/
+PaError Pa_AbortStream( PaStream *stream );
+
+
+/** Determine whether the stream is stopped.
+ A stream is considered to be stopped prior to a successful call to
+ Pa_StartStream and after a successful call to Pa_StopStream or Pa_AbortStream.
+ If a stream callback returns a value other than paContinue the stream is NOT
+ considered to be stopped.
+
+ @return Returns one (1) when the stream is stopped, zero (0) when
+ the stream is running or, a PaErrorCode (which are always negative) if
+ PortAudio is not initialized or an error is encountered.
+
+ @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamActive
+*/
+PaError Pa_IsStreamStopped( PaStream *stream );
+
+
+/** Determine whether the stream is active.
+ A stream is active after a successful call to Pa_StartStream(), until it
+ becomes inactive either as a result of a call to Pa_StopStream() or
+ Pa_AbortStream(), or as a result of a return value other than paContinue from
+ the stream callback. In the latter case, the stream is considered inactive
+ after the last buffer has finished playing.
+
+ @return Returns one (1) when the stream is active (ie playing or recording
+ audio), zero (0) when not playing or, a PaErrorCode (which are always negative)
+ if PortAudio is not initialized or an error is encountered.
+
+ @see Pa_StopStream, Pa_AbortStream, Pa_IsStreamStopped
+*/
+PaError Pa_IsStreamActive( PaStream *stream );
+
+
+
+/** A structure containing unchanging information about an open stream.
+ @see Pa_GetStreamInfo
+*/
+
+typedef struct PaStreamInfo
+{
+    /** this is struct version 1 */
+    int structVersion;
+
+    /** The input latency of the stream in seconds. This value provides the most
+     accurate estimate of input latency available to the implementation. It may
+     differ significantly from the suggestedLatency value passed to Pa_OpenStream().
+     The value of this field will be zero (0.) for output-only streams.
+     @see PaTime
+    */
+    PaTime inputLatency;
+
+    /** The output latency of the stream in seconds. This value provides the most
+     accurate estimate of output latency available to the implementation. It may
+     differ significantly from the suggestedLatency value passed to Pa_OpenStream().
+     The value of this field will be zero (0.) for input-only streams.
+     @see PaTime
+    */
+    PaTime outputLatency;
+
+    /** The sample rate of the stream in Hertz (samples per second). In cases
+     where the hardware sample rate is inaccurate and PortAudio is aware of it,
+     the value of this field may be different from the sampleRate parameter
+     passed to Pa_OpenStream(). If information about the actual hardware sample
+     rate is not available, this field will have the same value as the sampleRate
+     parameter passed to Pa_OpenStream().
+    */
+    double sampleRate;
+    
+} PaStreamInfo;
+
+
+/** Retrieve a pointer to a PaStreamInfo structure containing information
+ about the specified stream.
+ @return A pointer to an immutable PaStreamInfo structure. If the stream
+ parameter invalid, or an error is encountered, the function returns NULL.
+
+ @param stream A pointer to an open stream previously created with Pa_OpenStream.
+
+ @note PortAudio manages the memory referenced by the returned pointer,
+ the client must not manipulate or free the memory. The pointer is only
+ guaranteed to be valid until the specified stream is closed.
+
+ @see PaStreamInfo
+*/
+const PaStreamInfo* Pa_GetStreamInfo( PaStream *stream );
+
+
+/** Determine the current time for the stream according to the same clock used
+ to generate buffer timestamps. This time may be used for syncronising other
+ events to the audio stream, for example synchronizing audio to MIDI.
+                                        
+ @return The stream's current time in seconds, or 0 if an error occurred.
+
+ @see PaTime, PaStreamCallback
+*/
+PaTime Pa_GetStreamTime( PaStream *stream );
+
+
+/** Retrieve CPU usage information for the specified stream.
+ The "CPU Load" is a fraction of total CPU time consumed by a callback stream's
+ audio processing routines including, but not limited to the client supplied
+ stream callback. This function does not work with blocking read/write streams.
+
+ This function may be called from the stream callback function or the
+ application.
+     
+ @return
+ A floating point value, typically between 0.0 and 1.0, where 1.0 indicates
+ that the stream callback is consuming the maximum number of CPU cycles possible
+ to maintain real-time operation. A value of 0.5 would imply that PortAudio and
+ the stream callback was consuming roughly 50% of the available CPU time. The
+ return value may exceed 1.0. A value of 0.0 will always be returned for a
+ blocking read/write stream, or if an error occurrs.
+*/
+double Pa_GetStreamCpuLoad( PaStream* stream );
+
+
+/** Read samples from an input stream. The function doesn't return until
+ the entire buffer has been filled - this may involve waiting for the operating
+ system to supply the data.
+
+ @param stream A pointer to an open stream previously created with Pa_OpenStream.
+ @param buffer A pointer to a buffer of sample frames. The buffer contains
+ samples in the format specified by the inputParameters->sampleFormat field
+ used to open the stream, and the number of channels specified by
+ inputParameters->numChannels. If non-interleaved samples were requested,
+ buffer is a pointer to the first element of an array of non-interleaved
+ buffer pointers, one for each channel.
+
+ @param frames The number of frames to be read into buffer. This parameter
+ is not constrained to a specific range, however high performance applications
+ will want to match this parameter to the framesPerBuffer parameter used
+ when opening the stream.
+
+ @return On success PaNoError will be returned, or PaInputOverflowed if input
+ data was discarded by PortAudio after the previous call and before this call.
+*/
+PaError Pa_ReadStream( PaStream* stream,
+                       void *buffer,
+                       unsigned long frames );
+
+
+/** Write samples to an output stream. This function doesn't return until the
+ entire buffer has been consumed - this may involve waiting for the operating
+ system to consume the data.
+
+ @param stream A pointer to an open stream previously created with Pa_OpenStream.
+
+ @param buffer A pointer to a buffer of sample frames. The buffer contains
+ samples in the format specified by the outputParameters->sampleFormat field
+ used to open the stream, and the number of channels specified by
+ outputParameters->numChannels. If non-interleaved samples were requested,
+ buffer is a pointer to the first element of an array of non-interleaved
+ buffer pointers, one for each channel.
+
+ @param frames The number of frames to be written from buffer. This parameter
+ is not constrained to a specific range, however high performance applications
+ will want to match this parameter to the framesPerBuffer parameter used
+ when opening the stream.
+
+ @return On success PaNoError will be returned, or paOutputUnderflowed if
+ additional output data was inserted after the previous call and before this
+ call.
+*/
+PaError Pa_WriteStream( PaStream* stream,
+                        const void *buffer,
+                        unsigned long frames );
+
+
+/** Retrieve the number of frames that can be read from the stream without
+ waiting.
+
+ @return Returns a non-negative value representing the maximum number of frames
+ that can be read from the stream without blocking or busy waiting or, a
+ PaErrorCode (which are always negative) if PortAudio is not initialized or an
+ error is encountered.
+*/
+signed long Pa_GetStreamReadAvailable( PaStream* stream );
+
+
+/** Retrieve the number of frames that can be written to the stream without
+ waiting.
+
+ @return Returns a non-negative value representing the maximum number of frames
+ that can be written to the stream without blocking or busy waiting or, a
+ PaErrorCode (which are always negative) if PortAudio is not initialized or an
+ error is encountered.
+*/
+signed long Pa_GetStreamWriteAvailable( PaStream* stream );
+
+
+/* Miscellaneous utilities */
+
+
+/** Retrieve the size of a given sample format in bytes.
+
+ @return The size in bytes of a single sample in the specified format,
+ or paSampleFormatNotSupported if the format is not supported.
+*/
+PaError Pa_GetSampleSize( PaSampleFormat format );
+
+
+/** Put the caller to sleep for at least 'msec' milliseconds. This function is
+ provided only as a convenience for authors of portable code (such as the tests
+ and examples in the PortAudio distribution.)
+
+ The function may sleep longer than requested so don't rely on this for accurate
+ musical timing.
+*/
+void Pa_Sleep( long msec );
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* PORTAUDIO_H */
diff --git a/utils/iaxclient/lib/portaudio/index.html b/utils/iaxclient/lib/portaudio/index.html
new file mode 100644 (file)
index 0000000..91e5b4c
--- /dev/null
@@ -0,0 +1,89 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="GENERATOR" content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
+   <meta name="Author" content="Phil Burk">
+   <meta name="Description" content="PortAudio is a cross platform, open-source, audio I/O library.It provides a very simple API for recording and/or playing sound using a simple callback function.">
+   <meta name="KeyWords" content="audio, library, portable, open-source, DirectSound,sound, music, JSyn, synthesis,">
+   <title>PortAudio Implementations for DirectSound</title>
+</head>
+<body>
+&nbsp;
+<center><table COLS=1 WIDTH="100%" BGCOLOR="#FADA7A" >
+<tr>
+<td>
+<center>
+<h1>
+PortAudio - Portable Audio Library</h1></center>
+</td>
+</tr>
+</table></center>
+
+<p>Last updated 5/6/02.
+<p>PortAudio is a cross platform, <a href="#License">open-source</a>, audio
+I/O library proposed by <b>Ross Bencina</b> to the <a href="http://shoko.calarts.edu/~glmrboy/musicdsp/music-dsp.html">music-dsp</a>
+mailing list. It lets you write simple audio programs in 'C' that will
+compile and run on <b>Windows, Macintosh, Unix, BeOS</b>. PortAudio is
+intended to promote the exchange of audio synthesis software between developers
+on different platforms.
+<p>For complete information on PortAudio and to download the latest releases,
+please visit "<b><font size=+2><a href="http://www.portaudio.com">http://www.portaudio.com</a></font></b>".
+<br>&nbsp;
+<br>&nbsp;
+<center>
+<h2>
+<b><a href="docs/index.html">Click here for Documentation</a></b></h2></center>
+
+<h2>
+<b><font size=+2></font></b></h2>
+
+<h2>
+<b><font size=+2>Contacts and E-Mail List</font></b></h2>
+
+<ul>
+<li>
+If you are using or implementing PortAudio then please join the <b><font size=+1><a href="http://techweb.rfa.org/mailman/listinfo/portaudio">PortAudio
+mail list</a></font><font size=+2> </font></b>generously administered by
+<b>Bill
+Eldridge</b>.</li>
+
+<li>
+If you find bugs in one of these implementations, or have suggestions,
+please e-mail them to <a href="mailto:philburk@softsynth.com">Phil Burk</a>.</li>
+
+<li>
+If you make improvements to the library, please send them to us so we can
+incorporate the improvements.</li>
+</ul>
+
+<h2>
+<a NAME="License"></a>License</h2>
+PortAudio Portable Real-Time Audio Library
+<br>Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+<p>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:
+<ul>
+<li>
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.</li>
+
+<li>
+Any person wishing to distribute modifications to the Software is requested
+to send the modifications to the original developer so that they can be
+incorporated into the canonical version.</li>
+</ul>
+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 ON INFRINGEMENT.
+<br>IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
+OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+<br>&nbsp;
+</body>
+</html>
diff --git a/utils/iaxclient/lib/portaudio/install-sh b/utils/iaxclient/lib/portaudio/install-sh
new file mode 100755 (executable)
index 0000000..e9de238
--- /dev/null
@@ -0,0 +1,251 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# 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 "install:  no input file specified"
+       exit 1
+else
+       true
+fi
+
+if [ x"$dir_arg" != x ]; then
+       dst=$src
+       src=""
+       
+       if [ -d $dst ]; then
+               instcmd=:
+               chmodcmd=""
+       else
+               instcmd=mkdir
+       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 -o -d $src ]
+       then
+               true
+       else
+               echo "install:  $src does not exist"
+               exit 1
+       fi
+       
+       if [ x"$dst" = x ]
+       then
+               echo "install:  no destination specified"
+               exit 1
+       else
+               true
+       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
+               true
+       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
+               true
+       fi
+
+       pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+       $doit $instcmd $dst &&
+
+       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; 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
+               true
+       fi
+
+# Make a temp file name in the proper directory.
+
+       dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+       $doit $instcmd $src $dsttmp &&
+
+       trap "rm -f ${dsttmp}" 0 &&
+
+# 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 true;fi &&
+       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+       $doit $rmcmd -f $dstdir/$dstfile &&
+       $doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
diff --git a/utils/iaxclient/lib/portaudio/libtool b/utils/iaxclient/lib/portaudio/libtool
new file mode 100755 (executable)
index 0000000..6874ae3
--- /dev/null
@@ -0,0 +1,7969 @@
+#! /bin/sh
+
+# libtoolT - Provide generalized library-building support services.
+# Generated automatically by  (GNU  )
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+#
+# This file is part of GNU Libtool:
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 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 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.
+
+# A sed program that does not truncate output.
+SED="/usr/bin/sed"
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="/usr/bin/sed -e 1s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# The names of the tagged configurations supported by this script.
+available_tags=" CXX F77"
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Libtool was configured on host splash:
+
+# Shell to use when invoking shell scripts.
+SHELL="/bin/sh"
+
+# Whether or not to build shared libraries.
+build_libtool_libs=yes
+
+# Whether or not to build static libraries.
+build_old_libs=yes
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=yes
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=yes
+
+# Whether or not to optimize for fast installation.
+fast_install=needless
+
+# The host system.
+host_alias=
+host=i686-pc-cygwin
+host_os=cygwin
+
+# The build system.
+build_alias=
+build=i686-pc-cygwin
+build_os=cygwin
+
+# An echo program that does not interpret backslashes.
+echo="echo"
+
+# The archiver.
+AR="ar"
+AR_FLAGS="cru"
+
+# A C compiler.
+LTCC="gcc"
+
+# LTCC compiler flags.
+LTCFLAGS="-g -O2"
+
+# A language-specific compiler.
+CC="gcc"
+
+# Is the compiler the GNU C compiler?
+with_gcc=yes
+
+# An ERE matcher.
+EGREP="grep -E"
+
+# The linker used to build libraries.
+LD="/usr/i686-pc-cygwin/bin/ld.exe"
+
+# Whether we need hard or soft links.
+LN_S="ln -s"
+
+# A BSD-compatible nm program.
+NM="/usr/bin/nm -B"
+
+# A symbol stripping program
+STRIP="strip"
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=file
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="dlltool"
+
+# Used on cygwin: object dumper.
+OBJDUMP="objdump"
+
+# Used on cygwin: assembler.
+AS="as"
+
+# The name of the directory that contains temporary libtool files.
+objdir=.libs
+
+# How to create reloadable object files.
+reload_flag=" -r"
+reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs"
+
+# How to pass a linker flag through the compiler.
+wl="-Wl,"
+
+# Object file suffix (normally "o").
+objext="o"
+
+# Old archive suffix (normally "a").
+libext="a"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='.dll'
+
+# Executable file suffix (normally "").
+exeext=""
+
+# Additional compiler flags for building library objects.
+pic_flag=" -DPIC"
+pic_mode=default
+
+# What is the maximum length of a command?
+max_cmd_len=8192
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o="yes"
+
+# Must we lock files when doing compilation?
+need_locks="no"
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=no
+
+# Do we need a version for libraries?
+need_version=no
+
+# Whether dlopen is supported.
+dlopen_support=unknown
+
+# Whether dlopen of programs is supported.
+dlopen_self=unknown
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=unknown
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag="-static"
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=" -fno-builtin"
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec="\${wl}--export-dynamic"
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive"
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=""
+
+# Library versioning type.
+version_type=windows
+
+# Format of library name prefix.
+libname_spec="lib\$name"
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec="\$libname.dll.a"
+
+# The coded name of the library, if different from the real name.
+soname_spec="\`echo \${libname} | sed -e s/^lib/cyg/\`\`echo \${release} | \$SED -e s/[.]/-/g\`\${versuffix}\${shared_ext}"
+
+# Commands used to build and install an old-style archive.
+RANLIB="ranlib"
+old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs\$old_deplibs~\$RANLIB \$oldlib"
+old_postinstall_cmds="chmod 644 \$oldlib~\$RANLIB \$oldlib"
+old_postuninstall_cmds=""
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=""
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=""
+
+# Commands used to build and install a shared archive.
+archive_cmds="\$CC -shared \$libobjs \$deplibs \$compiler_flags -o \$output_objdir/\$soname \${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker \$lib"
+archive_expsym_cmds="if test \\\"x\\\`\$SED 1q \$export_symbols\\\`\\\" = xEXPORTS; then
+         cp \$export_symbols \$output_objdir/\$soname.def;
+       else
+         echo EXPORTS > \$output_objdir/\$soname.def;
+         cat \$export_symbols >> \$output_objdir/\$soname.def;
+       fi~
+       \$CC -shared \$output_objdir/\$soname.def \$libobjs \$deplibs \$compiler_flags -o \$output_objdir/\$soname \${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker \$lib"
+postinstall_cmds="base_file=\\\`basename \\\${file}\\\`~
+      dlpath=\\\`\$SHELL 2>&1 -c '. \$dir/'\\\${base_file}'i;echo \\\$dlname'\\\`~
+      dldir=\$destdir/\\\`dirname \\\$dlpath\\\`~
+      test -d \\\$dldir || mkdir -p \\\$dldir~
+      \$install_prog \$dir/\$dlname \\\$dldir/\$dlname~
+      chmod a+x \\\$dldir/\$dlname"
+postuninstall_cmds="dldll=\\\`\$SHELL 2>&1 -c '. \$file; echo \\\$dlname'\\\`~
+      dlpath=\$dir/\\\$dldll~
+       \$rm \\\$dlpath"
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=""
+module_expsym_cmds=""
+
+# Commands to strip libraries.
+old_striplib="strip --strip-debug"
+striplib="strip --strip-unneeded"
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=""
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=""
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=""
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=""
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=""
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method="file_magic ^x86 archive import|^x86 DLL"
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd="func_win32_libid"
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag="unsupported"
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=""
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=""
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=""
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe="sed -n -e 's/^.*[  ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[       ][      ]*_\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 _\\2 \\2/p'"
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern int \\1;/p'"
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address="sed -n -e 's/^: \\([^ ]*\\) \$/  {\\\"\\1\\\", (lt_ptr) 0},/p' -e 's/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/  {\"\\2\", (lt_ptr) \\&\\2},/p'"
+
+# This is the shared library runtime path variable.
+runpath_var=LD_RUN_PATH
+
+# This is the shared library path variable.
+shlibpath_var=PATH
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=yes
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=immediate
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=no
+
+# Flag to hardcode $libdir into a binary during linking.
+# This must work even if $libdir does not exist.
+hardcode_libdir_flag_spec="-L\$libdir"
+
+# If ld is used when linking, flag to hardcode $libdir into
+# a binary during linking. This must work even if $libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=""
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=""
+
+# Set to yes if using DIR/libNAME during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=no
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=no
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=unsupported
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=no
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="PATH PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=unknown
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+
+# Fix the shell variable $srcfile for the compiler.
+fix_srcfile_path=""
+
+# Set to yes if exported symbols are required.
+always_export_symbols=no
+
+# The commands to list exported symbols.
+export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED -e '/^[BCDGRS] /s/.* \\\\([^ ]*\\\\)/\\\\1 DATA/' | \$SED -e '/^[AITW] /s/.* //' | sort | uniq > \$export_symbols"
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=""
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+
+# Symbols that must always be exported.
+include_expsyms=""
+
+# ### END LIBTOOL CONFIG
+
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun configure.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 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 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.
+
+basename="s,^.*/,,g"
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+# define SED for historic ltconfig's generated by Libtool 1.3
+test -z "$SED" && SED=sed
+
+# The name of this program:
+progname=`echo "$progpath" | $SED $basename`
+modename="$progname"
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.5.22
+TIMESTAMP=" (1.1220.2.365 2005/12/18 22:14:06)"
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes.
+if test -n "${ZSH_VERSION+set}" ; then
+  setopt NO_GLOB_SUBST
+fi
+# Same for EGREP, and just to be sure, do LTCC as well
+if test "X$EGREP" = X ; then
+    EGREP=egrep
+fi
+if test "X$LTCC" = X ; then
+    LTCC=${CC-gcc}
+fi
+
+# Check that we have a working $echo.
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell, and then maybe $echo will work.
+  exec $SHELL "$progpath" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit $EXIT_SUCCESS
+fi
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  SP2NL='tr \040 \012'
+  NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  SP2NL='tr \100 \n'
+  NL2SP='tr \r\n \100\100'
+  ;;
+esac
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+# We save the old values to restore during execute mode.
+if test "${LC_ALL+set}" = set; then
+  save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
+fi
+if test "${LANG+set}" = set; then
+  save_LANG="$LANG"; LANG=C; export LANG
+fi
+
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS="  $lt_nl"
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+  $echo "$modename: not configured to build any kind of library" 1>&2
+  $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit $EXIT_FAILURE
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+duplicate_deps=no
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+
+if test -z "$max_cmd_len"; then
+  i=0
+  testring="ABCD"
+  new_result=
+  
+  # If test is not a shell built-in, we'll probably end up computing a
+  # maximum length that is only half of the actual maximum length, but
+  # we can't tell.
+  while (test "X"`$SHELL $0 --fallback-echo "X$testring" 2>/dev/null` \
+             = "XX$testring") >/dev/null 2>&1 &&
+          new_result=`expr "X$testring" : ".*" 2>&1` &&
+          max_cmd_len="$new_result" &&
+          test "$i" != 17 # 1/2 MB should be enough
+  do
+    i=`expr $i + 1`
+    testring="$testring$testring"
+  done
+  testring=
+  # Add a significant safety factor because C++ compilers can tack on massive
+  # amounts of additional arguments before passing them to the linker.
+  # It appears as though 1/2 is a usable value.
+  max_cmd_len=`expr $max_cmd_len \/ 2`
+fi
+
+#####################################
+# Shell function definitions:
+# This seems to be the best place for them
+
+# func_mktempdir [string]
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible.  If
+# given, STRING is the basename for that directory.
+func_mktempdir ()
+{
+    my_template="${TMPDIR-/tmp}/${1-$progname}"
+
+    if test "$run" = ":"; then
+      # Return a directory name, but don't create it in dry-run mode
+      my_tmpdir="${my_template}-$$"
+    else
+
+      # If mktemp works, use that first and foremost
+      my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
+
+      if test ! -d "$my_tmpdir"; then
+       # Failing that, at least try and use $RANDOM to avoid a race
+       my_tmpdir="${my_template}-${RANDOM-0}$$"
+
+       save_mktempdir_umask=`umask`
+       umask 0077
+       $mkdir "$my_tmpdir"
+       umask $save_mktempdir_umask
+      fi
+
+      # If we're not in dry-run mode, bomb out on failure
+      test -d "$my_tmpdir" || {
+        $echo "cannot create temporary directory \`$my_tmpdir'" 1>&2
+       exit $EXIT_FAILURE
+      }
+    fi
+
+    $echo "X$my_tmpdir" | $Xsed
+}
+
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+func_win32_libid ()
+{
+  win32_libid_type="unknown"
+  win32_fileres=`file -L $1 2>/dev/null`
+  case $win32_fileres in
+  *ar\ archive\ import\ library*) # definitely import
+    win32_libid_type="x86 archive import"
+    ;;
+  *ar\ archive*) # could be an import, or static
+    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \
+      $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
+      win32_nmres=`eval $NM -f posix -A $1 | \
+       $SED -n -e '1,100{/ I /{s,.*,import,;p;q;};}'`
+      case $win32_nmres in
+      import*)  win32_libid_type="x86 archive import";;
+      *)        win32_libid_type="x86 archive static";;
+      esac
+    fi
+    ;;
+  *DLL*)
+    win32_libid_type="x86 DLL"
+    ;;
+  *executable*) # but shell scripts are "executable" too...
+    case $win32_fileres in
+    *MS\ Windows\ PE\ Intel*)
+      win32_libid_type="x86 DLL"
+      ;;
+    esac
+    ;;
+  esac
+  $echo $win32_libid_type
+}
+
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+    if test -n "$available_tags" && test -z "$tagname"; then
+      CC_quoted=
+      for arg in $CC; do
+       case $arg in
+         *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+         arg="\"$arg\""
+         ;;
+       esac
+       CC_quoted="$CC_quoted $arg"
+      done
+      case $@ in
+      # Blanks in the command may have been stripped by the calling shell,
+      # but not from the CC environment variable when configure was run.
+      " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;;
+      # Blanks at the start of $base_compile will cause this to fail
+      # if we don't check for them as well.
+      *)
+       for z in $available_tags; do
+         if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+           # Evaluate the configuration.
+           eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+           CC_quoted=
+           for arg in $CC; do
+           # Double-quote args containing other shell metacharacters.
+           case $arg in
+             *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \     ]*|*]*|"")
+             arg="\"$arg\""
+             ;;
+           esac
+           CC_quoted="$CC_quoted $arg"
+         done
+           # user sometimes does CC=<HOST>-gcc so we need to match that to 'gcc'
+           trimedcc=`echo ${CC} | $SED -e "s/${host}-//g"`
+           # and sometimes libtool has CC=<HOST>-gcc but user does CC=gcc
+           extendcc=${host}-${CC}
+           # and sometimes libtool has CC=<OLDHOST>-gcc but user has CC=<NEWHOST>-gcc  
+           # (Gentoo-specific hack because we always export $CHOST)
+           mungedcc=${CHOST-${host}}-${trimedcc}
+           case "$@ " in
+             "cc "* | " cc "* | "${host}-cc "* | " ${host}-cc "*|\
+             "gcc "* | " gcc "* | "${host}-gcc "* | " ${host}-gcc "*)
+             tagname=CC
+             break ;;
+             "$trimedcc "* | " $trimedcc "* | "`$echo $trimedcc` "* | " `$echo $trimedcc` "*|\
+             "$extendcc "* | " $extendcc "* | "`$echo $extendcc` "* | " `$echo $extendcc` "*|\
+             "$mungedcc "* | " $mungedcc "* | "`$echo $mungedcc` "* | " `$echo $mungedcc` "*|\
+             " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*)
+             # The compiler in the base compile command matches
+             # the one in the tagged configuration.
+             # Assume this is the tagged configuration we want.
+             tagname=$z
+             break
+             ;;
+           esac
+         fi
+       done
+       # If $tagname still isn't set, then no tagged configuration
+       # was found and let the user know that the "--tag" command
+       # line option must be used.
+       if test -z "$tagname"; then
+         $echo "$modename: unable to infer tagged configuration"
+         $echo "$modename: specify a tag with \`--tag'" 1>&2
+         exit $EXIT_FAILURE
+#        else
+#          $echo "$modename: using $tagname tagged configuration"
+       fi
+       ;;
+      esac
+    fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+    f_ex_an_ar_dir="$1"; shift
+    f_ex_an_ar_oldlib="$1"
+
+    $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)"
+    $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $?
+    if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+     :
+    else
+      $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2
+      exit $EXIT_FAILURE
+    fi
+}
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+    my_gentop="$1"; shift
+    my_oldlibs=${1+"$@"}
+    my_oldobjs=""
+    my_xlib=""
+    my_xabs=""
+    my_xdir=""
+    my_status=""
+
+    $show "${rm}r $my_gentop"
+    $run ${rm}r "$my_gentop"
+    $show "$mkdir $my_gentop"
+    $run $mkdir "$my_gentop"
+    my_status=$?
+    if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then
+      exit $my_status
+    fi
+
+    for my_xlib in $my_oldlibs; do
+      # Extract the objects.
+      case $my_xlib in
+       [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+       *) my_xabs=`pwd`"/$my_xlib" ;;
+      esac
+      my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'`
+      my_xdir="$my_gentop/$my_xlib"
+
+      $show "${rm}r $my_xdir"
+      $run ${rm}r "$my_xdir"
+      $show "$mkdir $my_xdir"
+      $run $mkdir "$my_xdir"
+      exit_status=$?
+      if test "$exit_status" -ne 0 && test ! -d "$my_xdir"; then
+       exit $exit_status
+      fi
+      case $host in
+      *-darwin*)
+       $show "Extracting $my_xabs"
+       # Do not bother doing anything if just a dry run
+       if test -z "$run"; then
+         darwin_orig_dir=`pwd`
+         cd $my_xdir || exit $?
+         darwin_archive=$my_xabs
+         darwin_curdir=`pwd`
+         darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'`
+         darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null`
+         if test -n "$darwin_arches"; then 
+           darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'`
+           darwin_arch=
+           $show "$darwin_base_archive has multiple architectures $darwin_arches"
+           for darwin_arch in  $darwin_arches ; do
+             mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+             lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+             cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+             func_extract_an_archive "`pwd`" "${darwin_base_archive}"
+             cd "$darwin_curdir"
+             $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
+           done # $darwin_arches
+      ## Okay now we have a bunch of thin objects, gotta fatten them up :)
+           darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP`
+           darwin_file=
+           darwin_files=
+           for darwin_file in $darwin_filelist; do
+             darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP`
+             lipo -create -output "$darwin_file" $darwin_files
+           done # $darwin_filelist
+           ${rm}r unfat-$$
+           cd "$darwin_orig_dir"
+         else
+           cd "$darwin_orig_dir"
+           func_extract_an_archive "$my_xdir" "$my_xabs"
+         fi # $darwin_arches
+       fi # $run
+       ;;
+      *)
+        func_extract_an_archive "$my_xdir" "$my_xabs"
+        ;;
+      esac
+      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
+    done
+    func_extract_archives_result="$my_oldobjs"
+}
+# End of Shell function definitions
+#####################################
+
+# Darwin sucks
+eval std_shrext=\"$shrext_cmds\"
+
+disable_libs=no
+
+# Parse our command line options once, thoroughly.
+while test "$#" -gt 0
+do
+  arg="$1"
+  shift
+
+  case $arg in
+  -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    case $prev in
+    execute_dlfiles)
+      execute_dlfiles="$execute_dlfiles $arg"
+      ;;
+    tag)
+      tagname="$arg"
+      preserve_args="${preserve_args}=$arg"
+
+      # Check whether tagname contains only valid characters
+      case $tagname in
+      *[!-_A-Za-z0-9,/]*)
+       $echo "$progname: invalid tag name: $tagname" 1>&2
+       exit $EXIT_FAILURE
+       ;;
+      esac
+
+      case $tagname in
+      CC)
+       # Don't test for the "default" C tag, as we know, it's there, but
+       # not specially marked.
+       ;;
+      *)
+       if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then
+         taglist="$taglist $tagname"
+         # Evaluate the configuration.
+         eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`"
+       else
+         $echo "$progname: ignoring unknown tag $tagname" 1>&2
+       fi
+       ;;
+      esac
+      ;;
+    *)
+      eval "$prev=\$arg"
+      ;;
+    esac
+
+    prev=
+    prevopt=
+    continue
+  fi
+
+  # Have we seen a non-optional argument yet?
+  case $arg in
+  --help)
+    show_help=yes
+    ;;
+
+  --version)
+    $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
+    $echo
+    $echo "Copyright (C) 2005  Free Software Foundation, Inc."
+    $echo "This is free software; see the source for copying conditions.  There is NO"
+    $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+    exit $?
+    ;;
+
+  --config)
+    ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath
+    # Now print the configurations for the tags.
+    for tagname in $taglist; do
+      ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath"
+    done
+    exit $?
+    ;;
+
+  --debug)
+    $echo "$progname: enabling shell trace mode"
+    set -x
+    preserve_args="$preserve_args $arg"
+    ;;
+
+  --dry-run | -n)
+    run=:
+    ;;
+
+  --features)
+    $echo "host: $host"
+    if test "$build_libtool_libs" = yes; then
+      $echo "enable shared libraries"
+    else
+      $echo "disable shared libraries"
+    fi
+    if test "$build_old_libs" = yes; then
+      $echo "enable static libraries"
+    else
+      $echo "disable static libraries"
+    fi
+    exit $?
+    ;;
+
+  --finish) mode="finish" ;;
+
+  --mode) prevopt="--mode" prev=mode ;;
+  --mode=*) mode="$optarg" ;;
+
+  --preserve-dup-deps) duplicate_deps="yes" ;;
+
+  --quiet | --silent)
+    show=:
+    preserve_args="$preserve_args $arg"
+    ;;
+
+  --tag)
+    prevopt="--tag"
+    prev=tag
+    preserve_args="$preserve_args --tag"
+    ;;
+  --tag=*)
+    set tag "$optarg" ${1+"$@"}
+    shift
+    prev=tag
+    preserve_args="$preserve_args --tag"
+    ;;
+
+  -dlopen)
+    prevopt="-dlopen"
+    prev=execute_dlfiles
+    ;;
+
+  -*)
+    $echo "$modename: unrecognized option \`$arg'" 1>&2
+    $echo "$help" 1>&2
+    exit $EXIT_FAILURE
+    ;;
+
+  *)
+    nonopt="$arg"
+    break
+    ;;
+  esac
+done
+
+if test -n "$prevopt"; then
+  $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+  $echo "$help" 1>&2
+  exit $EXIT_FAILURE
+fi
+
+case $disable_libs in
+no) 
+  ;;
+shared)
+  build_libtool_libs=no
+  build_old_libs=yes
+  ;;
+static)
+  build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+  ;;
+esac
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end.  This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+if test -z "$show_help"; then
+
+  # Infer the operation mode.
+  if test -z "$mode"; then
+    $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2
+    $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2
+    case $nonopt in
+    *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*)
+      mode=link
+      for arg
+      do
+       case $arg in
+       -c)
+          mode=compile
+          break
+          ;;
+       esac
+      done
+      ;;
+    *db | *dbx | *strace | *truss)
+      mode=execute
+      ;;
+    *install*|cp|mv)
+      mode=install
+      ;;
+    *rm)
+      mode=uninstall
+      ;;
+    *)
+      # If we have no mode, but dlfiles were specified, then do execute mode.
+      test -n "$execute_dlfiles" && mode=execute
+
+      # Just use the default operation mode.
+      if test -z "$mode"; then
+       if test -n "$nonopt"; then
+         $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+       else
+         $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+       fi
+      fi
+      ;;
+    esac
+  fi
+
+  # Only execute mode is allowed to have -dlopen flags.
+  if test -n "$execute_dlfiles" && test "$mode" != execute; then
+    $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+    $echo "$help" 1>&2
+    exit $EXIT_FAILURE
+  fi
+
+  # Change the help message to a mode-specific one.
+  generic_help="$help"
+  help="Try \`$modename --help --mode=$mode' for more information."
+
+  # These modes are in order of execution frequency so that they run quickly.
+  case $mode in
+  # libtool compile mode
+  compile)
+    modename="$modename: compile"
+    # Get the compilation command and the source file.
+    base_compile=
+    srcfile="$nonopt"  #  always keep a non-empty value in "srcfile"
+    suppress_opt=yes
+    suppress_output=
+    arg_mode=normal
+    libobj=
+    later=
+
+    for arg
+    do
+      case $arg_mode in
+      arg  )
+       # do not "continue".  Instead, add this to base_compile
+       lastarg="$arg"
+       arg_mode=normal
+       ;;
+
+      target )
+       libobj="$arg"
+       arg_mode=normal
+       continue
+       ;;
+
+      normal )
+       # Accept any command-line options.
+       case $arg in
+       -o)
+         if test -n "$libobj" ; then
+           $echo "$modename: you cannot specify \`-o' more than once" 1>&2
+           exit $EXIT_FAILURE
+         fi
+         arg_mode=target
+         continue
+         ;;
+
+       -static | -prefer-pic | -prefer-non-pic)
+         later="$later $arg"
+         continue
+         ;;
+
+       -no-suppress)
+         suppress_opt=no
+         continue
+         ;;
+
+       -Xcompiler)
+         arg_mode=arg  #  the next one goes into the "base_compile" arg list
+         continue      #  The current "srcfile" will either be retained or
+         ;;            #  replaced later.  I would guess that would be a bug.
+
+       -Wc,*)
+         args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"`
+         lastarg=
+         save_ifs="$IFS"; IFS=','
+         for arg in $args; do
+           IFS="$save_ifs"
+
+           # Double-quote args containing other shell metacharacters.
+           # Many Bourne shells cannot handle close brackets correctly
+           # in scan sets, so we specify it separately.
+           case $arg in
+             *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \     ]*|*]*|"")
+             arg="\"$arg\""
+             ;;
+           esac
+           lastarg="$lastarg $arg"
+         done
+         IFS="$save_ifs"
+         lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"`
+
+         # Add the arguments to base_compile.
+         base_compile="$base_compile $lastarg"
+         continue
+         ;;
+
+       * )
+         # Accept the current argument as the source file.
+         # The previous "srcfile" becomes the current argument.
+         #
+         lastarg="$srcfile"
+         srcfile="$arg"
+         ;;
+       esac  #  case $arg
+       ;;
+      esac    #  case $arg_mode
+
+      # Aesthetically quote the previous argument.
+      lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+      case $lastarg in
+      # Double-quote args containing other shell metacharacters.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, and some SunOS ksh mistreat backslash-escaping
+      # in scan sets (worked around with variable expansion),
+      # and furthermore cannot handle '|' '&' '(' ')' in scan sets 
+      # at all, so we specify them separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
+       lastarg="\"$lastarg\""
+       ;;
+      esac
+
+      base_compile="$base_compile $lastarg"
+    done # for arg
+
+    case $arg_mode in
+    arg)
+      $echo "$modename: you must specify an argument for -Xcompile"
+      exit $EXIT_FAILURE
+      ;;
+    target)
+      $echo "$modename: you must specify a target with \`-o'" 1>&2
+      exit $EXIT_FAILURE
+      ;;
+    *)
+      # Get the name of the library object.
+      [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+      ;;
+    esac
+
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    xform='[cCFSifmso]'
+    case $libobj in
+    *.ada) xform=ada ;;
+    *.adb) xform=adb ;;
+    *.ads) xform=ads ;;
+    *.asm) xform=asm ;;
+    *.c++) xform=c++ ;;
+    *.cc) xform=cc ;;
+    *.ii) xform=ii ;;
+    *.class) xform=class ;;
+    *.cpp) xform=cpp ;;
+    *.cxx) xform=cxx ;;
+    *.f90) xform=f90 ;;
+    *.for) xform=for ;;
+    *.java) xform=java ;;
+    esac
+
+    libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+    case $libobj in
+    *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
+    *)
+      $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
+      exit $EXIT_FAILURE
+      ;;
+    esac
+
+    func_infer_tag $base_compile
+
+    for arg in $later; do
+      case $arg in
+      -static)
+       build_old_libs=yes
+       continue
+       ;;
+
+      -prefer-pic)
+       pic_mode=yes
+       continue
+       ;;
+
+      -prefer-non-pic)
+       pic_mode=no
+       continue
+       ;;
+      esac
+    done
+
+    qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"`
+    case $qlibobj in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
+       qlibobj="\"$qlibobj\"" ;;
+    esac
+    test "X$libobj" != "X$qlibobj" \
+       && $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"'  &()|`$[]' \
+       && $echo "$modename: libobj name \`$libobj' may not contain shell special characters."
+    objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
+    xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+    if test "X$xdir" = "X$obj"; then
+      xdir=
+    else
+      xdir=$xdir/
+    fi
+    lobj=${xdir}$objdir/$objname
+
+    if test -z "$base_compile"; then
+      $echo "$modename: you must specify a compilation command" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      removelist="$obj $lobj $libobj ${libobj}T"
+    else
+      removelist="$lobj $libobj ${libobj}T"
+    fi
+
+    $run $rm $removelist
+    trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15
+
+    # On Cygwin there's no "real" PIC flag so we must build both object types
+    case $host_os in
+    cygwin* | mingw* | pw32* | os2*)
+      pic_mode=default
+      ;;
+    esac
+    if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+      # non-PIC code in shared libraries is not supported
+      pic_mode=default
+    fi
+
+    # Calculate the filename of the output object if compiler does
+    # not support -o with -c
+    if test "$compiler_c_o" = no; then
+      output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
+      lockfile="$output_obj.lock"
+      removelist="$removelist $output_obj $lockfile"
+      trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15
+    else
+      output_obj=
+      need_locks=no
+      lockfile=
+    fi
+
+    # Lock this critical section if it is needed
+    # We use this script file to make the link, it avoids creating a new file
+    if test "$need_locks" = yes; then
+      until $run ln "$srcfile" "$lockfile" 2>/dev/null; do
+       $show "Waiting for $lockfile to be removed"
+       sleep 2
+      done
+    elif test "$need_locks" = warn; then
+      if test -f "$lockfile"; then
+       $echo "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+       $run $rm $removelist
+       exit $EXIT_FAILURE
+      fi
+      $echo "$srcfile" > "$lockfile"
+    fi
+
+    if test -n "$fix_srcfile_path"; then
+      eval srcfile=\"$fix_srcfile_path\"
+    fi
+    qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"`
+    case $qsrcfile in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
+      qsrcfile="\"$qsrcfile\"" ;;
+    esac
+
+    $run $rm "$libobj" "${libobj}T"
+
+    # Create a libtool object file (analogous to a ".la" file),
+    # but don't create it if we're doing a dry run.
+    test -z "$run" && cat > ${libobj}T <<EOF
+# $libobj - a libtool object file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+EOF
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      if test "$pic_mode" != no; then
+       command="$base_compile $qsrcfile $pic_flag"
+      else
+       # Don't build PIC code
+       command="$base_compile $qsrcfile"
+      fi
+
+      if test ! -d "${xdir}$objdir"; then
+       $show "$mkdir ${xdir}$objdir"
+       $run $mkdir ${xdir}$objdir
+       exit_status=$?
+       if test "$exit_status" -ne 0 && test ! -d "${xdir}$objdir"; then
+         exit $exit_status
+       fi
+      fi
+
+      if test -z "$output_obj"; then
+       # Place PIC objects in $objdir
+       command="$command -o $lobj"
+      fi
+
+      $run $rm "$lobj" "$output_obj"
+
+      $show "$command"
+      if $run eval "$command"; then :
+      else
+       test -n "$output_obj" && $run $rm $removelist
+       exit $EXIT_FAILURE
+      fi
+
+      if test "$need_locks" = warn &&
+        test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+       $echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+       $run $rm $removelist
+       exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed, then go on to compile the next one
+      if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+       $show "$mv $output_obj $lobj"
+       if $run $mv $output_obj $lobj; then :
+       else
+         error=$?
+         $run $rm $removelist
+         exit $error
+       fi
+      fi
+
+      # Append the name of the PIC object to the libtool object file.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+pic_object='$objdir/$objname'
+
+EOF
+
+      # Allow error messages only from the first compilation.
+      if test "$suppress_opt" = yes; then
+        suppress_output=' >/dev/null 2>&1'
+      fi
+    else
+      # No PIC object so indicate it doesn't exist in the libtool
+      # object file.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+pic_object=none
+
+EOF
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      if test "$pic_mode" != yes; then
+       # Don't build PIC code
+       command="$base_compile $qsrcfile"
+      else
+       command="$base_compile $qsrcfile $pic_flag"
+      fi
+      if test "$compiler_c_o" = yes; then
+       command="$command -o $obj"
+      fi
+
+      # Suppress compiler output if we already did a PIC compilation.
+      command="$command$suppress_output"
+      $run $rm "$obj" "$output_obj"
+      $show "$command"
+      if $run eval "$command"; then :
+      else
+       $run $rm $removelist
+       exit $EXIT_FAILURE
+      fi
+
+      if test "$need_locks" = warn &&
+        test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+       $echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+       $run $rm $removelist
+       exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed
+      if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+       $show "$mv $output_obj $obj"
+       if $run $mv $output_obj $obj; then :
+       else
+         error=$?
+         $run $rm $removelist
+         exit $error
+       fi
+      fi
+
+      # Append the name of the non-PIC object the libtool object file.
+      # Only append if the libtool object file exists.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+# Name of the non-PIC object.
+non_pic_object='$objname'
+
+EOF
+    else
+      # Append the name of the non-PIC object the libtool object file.
+      # Only append if the libtool object file exists.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+# Name of the non-PIC object.
+non_pic_object=none
+
+EOF
+    fi
+
+    $run $mv "${libobj}T" "${libobj}"
+
+    # Unlock the critical section if it was locked
+    if test "$need_locks" != no; then
+      $run $rm "$lockfile"
+    fi
+
+    exit $EXIT_SUCCESS
+    ;;
+
+  # libtool link mode
+  link | relink)
+    modename="$modename: link"
+    case $host in
+    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+      # It is impossible to link a dll without this setting, and
+      # we shouldn't force the makefile maintainer to figure out
+      # which system we are compiling for in order to pass an extra
+      # flag for every libtool invocation.
+      # allow_undefined=no
+
+      # FIXME: Unfortunately, there are problems with the above when trying
+      # to make a dll which has undefined symbols, in which case not
+      # even a static library is built.  For now, we need to specify
+      # -no-undefined on the libtool link line when we can be certain
+      # that all symbols are satisfied, otherwise we get a static library.
+      allow_undefined=yes
+      ;;
+    *)
+      allow_undefined=yes
+      ;;
+    esac
+    libtool_args="$nonopt"
+    base_compile="$nonopt $@"
+    compile_command="$nonopt"
+    finalize_command="$nonopt"
+
+    compile_rpath=
+    finalize_rpath=
+    compile_shlibpath=
+    finalize_shlibpath=
+    convenience=
+    old_convenience=
+    deplibs=
+    old_deplibs=
+    compiler_flags=
+    linker_flags=
+    dllsearchpath=
+    lib_search_path=`pwd`
+    inst_prefix_dir=
+
+    avoid_version=no
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    ltlibs=
+    module=no
+    no_install=no
+    objs=
+    non_pic_objects=
+    notinst_path= # paths that contain not-installed libtool libraries
+    precious_files_regex=
+    prefer_static_libs=no
+    preload=no
+    prev=
+    prevarg=
+    release=
+    rpath=
+    xrpath=
+    perm_rpath=
+    temp_rpath=
+    thread_safe=no
+    vinfo=
+    vinfo_number=no
+
+    func_infer_tag $base_compile
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case $arg in
+      -all-static | -static)
+       if test "X$arg" = "X-all-static"; then
+         if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+           $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+         fi
+         if test -n "$link_static_flag"; then
+           dlopen_self=$dlopen_self_static
+         fi
+         prefer_static_libs=yes
+       else
+         if test -z "$pic_flag" && test -n "$link_static_flag"; then
+           dlopen_self=$dlopen_self_static
+         fi
+         prefer_static_libs=built
+       fi
+       build_libtool_libs=no
+       build_old_libs=yes
+       break
+       ;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    while test "$#" -gt 0; do
+      arg="$1"
+      shift
+      case $arg in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
+       qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test
+       ;;
+      *) qarg=$arg ;;
+      esac
+      libtool_args="$libtool_args $qarg"
+
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+       case $prev in
+       output)
+         compile_command="$compile_command @OUTPUT@"
+         finalize_command="$finalize_command @OUTPUT@"
+         ;;
+       esac
+
+       case $prev in
+       dlfiles|dlprefiles)
+         if test "$preload" = no; then
+           # Add the symbol object into the linking commands.
+           compile_command="$compile_command @SYMFILE@"
+           finalize_command="$finalize_command @SYMFILE@"
+           preload=yes
+         fi
+         case $arg in
+         *.la | *.lo) ;;  # We handle these cases below.
+         force)
+           if test "$dlself" = no; then
+             dlself=needless
+             export_dynamic=yes
+           fi
+           prev=
+           continue
+           ;;
+         self)
+           if test "$prev" = dlprefiles; then
+             dlself=yes
+           elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+             dlself=yes
+           else
+             dlself=needless
+             export_dynamic=yes
+           fi
+           prev=
+           continue
+           ;;
+         *)
+           if test "$prev" = dlfiles; then
+             dlfiles="$dlfiles $arg"
+           else
+             dlprefiles="$dlprefiles $arg"
+           fi
+           prev=
+           continue
+           ;;
+         esac
+         ;;
+       expsyms)
+         export_symbols="$arg"
+         if test ! -f "$arg"; then
+           $echo "$modename: symbol file \`$arg' does not exist"
+           exit $EXIT_FAILURE
+         fi
+         prev=
+         continue
+         ;;
+       expsyms_regex)
+         export_symbols_regex="$arg"
+         prev=
+         continue
+         ;;
+       inst_prefix)
+         inst_prefix_dir="$arg"
+         prev=
+         continue
+         ;;
+       precious_regex)
+         precious_files_regex="$arg"
+         prev=
+         continue
+         ;;
+       release)
+         release="-$arg"
+         prev=
+         continue
+         ;;
+       objectlist)
+         if test -f "$arg"; then
+           save_arg=$arg
+           moreargs=
+           for fil in `cat $save_arg`
+           do
+#            moreargs="$moreargs $fil"
+             arg=$fil
+             # A libtool-controlled object.
+
+             # Check to see that this really is a libtool object.
+             if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+               pic_object=
+               non_pic_object=
+
+               # Read the .lo file
+               # If there is no directory component, then add one.
+               case $arg in
+               */* | *\\*) . $arg ;;
+               *) . ./$arg ;;
+               esac
+
+               if test -z "$pic_object" || \
+                  test -z "$non_pic_object" ||
+                  test "$pic_object" = none && \
+                  test "$non_pic_object" = none; then
+                 $echo "$modename: cannot find name of object for \`$arg'" 1>&2
+                 exit $EXIT_FAILURE
+               fi
+
+               # Extract subdirectory from the argument.
+               xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+               if test "X$xdir" = "X$arg"; then
+                 xdir=
+               else
+                 xdir="$xdir/"
+               fi
+
+               if test "$pic_object" != none; then
+                 # Prepend the subdirectory the object is found in.
+                 pic_object="$xdir$pic_object"
+
+                 if test "$prev" = dlfiles; then
+                   if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+                     dlfiles="$dlfiles $pic_object"
+                     prev=
+                     continue
+                   else
+                     # If libtool objects are unsupported, then we need to preload.
+                     prev=dlprefiles
+                   fi
+                 fi
+
+                 # CHECK ME:  I think I busted this.  -Ossama
+                 if test "$prev" = dlprefiles; then
+                   # Preload the old-style object.
+                   dlprefiles="$dlprefiles $pic_object"
+                   prev=
+                 fi
+
+                 # A PIC object.
+                 libobjs="$libobjs $pic_object"
+                 arg="$pic_object"
+               fi
+
+               # Non-PIC object.
+               if test "$non_pic_object" != none; then
+                 # Prepend the subdirectory the object is found in.
+                 non_pic_object="$xdir$non_pic_object"
+
+                 # A standard non-PIC object
+                 non_pic_objects="$non_pic_objects $non_pic_object"
+                 if test -z "$pic_object" || test "$pic_object" = none ; then
+                   arg="$non_pic_object"
+                 fi
+               else
+                 # If the PIC object exists, use it instead.
+                 # $xdir was prepended to $pic_object above.
+                 non_pic_object="$pic_object"
+                 non_pic_objects="$non_pic_objects $non_pic_object"
+               fi
+             else
+               # Only an error if not doing a dry-run.
+               if test -z "$run"; then
+                 $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
+                 exit $EXIT_FAILURE
+               else
+                 # Dry-run case.
+
+                 # Extract subdirectory from the argument.
+                 xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+                 if test "X$xdir" = "X$arg"; then
+                   xdir=
+                 else
+                   xdir="$xdir/"
+                 fi
+
+                 pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
+                 non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
+                 libobjs="$libobjs $pic_object"
+                 non_pic_objects="$non_pic_objects $non_pic_object"
+               fi
+             fi
+           done
+         else
+           $echo "$modename: link input file \`$save_arg' does not exist"
+           exit $EXIT_FAILURE
+         fi
+         arg=$save_arg
+         prev=
+         continue
+         ;;
+       rpath | xrpath)
+         # We need an absolute path.
+         case $arg in
+         [\\/]* | [A-Za-z]:[\\/]*) ;;
+         *)
+           $echo "$modename: only absolute run-paths are allowed" 1>&2
+           exit $EXIT_FAILURE
+           ;;
+         esac
+         if test "$prev" = rpath; then
+           case "$rpath " in
+           *" $arg "*) ;;
+           *) rpath="$rpath $arg" ;;
+           esac
+         else
+           case "$xrpath " in
+           *" $arg "*) ;;
+           *) xrpath="$xrpath $arg" ;;
+           esac
+         fi
+         prev=
+         continue
+         ;;
+       xcompiler)
+         compiler_flags="$compiler_flags $qarg"
+         prev=
+         compile_command="$compile_command $qarg"
+         finalize_command="$finalize_command $qarg"
+         continue
+         ;;
+       xlinker)
+         linker_flags="$linker_flags $qarg"
+         compiler_flags="$compiler_flags $wl$qarg"
+         prev=
+         compile_command="$compile_command $wl$qarg"
+         finalize_command="$finalize_command $wl$qarg"
+         continue
+         ;;
+       xcclinker)
+         linker_flags="$linker_flags $qarg"
+         compiler_flags="$compiler_flags $qarg"
+         prev=
+         compile_command="$compile_command $qarg"
+         finalize_command="$finalize_command $qarg"
+         continue
+         ;;
+       shrext)
+         shrext_cmds="$arg"
+         prev=
+         continue
+         ;;
+       darwin_framework|darwin_framework_skip)
+         test "$prev" = "darwin_framework" && compiler_flags="$compiler_flags $arg"
+         compile_command="$compile_command $arg"
+         finalize_command="$finalize_command $arg"
+         prev=
+         continue
+         ;;
+       *)
+         eval "$prev=\"\$arg\""
+         prev=
+         continue
+         ;;
+       esac
+      fi # test -n "$prev"
+
+      prevarg="$arg"
+
+      case $arg in
+      -all-static)
+       if test -n "$link_static_flag"; then
+         compile_command="$compile_command $link_static_flag"
+         finalize_command="$finalize_command $link_static_flag"
+       fi
+       continue
+       ;;
+
+      -allow-undefined)
+       # FIXME: remove this flag sometime in the future.
+       $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+       continue
+       ;;
+
+      -avoid-version)
+       avoid_version=yes
+       continue
+       ;;
+
+      -dlopen)
+       prev=dlfiles
+       continue
+       ;;
+
+      -dlpreopen)
+       prev=dlprefiles
+       continue
+       ;;
+
+      -export-dynamic)
+       export_dynamic=yes
+       continue
+       ;;
+
+      -export-symbols | -export-symbols-regex)
+       if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+         $echo "$modename: more than one -exported-symbols argument is not allowed"
+         exit $EXIT_FAILURE
+       fi
+       if test "X$arg" = "X-export-symbols"; then
+         prev=expsyms
+       else
+         prev=expsyms_regex
+       fi
+       continue
+       ;;
+
+      -framework|-arch|-isysroot)
+       case " $CC " in
+         *" ${arg} ${1} "* | *" ${arg} ${1} "*) 
+               prev=darwin_framework_skip ;;
+         *) compiler_flags="$compiler_flags $arg"
+            prev=darwin_framework ;;
+       esac
+       compile_command="$compile_command $arg"
+       finalize_command="$finalize_command $arg"
+       continue
+       ;;
+
+      -inst-prefix-dir)
+       prev=inst_prefix
+       continue
+       ;;
+
+      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+      # so, if we see these flags be careful not to treat them like -L
+      -L[A-Z][A-Z]*:*)
+       case $with_gcc/$host in
+       no/*-*-irix* | /*-*-irix*)
+         compile_command="$compile_command $arg"
+         finalize_command="$finalize_command $arg"
+         ;;
+       esac
+       continue
+       ;;
+
+      -L*)
+       dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
+       # We need an absolute path.
+       case $dir in
+       [\\/]* | [A-Za-z]:[\\/]*) ;;
+       *)
+         absdir=`cd "$dir" && pwd`
+         if test -z "$absdir"; then
+           $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
+           absdir="$dir"
+           notinst_path="$notinst_path $dir"
+         fi
+         dir="$absdir"
+         ;;
+       esac
+       case "$deplibs " in
+       *" -L$dir "*) ;;
+       *)
+         deplibs="$deplibs -L$dir"
+         lib_search_path="$lib_search_path $dir"
+         ;;
+       esac
+       case $host in
+       *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+         testbindir=`$echo "X$dir" | $Xsed -e 's*/lib$*/bin*'`
+         case :$dllsearchpath: in
+         *":$dir:"*) ;;
+         *) dllsearchpath="$dllsearchpath:$dir";;
+         esac
+         case :$dllsearchpath: in
+         *":$testbindir:"*) ;;
+         *) dllsearchpath="$dllsearchpath:$testbindir";;
+         esac
+         ;;
+       esac
+       continue
+       ;;
+
+      -l*)
+       if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+         case $host in
+         *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*)
+           # These systems don't actually have a C or math library (as such)
+           continue
+           ;;
+         *-*-os2*)
+           # These systems don't actually have a C library (as such)
+           test "X$arg" = "X-lc" && continue
+           ;;
+         *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+           # Do not include libc due to us having libc/libc_r.
+           test "X$arg" = "X-lc" && continue
+           ;;
+         *-*-rhapsody* | *-*-darwin1.[012])
+           # Rhapsody C and math libraries are in the System framework
+           deplibs="$deplibs -framework System"
+           continue
+           ;;
+         *-*-sco3.2v5* | *-*-sco5v6*)
+           # Causes problems with __ctype
+           test "X$arg" = "X-lc" && continue
+           ;;
+         *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+           # Compiler inserts libc in the correct place for threads to work
+           test "X$arg" = "X-lc" && continue
+           ;;
+         esac
+       elif test "X$arg" = "X-lc_r"; then
+        case $host in
+        *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+          # Do not include libc_r directly, use -pthread flag.
+          continue
+          ;;
+        esac
+       fi
+       deplibs="$deplibs $arg"
+       continue
+       ;;
+
+      # Tru64 UNIX uses -model [arg] to determine the layout of C++
+      # classes, name mangling, and exception handling.
+      -model)
+       compile_command="$compile_command $arg"
+       compiler_flags="$compiler_flags $arg"
+       finalize_command="$finalize_command $arg"
+       prev=xcompiler
+       continue
+       ;;
+
+     -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe)
+       compiler_flags="$compiler_flags $arg"
+       compile_command="$compile_command $arg"
+       finalize_command="$finalize_command $arg"
+       continue
+       ;;
+
+      -module)
+       module=yes
+       continue
+       ;;
+
+      # -64, -mips[0-9] enable 64-bit mode on the SGI compiler
+      # -r[0-9][0-9]* specifies the processor on the SGI compiler
+      # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler
+      # +DA*, +DD* enable 64-bit mode on the HP compiler
+      # -q* pass through compiler args for the IBM compiler
+      # -m* pass through architecture-specific compiler args for GCC
+      # -m*, -t[45]*, -txscale* pass through architecture-specific
+      # compiler args for GCC
+      # -pg pass through profiling flag for GCC
+      # @file GCC response files
+      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*|-pg| \
+      -t[45]*|-txscale*|@*)
+
+       # Unknown arguments in both finalize_command and compile_command need
+       # to be aesthetically quoted because they are evaled later.
+       arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+       case $arg in
+       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*|"")
+         arg="\"$arg\""
+         ;;
+       esac
+        compile_command="$compile_command $arg"
+        finalize_command="$finalize_command $arg"
+        compiler_flags="$compiler_flags $arg"
+        continue
+        ;;
+
+      -shrext)
+       prev=shrext
+       continue
+       ;;
+
+      -no-fast-install)
+       fast_install=no
+       continue
+       ;;
+
+      -no-install)
+       case $host in
+       *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+         # The PATH hackery in wrapper scripts is required on Windows
+         # in order for the loader to find any dlls it needs.
+         $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2
+         $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2
+         fast_install=no
+         ;;
+       *) no_install=yes ;;
+       esac
+       continue
+       ;;
+
+      -no-undefined)
+       allow_undefined=no
+       continue
+       ;;
+
+      -objectlist)
+       prev=objectlist
+       continue
+       ;;
+
+      -o) prev=output ;;
+
+      -precious-files-regex)
+       prev=precious_regex
+       continue
+       ;;
+
+      -release)
+       prev=release
+       continue
+       ;;
+
+      -rpath)
+       prev=rpath
+       continue
+       ;;
+
+      -R)
+       prev=xrpath
+       continue
+       ;;
+
+      -R*)
+       dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
+       # We need an absolute path.
+       case $dir in
+       [\\/]* | [A-Za-z]:[\\/]*) ;;
+       *)
+         $echo "$modename: only absolute run-paths are allowed" 1>&2
+         exit $EXIT_FAILURE
+         ;;
+       esac
+       case "$xrpath " in
+       *" $dir "*) ;;
+       *) xrpath="$xrpath $dir" ;;
+       esac
+       continue
+       ;;
+
+      -static)
+       # The effects of -static are defined in a previous loop.
+       # We used to do the same as -all-static on platforms that
+       # didn't have a PIC flag, but the assumption that the effects
+       # would be equivalent was wrong.  It would break on at least
+       # Digital Unix and AIX.
+       continue
+       ;;
+
+      -thread-safe)
+       thread_safe=yes
+       continue
+       ;;
+
+      -version-info)
+       prev=vinfo
+       continue
+       ;;
+      -version-number)
+       prev=vinfo
+       vinfo_number=yes
+       continue
+       ;;
+
+      -Wc,*)
+       args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'`
+       arg=
+       save_ifs="$IFS"; IFS=','
+       for flag in $args; do
+         IFS="$save_ifs"
+         case $flag in
+           *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \       ]*|*]*|"")
+           flag="\"$flag\""
+           ;;
+         esac
+         arg="$arg $wl$flag"
+         compiler_flags="$compiler_flags $flag"
+       done
+       IFS="$save_ifs"
+       arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
+       ;;
+
+      -Wl,*)
+       args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'`
+       arg=
+       save_ifs="$IFS"; IFS=','
+       for flag in $args; do
+         IFS="$save_ifs"
+         case $flag in
+           *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \       ]*|*]*|"")
+           flag="\"$flag\""
+           ;;
+         esac
+         arg="$arg $wl$flag"
+         compiler_flags="$compiler_flags $wl$flag"
+         linker_flags="$linker_flags $flag"
+       done
+       IFS="$save_ifs"
+       arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
+       ;;
+
+      -Xcompiler)
+       prev=xcompiler
+       continue
+       ;;
+
+      -Xlinker)
+       prev=xlinker
+       continue
+       ;;
+
+      -XCClinker)
+       prev=xcclinker
+       continue
+       ;;
+
+      # Some other compiler flag.
+      -* | +*)
+       # Unknown arguments in both finalize_command and compile_command need
+       # to be aesthetically quoted because they are evaled later.
+       arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+       case $arg in
+       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*|"")
+         arg="\"$arg\""
+         ;;
+       esac
+       ;;
+
+      *.$objext)
+       # A standard object.
+       objs="$objs $arg"
+       ;;
+
+      *.lo)
+       # A libtool-controlled object.
+
+       # Check to see that this really is a libtool object.
+       if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+         pic_object=
+         non_pic_object=
+
+         # Read the .lo file
+         # If there is no directory component, then add one.
+         case $arg in
+         */* | *\\*) . $arg ;;
+         *) . ./$arg ;;
+         esac
+
+         if test -z "$pic_object" || \
+            test -z "$non_pic_object" ||
+            test "$pic_object" = none && \
+            test "$non_pic_object" = none; then
+           $echo "$modename: cannot find name of object for \`$arg'" 1>&2
+           exit $EXIT_FAILURE
+         fi
+
+         # Extract subdirectory from the argument.
+         xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+         if test "X$xdir" = "X$arg"; then
+           xdir=
+         else
+           xdir="$xdir/"
+         fi
+
+         if test "$pic_object" != none; then
+           # Prepend the subdirectory the object is found in.
+           pic_object="$xdir$pic_object"
+
+           if test "$prev" = dlfiles; then
+             if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+               dlfiles="$dlfiles $pic_object"
+               prev=
+               continue
+             else
+               # If libtool objects are unsupported, then we need to preload.
+               prev=dlprefiles
+             fi
+           fi
+
+           # CHECK ME:  I think I busted this.  -Ossama
+           if test "$prev" = dlprefiles; then
+             # Preload the old-style object.
+             dlprefiles="$dlprefiles $pic_object"
+             prev=
+           fi
+
+           # A PIC object.
+           libobjs="$libobjs $pic_object"
+           arg="$pic_object"
+         fi
+
+         # Non-PIC object.
+         if test "$non_pic_object" != none; then
+           # Prepend the subdirectory the object is found in.
+           non_pic_object="$xdir$non_pic_object"
+
+           # A standard non-PIC object
+           non_pic_objects="$non_pic_objects $non_pic_object"
+           if test -z "$pic_object" || test "$pic_object" = none ; then
+             arg="$non_pic_object"
+           fi
+         else
+           # If the PIC object exists, use it instead.
+           # $xdir was prepended to $pic_object above.
+           non_pic_object="$pic_object"
+           non_pic_objects="$non_pic_objects $non_pic_object"
+         fi
+       else
+         # Only an error if not doing a dry-run.
+         if test -z "$run"; then
+           $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
+           exit $EXIT_FAILURE
+         else
+           # Dry-run case.
+
+           # Extract subdirectory from the argument.
+           xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+           if test "X$xdir" = "X$arg"; then
+             xdir=
+           else
+             xdir="$xdir/"
+           fi
+
+           pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
+           non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
+           libobjs="$libobjs $pic_object"
+           non_pic_objects="$non_pic_objects $non_pic_object"
+         fi
+       fi
+       ;;
+
+      *.$libext)
+       # An archive.
+       deplibs="$deplibs $arg"
+       old_deplibs="$old_deplibs $arg"
+       continue
+       ;;
+
+      *.la)
+       # A libtool-controlled library.
+
+       if test "$prev" = dlfiles; then
+         # This library was specified with -dlopen.
+         dlfiles="$dlfiles $arg"
+         prev=
+       elif test "$prev" = dlprefiles; then
+         # The library was specified with -dlpreopen.
+         dlprefiles="$dlprefiles $arg"
+         prev=
+       else
+         deplibs="$deplibs $arg"
+       fi
+       continue
+       ;;
+
+      # Some other compiler argument.
+      *)
+       # Unknown arguments in both finalize_command and compile_command need
+       # to be aesthetically quoted because they are evaled later.
+       arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+       case $arg in
+       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*|"")
+         arg="\"$arg\""
+         ;;
+       esac
+       ;;
+      esac # arg
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+       compile_command="$compile_command $arg"
+       finalize_command="$finalize_command $arg"
+      fi
+    done # argument parsing loop
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+      eval arg=\"$export_dynamic_flag_spec\"
+      compile_command="$compile_command $arg"
+      finalize_command="$finalize_command $arg"
+    fi
+
+    oldlibs=
+    # calculate the name of the file, without its directory
+    outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
+    libobjs_save="$libobjs"
+
+    if test -n "$shlibpath_var"; then
+      # get the directories listed in $shlibpath_var
+      eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+    else
+      shlib_search_path=
+    fi
+    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+    output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+    if test "X$output_objdir" = "X$output"; then
+      output_objdir="$objdir"
+    else
+      output_objdir="$output_objdir/$objdir"
+    fi
+    # Create the object directory.
+    if test ! -d "$output_objdir"; then
+      $show "$mkdir $output_objdir"
+      $run $mkdir $output_objdir
+      exit_status=$?
+      if test "$exit_status" -ne 0 && test ! -d "$output_objdir"; then
+       exit $exit_status
+      fi
+    fi
+
+    # Determine the type of output
+    case $output in
+    "")
+      $echo "$modename: you must specify an output file" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+      ;;
+    *.$libext) linkmode=oldlib ;;
+    *.lo | *.$objext) linkmode=obj ;;
+    *.la) linkmode=lib ;;
+    *) linkmode=prog ;; # Anything else should be a program.
+    esac
+
+    case $host in
+    *cygwin* | *mingw* | *pw32*)
+      # don't eliminate duplications in $postdeps and $predeps
+      duplicate_compiler_generated_deps=yes
+      ;;
+    *)
+      duplicate_compiler_generated_deps=$duplicate_deps
+      ;;
+    esac
+    specialdeplibs=
+
+    libs=
+    # Find all interdependent deplibs by searching for libraries
+    # that are linked more than once (e.g. -la -lb -la)
+    for deplib in $deplibs; do
+      if test "X$duplicate_deps" = "Xyes" ; then
+       case "$libs " in
+       *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+       esac
+      fi
+      libs="$libs $deplib"
+    done
+
+    if test "$linkmode" = lib; then
+      libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+      # Compute libraries that are listed more than once in $predeps
+      # $postdeps and mark them as special (i.e., whose duplicates are
+      # not to be eliminated).
+      pre_post_deps=
+      if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then
+       for pre_post_dep in $predeps $postdeps; do
+         case "$pre_post_deps " in
+         *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;;
+         esac
+         pre_post_deps="$pre_post_deps $pre_post_dep"
+       done
+      fi
+      pre_post_deps=
+    fi
+
+    deplibs=
+    newdependency_libs=
+    newlib_search_path=
+    need_relink=no # whether we're linking any uninstalled libtool libraries
+    notinst_deplibs= # not-installed libtool libraries
+    case $linkmode in
+    lib)
+       passes="conv link"
+       for file in $dlfiles $dlprefiles; do
+         case $file in
+         *.la) ;;
+         *)
+           $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2
+           exit $EXIT_FAILURE
+           ;;
+         esac
+       done
+       ;;
+    prog)
+       compile_deplibs=
+       finalize_deplibs=
+       alldeplibs=no
+       newdlfiles=
+       newdlprefiles=
+       passes="conv scan dlopen dlpreopen link"
+       ;;
+    *)  passes="conv"
+       ;;
+    esac
+    for pass in $passes; do
+      if test "$linkmode,$pass" = "lib,link" ||
+        test "$linkmode,$pass" = "prog,scan"; then
+       libs="$deplibs"
+       deplibs=
+      fi
+      if test "$linkmode" = prog; then
+       case $pass in
+       dlopen) libs="$dlfiles" ;;
+       dlpreopen) libs="$dlprefiles" ;;
+       link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+       esac
+      fi
+      if test "$pass" = dlopen; then
+       # Collect dlpreopened libraries
+       save_deplibs="$deplibs"
+       deplibs=
+      fi
+      for deplib in $libs; do
+       lib=
+       found=no
+       case $deplib in
+       -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe)
+         if test "$linkmode,$pass" = "prog,link"; then
+           compile_deplibs="$deplib $compile_deplibs"
+           finalize_deplibs="$deplib $finalize_deplibs"
+         else
+           compiler_flags="$compiler_flags $deplib"
+         fi
+         continue
+         ;;
+       -l*)
+         if test "$linkmode" != lib && test "$linkmode" != prog; then
+           $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2
+           continue
+         fi
+         name=`$echo "X$deplib" | $Xsed -e 's/^-l//'`
+         for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do
+           for search_ext in .la $std_shrext .so .a; do
+             # Search the libtool library
+             lib="$searchdir/lib${name}${search_ext}"
+             if test -f "$lib"; then
+               if test "$search_ext" = ".la"; then
+                 found=yes
+               else
+                 found=no
+               fi
+               break 2
+             fi
+           done
+         done
+         if test "$found" != yes; then
+           # deplib doesn't seem to be a libtool library
+           if test "$linkmode,$pass" = "prog,link"; then
+             compile_deplibs="$deplib $compile_deplibs"
+             finalize_deplibs="$deplib $finalize_deplibs"
+           else
+             deplibs="$deplib $deplibs"
+             test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+           fi
+           continue
+         else # deplib is a libtool library
+           # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+           # We need to do some special things here, and not later.
+           if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+             case " $predeps $postdeps " in
+             *" $deplib "*)
+               if (${SED} -e '2q' $lib |
+                    grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+                 library_names=
+                 old_library=
+                 case $lib in
+                 */* | *\\*) . $lib ;;
+                 *) . ./$lib ;;
+                 esac
+                 for l in $old_library $library_names; do
+                   ll="$l"
+                 done
+                 if test "X$ll" = "X$old_library" ; then # only static version available
+                   found=no
+                   ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
+                   test "X$ladir" = "X$lib" && ladir="."
+                   lib=$ladir/$old_library
+                   if test "$linkmode,$pass" = "prog,link"; then
+                     compile_deplibs="$deplib $compile_deplibs"
+                     finalize_deplibs="$deplib $finalize_deplibs"
+                   else
+                     deplibs="$deplib $deplibs"
+                     test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+                   fi
+                   continue
+                 fi
+               fi
+               ;;
+             *) ;;
+             esac
+           fi
+         fi
+         ;; # -l
+       -L*)
+         case $linkmode in
+         lib)
+           deplibs="$deplib $deplibs"
+           test "$pass" = conv && continue
+           newdependency_libs="$deplib $newdependency_libs"
+           newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+           ;;
+         prog)
+           if test "$pass" = conv; then
+             deplibs="$deplib $deplibs"
+             continue
+           fi
+           if test "$pass" = scan; then
+             deplibs="$deplib $deplibs"
+           else
+             compile_deplibs="$deplib $compile_deplibs"
+             finalize_deplibs="$deplib $finalize_deplibs"
+           fi
+           newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+           ;;
+         *)
+           $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2
+           ;;
+         esac # linkmode
+         continue
+         ;; # -L
+       -R*)
+         if test "$pass" = link; then
+           dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
+           # Make sure the xrpath contains only unique directories.
+           case "$xrpath " in
+           *" $dir "*) ;;
+           *) xrpath="$xrpath $dir" ;;
+           esac
+         fi
+         deplibs="$deplib $deplibs"
+         continue
+         ;;
+       *.la) lib="$deplib" ;;
+       *.$libext)
+         if test "$pass" = conv; then
+           deplibs="$deplib $deplibs"
+           continue
+         fi
+         case $linkmode in
+         lib)
+           valid_a_lib=no
+           case $deplibs_check_method in
+             match_pattern*)
+               set dummy $deplibs_check_method
+               match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+               if eval $echo \"$deplib\" 2>/dev/null \
+                   | $SED 10q \
+                   | $EGREP "$match_pattern_regex" > /dev/null; then
+                 valid_a_lib=yes
+               fi
+               ;;
+             pass_all)
+               valid_a_lib=yes
+               ;;
+            esac
+           if test "$valid_a_lib" != yes; then
+             $echo
+             $echo "*** Warning: Trying to link with static lib archive $deplib."
+             $echo "*** I have the capability to make that library automatically link in when"
+             $echo "*** you link to this library.  But I can only do this if you have a"
+             $echo "*** shared version of the library, which you do not appear to have"
+             $echo "*** because the file extensions .$libext of this argument makes me believe"
+             $echo "*** that it is just a static archive that I should not used here."
+           else
+             $echo
+             $echo "*** Warning: Linking the shared library $output against the"
+             $echo "*** static library $deplib is not portable!"
+             deplibs="$deplib $deplibs"
+           fi
+           continue
+           ;;
+         prog)
+           if test "$pass" != link; then
+             deplibs="$deplib $deplibs"
+           else
+             compile_deplibs="$deplib $compile_deplibs"
+             finalize_deplibs="$deplib $finalize_deplibs"
+           fi
+           continue
+           ;;
+         esac # linkmode
+         ;; # *.$libext
+       *.lo | *.$objext)
+         if test "$pass" = conv; then
+           deplibs="$deplib $deplibs"
+         elif test "$linkmode" = prog; then
+           if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+             # If there is no dlopen support or we're linking statically,
+             # we need to preload.
+             newdlprefiles="$newdlprefiles $deplib"
+             compile_deplibs="$deplib $compile_deplibs"
+             finalize_deplibs="$deplib $finalize_deplibs"
+           else
+             newdlfiles="$newdlfiles $deplib"
+           fi
+         fi
+         continue
+         ;;
+       %DEPLIBS%)
+         alldeplibs=yes
+         continue
+         ;;
+       esac # case $deplib
+       if test "$found" = yes || test -f "$lib"; then :
+       else
+         $echo "$modename: cannot find the library \`$lib' or unhandled argument \`$deplib'" 1>&2
+         exit $EXIT_FAILURE
+       fi
+
+       # Check to see that this really is a libtool archive.
+       if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+       else
+         $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+         exit $EXIT_FAILURE
+       fi
+
+       ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
+       test "X$ladir" = "X$lib" && ladir="."
+
+       dlname=
+       dlopen=
+       dlpreopen=
+       libdir=
+       library_names=
+       old_library=
+       # If the library was installed with an old release of libtool,
+       # it will not redefine variables installed, or shouldnotlink
+       installed=yes
+       shouldnotlink=no
+       avoidtemprpath=
+
+
+       # Read the .la file
+       case $lib in
+       */* | *\\*) . $lib ;;
+       *) . ./$lib ;;
+       esac
+
+       if test "$linkmode,$pass" = "lib,link" ||
+          test "$linkmode,$pass" = "prog,scan" ||
+          { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+         test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
+         test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
+       fi
+
+       if test "$pass" = conv; then
+         # Only check for convenience libraries
+         deplibs="$lib $deplibs"
+         if test -z "$libdir"; then
+           if test -z "$old_library"; then
+             $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
+             exit $EXIT_FAILURE
+           fi
+           # It is a libtool convenience library, so add in its objects.
+           convenience="$convenience $ladir/$objdir/$old_library"
+           old_convenience="$old_convenience $ladir/$objdir/$old_library"
+           tmp_libs=
+           for deplib in $dependency_libs; do
+             deplibs="$deplib $deplibs"
+              if test "X$duplicate_deps" = "Xyes" ; then
+               case "$tmp_libs " in
+               *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+               esac
+              fi
+             tmp_libs="$tmp_libs $deplib"
+           done
+         elif test "$linkmode" != prog && test "$linkmode" != lib; then
+           $echo "$modename: \`$lib' is not a convenience library" 1>&2
+           exit $EXIT_FAILURE
+         fi
+         continue
+       fi # $pass = conv
+
+
+       # Get the name of the library we link against.
+       linklib=
+       for l in $old_library $library_names; do
+         linklib="$l"
+       done
+       if test -z "$linklib"; then
+         $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
+         exit $EXIT_FAILURE
+       fi
+
+       # This library was specified with -dlopen.
+       if test "$pass" = dlopen; then
+         if test -z "$libdir"; then
+           $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2
+           exit $EXIT_FAILURE
+         fi
+         if test -z "$dlname" ||
+            test "$dlopen_support" != yes ||
+            test "$build_libtool_libs" = no; then
+           # If there is no dlname, no dlopen support or we're linking
+           # statically, we need to preload.  We also need to preload any
+           # dependent libraries so libltdl's deplib preloader doesn't
+           # bomb out in the load deplibs phase.
+           dlprefiles="$dlprefiles $lib $dependency_libs"
+         else
+           newdlfiles="$newdlfiles $lib"
+         fi
+         continue
+       fi # $pass = dlopen
+
+       # We need an absolute path.
+       case $ladir in
+       [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+       *)
+         abs_ladir=`cd "$ladir" && pwd`
+         if test -z "$abs_ladir"; then
+           $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2
+           $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+           abs_ladir="$ladir"
+         fi
+         ;;
+       esac
+       laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+
+       # Find the relevant object directory and library name.
+       if test "X$installed" = Xyes; then
+         if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+           $echo "$modename: warning: library \`$lib' was moved." 1>&2
+           dir="$ladir"
+           absdir="$abs_ladir"
+           libdir="$abs_ladir"
+         else
+           dir="$libdir"
+           absdir="$libdir"
+         fi
+         test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
+       else
+         if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+           dir="$ladir"
+           absdir="$abs_ladir"
+           # Remove this search path later
+           notinst_path="$notinst_path $abs_ladir"
+         else
+           dir="$ladir/$objdir"
+           absdir="$abs_ladir/$objdir"
+           # Remove this search path later
+           notinst_path="$notinst_path $abs_ladir"
+         fi
+       fi # $installed = yes
+       name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+
+       # This library was specified with -dlpreopen.
+       if test "$pass" = dlpreopen; then
+         if test -z "$libdir"; then
+           $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2
+           exit $EXIT_FAILURE
+         fi
+         # Prefer using a static library (so that no silly _DYNAMIC symbols
+         # are required to link).
+         if test -n "$old_library"; then
+           newdlprefiles="$newdlprefiles $dir/$old_library"
+         # Otherwise, use the dlname, so that lt_dlopen finds it.
+         elif test -n "$dlname"; then
+           newdlprefiles="$newdlprefiles $dir/$dlname"
+         else
+           newdlprefiles="$newdlprefiles $dir/$linklib"
+         fi
+       fi # $pass = dlpreopen
+
+       if test -z "$libdir"; then
+         # Link the convenience library
+         if test "$linkmode" = lib; then
+           deplibs="$dir/$old_library $deplibs"
+         elif test "$linkmode,$pass" = "prog,link"; then
+           compile_deplibs="$dir/$old_library $compile_deplibs"
+           finalize_deplibs="$dir/$old_library $finalize_deplibs"
+         else
+           deplibs="$lib $deplibs" # used for prog,scan pass
+         fi
+         continue
+       fi
+
+
+       if test "$linkmode" = prog && test "$pass" != link; then
+         newlib_search_path="$newlib_search_path $ladir"
+         deplibs="$lib $deplibs"
+
+         linkalldeplibs=no
+         if test "$link_all_deplibs" != no || test -z "$library_names" ||
+            test "$build_libtool_libs" = no; then
+           linkalldeplibs=yes
+         fi
+
+         tmp_libs=
+         for deplib in $dependency_libs; do
+           case $deplib in
+           -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test
+           esac
+           # Need to link against all dependency_libs?
+           if test "$linkalldeplibs" = yes; then
+             deplibs="$deplib $deplibs"
+           else
+             # Need to hardcode shared library paths
+             # or/and link against static libraries
+             newdependency_libs="$deplib $newdependency_libs"
+           fi
+           if test "X$duplicate_deps" = "Xyes" ; then
+             case "$tmp_libs " in
+             *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+             esac
+           fi
+           tmp_libs="$tmp_libs $deplib"
+         done # for deplib
+         continue
+       fi # $linkmode = prog...
+
+       if test "$linkmode,$pass" = "prog,link"; then
+         if test -n "$library_names" &&
+            { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+           # We need to hardcode the library path
+           if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
+             # Make sure the rpath contains only unique directories.
+             case "$temp_rpath " in
+             *" $dir "*) ;;
+             *" $absdir "*) ;;
+             *) temp_rpath="$temp_rpath $absdir" ;;
+             esac
+           fi
+
+           # Hardcode the library path.
+           # Skip directories that are in the system default run-time
+           # search path.
+           case " $sys_lib_dlsearch_path " in
+           *" $absdir "*) ;;
+           *)
+             case "$compile_rpath " in
+             *" $absdir "*) ;;
+             *) compile_rpath="$compile_rpath $absdir"
+             esac
+             ;;
+           esac
+           case " $sys_lib_dlsearch_path " in
+           *" $libdir "*) ;;
+           *)
+             case "$finalize_rpath " in
+             *" $libdir "*) ;;
+             *) finalize_rpath="$finalize_rpath $libdir"
+             esac
+             ;;
+           esac
+         fi # $linkmode,$pass = prog,link...
+
+         if test "$alldeplibs" = yes &&
+            { test "$deplibs_check_method" = pass_all ||
+              { test "$build_libtool_libs" = yes &&
+                test -n "$library_names"; }; }; then
+           # We only need to search for static libraries
+           continue
+         fi
+       fi
+
+       link_static=no # Whether the deplib will be linked statically
+       use_static_libs=$prefer_static_libs
+       if test "$use_static_libs" = built && test "$installed" = yes ; then
+         use_static_libs=no
+       fi
+       if test -n "$library_names" &&
+          { test "$use_static_libs" = no || test -z "$old_library"; }; then
+         if test "$installed" = no; then
+           notinst_deplibs="$notinst_deplibs $lib"
+           need_relink=yes
+         fi
+         # This is a shared library
+
+         # Warn about portability, can't link against -module's on
+         # some systems (darwin)
+         if test "$shouldnotlink" = yes && test "$pass" = link ; then
+           $echo
+           if test "$linkmode" = prog; then
+             $echo "*** Warning: Linking the executable $output against the loadable module"
+           else
+             $echo "*** Warning: Linking the shared library $output against the loadable module"
+           fi
+           $echo "*** $linklib is not portable!"
+         fi
+         if test "$linkmode" = lib &&
+            test "$hardcode_into_libs" = yes; then
+           # Hardcode the library path.
+           # Skip directories that are in the system default run-time
+           # search path.
+           case " $sys_lib_dlsearch_path " in
+           *" $absdir "*) ;;
+           *)
+             case "$compile_rpath " in
+             *" $absdir "*) ;;
+             *) compile_rpath="$compile_rpath $absdir"
+             esac
+             ;;
+           esac
+           case " $sys_lib_dlsearch_path " in
+           *" $libdir "*) ;;
+           *)
+             case "$finalize_rpath " in
+             *" $libdir "*) ;;
+             *) finalize_rpath="$finalize_rpath $libdir"
+             esac
+             ;;
+           esac
+         fi
+
+         if test -n "$old_archive_from_expsyms_cmds"; then
+           # figure out the soname
+           set dummy $library_names
+           realname="$2"
+           shift; shift
+           libname=`eval \\$echo \"$libname_spec\"`
+           # use dlname if we got it. it's perfectly good, no?
+           if test -n "$dlname"; then
+             soname="$dlname"
+           elif test -n "$soname_spec"; then
+             # bleh windows
+             case $host in
+             *cygwin* | mingw*)
+               major=`expr $current - $age`
+               versuffix="-$major"
+               ;;
+             esac
+             eval soname=\"$soname_spec\"
+           else
+             soname="$realname"
+           fi
+
+           # Make a new name for the extract_expsyms_cmds to use
+           soroot="$soname"
+           soname=`$echo $soroot | ${SED} -e 's/^.*\///'`
+           newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a"
+
+           # If the library has no export list, then create one now
+           if test -f "$output_objdir/$soname-def"; then :
+           else
+             $show "extracting exported symbol list from \`$soname'"
+             save_ifs="$IFS"; IFS='~'
+             cmds=$extract_expsyms_cmds
+             for cmd in $cmds; do
+               IFS="$save_ifs"
+               eval cmd=\"$cmd\"
+               $show "$cmd"
+               $run eval "$cmd" || exit $?
+             done
+             IFS="$save_ifs"
+           fi
+
+           # Create $newlib
+           if test -f "$output_objdir/$newlib"; then :; else
+             $show "generating import library for \`$soname'"
+             save_ifs="$IFS"; IFS='~'
+             cmds=$old_archive_from_expsyms_cmds
+             for cmd in $cmds; do
+               IFS="$save_ifs"
+               eval cmd=\"$cmd\"
+               $show "$cmd"
+               $run eval "$cmd" || exit $?
+             done
+             IFS="$save_ifs"
+           fi
+           # make sure the library variables are pointing to the new library
+           dir=$output_objdir
+           linklib=$newlib
+         fi # test -n "$old_archive_from_expsyms_cmds"
+
+         if test "$linkmode" = prog || test "$mode" != relink; then
+           add_shlibpath=
+           add_dir=
+           add=
+           lib_linked=yes
+           case $hardcode_action in
+           immediate | unsupported)
+             if test "$hardcode_direct" = no; then
+               add="$dir/$linklib"
+               case $host in
+                 *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+                 *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+                 *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+                   *-*-unixware7*) add_dir="-L$dir" ;;
+                 *-*-darwin* )
+                   # if the lib is a module then we can not link against
+                   # it, someone is ignoring the new warnings I added
+                   if /usr/bin/file -L $add 2> /dev/null |
+                      $EGREP ": [^:]* bundle" >/dev/null ; then
+                     $echo "** Warning, lib $linklib is a module, not a shared library"
+                     if test -z "$old_library" ; then
+                       $echo
+                       $echo "** And there doesn't seem to be a static archive available"
+                       $echo "** The link will probably fail, sorry"
+                     else
+                       add="$dir/$old_library"
+                     fi
+                   fi
+               esac
+             elif test "$hardcode_minus_L" = no; then
+               case $host in
+               *-*-sunos*) add_shlibpath="$dir" ;;
+               esac
+               add_dir="-L$dir"
+               add="-l$name"
+             elif test "$hardcode_shlibpath_var" = no; then
+               add_shlibpath="$dir"
+               add="-l$name"
+             else
+               lib_linked=no
+             fi
+             ;;
+           relink)
+             if test "$hardcode_direct" = yes; then
+               add="$dir/$linklib"
+             elif test "$hardcode_minus_L" = yes; then
+               add_dir="-L$dir"
+               # Try looking first in the location we're being installed to.
+               if test -n "$inst_prefix_dir"; then
+                 case $libdir in
+                   [\\/]*)
+                     add_dir="$add_dir -L$inst_prefix_dir$libdir"
+                     ;;
+                 esac
+               fi
+               add="-l$name"
+             elif test "$hardcode_shlibpath_var" = yes; then
+               add_shlibpath="$dir"
+               add="-l$name"
+             else
+               lib_linked=no
+             fi
+             ;;
+           *) lib_linked=no ;;
+           esac
+
+           if test "$lib_linked" != yes; then
+             $echo "$modename: configuration error: unsupported hardcode properties"
+             exit $EXIT_FAILURE
+           fi
+
+           if test -n "$add_shlibpath"; then
+             case :$compile_shlibpath: in
+             *":$add_shlibpath:"*) ;;
+             *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
+             esac
+           fi
+           if test "$linkmode" = prog; then
+             test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+             test -n "$add" && compile_deplibs="$add $compile_deplibs"
+           else
+             test -n "$add_dir" && deplibs="$add_dir $deplibs"
+             test -n "$add" && deplibs="$add $deplibs"
+             if test "$hardcode_direct" != yes && \
+                test "$hardcode_minus_L" != yes && \
+                test "$hardcode_shlibpath_var" = yes; then
+               case :$finalize_shlibpath: in
+               *":$libdir:"*) ;;
+               *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+               esac
+             fi
+           fi
+         fi
+
+         if test "$linkmode" = prog || test "$mode" = relink; then
+           add_shlibpath=
+           add_dir=
+           add=
+           # Finalize command for both is simple: just hardcode it.
+           if test "$hardcode_direct" = yes; then
+             add="$libdir/$linklib"
+           elif test "$hardcode_minus_L" = yes; then
+             add_dir="-L$libdir"
+             add="-l$name"
+           elif test "$hardcode_shlibpath_var" = yes; then
+             case :$finalize_shlibpath: in
+             *":$libdir:"*) ;;
+             *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+             esac
+             add="-l$name"
+           elif test "$hardcode_automatic" = yes; then
+             if test -n "$inst_prefix_dir" &&
+                test -f "$inst_prefix_dir$libdir/$linklib" ; then
+               add="$inst_prefix_dir$libdir/$linklib"
+             else
+               add="$libdir/$linklib"
+             fi
+           else
+             # We cannot seem to hardcode it, guess we'll fake it.
+             add_dir="-L$libdir"
+             # Try looking first in the location we're being installed to.
+             if test -n "$inst_prefix_dir"; then
+               case $libdir in
+                 [\\/]*)
+                   add_dir="$add_dir -L$inst_prefix_dir$libdir"
+                   ;;
+               esac
+             fi
+             add="-l$name"
+           fi
+
+           if test "$linkmode" = prog; then
+             test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+             test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+           else
+             test -n "$add_dir" && deplibs="$add_dir $deplibs"
+             test -n "$add" && deplibs="$add $deplibs"
+           fi
+         fi
+       elif test "$linkmode" = prog; then
+         # Here we assume that one of hardcode_direct or hardcode_minus_L
+         # is not unsupported.  This is valid on all known static and
+         # shared platforms.
+         if test "$hardcode_direct" != unsupported; then
+           test -n "$old_library" && linklib="$old_library"
+           compile_deplibs="$dir/$linklib $compile_deplibs"
+           finalize_deplibs="$dir/$linklib $finalize_deplibs"
+         else
+           compile_deplibs="-l$name -L$dir $compile_deplibs"
+           finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+         fi
+       elif test "$build_libtool_libs" = yes; then
+         # Not a shared library
+         if test "$deplibs_check_method" != pass_all; then
+           # We're trying link a shared library against a static one
+           # but the system doesn't support it.
+
+           # Just print a warning and add the library to dependency_libs so
+           # that the program can be linked against the static library.
+           $echo
+           $echo "*** Warning: This system can not link to static lib archive $lib."
+           $echo "*** I have the capability to make that library automatically link in when"
+           $echo "*** you link to this library.  But I can only do this if you have a"
+           $echo "*** shared version of the library, which you do not appear to have."
+           if test "$module" = yes; then
+             $echo "*** But as you try to build a module library, libtool will still create "
+             $echo "*** a static module, that should work as long as the dlopening application"
+             $echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+             if test -z "$global_symbol_pipe"; then
+               $echo
+               $echo "*** However, this would only work if libtool was able to extract symbol"
+               $echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+               $echo "*** not find such a program.  So, this module is probably useless."
+               $echo "*** \`nm' from GNU binutils and a full rebuild may help."
+             fi
+             if test "$build_old_libs" = no; then
+               build_libtool_libs=module
+               build_old_libs=yes
+             else
+               build_libtool_libs=no
+             fi
+           fi
+         else
+           deplibs="$dir/$old_library $deplibs"
+           link_static=yes
+         fi
+       fi # link shared/static library?
+
+       if test "$linkmode" = lib; then
+         if test -n "$dependency_libs" &&
+            { test "$hardcode_into_libs" != yes ||
+              test "$build_old_libs" = yes ||
+              test "$link_static" = yes; }; then
+           # Extract -R from dependency_libs
+           temp_deplibs=
+           for libdir in $dependency_libs; do
+             case $libdir in
+             -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'`
+                  case " $xrpath " in
+                  *" $temp_xrpath "*) ;;
+                  *) xrpath="$xrpath $temp_xrpath";;
+                  esac;;
+             *) temp_deplibs="$temp_deplibs $libdir";;
+             esac
+           done
+           dependency_libs="$temp_deplibs"
+         fi
+
+         newlib_search_path="$newlib_search_path $absdir"
+         # Link against this library
+         test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+         # ... and its dependency_libs
+         tmp_libs=
+         for deplib in $dependency_libs; do
+           newdependency_libs="$deplib $newdependency_libs"
+           if test "X$duplicate_deps" = "Xyes" ; then
+             case "$tmp_libs " in
+             *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+             esac
+           fi
+           tmp_libs="$tmp_libs $deplib"
+         done
+
+         if test "$link_all_deplibs" != no; then
+           # Add the search paths of all dependency libraries
+           for deplib in $dependency_libs; do
+             case $deplib in
+             -L*) path="$deplib" ;;
+             *.la)
+               dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'`
+               test "X$dir" = "X$deplib" && dir="."
+               # We need an absolute path.
+               case $dir in
+               [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+               *)
+                 absdir=`cd "$dir" && pwd`
+                 if test -z "$absdir"; then
+                   $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+                   absdir="$dir"
+                 fi
+                 ;;
+               esac
+               if grep "^installed=no" $deplib > /dev/null; then
+                 path="$absdir/$objdir"
+               else
+                 eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+                 if test -z "$libdir"; then
+                   $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
+                   exit $EXIT_FAILURE
+                 fi
+                 if test "$absdir" != "$libdir"; then
+                   $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2
+                 fi
+                 path="$absdir"
+               fi
+               depdepl=
+               case $host in
+               *-*-darwin*)
+                 # we do not want to link against static libs,
+                 # but need to link against shared
+                 eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+                 if test -n "$deplibrary_names" ; then
+                   for tmp in $deplibrary_names ; do
+                     depdepl=$tmp
+                   done
+                   if test -f "$path/$depdepl" ; then
+                     depdepl="$path/$depdepl"
+                   fi
+                   # do not add paths which are already there
+                   case " $newlib_search_path " in
+                   *" $path "*) ;;
+                   *) newlib_search_path="$newlib_search_path $path";;
+                   esac
+                 fi
+                 path=""
+                 ;;
+               *)
+                 path="-L$path"
+                 ;;
+               esac
+               ;;
+             -l*)
+               case $host in
+               *-*-darwin*)
+                 # Again, we only want to link against shared libraries
+                 eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"`
+                 for tmp in $newlib_search_path ; do
+                   if test -f "$tmp/lib$tmp_libs.dylib" ; then
+                     eval depdepl="$tmp/lib$tmp_libs.dylib"
+                     break
+                   fi
+                 done
+                 path=""
+                 ;;
+               *) continue ;;
+               esac
+               ;;
+             *) continue ;;
+             esac
+             case " $deplibs " in
+             *" $path "*) ;;
+             *) deplibs="$path $deplibs" ;;
+             esac
+             case " $deplibs " in
+             *" $depdepl "*) ;;
+             *) deplibs="$depdepl $deplibs" ;;
+             esac
+           done
+         fi # link_all_deplibs != no
+       fi # linkmode = lib
+      done # for deplib in $libs
+      dependency_libs="$newdependency_libs"
+      if test "$pass" = dlpreopen; then
+       # Link the dlpreopened libraries before other libraries
+       for deplib in $save_deplibs; do
+         deplibs="$deplib $deplibs"
+       done
+      fi
+      if test "$pass" != dlopen; then
+       if test "$pass" != conv; then
+         # Make sure lib_search_path contains only unique directories.
+         lib_search_path=
+         for dir in $newlib_search_path; do
+           case "$lib_search_path " in
+           *" $dir "*) ;;
+           *) lib_search_path="$lib_search_path $dir" ;;
+           esac
+         done
+         newlib_search_path=
+       fi
+
+       if test "$linkmode,$pass" != "prog,link"; then
+         vars="deplibs"
+       else
+         vars="compile_deplibs finalize_deplibs"
+       fi
+       for var in $vars dependency_libs; do
+         # Add libraries to $var in reverse order
+         eval tmp_libs=\"\$$var\"
+         new_libs=
+         for deplib in $tmp_libs; do
+           # FIXME: Pedantically, this is the right thing to do, so
+           #        that some nasty dependency loop isn't accidentally
+           #        broken:
+           #new_libs="$deplib $new_libs"
+           # Pragmatically, this seems to cause very few problems in
+           # practice:
+           case $deplib in
+           -L*) new_libs="$deplib $new_libs" ;;
+           -R*) ;;
+           *)
+             # And here is the reason: when a library appears more
+             # than once as an explicit dependence of a library, or
+             # is implicitly linked in more than once by the
+             # compiler, it is considered special, and multiple
+             # occurrences thereof are not removed.  Compare this
+             # with having the same library being listed as a
+             # dependency of multiple other libraries: in this case,
+             # we know (pedantically, we assume) the library does not
+             # need to be listed more than once, so we keep only the
+             # last copy.  This is not always right, but it is rare
+             # enough that we require users that really mean to play
+             # such unportable linking tricks to link the library
+             # using -Wl,-lname, so that libtool does not consider it
+             # for duplicate removal.
+             case " $specialdeplibs " in
+             *" $deplib "*) new_libs="$deplib $new_libs" ;;
+             *)
+               case " $new_libs " in
+               *" $deplib "*) ;;
+               *) new_libs="$deplib $new_libs" ;;
+               esac
+               ;;
+             esac
+             ;;
+           esac
+         done
+         tmp_libs=
+         for deplib in $new_libs; do
+           case $deplib in
+           -L*)
+             case " $tmp_libs " in
+             *" $deplib "*) ;;
+             *) tmp_libs="$tmp_libs $deplib" ;;
+             esac
+             ;;
+           *) tmp_libs="$tmp_libs $deplib" ;;
+           esac
+         done
+         eval $var=\"$tmp_libs\"
+       done # for var
+      fi
+      # Last step: remove runtime libs from dependency_libs
+      # (they stay in deplibs)
+      tmp_libs=
+      for i in $dependency_libs ; do
+       case " $predeps $postdeps $compiler_lib_search_path " in
+       *" $i "*)
+         i=""
+         ;;
+       esac
+       if test -n "$i" ; then
+         tmp_libs="$tmp_libs $i"
+       fi
+      done
+      dependency_libs=$tmp_libs
+    done # for pass
+    if test "$linkmode" = prog; then
+      dlfiles="$newdlfiles"
+      dlprefiles="$newdlprefiles"
+    fi
+
+    case $linkmode in
+    oldlib)
+      if test -n "$deplibs"; then
+       $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+       $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+       $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$xrpath"; then
+       $echo "$modename: warning: \`-R' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+       $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$release"; then
+       $echo "$modename: warning: \`-release' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+       $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
+      fi
+
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      oldlibs="$output"
+      objs="$objs$old_deplibs"
+      ;;
+
+    lib)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case $outputname in
+      lib*)
+       name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+       eval shared_ext=\"$shrext_cmds\"
+       eval libname=\"$libname_spec\"
+       ;;
+      *)
+       if test "$module" = no; then
+         $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
+         $echo "$help" 1>&2
+         exit $EXIT_FAILURE
+       fi
+       if test "$need_lib_prefix" != no; then
+         # Add the "lib" prefix for modules if required
+         name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+         eval shared_ext=\"$shrext_cmds\"
+         eval libname=\"$libname_spec\"
+       else
+         libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+       fi
+       ;;
+      esac
+
+      if test -n "$objs"; then
+       if test "$deplibs_check_method" != pass_all; then
+         $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1
+         exit $EXIT_FAILURE
+       else
+         $echo
+         $echo "*** Warning: Linking the shared library $output against the non-libtool"
+         $echo "*** objects $objs is not portable!"
+         libobjs="$libobjs $objs"
+       fi
+      fi
+
+      if test "$dlself" != no; then
+       $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2
+      fi
+
+      set dummy $rpath
+      if test "$#" -gt 2; then
+       $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+      fi
+      install_libdir="$2"
+
+      oldlibs=
+      if test -z "$rpath"; then
+       if test "$build_libtool_libs" = yes; then
+         # Building a libtool convenience library.
+         # Some compilers have problems with a `.al' extension so
+         # convenience libraries should have the same extension an
+         # archive normally would.
+         oldlibs="$output_objdir/$libname.$libext $oldlibs"
+         build_libtool_libs=convenience
+         build_old_libs=yes
+       fi
+
+       if test -n "$vinfo"; then
+         $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2
+       fi
+
+       if test -n "$release"; then
+         $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
+       fi
+      else
+
+       # Parse the version information argument.
+       save_ifs="$IFS"; IFS=':'
+       set dummy $vinfo 0 0 0
+       IFS="$save_ifs"
+
+       if test -n "$8"; then
+         $echo "$modename: too many parameters to \`-version-info'" 1>&2
+         $echo "$help" 1>&2
+         exit $EXIT_FAILURE
+       fi
+
+       # convert absolute version numbers to libtool ages
+       # this retains compatibility with .la files and attempts
+       # to make the code below a bit more comprehensible
+
+       case $vinfo_number in
+       yes)
+         number_major="$2"
+         number_minor="$3"
+         number_revision="$4"
+         #
+         # There are really only two kinds -- those that
+         # use the current revision as the major version
+         # and those that subtract age and use age as
+         # a minor version.  But, then there is irix
+         # which has an extra 1 added just for fun
+         #
+         case $version_type in
+         darwin|linux|osf|windows)
+           current=`expr $number_major + $number_minor`
+           age="$number_minor"
+           revision="$number_revision"
+           ;;
+         freebsd-aout|freebsd-elf|sunos)
+           current="$number_major"
+           revision="$number_minor"
+           age="0"
+           ;;
+         irix|nonstopux)
+           current=`expr $number_major + $number_minor - 1`
+           age="$number_minor"
+           revision="$number_minor"
+           ;;
+         esac
+         ;;
+       no)
+         current="$2"
+         revision="$3"
+         age="$4"
+         ;;
+       esac
+
+       # Check that each of the things are valid numbers.
+       case $current in
+       0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+       *)
+         $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2
+         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+         exit $EXIT_FAILURE
+         ;;
+       esac
+
+       case $revision in
+       0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+       *)
+         $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2
+         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+         exit $EXIT_FAILURE
+         ;;
+       esac
+
+       case $age in
+       0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+       *)
+         $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2
+         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+         exit $EXIT_FAILURE
+         ;;
+       esac
+
+       if test "$age" -gt "$current"; then
+         $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+         exit $EXIT_FAILURE
+       fi
+
+       # Calculate the version variables.
+       major=
+       versuffix=
+       verstring=
+       case $version_type in
+       none) ;;
+
+       darwin)
+         # Like Linux, but with the current version available in
+         # verstring for coding it into the library header
+         major=.`expr $current - $age`
+         versuffix="$major.$age.$revision"
+         # Darwin ld doesn't like 0 for these options...
+         minor_current=`expr $current + 1`
+         verstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
+         ;;
+
+       freebsd-aout)
+         major=".$current"
+         versuffix=".$current.$revision";
+         ;;
+
+       freebsd-elf)
+         major=".$current"
+         versuffix=".$current";
+         ;;
+
+       irix | nonstopux)
+         major=`expr $current - $age + 1`
+
+         case $version_type in
+           nonstopux) verstring_prefix=nonstopux ;;
+           *)         verstring_prefix=sgi ;;
+         esac
+         verstring="$verstring_prefix$major.$revision"
+
+         # Add in all the interfaces that we are compatible with.
+         loop=$revision
+         while test "$loop" -ne 0; do
+           iface=`expr $revision - $loop`
+           loop=`expr $loop - 1`
+           verstring="$verstring_prefix$major.$iface:$verstring"
+         done
+
+         # Before this point, $major must not contain `.'.
+         major=.$major
+         versuffix="$major.$revision"
+         ;;
+
+       linux)
+         major=.`expr $current - $age`
+         versuffix="$major.$age.$revision"
+         ;;
+
+       osf)
+         major=.`expr $current - $age`
+         versuffix=".$current.$age.$revision"
+         verstring="$current.$age.$revision"
+
+         # Add in all the interfaces that we are compatible with.
+         loop=$age
+         while test "$loop" -ne 0; do
+           iface=`expr $current - $loop`
+           loop=`expr $loop - 1`
+           verstring="$verstring:${iface}.0"
+         done
+
+         # Make executables depend on our current version.
+         verstring="$verstring:${current}.0"
+         ;;
+
+       sunos)
+         major=".$current"
+         versuffix=".$current.$revision"
+         ;;
+
+       windows)
+         # Use '-' rather than '.', since we only want one
+         # extension on DOS 8.3 filesystems.
+         major=`expr $current - $age`
+         versuffix="-$major"
+         ;;
+
+       *)
+         $echo "$modename: unknown library version type \`$version_type'" 1>&2
+         $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+         exit $EXIT_FAILURE
+         ;;
+       esac
+
+       # Clear the version info if we defaulted, and they specified a release.
+       if test -z "$vinfo" && test -n "$release"; then
+         major=
+         case $version_type in
+         darwin)
+           # we can't check for "0.0" in archive_cmds due to quoting
+           # problems, so we reset it completely
+           verstring=
+           ;;
+         *)
+           verstring="0.0"
+           ;;
+         esac
+         if test "$need_version" = no; then
+           versuffix=
+         else
+           versuffix=".0.0"
+         fi
+       fi
+
+       # Remove version info from name if versioning should be avoided
+       if test "$avoid_version" = yes && test "$need_version" = no; then
+         major=
+         versuffix=
+         verstring=""
+       fi
+
+       # Check to see if the archive will have undefined symbols.
+       if test "$allow_undefined" = yes; then
+         if test "$allow_undefined_flag" = unsupported; then
+           $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+           build_libtool_libs=no
+           build_old_libs=yes
+         fi
+       else
+         # Don't allow undefined symbols.
+         allow_undefined_flag="$no_undefined_flag"
+       fi
+      fi
+
+      if test "$mode" != relink; then
+       # Remove our outputs, but don't remove object files since they
+       # may have been created when compiling PIC objects.
+       removelist=
+       tempremovelist=`$echo "$output_objdir/*"`
+       for p in $tempremovelist; do
+         case $p in
+           *.$objext)
+              ;;
+           $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+              if test "X$precious_files_regex" != "X"; then
+                if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+                then
+                  continue
+                fi
+              fi
+              removelist="$removelist $p"
+              ;;
+           *) ;;
+         esac
+       done
+       if test -n "$removelist"; then
+         $show "${rm}r $removelist"
+         $run ${rm}r $removelist
+       fi
+      fi
+
+      # Now set the variables for building old libraries.
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+       oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+       # Transform .lo files to .o files.
+       oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+      fi
+
+      # Eliminate all temporary directories.
+      for path in $notinst_path; do
+       lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"`
+       deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"`
+       dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"`
+      done
+
+      if test -n "$xrpath"; then
+       # If the user specified any rpath flags, then add them.
+       temp_xrpath=
+       for libdir in $xrpath; do
+         temp_xrpath="$temp_xrpath -R$libdir"
+         case "$finalize_rpath " in
+         *" $libdir "*) ;;
+         *) finalize_rpath="$finalize_rpath $libdir" ;;
+         esac
+       done
+       if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+         dependency_libs="$temp_xrpath $dependency_libs"
+       fi
+      fi
+
+      # Make sure dlfiles contains only unique files that won't be dlpreopened
+      old_dlfiles="$dlfiles"
+      dlfiles=
+      for lib in $old_dlfiles; do
+       case " $dlprefiles $dlfiles " in
+       *" $lib "*) ;;
+       *) dlfiles="$dlfiles $lib" ;;
+       esac
+      done
+
+      # Make sure dlprefiles contains only unique files
+      old_dlprefiles="$dlprefiles"
+      dlprefiles=
+      for lib in $old_dlprefiles; do
+       case "$dlprefiles " in
+       *" $lib "*) ;;
+       *) dlprefiles="$dlprefiles $lib" ;;
+       esac
+      done
+
+      if test "$build_libtool_libs" = yes; then
+       if test -n "$rpath"; then
+         case $host in
+         *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*)
+           # these systems don't actually have a c library (as such)!
+           ;;
+         *-*-rhapsody* | *-*-darwin1.[012])
+           # Rhapsody C library is in the System framework
+           deplibs="$deplibs -framework System"
+           ;;
+         *-*-netbsd*)
+           # Don't link with libc until the a.out ld.so is fixed.
+           ;;
+         *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+           # Do not include libc due to us having libc/libc_r.
+           ;;
+         *-*-sco3.2v5* | *-*-sco5v6*)
+           # Causes problems with __ctype
+           ;;
+         *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+           # Compiler inserts libc in the correct place for threads to work
+           ;;
+         *)
+           # Add libc to deplibs on all other systems if necessary.
+           if test "$build_libtool_need_lc" = "yes"; then
+             deplibs="$deplibs -lc"
+           fi
+           ;;
+         esac
+       fi
+
+       # Transform deplibs into only deplibs that can be linked in shared.
+       name_save=$name
+       libname_save=$libname
+       release_save=$release
+       versuffix_save=$versuffix
+       major_save=$major
+       # I'm not sure if I'm treating the release correctly.  I think
+       # release should show up in the -l (ie -lgmp5) so we don't want to
+       # add it in twice.  Is that correct?
+       release=""
+       versuffix=""
+       major=""
+       newdeplibs=
+       droppeddeps=no
+       case $deplibs_check_method in
+       pass_all)
+         # Don't check for shared/static.  Everything works.
+         # This might be a little naive.  We might want to check
+         # whether the library exists or not.  But this is on
+         # osf3 & osf4 and I'm not really sure... Just
+         # implementing what was already the behavior.
+         newdeplibs=$deplibs
+         ;;
+       test_compile)
+         # This code stresses the "libraries are programs" paradigm to its
+         # limits. Maybe even breaks it.  We compile a program, linking it
+         # against the deplibs as a proxy for the library.  Then we can check
+         # whether they linked in statically or dynamically with ldd.
+         $rm conftest.c
+         cat > conftest.c <<EOF
+         int main() { return 0; }
+EOF
+         $rm conftest
+         $LTCC $LTCFLAGS -o conftest conftest.c $deplibs
+         if test "$?" -eq 0 ; then
+           ldd_output=`ldd conftest`
+           for i in $deplibs; do
+             name=`expr $i : '-l\(.*\)'`
+             # If $name is empty we are operating on a -L argument.
+              if test "$name" != "" && test "$name" -ne "0"; then
+               if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+                 case " $predeps $postdeps " in
+                 *" $i "*)
+                   newdeplibs="$newdeplibs $i"
+                   i=""
+                   ;;
+                 esac
+               fi
+               if test -n "$i" ; then
+                 libname=`eval \\$echo \"$libname_spec\"`
+                 deplib_matches=`eval \\$echo \"$library_names_spec\"`
+                 set dummy $deplib_matches
+                 deplib_match=$2
+                 if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+                   newdeplibs="$newdeplibs $i"
+                 else
+                   droppeddeps=yes
+                   $echo
+                   $echo "*** Warning: dynamic linker does not accept needed library $i."
+                   $echo "*** I have the capability to make that library automatically link in when"
+                   $echo "*** you link to this library.  But I can only do this if you have a"
+                   $echo "*** shared version of the library, which I believe you do not have"
+                   $echo "*** because a test_compile did reveal that the linker did not use it for"
+                   $echo "*** its dynamic dependency list that programs get resolved with at runtime."
+                 fi
+               fi
+             else
+               newdeplibs="$newdeplibs $i"
+             fi
+           done
+         else
+           # Error occurred in the first compile.  Let's try to salvage
+           # the situation: Compile a separate program for each library.
+           for i in $deplibs; do
+             name=`expr $i : '-l\(.*\)'`
+             # If $name is empty we are operating on a -L argument.
+              if test "$name" != "" && test "$name" != "0"; then
+               $rm conftest
+               $LTCC $LTCFLAGS -o conftest conftest.c $i
+               # Did it work?
+               if test "$?" -eq 0 ; then
+                 ldd_output=`ldd conftest`
+                 if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+                   case " $predeps $postdeps " in
+                   *" $i "*)
+                     newdeplibs="$newdeplibs $i"
+                     i=""
+                     ;;
+                   esac
+                 fi
+                 if test -n "$i" ; then
+                   libname=`eval \\$echo \"$libname_spec\"`
+                   deplib_matches=`eval \\$echo \"$library_names_spec\"`
+                   set dummy $deplib_matches
+                   deplib_match=$2
+                   if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+                     newdeplibs="$newdeplibs $i"
+                   else
+                     droppeddeps=yes
+                     $echo
+                     $echo "*** Warning: dynamic linker does not accept needed library $i."
+                     $echo "*** I have the capability to make that library automatically link in when"
+                     $echo "*** you link to this library.  But I can only do this if you have a"
+                     $echo "*** shared version of the library, which you do not appear to have"
+                     $echo "*** because a test_compile did reveal that the linker did not use this one"
+                     $echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+                   fi
+                 fi
+               else
+                 droppeddeps=yes
+                 $echo
+                 $echo "*** Warning!  Library $i is needed by this library but I was not able to"
+                 $echo "***  make it link in!  You will probably need to install it or some"
+                 $echo "*** library that it depends on before this library will be fully"
+                 $echo "*** functional.  Installing it before continuing would be even better."
+               fi
+             else
+               newdeplibs="$newdeplibs $i"
+             fi
+           done
+         fi
+         ;;
+       file_magic*)
+         set dummy $deplibs_check_method
+         file_magic_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+         for a_deplib in $deplibs; do
+           name=`expr $a_deplib : '-l\(.*\)'`
+           # If $name is empty we are operating on a -L argument.
+            if test "$name" != "" && test  "$name" != "0"; then
+             if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+               case " $predeps $postdeps " in
+               *" $a_deplib "*)
+                 newdeplibs="$newdeplibs $a_deplib"
+                 a_deplib=""
+                 ;;
+               esac
+             fi
+             if test -n "$a_deplib" ; then
+               libname=`eval \\$echo \"$libname_spec\"`
+               for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+                 potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+                 for potent_lib in $potential_libs; do
+                     # Follow soft links.
+                     if ls -lLd "$potent_lib" 2>/dev/null \
+                        | grep " -> " >/dev/null; then
+                       continue
+                     fi
+                     # The statement above tries to avoid entering an
+                     # endless loop below, in case of cyclic links.
+                     # We might still enter an endless loop, since a link
+                     # loop can be closed while we follow links,
+                     # but so what?
+                     potlib="$potent_lib"
+                     while test -h "$potlib" 2>/dev/null; do
+                       potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+                       case $potliblink in
+                       [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+                       *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+                       esac
+                     done
+                     # It is ok to link against an archive when
+                     # building a shared library.
+                     if $AR -t $potlib > /dev/null 2>&1; then
+                       newdeplibs="$newdeplibs $a_deplib"
+                       a_deplib=""
+                       break 2
+                     fi
+                     if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
+                        | ${SED} 10q \
+                        | $EGREP "$file_magic_regex" > /dev/null; then
+                       newdeplibs="$newdeplibs $a_deplib"
+                       a_deplib=""
+                       break 2
+                     fi
+                 done
+               done
+             fi
+             if test -n "$a_deplib" ; then
+               droppeddeps=yes
+               $echo
+               $echo "*** Warning: linker path does not have real file for library $a_deplib."
+               $echo "*** I have the capability to make that library automatically link in when"
+               $echo "*** you link to this library.  But I can only do this if you have a"
+               $echo "*** shared version of the library, which you do not appear to have"
+               $echo "*** because I did check the linker path looking for a file starting"
+               if test -z "$potlib" ; then
+                 $echo "*** with $libname but no candidates were found. (...for file magic test)"
+               else
+                 $echo "*** with $libname and none of the candidates passed a file format test"
+                 $echo "*** using a file magic. Last file checked: $potlib"
+               fi
+             fi
+           else
+             # Add a -L argument.
+             newdeplibs="$newdeplibs $a_deplib"
+           fi
+         done # Gone through all deplibs.
+         ;;
+       match_pattern*)
+         set dummy $deplibs_check_method
+         match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+         for a_deplib in $deplibs; do
+           name=`expr $a_deplib : '-l\(.*\)'`
+           # If $name is empty we are operating on a -L argument.
+           if test -n "$name" && test "$name" != "0"; then
+             if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+               case " $predeps $postdeps " in
+               *" $a_deplib "*)
+                 newdeplibs="$newdeplibs $a_deplib"
+                 a_deplib=""
+                 ;;
+               esac
+             fi
+             if test -n "$a_deplib" ; then
+               libname=`eval \\$echo \"$libname_spec\"`
+               for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+                 potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+                 for potent_lib in $potential_libs; do
+                   potlib="$potent_lib" # see symlink-check above in file_magic test
+                   if eval $echo \"$potent_lib\" 2>/dev/null \
+                       | ${SED} 10q \
+                       | $EGREP "$match_pattern_regex" > /dev/null; then
+                     newdeplibs="$newdeplibs $a_deplib"
+                     a_deplib=""
+                     break 2
+                   fi
+                 done
+               done
+             fi
+             if test -n "$a_deplib" ; then
+               droppeddeps=yes
+               $echo
+               $echo "*** Warning: linker path does not have real file for library $a_deplib."
+               $echo "*** I have the capability to make that library automatically link in when"
+               $echo "*** you link to this library.  But I can only do this if you have a"
+               $echo "*** shared version of the library, which you do not appear to have"
+               $echo "*** because I did check the linker path looking for a file starting"
+               if test -z "$potlib" ; then
+                 $echo "*** with $libname but no candidates were found. (...for regex pattern test)"
+               else
+                 $echo "*** with $libname and none of the candidates passed a file format test"
+                 $echo "*** using a regex pattern. Last file checked: $potlib"
+               fi
+             fi
+           else
+             # Add a -L argument.
+             newdeplibs="$newdeplibs $a_deplib"
+           fi
+         done # Gone through all deplibs.
+         ;;
+       none | unknown | *)
+         newdeplibs=""
+         tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
+           -e 's/ -[LR][^ ]*//g'`
+         if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+           for i in $predeps $postdeps ; do
+             # can't use Xsed below, because $i might contain '/'
+             tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"`
+           done
+         fi
+         if $echo "X $tmp_deplibs" | $Xsed -e 's/[     ]//g' \
+           | grep . >/dev/null; then
+           $echo
+           if test "X$deplibs_check_method" = "Xnone"; then
+             $echo "*** Warning: inter-library dependencies are not supported in this platform."
+           else
+             $echo "*** Warning: inter-library dependencies are not known to be supported."
+           fi
+           $echo "*** All declared inter-library dependencies are being dropped."
+           droppeddeps=yes
+         fi
+         ;;
+       esac
+       versuffix=$versuffix_save
+       major=$major_save
+       release=$release_save
+       libname=$libname_save
+       name=$name_save
+
+       case $host in
+       *-*-rhapsody* | *-*-darwin1.[012])
+         # On Rhapsody replace the C library is the System framework
+         newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'`
+         ;;
+       esac
+
+       if test "$droppeddeps" = yes; then
+         if test "$module" = yes; then
+           $echo
+           $echo "*** Warning: libtool could not satisfy all declared inter-library"
+           $echo "*** dependencies of module $libname.  Therefore, libtool will create"
+           $echo "*** a static module, that should work as long as the dlopening"
+           $echo "*** application is linked with the -dlopen flag."
+           if test -z "$global_symbol_pipe"; then
+             $echo
+             $echo "*** However, this would only work if libtool was able to extract symbol"
+             $echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+             $echo "*** not find such a program.  So, this module is probably useless."
+             $echo "*** \`nm' from GNU binutils and a full rebuild may help."
+           fi
+           if test "$build_old_libs" = no; then
+             oldlibs="$output_objdir/$libname.$libext"
+             build_libtool_libs=module
+             build_old_libs=yes
+           else
+             build_libtool_libs=no
+           fi
+         else
+           $echo "*** The inter-library dependencies that have been dropped here will be"
+           $echo "*** automatically added whenever a program is linked with this library"
+           $echo "*** or is declared to -dlopen it."
+
+           if test "$allow_undefined" = no; then
+             $echo
+             $echo "*** Since this library must not contain undefined symbols,"
+             $echo "*** because either the platform does not support them or"
+             $echo "*** it was explicitly requested with -no-undefined,"
+             $echo "*** libtool will only create a static version of it."
+             if test "$build_old_libs" = no; then
+               oldlibs="$output_objdir/$libname.$libext"
+               build_libtool_libs=module
+               build_old_libs=yes
+             else
+               build_libtool_libs=no
+             fi
+           fi
+         fi
+       fi
+       # Done checking deplibs!
+       deplibs=$newdeplibs
+      fi
+
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+       case " $new_libs " in
+       *" -L$path/$objdir "*) ;;
+       *)
+         case " $deplibs " in
+         *" -L$path/$objdir "*)
+           new_libs="$new_libs -L$path/$objdir" ;;
+         esac
+         ;;
+       esac
+      done
+      for deplib in $deplibs; do
+       case $deplib in
+       -L*)
+         case " $new_libs " in
+         *" $deplib "*) ;;
+         *) new_libs="$new_libs $deplib" ;;
+         esac
+         ;;
+       *) new_libs="$new_libs $deplib" ;;
+       esac
+      done
+      deplibs="$new_libs"
+
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+
+      # Test again, we may have decided not to build it any more
+      if test "$build_libtool_libs" = yes; then
+       if test "$hardcode_into_libs" = yes; then
+         # Hardcode the library paths
+         hardcode_libdirs=
+         dep_rpath=
+         rpath="$finalize_rpath"
+         test "$mode" != relink && rpath="$compile_rpath$rpath"
+         for libdir in $rpath; do
+           if test -n "$hardcode_libdir_flag_spec"; then
+             if test -n "$hardcode_libdir_separator"; then
+               if test -z "$hardcode_libdirs"; then
+                 hardcode_libdirs="$libdir"
+               else
+                 # Just accumulate the unique libdirs.
+                 case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+                 *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+                   ;;
+                 *)
+                   hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+                   ;;
+                 esac
+               fi
+             else
+               eval flag=\"$hardcode_libdir_flag_spec\"
+               dep_rpath="$dep_rpath $flag"
+             fi
+           elif test -n "$runpath_var"; then
+             case "$perm_rpath " in
+             *" $libdir "*) ;;
+             *) perm_rpath="$perm_rpath $libdir" ;;
+             esac
+           fi
+         done
+         # Substitute the hardcoded libdirs into the rpath.
+         if test -n "$hardcode_libdir_separator" &&
+            test -n "$hardcode_libdirs"; then
+           libdir="$hardcode_libdirs"
+           if test -n "$hardcode_libdir_flag_spec_ld"; then
+             eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\"
+           else
+             eval dep_rpath=\"$hardcode_libdir_flag_spec\"
+           fi
+         fi
+         if test -n "$runpath_var" && test -n "$perm_rpath"; then
+           # We should set the runpath_var.
+           rpath=
+           for dir in $perm_rpath; do
+             rpath="$rpath$dir:"
+           done
+           eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+         fi
+         test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+       fi
+
+       shlibpath="$finalize_shlibpath"
+       test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+       if test -n "$shlibpath"; then
+         eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+       fi
+
+       # Get the real and link names of the library.
+       eval shared_ext=\"$shrext_cmds\"
+       eval library_names=\"$library_names_spec\"
+       set dummy $library_names
+       realname="$2"
+       shift; shift
+
+       if test -n "$soname_spec"; then
+         eval soname=\"$soname_spec\"
+       else
+         soname="$realname"
+       fi
+       if test -z "$dlname"; then
+         dlname=$soname
+       fi
+
+       lib="$output_objdir/$realname"
+       linknames=
+       for link
+       do
+         linknames="$linknames $link"
+       done
+
+       # Use standard objects if they are pic
+       test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+
+       # Prepare the list of exported symbols
+       if test -z "$export_symbols"; then
+         if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+           $show "generating symbol list for \`$libname.la'"
+           export_symbols="$output_objdir/$libname.exp"
+           $run $rm $export_symbols
+           cmds=$export_symbols_cmds
+           save_ifs="$IFS"; IFS='~'
+           for cmd in $cmds; do
+             IFS="$save_ifs"
+             eval cmd=\"$cmd\"
+             if len=`expr "X$cmd" : ".*"` &&
+              test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+               $show "$cmd"
+               $run eval "$cmd" || exit $?
+               skipped_export=false
+             else
+               # The command line is too long to execute in one step.
+               $show "using reloadable object file for export list..."
+               skipped_export=:
+               # Break out early, otherwise skipped_export may be
+               # set to false by a later but shorter cmd.
+               break
+             fi
+           done
+           IFS="$save_ifs"
+           if test -n "$export_symbols_regex"; then
+             $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
+             $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+             $show "$mv \"${export_symbols}T\" \"$export_symbols\""
+             $run eval '$mv "${export_symbols}T" "$export_symbols"'
+           fi
+         fi
+       fi
+
+       if test -n "$export_symbols" && test -n "$include_expsyms"; then
+         $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
+       fi
+
+       tmp_deplibs=
+       for test_deplib in $deplibs; do
+               case " $convenience " in
+               *" $test_deplib "*) ;;
+               *)
+                       tmp_deplibs="$tmp_deplibs $test_deplib"
+                       ;;
+               esac
+       done
+       deplibs="$tmp_deplibs"
+
+       if test -n "$convenience"; then
+         if test -n "$whole_archive_flag_spec"; then
+           save_libobjs=$libobjs
+           eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+         else
+           gentop="$output_objdir/${outputname}x"
+           generated="$generated $gentop"
+
+           func_extract_archives $gentop $convenience
+           libobjs="$libobjs $func_extract_archives_result"
+         fi
+       fi
+       
+       if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+         eval flag=\"$thread_safe_flag_spec\"
+         linker_flags="$linker_flags $flag"
+       fi
+
+       # Make a backup of the uninstalled library when relinking
+       if test "$mode" = relink; then
+         $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $?
+       fi
+
+       # Do each of the archive commands.
+       if test "$module" = yes && test -n "$module_cmds" ; then
+         if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+           eval test_cmds=\"$module_expsym_cmds\"
+           cmds=$module_expsym_cmds
+         else
+           eval test_cmds=\"$module_cmds\"
+           cmds=$module_cmds
+         fi
+       else
+       if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+         eval test_cmds=\"$archive_expsym_cmds\"
+         cmds=$archive_expsym_cmds
+       else
+         eval test_cmds=\"$archive_cmds\"
+         cmds=$archive_cmds
+         fi
+       fi
+
+       if test "X$skipped_export" != "X:" &&
+          len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
+          test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+         :
+       else
+         # The command line is too long to link in one step, link piecewise.
+         $echo "creating reloadable object files..."
+
+         # Save the value of $output and $libobjs because we want to
+         # use them later.  If we have whole_archive_flag_spec, we
+         # want to use save_libobjs as it was before
+         # whole_archive_flag_spec was expanded, because we can't
+         # assume the linker understands whole_archive_flag_spec.
+         # This may have to be revisited, in case too many
+         # convenience libraries get linked in and end up exceeding
+         # the spec.
+         if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+           save_libobjs=$libobjs
+         fi
+         save_output=$output
+         output_la=`$echo "X$output" | $Xsed -e "$basename"`
+
+         # Clear the reloadable object creation command queue and
+         # initialize k to one.
+         test_cmds=
+         concat_cmds=
+         objlist=
+         delfiles=
+         last_robj=
+         k=1
+         output=$output_objdir/$output_la-${k}.$objext
+         # Loop over the list of objects to be linked.
+         for obj in $save_libobjs
+         do
+           eval test_cmds=\"$reload_cmds $objlist $last_robj\"
+           if test "X$objlist" = X ||
+              { len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
+                test "$len" -le "$max_cmd_len"; }; then
+             objlist="$objlist $obj"
+           else
+             # The command $test_cmds is almost too long, add a
+             # command to the queue.
+             if test "$k" -eq 1 ; then
+               # The first file doesn't have a previous command to add.
+               eval concat_cmds=\"$reload_cmds $objlist $last_robj\"
+             else
+               # All subsequent reloadable object files will link in
+               # the last one created.
+               eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\"
+             fi
+             last_robj=$output_objdir/$output_la-${k}.$objext
+             k=`expr $k + 1`
+             output=$output_objdir/$output_la-${k}.$objext
+             objlist=$obj
+             len=1
+           fi
+         done
+         # Handle the remaining objects by creating one last
+         # reloadable object file.  All subsequent reloadable object
+         # files will link in the last one created.
+         test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+         eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\"
+
+         if ${skipped_export-false}; then
+           $show "generating symbol list for \`$libname.la'"
+           export_symbols="$output_objdir/$libname.exp"
+           $run $rm $export_symbols
+           libobjs=$output
+           # Append the command to create the export file.
+           eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\"
+          fi
+
+         # Set up a command to remove the reloadable object files
+         # after they are used.
+         i=0
+         while test "$i" -lt "$k"
+         do
+           i=`expr $i + 1`
+           delfiles="$delfiles $output_objdir/$output_la-${i}.$objext"
+         done
+
+         $echo "creating a temporary reloadable object file: $output"
+
+         # Loop through the commands generated above and execute them.
+         save_ifs="$IFS"; IFS='~'
+         for cmd in $concat_cmds; do
+           IFS="$save_ifs"
+           $show "$cmd"
+           $run eval "$cmd" || exit $?
+         done
+         IFS="$save_ifs"
+
+         libobjs=$output
+         # Restore the value of output.
+         output=$save_output
+
+         if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+           eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+         fi
+         # Expand the library linking commands again to reset the
+         # value of $libobjs for piecewise linking.
+
+         # Do each of the archive commands.
+         if test "$module" = yes && test -n "$module_cmds" ; then
+           if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+             cmds=$module_expsym_cmds
+           else
+             cmds=$module_cmds
+           fi
+         else
+         if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+           cmds=$archive_expsym_cmds
+         else
+           cmds=$archive_cmds
+           fi
+         fi
+
+         # Append the command to remove the reloadable object files
+         # to the just-reset $cmds.
+         eval cmds=\"\$cmds~\$rm $delfiles\"
+       fi
+       save_ifs="$IFS"; IFS='~'
+       for cmd in $cmds; do
+         IFS="$save_ifs"
+         eval cmd=\"$cmd\"
+         $show "$cmd"
+         $run eval "$cmd" || {
+           lt_exit=$?
+
+           # Restore the uninstalled library and exit
+           if test "$mode" = relink; then
+             $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)'
+           fi
+
+           exit $lt_exit
+         }
+       done
+       IFS="$save_ifs"
+
+       # Restore the uninstalled library and exit
+       if test "$mode" = relink; then
+         $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $?
+
+         if test -n "$convenience"; then
+           if test -z "$whole_archive_flag_spec"; then
+             $show "${rm}r $gentop"
+             $run ${rm}r "$gentop"
+           fi
+         fi
+
+         exit $EXIT_SUCCESS
+       fi
+
+       # Create links to the real library.
+       for linkname in $linknames; do
+         if test "$realname" != "$linkname"; then
+           $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
+           $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
+         fi
+       done
+
+       # If -module or -export-dynamic was specified, set the dlname.
+       if test "$module" = yes || test "$export_dynamic" = yes; then
+         # On all known operating systems, these are identical.
+         dlname="$soname"
+       fi
+      fi
+      ;;
+
+    obj)
+      if test -n "$deplibs"; then
+       $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+       $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+       $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$xrpath"; then
+       $echo "$modename: warning: \`-R' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+       $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$release"; then
+       $echo "$modename: warning: \`-release' is ignored for objects" 1>&2
+      fi
+
+      case $output in
+      *.lo)
+       if test -n "$objs$old_deplibs"; then
+         $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
+         exit $EXIT_FAILURE
+       fi
+       libobj="$output"
+       obj=`$echo "X$output" | $Xsed -e "$lo2o"`
+       ;;
+      *)
+       libobj=
+       obj="$output"
+       ;;
+      esac
+
+      # Delete the old objects.
+      $run $rm $obj $libobj
+
+      # Objects from convenience libraries.  This assumes
+      # single-version convenience libraries.  Whenever we create
+      # different ones for PIC/non-PIC, this we'll have to duplicate
+      # the extraction.
+      reload_conv_objs=
+      gentop=
+      # reload_cmds runs $LD directly, so let us get rid of
+      # -Wl from whole_archive_flag_spec
+      wl=
+
+      if test -n "$convenience"; then
+       if test -n "$whole_archive_flag_spec"; then
+         eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\"
+       else
+         gentop="$output_objdir/${obj}x"
+         generated="$generated $gentop"
+
+         func_extract_archives $gentop $convenience
+         reload_conv_objs="$reload_objs $func_extract_archives_result"
+       fi
+      fi
+
+      # Create the old-style object.
+      reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+      output="$obj"
+      cmds=$reload_cmds
+      save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+       IFS="$save_ifs"
+       eval cmd=\"$cmd\"
+       $show "$cmd"
+       $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+
+      # Exit if we aren't doing a library object file.
+      if test -z "$libobj"; then
+       if test -n "$gentop"; then
+         $show "${rm}r $gentop"
+         $run ${rm}r $gentop
+       fi
+
+       exit $EXIT_SUCCESS
+      fi
+
+      if test "$build_libtool_libs" != yes; then
+       if test -n "$gentop"; then
+         $show "${rm}r $gentop"
+         $run ${rm}r $gentop
+       fi
+
+       # Create an invalid libtool object if no PIC, so that we don't
+       # accidentally link it into a program.
+       # $show "echo timestamp > $libobj"
+       # $run eval "echo timestamp > $libobj" || exit $?
+       exit $EXIT_SUCCESS
+      fi
+
+      if test -n "$pic_flag" || test "$pic_mode" != default; then
+       # Only do commands if we really have different PIC objects.
+       reload_objs="$libobjs $reload_conv_objs"
+       output="$libobj"
+       cmds=$reload_cmds
+       save_ifs="$IFS"; IFS='~'
+       for cmd in $cmds; do
+         IFS="$save_ifs"
+         eval cmd=\"$cmd\"
+         $show "$cmd"
+         $run eval "$cmd" || exit $?
+       done
+       IFS="$save_ifs"
+      fi
+
+      if test -n "$gentop"; then
+       $show "${rm}r $gentop"
+       $run ${rm}r $gentop
+      fi
+
+      exit $EXIT_SUCCESS
+      ;;
+
+    prog)
+      case $host in
+       *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;;
+      esac
+      if test -n "$vinfo"; then
+       $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
+      fi
+
+      if test -n "$release"; then
+       $echo "$modename: warning: \`-release' is ignored for programs" 1>&2
+      fi
+
+      if test "$preload" = yes; then
+       if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown &&
+          test "$dlopen_self_static" = unknown; then
+         $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
+       fi
+      fi
+
+      case $host in
+      *-*-rhapsody* | *-*-darwin1.[012])
+       # On Rhapsody replace the C library is the System framework
+       compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
+       finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
+       ;;
+      esac
+
+      case $host in
+      *darwin*)
+        # Don't allow lazy linking, it breaks C++ global constructors
+        if test "$tagname" = CXX ; then
+        compile_command="$compile_command ${wl}-bind_at_load"
+        finalize_command="$finalize_command ${wl}-bind_at_load"
+        fi
+        ;;
+      esac
+
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+       case " $new_libs " in
+       *" -L$path/$objdir "*) ;;
+       *)
+         case " $compile_deplibs " in
+         *" -L$path/$objdir "*)
+           new_libs="$new_libs -L$path/$objdir" ;;
+         esac
+         ;;
+       esac
+      done
+      for deplib in $compile_deplibs; do
+       case $deplib in
+       -L*)
+         case " $new_libs " in
+         *" $deplib "*) ;;
+         *) new_libs="$new_libs $deplib" ;;
+         esac
+         ;;
+       *) new_libs="$new_libs $deplib" ;;
+       esac
+      done
+      compile_deplibs="$new_libs"
+
+
+      compile_command="$compile_command $compile_deplibs"
+      finalize_command="$finalize_command $finalize_deplibs"
+
+      if test -n "$rpath$xrpath"; then
+       # If the user specified any rpath flags, then add them.
+       for libdir in $rpath $xrpath; do
+         # This is the magic to use -rpath.
+         case "$finalize_rpath " in
+         *" $libdir "*) ;;
+         *) finalize_rpath="$finalize_rpath $libdir" ;;
+         esac
+       done
+      fi
+
+      # Now hardcode the library paths
+      rpath=
+      hardcode_libdirs=
+      for libdir in $compile_rpath $finalize_rpath; do
+       if test -n "$hardcode_libdir_flag_spec"; then
+         if test -n "$hardcode_libdir_separator"; then
+           if test -z "$hardcode_libdirs"; then
+             hardcode_libdirs="$libdir"
+           else
+             # Just accumulate the unique libdirs.
+             case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+             *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+               ;;
+             *)
+               hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+               ;;
+             esac
+           fi
+         else
+           eval flag=\"$hardcode_libdir_flag_spec\"
+           rpath="$rpath $flag"
+         fi
+       elif test -n "$runpath_var"; then
+         case "$perm_rpath " in
+         *" $libdir "*) ;;
+         *) perm_rpath="$perm_rpath $libdir" ;;
+         esac
+       fi
+       case $host in
+       *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+         testbindir=`$echo "X$libdir" | $Xsed -e 's*/lib$*/bin*'`
+         case :$dllsearchpath: in
+         *":$libdir:"*) ;;
+         *) dllsearchpath="$dllsearchpath:$libdir";;
+         esac
+         case :$dllsearchpath: in
+         *":$testbindir:"*) ;;
+         *) dllsearchpath="$dllsearchpath:$testbindir";;
+         esac
+         ;;
+       esac
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+        test -n "$hardcode_libdirs"; then
+       libdir="$hardcode_libdirs"
+       eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      compile_rpath="$rpath"
+
+      rpath=
+      hardcode_libdirs=
+      for libdir in $finalize_rpath; do
+       if test -n "$hardcode_libdir_flag_spec"; then
+         if test -n "$hardcode_libdir_separator"; then
+           if test -z "$hardcode_libdirs"; then
+             hardcode_libdirs="$libdir"
+           else
+             # Just accumulate the unique libdirs.
+             case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+             *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+               ;;
+             *)
+               hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+               ;;
+             esac
+           fi
+         else
+           eval flag=\"$hardcode_libdir_flag_spec\"
+           rpath="$rpath $flag"
+         fi
+       elif test -n "$runpath_var"; then
+         case "$finalize_perm_rpath " in
+         *" $libdir "*) ;;
+         *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+         esac
+       fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+        test -n "$hardcode_libdirs"; then
+       libdir="$hardcode_libdirs"
+       eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      finalize_rpath="$rpath"
+
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
+       # Transform all the library objects into standard objects.
+       compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+       finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+      fi
+
+      dlsyms=
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+       if test -n "$NM" && test -n "$global_symbol_pipe"; then
+         dlsyms="${outputname}S.c"
+       else
+         $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+       fi
+      fi
+
+      if test -n "$dlsyms"; then
+       case $dlsyms in
+       "") ;;
+       *.c)
+         # Discover the nlist of each of the dlfiles.
+         nlist="$output_objdir/${outputname}.nm"
+
+         $show "$rm $nlist ${nlist}S ${nlist}T"
+         $run $rm "$nlist" "${nlist}S" "${nlist}T"
+
+         # Parse the name list into a source file.
+         $show "creating $output_objdir/$dlsyms"
+
+         test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
+/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define lt_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */\
+"
+
+         if test "$dlself" = yes; then
+           $show "generating symbol list for \`$output'"
+
+           test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
+
+           # Add our own program objects to the symbol list.
+           progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+           for arg in $progfiles; do
+             $show "extracting global C symbols from \`$arg'"
+             $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+           done
+
+           if test -n "$exclude_expsyms"; then
+             $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+             $run eval '$mv "$nlist"T "$nlist"'
+           fi
+
+           if test -n "$export_symbols_regex"; then
+             $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+             $run eval '$mv "$nlist"T "$nlist"'
+           fi
+
+           # Prepare the list of exported symbols
+           if test -z "$export_symbols"; then
+             export_symbols="$output_objdir/$outputname.exp"
+             $run $rm $export_symbols
+             $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+              case $host in
+              *cygwin* | *mingw* )
+               $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+               $run eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+                ;;
+              esac
+           else
+             $run eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+             $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+             $run eval 'mv "$nlist"T "$nlist"'
+              case $host in
+              *cygwin* | *mingw* )
+               $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+               $run eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+                ;;
+              esac
+           fi
+         fi
+
+         for arg in $dlprefiles; do
+           $show "extracting global C symbols from \`$arg'"
+           name=`$echo "$arg" | ${SED} -e 's%^.*/%%'`
+           $run eval '$echo ": $name " >> "$nlist"'
+           $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+         done
+
+         if test -z "$run"; then
+           # Make sure we have at least an empty file.
+           test -f "$nlist" || : > "$nlist"
+
+           if test -n "$exclude_expsyms"; then
+             $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+             $mv "$nlist"T "$nlist"
+           fi
+
+           # Try sorting and uniquifying the output.
+           if grep -v "^: " < "$nlist" |
+               if sort -k 3 </dev/null >/dev/null 2>&1; then
+                 sort -k 3
+               else
+                 sort +2
+               fi |
+               uniq > "$nlist"S; then
+             :
+           else
+             grep -v "^: " < "$nlist" > "$nlist"S
+           fi
+
+           if test -f "$nlist"S; then
+             eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
+           else
+             $echo '/* NONE */' >> "$output_objdir/$dlsyms"
+           fi
+
+           $echo >> "$output_objdir/$dlsyms" "\
+
+#undef lt_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define lt_ptr void *
+#else
+# define lt_ptr char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+"
+
+           case $host in
+           *cygwin* | *mingw* )
+         $echo >> "$output_objdir/$dlsyms" "\
+/* DATA imports from DLLs on WIN32 can't be const, because
+   runtime relocations are performed -- see ld's documentation
+   on pseudo-relocs */
+struct {
+"
+             ;;
+           * )
+         $echo >> "$output_objdir/$dlsyms" "\
+const struct {
+"
+             ;;
+           esac
+
+
+         $echo >> "$output_objdir/$dlsyms" "\
+  const char *name;
+  lt_ptr address;
+}
+lt_preloaded_symbols[] =
+{\
+"
+
+           eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms"
+
+           $echo >> "$output_objdir/$dlsyms" "\
+  {0, (lt_ptr) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+         fi
+
+         pic_flag_for_symtable=
+         case $host in
+         # compiling the symbol table file with pic_flag works around
+         # a FreeBSD bug that causes programs to crash when -lm is
+         # linked before any other PIC object.  But we must not use
+         # pic_flag when linking with -static.  The problem exists in
+         # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+         *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+           case "$compile_command " in
+           *" -static "*) ;;
+           *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";;
+           esac;;
+         *-*-hpux*)
+           case "$compile_command " in
+           *" -static "*) ;;
+           *) pic_flag_for_symtable=" $pic_flag";;
+           esac
+         esac
+
+         # Now compile the dynamic symbol file.
+         $show "(cd $output_objdir && $LTCC  $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
+         $run eval '(cd $output_objdir && $LTCC  $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+
+         # Clean up the generated files.
+         $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
+         $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
+
+         # Transform the symbol file into the correct name.
+          case $host in
+          *cygwin* | *mingw* )
+            if test -f "$output_objdir/${outputname}.def" ; then
+              compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%"`
+              finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%"`
+            else
+              compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+              finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+             fi
+            ;;
+          * )
+            compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+            finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+            ;;
+          esac
+         ;;
+       *)
+         $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
+         exit $EXIT_FAILURE
+         ;;
+       esac
+      else
+       # We keep going just in case the user didn't refer to
+       # lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
+       # really was required.
+
+       # Nullify the symbol file.
+       compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+       finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+      fi
+
+      if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+       # Replace the output file specification.
+       compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+       link_command="$compile_command$compile_rpath"
+
+       # We have no uninstalled library dependencies, so finalize right now.
+       $show "$link_command"
+       $run eval "$link_command"
+       exit_status=$?
+
+       # Delete the generated files.
+       if test -n "$dlsyms"; then
+         $show "$rm $output_objdir/${outputname}S.${objext}"
+         $run $rm "$output_objdir/${outputname}S.${objext}"
+       fi
+
+       exit $exit_status
+      fi
+
+      if test -n "$shlibpath_var"; then
+       # We should set the shlibpath_var
+       rpath=
+       for dir in $temp_rpath; do
+         case $dir in
+         [\\/]* | [A-Za-z]:[\\/]*)
+           # Absolute path.
+           rpath="$rpath$dir:"
+           ;;
+         *)
+           # Relative path: add a thisdir entry.
+           rpath="$rpath\$thisdir/$dir:"
+           ;;
+         esac
+       done
+       temp_rpath="$rpath"
+      fi
+
+      if test -n "$compile_shlibpath$finalize_shlibpath"; then
+       compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+       finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      compile_var=
+      finalize_var=
+      if test -n "$runpath_var"; then
+       if test -n "$perm_rpath"; then
+         # We should set the runpath_var.
+         rpath=
+         for dir in $perm_rpath; do
+           rpath="$rpath$dir:"
+         done
+         compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+       fi
+       if test -n "$finalize_perm_rpath"; then
+         # We should set the runpath_var.
+         rpath=
+         for dir in $finalize_perm_rpath; do
+           rpath="$rpath$dir:"
+         done
+         finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+       fi
+      fi
+
+      if test "$no_install" = yes; then
+       # We don't need to create a wrapper script.
+       link_command="$compile_var$compile_command$compile_rpath"
+       # Replace the output file specification.
+       link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+       # Delete the old output file.
+       $run $rm $output
+       # Link the executable and exit
+       $show "$link_command"
+       $run eval "$link_command" || exit $?
+       exit $EXIT_SUCCESS
+      fi
+
+      if test "$hardcode_action" = relink; then
+       # Fast installation is not supported
+       link_command="$compile_var$compile_command$compile_rpath"
+       relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+       $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
+       $echo "$modename: \`$output' will be relinked during installation" 1>&2
+      else
+       if test "$fast_install" != no; then
+         link_command="$finalize_var$compile_command$finalize_rpath"
+         if test "$fast_install" = yes; then
+           relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+         else
+           # fast_install is set to needless
+           relink_command=
+         fi
+       else
+         link_command="$compile_var$compile_command$compile_rpath"
+         relink_command="$finalize_var$finalize_command$finalize_rpath"
+       fi
+      fi
+
+      # Replace the output file specification.
+      link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+      # Delete the old output files.
+      $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+      $show "$link_command"
+      $run eval "$link_command" || exit $?
+
+      # Now create the wrapper script.
+      $show "creating $output"
+
+      # Quote the relink command for shipping.
+      if test -n "$relink_command"; then
+       # Preserve any variables that may affect compiler behavior
+       for var in $variables_saved_for_relink; do
+         if eval test -z \"\${$var+set}\"; then
+           relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
+         elif eval var_value=\$$var; test -z "$var_value"; then
+           relink_command="$var=; export $var; $relink_command"
+         else
+           var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
+           relink_command="$var=\"$var_value\"; export $var; $relink_command"
+         fi
+       done
+       relink_command="(cd `pwd`; $relink_command)"
+       relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Quote $echo for shipping.
+      if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then
+       case $progpath in
+       [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";;
+       *) qecho="$SHELL `pwd`/$progpath --fallback-echo";;
+       esac
+       qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
+      else
+       qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Only actually do things if our run command is non-null.
+      if test -z "$run"; then
+       # win32 will think the script is a binary if it has
+       # a .exe suffix, so we strip it off here.
+       case $output in
+         *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;;
+       esac
+       # test for cygwin because mv fails w/o .exe extensions
+       case $host in
+         *cygwin*)
+           exeext=.exe
+           outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;;
+         *) exeext= ;;
+       esac
+       case $host in
+         *cygwin* | *mingw* )
+            output_name=`basename $output`
+            output_path=`dirname $output`
+            cwrappersource="$output_path/$objdir/lt-$output_name.c"
+            cwrapper="$output_path/$output_name.exe"
+            $rm $cwrappersource $cwrapper
+            trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+           cat > $cwrappersource <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+   Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+
+   The $output program cannot be directly executed until all the libtool
+   libraries that it depends on are installed.
+
+   This wrapper executable should never be moved out of the build directory.
+   If it is, it will not operate correctly.
+
+   Currently, it simply execs the wrapper *script* "/bin/sh $output",
+   but could eventually absorb all of the scripts functionality and
+   exec $objdir/$outputname directly.
+*/
+EOF
+           cat >> $cwrappersource<<"EOF"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/stat.h>
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+  defined (__OS2__)
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# ifndef DIR_SEPARATOR_2
+#  define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+#  define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+        (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+  if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+/* -DDEBUG is fairly common in CFLAGS.  */
+#undef DEBUG
+#if defined DEBUGWRAPPER
+# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__)
+#else
+# define DEBUG(format, ...)
+#endif
+
+const char *program_name = NULL;
+
+void * xmalloc (size_t num);
+char * xstrdup (const char *string);
+const char * base_name (const char *name);
+char * find_executable(const char *wrapper);
+int    check_executable(const char *path);
+char * strendzap(char *str, const char *pat);
+void lt_fatal (const char *message, ...);
+
+int
+main (int argc, char *argv[])
+{
+  char **newargz;
+  int i;
+
+  program_name = (char *) xstrdup (base_name (argv[0]));
+  DEBUG("(main) argv[0]      : %s\n",argv[0]);
+  DEBUG("(main) program_name : %s\n",program_name);
+  newargz = XMALLOC(char *, argc+2);
+EOF
+
+            cat >> $cwrappersource <<EOF
+  newargz[0] = (char *) xstrdup("$SHELL");
+EOF
+
+            cat >> $cwrappersource <<"EOF"
+  newargz[1] = find_executable(argv[0]);
+  if (newargz[1] == NULL)
+    lt_fatal("Couldn't find %s", argv[0]);
+  DEBUG("(main) found exe at : %s\n",newargz[1]);
+  /* we know the script has the same name, without the .exe */
+  /* so make sure newargz[1] doesn't end in .exe */
+  strendzap(newargz[1],".exe");
+  for (i = 1; i < argc; i++)
+    newargz[i+1] = xstrdup(argv[i]);
+  newargz[argc+1] = NULL;
+
+  for (i=0; i<argc+1; i++)
+  {
+    DEBUG("(main) newargz[%d]   : %s\n",i,newargz[i]);
+    ;
+  }
+
+EOF
+
+            case $host_os in
+              mingw*)
+                cat >> $cwrappersource <<EOF
+  execv("$SHELL",(char const **)newargz);
+EOF
+              ;;
+              *)
+                cat >> $cwrappersource <<EOF
+  execv("$SHELL",newargz);
+EOF
+              ;;
+            esac
+
+            cat >> $cwrappersource <<"EOF"
+  return 127;
+}
+
+void *
+xmalloc (size_t num)
+{
+  void * p = (void *) malloc (num);
+  if (!p)
+    lt_fatal ("Memory exhausted");
+
+  return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+  return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL
+;
+}
+
+const char *
+base_name (const char *name)
+{
+  const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  /* Skip over the disk name in MSDOS pathnames. */
+  if (isalpha ((unsigned char)name[0]) && name[1] == ':')
+    name += 2;
+#endif
+
+  for (base = name; *name; name++)
+    if (IS_DIR_SEPARATOR (*name))
+      base = name + 1;
+  return base;
+}
+
+int
+check_executable(const char * path)
+{
+  struct stat st;
+
+  DEBUG("(check_executable)  : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!");
+  if ((!path) || (!*path))
+    return 0;
+
+  if ((stat (path, &st) >= 0) &&
+      (
+        /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */
+#if defined (S_IXOTH)
+       ((st.st_mode & S_IXOTH) == S_IXOTH) ||
+#endif
+#if defined (S_IXGRP)
+       ((st.st_mode & S_IXGRP) == S_IXGRP) ||
+#endif
+       ((st.st_mode & S_IXUSR) == S_IXUSR))
+      )
+    return 1;
+  else
+    return 0;
+}
+
+/* Searches for the full path of the wrapper.  Returns
+   newly allocated full path name if found, NULL otherwise */
+char *
+find_executable (const char* wrapper)
+{
+  int has_slash = 0;
+  const char* p;
+  const char* p_next;
+  /* static buffer for getcwd */
+  char tmp[LT_PATHMAX + 1];
+  int tmp_len;
+  char* concat_name;
+
+  DEBUG("(find_executable)  : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!");
+
+  if ((wrapper == NULL) || (*wrapper == '\0'))
+    return NULL;
+
+  /* Absolute path? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  if (isalpha ((unsigned char)wrapper[0]) && wrapper[1] == ':')
+  {
+    concat_name = xstrdup (wrapper);
+    if (check_executable(concat_name))
+      return concat_name;
+    XFREE(concat_name);
+  }
+  else
+  {
+#endif
+    if (IS_DIR_SEPARATOR (wrapper[0]))
+    {
+      concat_name = xstrdup (wrapper);
+      if (check_executable(concat_name))
+        return concat_name;
+      XFREE(concat_name);
+    }
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  }
+#endif
+
+  for (p = wrapper; *p; p++)
+    if (*p == '/')
+    {
+      has_slash = 1;
+      break;
+    }
+  if (!has_slash)
+  {
+    /* no slashes; search PATH */
+    const char* path = getenv ("PATH");
+    if (path != NULL)
+    {
+      for (p = path; *p; p = p_next)
+      {
+        const char* q;
+        size_t p_len;
+        for (q = p; *q; q++)
+          if (IS_PATH_SEPARATOR(*q))
+            break;
+        p_len = q - p;
+        p_next = (*q == '\0' ? q : q + 1);
+        if (p_len == 0)
+        {
+          /* empty path: current directory */
+          if (getcwd (tmp, LT_PATHMAX) == NULL)
+            lt_fatal ("getcwd failed");
+          tmp_len = strlen(tmp);
+          concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1);
+          memcpy (concat_name, tmp, tmp_len);
+          concat_name[tmp_len] = '/';
+          strcpy (concat_name + tmp_len + 1, wrapper);
+        }
+        else
+        {
+          concat_name = XMALLOC(char, p_len + 1 + strlen(wrapper) + 1);
+          memcpy (concat_name, p, p_len);
+          concat_name[p_len] = '/';
+          strcpy (concat_name + p_len + 1, wrapper);
+        }
+        if (check_executable(concat_name))
+          return concat_name;
+        XFREE(concat_name);
+      }
+    }
+    /* not found in PATH; assume curdir */
+  }
+  /* Relative path | not found in path: prepend cwd */
+  if (getcwd (tmp, LT_PATHMAX) == NULL)
+    lt_fatal ("getcwd failed");
+  tmp_len = strlen(tmp);
+  concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1);
+  memcpy (concat_name, tmp, tmp_len);
+  concat_name[tmp_len] = '/';
+  strcpy (concat_name + tmp_len + 1, wrapper);
+
+  if (check_executable(concat_name))
+    return concat_name;
+  XFREE(concat_name);
+  return NULL;
+}
+
+char *
+strendzap(char *str, const char *pat)
+{
+  size_t len, patlen;
+
+  assert(str != NULL);
+  assert(pat != NULL);
+
+  len = strlen(str);
+  patlen = strlen(pat);
+
+  if (patlen <= len)
+  {
+    str += len - patlen;
+    if (strcmp(str, pat) == 0)
+      *str = '\0';
+  }
+  return str;
+}
+
+static void
+lt_error_core (int exit_status, const char * mode,
+          const char * message, va_list ap)
+{
+  fprintf (stderr, "%s: %s: ", program_name, mode);
+  vfprintf (stderr, message, ap);
+  fprintf (stderr, ".\n");
+
+  if (exit_status >= 0)
+    exit (exit_status);
+}
+
+void
+lt_fatal (const char *message, ...)
+{
+  va_list ap;
+  va_start (ap, message);
+  lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
+  va_end (ap);
+}
+EOF
+          # we should really use a build-platform specific compiler
+          # here, but OTOH, the wrappers (shell script and this C one)
+          # are only useful if you want to execute the "real" binary.
+          # Since the "real" binary is built for $host, then this
+          # wrapper might as well be built for $host, too.
+          $run $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource
+          ;;
+        esac
+        $rm $output
+        trap "$rm $output; exit $EXIT_FAILURE" 1 2 15
+
+       $echo > $output "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='${SED} -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variable:
+  notinst_deplibs='$notinst_deplibs'
+else
+  # When we are sourced in execute mode, \$file and \$echo are already set.
+  if test \"\$libtool_execute_magic\" != \"$magic\"; then
+    echo=\"$qecho\"
+    file=\"\$0\"
+    # Make sure echo works.
+    if test \"X\$1\" = X--no-reexec; then
+      # Discard the --no-reexec flag, and continue.
+      shift
+    elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
+      # Yippee, \$echo works!
+      :
+    else
+      # Restart under the correct shell, and then maybe \$echo will work.
+      exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+    fi
+  fi\
+"
+       $echo >> $output "\
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
+
+    file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
+  done
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+       if test "$fast_install" = yes; then
+         $echo >> $output "\
+  program=lt-'$outputname'$exeext
+  progdir=\"\$thisdir/$objdir\"
+
+  if test ! -f \"\$progdir/\$program\" || \\
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+    file=\"\$\$-\$program\"
+
+    if test ! -d \"\$progdir\"; then
+      $mkdir \"\$progdir\"
+    else
+      $rm \"\$progdir/\$file\"
+    fi"
+
+         $echo >> $output "\
+
+    # relink executable if necessary
+    if test -n \"\$relink_command\"; then
+      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+      else
+       $echo \"\$relink_command_output\" >&2
+       $rm \"\$progdir/\$file\"
+       exit $EXIT_FAILURE
+      fi
+    fi
+
+    $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+    { $rm \"\$progdir/\$program\";
+      $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+    $rm \"\$progdir/\$file\"
+  fi"
+       else
+         $echo >> $output "\
+  program='$outputname'
+  progdir=\"\$thisdir/$objdir\"
+"
+       fi
+
+       $echo >> $output "\
+
+  if test -f \"\$progdir/\$program\"; then"
+
+       # Export our shlibpath_var if we have one.
+       if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+         $echo >> $output "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    # The second colon is a workaround for a bug in BeOS R4 sed
+    $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+    export $shlibpath_var
+"
+       fi
+
+       # fixup the dll searchpath if we need to.
+       if test -n "$dllsearchpath"; then
+         $echo >> $output "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
+       fi
+
+       $echo >> $output "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+
+      # Make sure env LD_LIBRARY_PATH does not mess us up
+      if test -n \"\${LD_LIBRARY_PATH+set}\"; then
+        export LD_LIBRARY_PATH=\$progdir:\$LD_LIBRARY_PATH
+      fi
+"
+       case $host in
+       # Backslashes separate directories on plain windows
+       *-*-mingw | *-*-os2*)
+         $echo >> $output "\
+      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+         ;;
+
+       *)
+         $echo >> $output "\
+      exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+         ;;
+       esac
+       $echo >> $output "\
+      \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+      exit $EXIT_FAILURE
+    fi
+  else
+    # The program doesn't exist.
+    \$echo \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
+    \$echo \"This script is just a wrapper for \$program.\" 1>&2
+    $echo \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit $EXIT_FAILURE
+  fi
+fi\
+"
+       chmod +x $output
+      fi
+      exit $EXIT_SUCCESS
+      ;;
+    esac
+
+    # See if we need to build an old-fashioned archive.
+    for oldlib in $oldlibs; do
+
+      if test "$build_libtool_libs" = convenience; then
+       oldobjs="$libobjs_save"
+       addlibs="$convenience"
+       build_libtool_libs=no
+      else
+       if test "$build_libtool_libs" = module; then
+         oldobjs="$libobjs_save"
+         build_libtool_libs=no
+       else
+         oldobjs="$old_deplibs $non_pic_objects"
+       fi
+       addlibs="$old_convenience"
+      fi
+
+      if test -n "$addlibs"; then
+       gentop="$output_objdir/${outputname}x"
+       generated="$generated $gentop"
+
+       func_extract_archives $gentop $addlibs
+       oldobjs="$oldobjs $func_extract_archives_result"
+      fi
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+       cmds=$old_archive_from_new_cmds
+      else
+       # POSIX demands no paths to be encoded in archives.  We have
+       # to avoid creating archives with duplicate basenames if we
+       # might have to extract them afterwards, e.g., when creating a
+       # static archive out of a convenience library, or when linking
+       # the entirety of a libtool archive into another (currently
+       # not supported by libtool).
+       if (for obj in $oldobjs
+           do
+             $echo "X$obj" | $Xsed -e 's%^.*/%%'
+           done | sort | sort -uc >/dev/null 2>&1); then
+         :
+       else
+         $echo "copying selected object files to avoid basename conflicts..."
+
+         if test -z "$gentop"; then
+           gentop="$output_objdir/${outputname}x"
+           generated="$generated $gentop"
+
+           $show "${rm}r $gentop"
+           $run ${rm}r "$gentop"
+           $show "$mkdir $gentop"
+           $run $mkdir "$gentop"
+           exit_status=$?
+           if test "$exit_status" -ne 0 && test ! -d "$gentop"; then
+             exit $exit_status
+           fi
+         fi
+
+         save_oldobjs=$oldobjs
+         oldobjs=
+         counter=1
+         for obj in $save_oldobjs
+         do
+           objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
+           case " $oldobjs " in
+           " ") oldobjs=$obj ;;
+           *[\ /]"$objbase "*)
+             while :; do
+               # Make sure we don't pick an alternate name that also
+               # overlaps.
+               newobj=lt$counter-$objbase
+               counter=`expr $counter + 1`
+               case " $oldobjs " in
+               *[\ /]"$newobj "*) ;;
+               *) if test ! -f "$gentop/$newobj"; then break; fi ;;
+               esac
+             done
+             $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+             $run ln "$obj" "$gentop/$newobj" ||
+             $run cp "$obj" "$gentop/$newobj"
+             oldobjs="$oldobjs $gentop/$newobj"
+             ;;
+           *) oldobjs="$oldobjs $obj" ;;
+           esac
+         done
+       fi
+
+       eval cmds=\"$old_archive_cmds\"
+
+       if len=`expr "X$cmds" : ".*"` &&
+            test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+         cmds=$old_archive_cmds
+       else
+         # the command line is too long to link in one step, link in parts
+         $echo "using piecewise archive linking..."
+         save_RANLIB=$RANLIB
+         RANLIB=:
+         objlist=
+         concat_cmds=
+         save_oldobjs=$oldobjs
+
+         # Is there a better way of finding the last object in the list?
+         for obj in $save_oldobjs
+         do
+           last_oldobj=$obj
+         done
+         for obj in $save_oldobjs
+         do
+           oldobjs="$objlist $obj"
+           objlist="$objlist $obj"
+           eval test_cmds=\"$old_archive_cmds\"
+           if len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
+              test "$len" -le "$max_cmd_len"; then
+             :
+           else
+             # the above command should be used before it gets too long
+             oldobjs=$objlist
+             if test "$obj" = "$last_oldobj" ; then
+               RANLIB=$save_RANLIB
+             fi
+             test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+             eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+             objlist=
+           fi
+         done
+         RANLIB=$save_RANLIB
+         oldobjs=$objlist
+         if test "X$oldobjs" = "X" ; then
+           eval cmds=\"\$concat_cmds\"
+         else
+           eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+         fi
+       fi
+      fi
+      save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+        eval cmd=\"$cmd\"
+       IFS="$save_ifs"
+       $show "$cmd"
+       $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$generated"; then
+      $show "${rm}r$generated"
+      $run ${rm}r$generated
+    fi
+
+    # Now create the libtool archive.
+    case $output in
+    *.la)
+      old_library=
+      test "$build_old_libs" = yes && old_library="$libname.$libext"
+      $show "creating $output"
+
+      # Preserve any variables that may affect compiler behavior
+      for var in $variables_saved_for_relink; do
+       if eval test -z \"\${$var+set}\"; then
+         relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
+       elif eval var_value=\$$var; test -z "$var_value"; then
+         relink_command="$var=; export $var; $relink_command"
+       else
+         var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
+         relink_command="$var=\"$var_value\"; export $var; $relink_command"
+       fi
+      done
+      # Quote the link command for shipping.
+      relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+      relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+      if test "$hardcode_automatic" = yes ; then
+       relink_command=
+      fi
+
+
+      # Only create the output if not a dry run.
+      if test -z "$run"; then
+       for installed in no yes; do
+         if test "$installed" = yes; then
+           if test -z "$install_libdir"; then
+             break
+           fi
+           output="$output_objdir/$outputname"i
+           # Replace all uninstalled libtool libraries with the installed ones
+           newdependency_libs=
+           for deplib in $dependency_libs; do
+             case $deplib in
+             *.la)
+               name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'`
+               eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+               if test -z "$libdir"; then
+                 $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
+                 exit $EXIT_FAILURE
+               fi
+               if test "X$EGREP" = X ; then
+                       EGREP=egrep
+               fi
+               # We do not want portage's install root ($D) present.  Check only for
+               # this if the .la is being installed.
+               if test "$installed" = yes && test "$D"; then
+                 eval mynewdependency_lib=`echo "$libdir/$name" |sed -e "s:$D:/:g" -e 's:/\+:/:g'`
+               else
+                 mynewdependency_lib="$libdir/$name"
+               fi
+               # Do not add duplicates
+               if test "$mynewdependency_lib"; then
+                 my_little_ninja_foo_1=`echo $newdependency_libs |$EGREP -e "$mynewdependency_lib"`
+                 if test -z "$my_little_ninja_foo_1"; then
+                   newdependency_libs="$newdependency_libs $mynewdependency_lib"
+                 fi
+               fi
+               ;;
+                 *)
+               if test "$installed" = yes; then
+                 # Rather use S=WORKDIR if our version of portage supports it.
+                 # This is because some ebuild (gcc) do not use $S as buildroot.
+                 if test "$PWORKDIR"; then
+                   S="$PWORKDIR"
+                 fi
+                 # We do not want portage's build root ($S) present.
+                 my_little_ninja_foo_2=`echo $deplib |$EGREP -e "$S"`
+                 # We do not want portage's install root ($D) present.
+                 my_little_ninja_foo_3=`echo $deplib |$EGREP -e "$D"`
+                 if test -n "$my_little_ninja_foo_2" && test "$S"; then
+                   mynewdependency_lib=""
+                 elif test -n "$my_little_ninja_foo_3" && test "$D"; then
+                   eval mynewdependency_lib=`echo "$deplib" |sed -e "s:$D:/:g" -e 's:/\+:/:g'`
+                 else
+                   mynewdependency_lib="$deplib"
+                 fi
+               else
+                 mynewdependency_lib="$deplib"
+               fi
+               # Do not add duplicates
+               if test "$mynewdependency_lib"; then
+                 my_little_ninja_foo_4=`echo $newdependency_libs |$EGREP -e "$mynewdependency_lib"`
+                 if test -z "$my_little_ninja_foo_4"; then
+                       newdependency_libs="$newdependency_libs $mynewdependency_lib"
+                 fi
+               fi
+               ;;
+             esac
+           done
+           dependency_libs="$newdependency_libs"
+           newdlfiles=
+           for lib in $dlfiles; do
+             name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+             eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+             if test -z "$libdir"; then
+               $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+               exit $EXIT_FAILURE
+             fi
+             newdlfiles="$newdlfiles $libdir/$name"
+           done
+           dlfiles="$newdlfiles"
+           newdlprefiles=
+           for lib in $dlprefiles; do
+             name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+             eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+             if test -z "$libdir"; then
+               $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+               exit $EXIT_FAILURE
+             fi
+             newdlprefiles="$newdlprefiles $libdir/$name"
+           done
+           dlprefiles="$newdlprefiles"
+         else
+           newdlfiles=
+           for lib in $dlfiles; do
+             case $lib in
+               [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+               *) abs=`pwd`"/$lib" ;;
+             esac
+             newdlfiles="$newdlfiles $abs"
+           done
+           dlfiles="$newdlfiles"
+           newdlprefiles=
+           for lib in $dlprefiles; do
+             case $lib in
+               [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+               *) abs=`pwd`"/$lib" ;;
+             esac
+             newdlprefiles="$newdlprefiles $abs"
+           done
+           dlprefiles="$newdlprefiles"
+         fi
+         $rm $output
+         # place dlname in correct position for cygwin
+         tdlname=$dlname
+         case $host,$output,$installed,$module,$dlname in
+           *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
+         esac
+         # Do not add duplicates
+         if test "$installed" = yes && test "$D"; then
+           install_libdir=`echo "$install_libdir" |sed -e "s:$D:/:g" -e 's:/\+:/:g'`
+         fi
+         $echo > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+         if test "$installed" = no && test "$need_relink" = yes; then
+           $echo >> $output "\
+relink_command=\"$relink_command\""
+         fi
+       done
+      fi
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
+      $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $?
+      ;;
+    esac
+    exit $EXIT_SUCCESS
+    ;;
+
+  # libtool install mode
+  install)
+    modename="$modename: install"
+
+    # There may be an optional sh(1) argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+       # Allow the use of GNU shtool's install command.
+       $echo "X$nonopt" | grep shtool > /dev/null; then
+      # Aesthetically quote it.
+      arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
+      case $arg in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
+       arg="\"$arg\""
+       ;;
+      esac
+      install_prog="$arg "
+      arg="$1"
+      shift
+    else
+      install_prog=
+      arg=$nonopt
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+    case $arg in
+    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \      ]*|*]*|"")
+      arg="\"$arg\""
+      ;;
+    esac
+    install_prog="$install_prog$arg"
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=no
+    stripme=
+    for arg
+    do
+      if test -n "$dest"; then
+       files="$files $dest"
+       dest=$arg
+       continue
+      fi
+
+      case $arg in
+      -d) isdir=yes ;;
+      -f) 
+       case " $install_prog " in
+       *[\\\ /]cp\ *) ;;
+       *) prev=$arg ;;
+       esac
+       ;;
+      -g | -m | -o) prev=$arg ;;
+      -s)
+       stripme=" -s"
+       continue
+       ;;
+      -*)
+       ;;
+      *)
+       # If the previous option needed an argument, then skip it.
+       if test -n "$prev"; then
+         prev=
+       else
+         dest=$arg
+         continue
+       fi
+       ;;
+      esac
+
+      # Aesthetically quote the argument.
+      arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+      case $arg in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
+       arg="\"$arg\""
+       ;;
+      esac
+      install_prog="$install_prog $arg"
+    done
+
+    if test -z "$install_prog"; then
+      $echo "$modename: you must specify an install program" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prev' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+       $echo "$modename: no file or destination specified" 1>&2
+      else
+       $echo "$modename: you must specify a destination" 1>&2
+      fi
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    # Strip any trailing slash from the destination.
+    dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test "$isdir" = yes; then
+      destdir="$dest"
+      destname=
+    else
+      destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
+      test "X$destdir" = "X$dest" && destdir=.
+      destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files
+      if test "$#" -gt 2; then
+       $echo "$modename: \`$dest' is not a directory" 1>&2
+       $echo "$help" 1>&2
+       exit $EXIT_FAILURE
+      fi
+    fi
+    case $destdir in
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
+    *)
+      for file in $files; do
+       case $file in
+       *.lo) ;;
+       *)
+         $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
+         $echo "$help" 1>&2
+         exit $EXIT_FAILURE
+         ;;
+       esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case $file in
+      *.$libext)
+       # Do the static libraries later.
+       staticlibs="$staticlibs $file"
+       ;;
+
+      *.la)
+       # Check to see that this really is a libtool archive.
+       if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+       else
+         $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
+         $echo "$help" 1>&2
+         exit $EXIT_FAILURE
+       fi
+
+       library_names=
+       old_library=
+       relink_command=
+       # If there is no directory component, then add one.
+       case $file in
+       */* | *\\*) . $file ;;
+       *) . ./$file ;;
+       esac
+
+       # Add the libdir to current_libdirs if it is the destination.
+       if test "X$destdir" = "X$libdir"; then
+         case "$current_libdirs " in
+         *" $libdir "*) ;;
+         *) current_libdirs="$current_libdirs $libdir" ;;
+         esac
+       else
+         # Note the libdir as a future libdir.
+         case "$future_libdirs " in
+         *" $libdir "*) ;;
+         *) future_libdirs="$future_libdirs $libdir" ;;
+         esac
+       fi
+
+       dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/
+       test "X$dir" = "X$file/" && dir=
+       dir="$dir$objdir"
+
+       if test -n "$relink_command"; then
+         # Determine the prefix the user has applied to our future dir.
+         inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"`
+
+         # Don't allow the user to place us outside of our expected
+         # location b/c this prevents finding dependent libraries that
+         # are installed to the same prefix.
+         # At present, this check doesn't affect windows .dll's that
+         # are installed into $libdir/../bin (currently, that works fine)
+         # but it's something to keep an eye on.
+         if test "$inst_prefix_dir" = "$destdir"; then
+           $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2
+           exit $EXIT_FAILURE
+         fi
+
+         if test -n "$inst_prefix_dir"; then
+           # Stick the inst_prefix_dir data into the link command.
+           relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+         else
+           relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+         fi
+
+         $echo "$modename: warning: relinking \`$file'" 1>&2
+         $show "$relink_command"
+         if $run eval "$relink_command"; then :
+         else
+           $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+           exit $EXIT_FAILURE
+         fi
+       fi
+
+       # See the names of the shared library.
+       set dummy $library_names
+       if test -n "$2"; then
+         realname="$2"
+         shift
+         shift
+
+         srcname="$realname"
+         test -n "$relink_command" && srcname="$realname"T
+
+         # Install the shared library and build the symlinks.
+         $show "$install_prog $dir/$srcname $destdir/$realname"
+         $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $?
+         if test -n "$stripme" && test -n "$striplib"; then
+           $show "$striplib $destdir/$realname"
+           $run eval "$striplib $destdir/$realname" || exit $?
+         fi
+
+         if test "$#" -gt 0; then
+           # Delete the old symlinks, and create new ones.
+           # Try `ln -sf' first, because the `ln' binary might depend on
+           # the symlink we replace!  Solaris /bin/ln does not understand -f,
+           # so we also need to try rm && ln -s.
+           for linkname
+           do
+             if test "$linkname" != "$realname"; then
+                $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })"
+                $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })"
+             fi
+           done
+         fi
+
+         # Do each command in the postinstall commands.
+         lib="$destdir/$realname"
+         cmds=$postinstall_cmds
+         save_ifs="$IFS"; IFS='~'
+         for cmd in $cmds; do
+           IFS="$save_ifs"
+           eval cmd=\"$cmd\"
+           $show "$cmd"
+           $run eval "$cmd" || {
+             lt_exit=$?
+
+             # Restore the uninstalled library and exit
+             if test "$mode" = relink; then
+               $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)'
+             fi
+
+             exit $lt_exit
+           }
+         done
+         IFS="$save_ifs"
+       fi
+
+       # Install the pseudo-library for information purposes.
+       name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+       instname="$dir/$name"i
+       $show "$install_prog $instname $destdir/$name"
+       $run eval "$install_prog $instname $destdir/$name" || exit $?
+
+       # Maybe install the static library, too.
+       test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+       ;;
+
+      *.lo)
+       # Install (i.e. copy) a libtool object.
+
+       # Figure out destination file name, if it wasn't already specified.
+       if test -n "$destname"; then
+         destfile="$destdir/$destname"
+       else
+         destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+         destfile="$destdir/$destfile"
+       fi
+
+       # Deduce the name of the destination old-style object file.
+       case $destfile in
+       *.lo)
+         staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
+         ;;
+       *.$objext)
+         staticdest="$destfile"
+         destfile=
+         ;;
+       *)
+         $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
+         $echo "$help" 1>&2
+         exit $EXIT_FAILURE
+         ;;
+       esac
+
+       # Install the libtool object if requested.
+       if test -n "$destfile"; then
+         $show "$install_prog $file $destfile"
+         $run eval "$install_prog $file $destfile" || exit $?
+       fi
+
+       # Install the old object if enabled.
+       if test "$build_old_libs" = yes; then
+         # Deduce the name of the old-style object file.
+         staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
+
+         $show "$install_prog $staticobj $staticdest"
+         $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+       fi
+       exit $EXIT_SUCCESS
+       ;;
+
+      *)
+       # Figure out destination file name, if it wasn't already specified.
+       if test -n "$destname"; then
+         destfile="$destdir/$destname"
+       else
+         destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+         destfile="$destdir/$destfile"
+       fi
+
+       # If the file is missing, and there is a .exe on the end, strip it
+       # because it is most likely a libtool script we actually want to
+       # install
+       stripped_ext=""
+       case $file in
+         *.exe)
+           if test ! -f "$file"; then
+             file=`$echo $file|${SED} 's,.exe$,,'`
+             stripped_ext=".exe"
+           fi
+           ;;
+       esac
+
+       # Do a test to see if this is really a libtool program.
+       case $host in
+       *cygwin*|*mingw*)
+           wrapper=`$echo $file | ${SED} -e 's,.exe$,,'`
+           ;;
+       *)
+           wrapper=$file
+           ;;
+       esac
+       if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then
+         notinst_deplibs=
+         relink_command=
+
+         # Note that it is not necessary on cygwin/mingw to append a dot to
+         # foo even if both foo and FILE.exe exist: automatic-append-.exe
+         # behavior happens only for exec(3), not for open(2)!  Also, sourcing
+         # `FILE.' does not work on cygwin managed mounts.
+         #
+         # If there is no directory component, then add one.
+         case $wrapper in
+         */* | *\\*) . ${wrapper} ;;
+         *) . ./${wrapper} ;;
+         esac
+
+         # Check the variables that should have been set.
+         if test -z "$notinst_deplibs"; then
+           $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2
+           exit $EXIT_FAILURE
+         fi
+
+         finalize=yes
+         for lib in $notinst_deplibs; do
+           # Check to see that each library is installed.
+           libdir=
+           if test -f "$lib"; then
+             # If there is no directory component, then add one.
+             case $lib in
+             */* | *\\*) . $lib ;;
+             *) . ./$lib ;;
+             esac
+           fi
+           libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test
+           if test -n "$libdir" && test ! -f "$libfile"; then
+             $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+             finalize=no
+           fi
+         done
+
+         relink_command=
+         # Note that it is not necessary on cygwin/mingw to append a dot to
+         # foo even if both foo and FILE.exe exist: automatic-append-.exe
+         # behavior happens only for exec(3), not for open(2)!  Also, sourcing
+         # `FILE.' does not work on cygwin managed mounts.
+         #
+         # If there is no directory component, then add one.
+         case $wrapper in
+         */* | *\\*) . ${wrapper} ;;
+         *) . ./${wrapper} ;;
+         esac
+
+         outputname=
+         if test "$fast_install" = no && test -n "$relink_command"; then
+           if test "$finalize" = yes && test -z "$run"; then
+             tmpdir=`func_mktempdir`
+             file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'`
+             outputname="$tmpdir/$file"
+             # Replace the output file specification.
+             relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+             $show "$relink_command"
+             if $run eval "$relink_command"; then :
+             else
+               $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+               ${rm}r "$tmpdir"
+               continue
+             fi
+             file="$outputname"
+           else
+             $echo "$modename: warning: cannot relink \`$file'" 1>&2
+           fi
+         else
+           # Install the binary that we compiled earlier.
+           file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+         fi
+       fi
+
+       # remove .exe since cygwin /usr/bin/install will append another
+       # one anyway 
+       case $install_prog,$host in
+       */usr/bin/install*,*cygwin*)
+         case $file:$destfile in
+         *.exe:*.exe)
+           # this is ok
+           ;;
+         *.exe:*)
+           destfile=$destfile.exe
+           ;;
+         *:*.exe)
+           destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'`
+           ;;
+         esac
+         ;;
+       esac
+       $show "$install_prog$stripme $file $destfile"
+       $run eval "$install_prog\$stripme \$file \$destfile" || exit $?
+       test -n "$outputname" && ${rm}r "$tmpdir"
+       ;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+
+      $show "$install_prog $file $oldlib"
+      $run eval "$install_prog \$file \$oldlib" || exit $?
+
+      if test -n "$stripme" && test -n "$old_striplib"; then
+       $show "$old_striplib $oldlib"
+       $run eval "$old_striplib $oldlib" || exit $?
+      fi
+
+      # Do each command in the postinstall commands.
+      cmds=$old_postinstall_cmds
+      save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+       IFS="$save_ifs"
+       eval cmd=\"$cmd\"
+       $show "$cmd"
+       $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$future_libdirs"; then
+      $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+    fi
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      test -n "$run" && current_libdirs=" -n$current_libdirs"
+      exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+    else
+      exit $EXIT_SUCCESS
+    fi
+    ;;
+
+  # libtool finish mode
+  finish)
+    modename="$modename: finish"
+    libdirs="$nonopt"
+    admincmds=
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for dir
+      do
+       libdirs="$libdirs $dir"
+      done
+
+      for libdir in $libdirs; do
+       if test -n "$finish_cmds"; then
+         # Do each command in the finish commands.
+         cmds=$finish_cmds
+         save_ifs="$IFS"; IFS='~'
+         for cmd in $cmds; do
+           IFS="$save_ifs"
+           eval cmd=\"$cmd\"
+           $show "$cmd"
+           $run eval "$cmd" || admincmds="$admincmds
+       $cmd"
+         done
+         IFS="$save_ifs"
+       fi
+       if test -n "$finish_eval"; then
+         # Do the single finish_eval.
+         eval cmds=\"$finish_eval\"
+         $run eval "$cmds" || admincmds="$admincmds
+       $cmds"
+       fi
+      done
+    fi
+
+    # Exit here if they wanted silent mode.
+    test "$show" = : && exit $EXIT_SUCCESS
+
+    $echo "X----------------------------------------------------------------------" | $Xsed
+    $echo "Libraries have been installed in:"
+    for libdir in $libdirs; do
+      $echo "   $libdir"
+    done
+    $echo
+    $echo "If you ever happen to want to link against installed libraries"
+    $echo "in a given directory, LIBDIR, you must either use libtool, and"
+    $echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+    $echo "flag during linking and do at least one of the following:"
+    if test -n "$shlibpath_var"; then
+      $echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
+      $echo "     during execution"
+    fi
+    if test -n "$runpath_var"; then
+      $echo "   - add LIBDIR to the \`$runpath_var' environment variable"
+      $echo "     during linking"
+    fi
+    if test -n "$hardcode_libdir_flag_spec"; then
+      libdir=LIBDIR
+      eval flag=\"$hardcode_libdir_flag_spec\"
+
+      $echo "   - use the \`$flag' linker flag"
+    fi
+    if test -n "$admincmds"; then
+      $echo "   - have your system administrator run these commands:$admincmds"
+    fi
+    if test -f /etc/ld.so.conf; then
+      $echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+    fi
+    $echo
+    $echo "See any operating system documentation about shared libraries for"
+    $echo "more information, such as the ld(1) and ld.so(8) manual pages."
+    $echo "X----------------------------------------------------------------------" | $Xsed
+    exit $EXIT_SUCCESS
+    ;;
+
+  # libtool execute mode
+  execute)
+    modename="$modename: execute"
+
+    # The first argument is the command name.
+    cmd="$nonopt"
+    if test -z "$cmd"; then
+      $echo "$modename: you must specify a COMMAND" 1>&2
+      $echo "$help"
+      exit $EXIT_FAILURE
+    fi
+
+    # Handle -dlopen flags immediately.
+    for file in $execute_dlfiles; do
+      if test ! -f "$file"; then
+       $echo "$modename: \`$file' is not a file" 1>&2
+       $echo "$help" 1>&2
+       exit $EXIT_FAILURE
+      fi
+
+      dir=
+      case $file in
+      *.la)
+       # Check to see that this really is a libtool archive.
+       if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+       else
+         $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+         $echo "$help" 1>&2
+         exit $EXIT_FAILURE
+       fi
+
+       # Read the libtool library.
+       dlname=
+       library_names=
+
+       # If there is no directory component, then add one.
+       case $file in
+       */* | *\\*) . $file ;;
+       *) . ./$file ;;
+       esac
+
+       # Skip this library if it cannot be dlopened.
+       if test -z "$dlname"; then
+         # Warn if it was a shared library.
+         test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
+         continue
+       fi
+
+       dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+       test "X$dir" = "X$file" && dir=.
+
+       if test -f "$dir/$objdir/$dlname"; then
+         dir="$dir/$objdir"
+       else
+         $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+         exit $EXIT_FAILURE
+       fi
+       ;;
+
+      *.lo)
+       # Just add the directory containing the .lo file.
+       dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+       test "X$dir" = "X$file" && dir=.
+       ;;
+
+      *)
+       $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+       continue
+       ;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir="$absdir"
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+       eval "$shlibpath_var=\"\$dir\""
+      else
+       eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic="$magic"
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case $file in
+      -*) ;;
+      *)
+       # Do a test to see if this is really a libtool program.
+       if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+         # If there is no directory component, then add one.
+         case $file in
+         */* | *\\*) . $file ;;
+         *) . ./$file ;;
+         esac
+
+         # Transform arg to wrapped name.
+         file="$progdir/$program"
+       fi
+       ;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
+      args="$args \"$file\""
+    done
+
+    if test -z "$run"; then
+      if test -n "$shlibpath_var"; then
+       # Export the shlibpath_var.
+       eval "export $shlibpath_var"
+      fi
+
+      # Restore saved environment variables
+      if test "${save_LC_ALL+set}" = set; then
+       LC_ALL="$save_LC_ALL"; export LC_ALL
+      fi
+      if test "${save_LANG+set}" = set; then
+       LANG="$save_LANG"; export LANG
+      fi
+
+      # Now prepare to actually exec the command.
+      exec_cmd="\$cmd$args"
+    else
+      # Display what would be done.
+      if test -n "$shlibpath_var"; then
+       eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+       $echo "export $shlibpath_var"
+      fi
+      $echo "$cmd$args"
+      exit $EXIT_SUCCESS
+    fi
+    ;;
+
+  # libtool clean and uninstall mode
+  clean | uninstall)
+    modename="$modename: $mode"
+    rm="$nonopt"
+    files=
+    rmforce=
+    exit_status=0
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    for arg
+    do
+      case $arg in
+      -f) rm="$rm $arg"; rmforce=yes ;;
+      -*) rm="$rm $arg" ;;
+      *) files="$files $arg" ;;
+      esac
+    done
+
+    if test -z "$rm"; then
+      $echo "$modename: you must specify an RM program" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    rmdirs=
+
+    origobjdir="$objdir"
+    for file in $files; do
+      dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+      if test "X$dir" = "X$file"; then
+       dir=.
+       objdir="$origobjdir"
+      else
+       objdir="$dir/$origobjdir"
+      fi
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+      test "$mode" = uninstall && objdir="$dir"
+
+      # Remember objdir for removal later, being careful to avoid duplicates
+      if test "$mode" = clean; then
+       case " $rmdirs " in
+         *" $objdir "*) ;;
+         *) rmdirs="$rmdirs $objdir" ;;
+       esac
+      fi
+
+      # Don't error if the file doesn't exist and rm -f was used.
+      if (test -L "$file") >/dev/null 2>&1 \
+       || (test -h "$file") >/dev/null 2>&1 \
+       || test -f "$file"; then
+       :
+      elif test -d "$file"; then
+       exit_status=1
+       continue
+      elif test "$rmforce" = yes; then
+       continue
+      fi
+
+      rmfiles="$file"
+
+      case $name in
+      *.la)
+       # Possibly a libtool archive, so verify it.
+       if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+         . $dir/$name
+
+         # Delete the libtool libraries and symlinks.
+         for n in $library_names; do
+           rmfiles="$rmfiles $objdir/$n"
+         done
+         test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
+
+         case "$mode" in
+         clean)
+           case "  $library_names " in
+           # "  " in the beginning catches empty $dlname
+           *" $dlname "*) ;;
+           *) rmfiles="$rmfiles $objdir/$dlname" ;;
+           esac
+            test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
+           ;;
+         uninstall)
+           if test -n "$library_names"; then
+             # Do each command in the postuninstall commands.
+             cmds=$postuninstall_cmds
+             save_ifs="$IFS"; IFS='~'
+             for cmd in $cmds; do
+               IFS="$save_ifs"
+               eval cmd=\"$cmd\"
+               $show "$cmd"
+               $run eval "$cmd"
+               if test "$?" -ne 0 && test "$rmforce" != yes; then
+                 exit_status=1
+               fi
+             done
+             IFS="$save_ifs"
+           fi
+
+           if test -n "$old_library"; then
+             # Do each command in the old_postuninstall commands.
+             cmds=$old_postuninstall_cmds
+             save_ifs="$IFS"; IFS='~'
+             for cmd in $cmds; do
+               IFS="$save_ifs"
+               eval cmd=\"$cmd\"
+               $show "$cmd"
+               $run eval "$cmd"
+               if test "$?" -ne 0 && test "$rmforce" != yes; then
+                 exit_status=1
+               fi
+             done
+             IFS="$save_ifs"
+           fi
+           # FIXME: should reinstall the best remaining shared library.
+           ;;
+         esac
+       fi
+       ;;
+
+      *.lo)
+       # Possibly a libtool object, so verify it.
+       if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+
+         # Read the .lo file
+         . $dir/$name
+
+         # Add PIC object to the list of files to remove.
+         if test -n "$pic_object" \
+            && test "$pic_object" != none; then
+           rmfiles="$rmfiles $dir/$pic_object"
+         fi
+
+         # Add non-PIC object to the list of files to remove.
+         if test -n "$non_pic_object" \
+            && test "$non_pic_object" != none; then
+           rmfiles="$rmfiles $dir/$non_pic_object"
+         fi
+       fi
+       ;;
+
+      *)
+       if test "$mode" = clean ; then
+         noexename=$name
+         case $file in
+         *.exe)
+           file=`$echo $file|${SED} 's,.exe$,,'`
+           noexename=`$echo $name|${SED} 's,.exe$,,'`
+           # $file with .exe has already been added to rmfiles,
+           # add $file without .exe
+           rmfiles="$rmfiles $file"
+           ;;
+         esac
+         # Do a test to see if this is a libtool program.
+         if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+           relink_command=
+           . $dir/$noexename
+
+           # note $name still contains .exe if it was in $file originally
+           # as does the version of $file that was added into $rmfiles
+           rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
+           if test "$fast_install" = yes && test -n "$relink_command"; then
+             rmfiles="$rmfiles $objdir/lt-$name"
+           fi
+           if test "X$noexename" != "X$name" ; then
+             rmfiles="$rmfiles $objdir/lt-${noexename}.c"
+           fi
+         fi
+       fi
+       ;;
+      esac
+      $show "$rm $rmfiles"
+      $run $rm $rmfiles || exit_status=1
+    done
+    objdir="$origobjdir"
+
+    # Try to remove the ${objdir}s in the directories where we deleted files
+    for dir in $rmdirs; do
+      if test -d "$dir"; then
+       $show "rmdir $dir"
+       $run rmdir $dir >/dev/null 2>&1
+      fi
+    done
+
+    exit $exit_status
+    ;;
+
+  "")
+    $echo "$modename: you must specify a MODE" 1>&2
+    $echo "$generic_help" 1>&2
+    exit $EXIT_FAILURE
+    ;;
+  esac
+
+  if test -z "$exec_cmd"; then
+    $echo "$modename: invalid operation mode \`$mode'" 1>&2
+    $echo "$generic_help" 1>&2
+    exit $EXIT_FAILURE
+  fi
+fi # test -z "$show_help"
+
+if test -n "$exec_cmd"; then
+  eval exec $exec_cmd
+  exit $EXIT_FAILURE
+fi
+
+# We need to display help for each of the modes.
+case $mode in
+"") $echo \
+"Usage: $modename [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+    --config          show all configuration variables
+    --debug           enable verbose shell tracing
+-n, --dry-run         display commands without modifying any files
+    --features        display basic configuration information and exit
+    --finish          same as \`--mode=finish'
+    --help            display this help message and exit
+    --mode=MODE       use operation mode MODE [default=inferred from MODE-ARGS]
+    --quiet           same as \`--silent'
+    --silent          don't print informational messages
+    --tag=TAG         use configuration variables from tag TAG
+    --version         print version information
+
+MODE must be one of the following:
+
+      clean           remove files from the build directory
+      compile         compile a source file into a libtool object
+      execute         automatically set library path, then run a program
+      finish          complete the installation of libtool libraries
+      install         install libraries or executables
+      link            create a library or an executable
+      uninstall       remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE.  Try \`$modename --help --mode=MODE' for
+a more detailed description of MODE.
+
+Report bugs to <bug-libtool@gnu.org>."
+  exit $EXIT_SUCCESS
+  ;;
+
+clean)
+  $echo \
+"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+  ;;
+
+compile)
+  $echo \
+"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
+  -prefer-pic       try to building PIC objects only
+  -prefer-non-pic   try to building non-PIC objects only
+  -static           always build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+  ;;
+
+execute)
+  $echo \
+"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+  ;;
+
+finish)
+  $echo \
+"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the \`--dry-run' option if you just want to see what would be executed."
+  ;;
+
+install)
+  $echo \
+"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+  ;;
+
+link)
+  $echo \
+"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -avoid-version    do not add a version suffix if possible
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -export-symbols SYMFILE
+                   try to export only the symbols listed in SYMFILE
+  -export-symbols-regex REGEX
+                   try to export only the symbols matching REGEX
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -module           build a library that can dlopened
+  -no-fast-install  disable the fast-install mode
+  -no-install       link a not-installable executable
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -objectlist FILE  Use a list of object files found in FILE to specify objects
+  -precious-files-regex REGEX
+                    don't remove output files matching REGEX
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
+  -static           do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+                   specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+  ;;
+
+uninstall)
+  $echo \
+"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+  ;;
+
+*)
+  $echo "$modename: invalid operation mode \`$mode'" 1>&2
+  $echo "$help" 1>&2
+  exit $EXIT_FAILURE
+  ;;
+esac
+
+$echo
+$echo "Try \`$modename --help' for more information about other modes."
+
+exit $?
+
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries.  Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them.  This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration.  But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+disable_libs=shared
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+disable_libs=static
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
+# ### BEGIN LIBTOOL TAG CONFIG: CXX
+
+# Libtool was configured on host splash:
+
+# Shell to use when invoking shell scripts.
+SHELL="/bin/sh"
+
+# Whether or not to build shared libraries.
+build_libtool_libs=yes
+
+# Whether or not to build static libraries.
+build_old_libs=yes
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=no
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=yes
+
+# Whether or not to optimize for fast installation.
+fast_install=needless
+
+# The host system.
+host_alias=
+host=i686-pc-cygwin
+host_os=cygwin
+
+# The build system.
+build_alias=
+build=i686-pc-cygwin
+build_os=cygwin
+
+# An echo program that does not interpret backslashes.
+echo="echo"
+
+# The archiver.
+AR="ar"
+AR_FLAGS="cru"
+
+# A C compiler.
+LTCC="gcc"
+
+# LTCC compiler flags.
+LTCFLAGS="-g -O2"
+
+# A language-specific compiler.
+CC="g++"
+
+# Is the compiler the GNU C compiler?
+with_gcc=yes
+
+# An ERE matcher.
+EGREP="grep -E"
+
+# The linker used to build libraries.
+LD="/usr/i686-pc-cygwin/bin/ld.exe"
+
+# Whether we need hard or soft links.
+LN_S="ln -s"
+
+# A BSD-compatible nm program.
+NM="/usr/bin/nm -B"
+
+# A symbol stripping program
+STRIP="strip"
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=file
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="dlltool"
+
+# Used on cygwin: object dumper.
+OBJDUMP="objdump"
+
+# Used on cygwin: assembler.
+AS="as"
+
+# The name of the directory that contains temporary libtool files.
+objdir=.libs
+
+# How to create reloadable object files.
+reload_flag=" -r"
+reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs"
+
+# How to pass a linker flag through the compiler.
+wl="-Wl,"
+
+# Object file suffix (normally "o").
+objext="o"
+
+# Old archive suffix (normally "a").
+libext="a"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='.dll'
+
+# Executable file suffix (normally "").
+exeext=""
+
+# Additional compiler flags for building library objects.
+pic_flag=" -DPIC"
+pic_mode=default
+
+# What is the maximum length of a command?
+max_cmd_len=8192
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o="yes"
+
+# Must we lock files when doing compilation?
+need_locks="no"
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=no
+
+# Do we need a version for libraries?
+need_version=no
+
+# Whether dlopen is supported.
+dlopen_support=unknown
+
+# Whether dlopen of programs is supported.
+dlopen_self=unknown
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=unknown
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag="-static"
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=" -fno-builtin"
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec="\${wl}--export-dynamic"
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive"
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=""
+
+# Library versioning type.
+version_type=windows
+
+# Format of library name prefix.
+libname_spec="lib\$name"
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec="\$libname.dll.a"
+
+# The coded name of the library, if different from the real name.
+soname_spec="\`echo \${libname} | sed -e s/^lib/cyg/\`\`echo \${release} | \$SED -e s/[.]/-/g\`\${versuffix}\${shared_ext}"
+
+# Commands used to build and install an old-style archive.
+RANLIB="ranlib"
+old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs\$old_deplibs~\$RANLIB \$oldlib"
+old_postinstall_cmds="chmod 644 \$oldlib~\$RANLIB \$oldlib"
+old_postuninstall_cmds=""
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=""
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=""
+
+# Commands used to build and install a shared archive.
+archive_cmds="\$CC -shared -nostdlib \$predep_objects \$libobjs \$deplibs \$postdep_objects \$compiler_flags -o \$output_objdir/\$soname \${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker \$lib"
+archive_expsym_cmds="if test \\\"x\\\`\$SED 1q \$export_symbols\\\`\\\" = xEXPORTS; then
+       cp \$export_symbols \$output_objdir/\$soname.def;
+      else
+       echo EXPORTS > \$output_objdir/\$soname.def;
+       cat \$export_symbols >> \$output_objdir/\$soname.def;
+      fi~
+      \$CC -shared -nostdlib \$output_objdir/\$soname.def \$predep_objects \$libobjs \$deplibs \$postdep_objects \$compiler_flags -o \$output_objdir/\$soname \${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker \$lib"
+postinstall_cmds="base_file=\\\`basename \\\${file}\\\`~
+      dlpath=\\\`\$SHELL 2>&1 -c '. \$dir/'\\\${base_file}'i;echo \\\$dlname'\\\`~
+      dldir=\$destdir/\\\`dirname \\\$dlpath\\\`~
+      test -d \\\$dldir || mkdir -p \\\$dldir~
+      \$install_prog \$dir/\$dlname \\\$dldir/\$dlname~
+      chmod a+x \\\$dldir/\$dlname"
+postuninstall_cmds="dldll=\\\`\$SHELL 2>&1 -c '. \$file; echo \\\$dlname'\\\`~
+      dlpath=\$dir/\\\$dldll~
+       \$rm \\\$dlpath"
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=""
+module_expsym_cmds=""
+
+# Commands to strip libraries.
+old_striplib="strip --strip-debug"
+striplib="strip --strip-unneeded"
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=""
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=""
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=""
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps="-lstdc++ -lgcc -lcygwin -luser32 -lkernel32 -ladvapi32 -lshell32 -lgcc"
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path="-L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -L/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../.."
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method="file_magic ^x86 archive import|^x86 DLL"
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd="func_win32_libid"
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag="unsupported"
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=""
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=""
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=""
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe="sed -n -e 's/^.*[  ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[       ][      ]*_\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 _\\2 \\2/p'"
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern int \\1;/p'"
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address="sed -n -e 's/^: \\([^ ]*\\) \$/  {\\\"\\1\\\", (lt_ptr) 0},/p' -e 's/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/  {\"\\2\", (lt_ptr) \\&\\2},/p'"
+
+# This is the shared library runtime path variable.
+runpath_var=LD_RUN_PATH
+
+# This is the shared library path variable.
+shlibpath_var=PATH
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=yes
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=immediate
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=no
+
+# Flag to hardcode $libdir into a binary during linking.
+# This must work even if $libdir does not exist.
+hardcode_libdir_flag_spec="-L\$libdir"
+
+# If ld is used when linking, flag to hardcode $libdir into
+# a binary during linking. This must work even if $libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=""
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=""
+
+# Set to yes if using DIR/libNAME during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=no
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=no
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=unsupported
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=no
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="PATH PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=unknown
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+
+# Fix the shell variable $srcfile for the compiler.
+fix_srcfile_path=""
+
+# Set to yes if exported symbols are required.
+always_export_symbols=no
+
+# The commands to list exported symbols.
+export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED -e '/^[BCDGRS] /s/.* \\\\([^ ]*\\\\)/\\\\1 DATA/;/^.* __nm__/s/^.* __nm__\\\\([^ ]*\\\\) [^ ]*/\\\\1 DATA/;/^I /d;/^[AITW] /s/.* //' | sort | uniq > \$export_symbols"
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=""
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=""
+
+# Symbols that must always be exported.
+include_expsyms=""
+
+# ### END LIBTOOL TAG CONFIG: CXX
+
+# ### BEGIN LIBTOOL TAG CONFIG: F77
+
+# Libtool was configured on host splash:
+
+# Shell to use when invoking shell scripts.
+SHELL="/bin/sh"
+
+# Whether or not to build shared libraries.
+build_libtool_libs=yes
+
+# Whether or not to build static libraries.
+build_old_libs=yes
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=no
+
+# Whether or not to disallow shared libs when runtime libs are static
+allow_libtool_libs_with_static_runtimes=yes
+
+# Whether or not to optimize for fast installation.
+fast_install=needless
+
+# The host system.
+host_alias=
+host=i686-pc-cygwin
+host_os=cygwin
+
+# The build system.
+build_alias=
+build=i686-pc-cygwin
+build_os=cygwin
+
+# An echo program that does not interpret backslashes.
+echo="echo"
+
+# The archiver.
+AR="ar"
+AR_FLAGS="cru"
+
+# A C compiler.
+LTCC="gcc"
+
+# LTCC compiler flags.
+LTCFLAGS="-g -O2"
+
+# A language-specific compiler.
+CC="g77"
+
+# Is the compiler the GNU C compiler?
+with_gcc=yes
+
+# An ERE matcher.
+EGREP="grep -E"
+
+# The linker used to build libraries.
+LD="/usr/i686-pc-cygwin/bin/ld.exe"
+
+# Whether we need hard or soft links.
+LN_S="ln -s"
+
+# A BSD-compatible nm program.
+NM="/usr/bin/nm -B"
+
+# A symbol stripping program
+STRIP="strip"
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=file
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="dlltool"
+
+# Used on cygwin: object dumper.
+OBJDUMP="objdump"
+
+# Used on cygwin: assembler.
+AS="as"
+
+# The name of the directory that contains temporary libtool files.
+objdir=.libs
+
+# How to create reloadable object files.
+reload_flag=" -r"
+reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs"
+
+# How to pass a linker flag through the compiler.
+wl="-Wl,"
+
+# Object file suffix (normally "o").
+objext="o"
+
+# Old archive suffix (normally "a").
+libext="a"
+
+# Shared library suffix (normally ".so").
+shrext_cmds='.dll'
+
+# Executable file suffix (normally "").
+exeext=""
+
+# Additional compiler flags for building library objects.
+pic_flag=""
+pic_mode=default
+
+# What is the maximum length of a command?
+max_cmd_len=8192
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o="yes"
+
+# Must we lock files when doing compilation?
+need_locks="no"
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=no
+
+# Do we need a version for libraries?
+need_version=no
+
+# Whether dlopen is supported.
+dlopen_support=unknown
+
+# Whether dlopen of programs is supported.
+dlopen_self=unknown
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=unknown
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag="-static"
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=""
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec="\${wl}--export-dynamic"
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive"
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=""
+
+# Library versioning type.
+version_type=windows
+
+# Format of library name prefix.
+libname_spec="lib\$name"
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec="\$libname.dll.a"
+
+# The coded name of the library, if different from the real name.
+soname_spec="\`echo \${libname} | sed -e s/^lib/cyg/\`\`echo \${release} | \$SED -e s/[.]/-/g\`\${versuffix}\${shared_ext}"
+
+# Commands used to build and install an old-style archive.
+RANLIB="ranlib"
+old_archive_cmds="\$AR \$AR_FLAGS \$oldlib\$oldobjs\$old_deplibs~\$RANLIB \$oldlib"
+old_postinstall_cmds="chmod 644 \$oldlib~\$RANLIB \$oldlib"
+old_postuninstall_cmds=""
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=""
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=""
+
+# Commands used to build and install a shared archive.
+archive_cmds="\$CC -shared \$libobjs \$deplibs \$compiler_flags -o \$output_objdir/\$soname \${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker \$lib"
+archive_expsym_cmds="if test \\\"x\\\`\$SED 1q \$export_symbols\\\`\\\" = xEXPORTS; then
+         cp \$export_symbols \$output_objdir/\$soname.def;
+       else
+         echo EXPORTS > \$output_objdir/\$soname.def;
+         cat \$export_symbols >> \$output_objdir/\$soname.def;
+       fi~
+       \$CC -shared \$output_objdir/\$soname.def \$libobjs \$deplibs \$compiler_flags -o \$output_objdir/\$soname \${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker \$lib"
+postinstall_cmds="base_file=\\\`basename \\\${file}\\\`~
+      dlpath=\\\`\$SHELL 2>&1 -c '. \$dir/'\\\${base_file}'i;echo \\\$dlname'\\\`~
+      dldir=\$destdir/\\\`dirname \\\$dlpath\\\`~
+      test -d \\\$dldir || mkdir -p \\\$dldir~
+      \$install_prog \$dir/\$dlname \\\$dldir/\$dlname~
+      chmod a+x \\\$dldir/\$dlname"
+postuninstall_cmds="dldll=\\\`\$SHELL 2>&1 -c '. \$file; echo \\\$dlname'\\\`~
+      dlpath=\$dir/\\\$dldll~
+       \$rm \\\$dlpath"
+
+# Commands used to build a loadable module (assumed same as above if empty)
+module_cmds=""
+module_expsym_cmds=""
+
+# Commands to strip libraries.
+old_striplib="strip --strip-debug"
+striplib="strip --strip-unneeded"
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predep_objects=""
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdep_objects=""
+
+# Dependencies to place before the objects being linked to create a
+# shared library.
+predeps=""
+
+# Dependencies to place after the objects being linked to create a
+# shared library.
+postdeps=""
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=""
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method="file_magic ^x86 archive import|^x86 DLL"
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd="func_win32_libid"
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag="unsupported"
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=""
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=""
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=""
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe="sed -n -e 's/^.*[  ]\\([ABCDGIRSTW][ABCDGIRSTW]*\\)[       ][      ]*_\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 _\\2 \\2/p'"
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern int \\1;/p'"
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address="sed -n -e 's/^: \\([^ ]*\\) \$/  {\\\"\\1\\\", (lt_ptr) 0},/p' -e 's/^[BCDEGRST] \\([^ ]*\\) \\([^ ]*\\)\$/  {\"\\2\", (lt_ptr) \\&\\2},/p'"
+
+# This is the shared library runtime path variable.
+runpath_var=LD_RUN_PATH
+
+# This is the shared library path variable.
+shlibpath_var=PATH
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=yes
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=immediate
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=no
+
+# Flag to hardcode $libdir into a binary during linking.
+# This must work even if $libdir does not exist.
+hardcode_libdir_flag_spec="-L\$libdir"
+
+# If ld is used when linking, flag to hardcode $libdir into
+# a binary during linking. This must work even if $libdir does
+# not exist.
+hardcode_libdir_flag_spec_ld=""
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=""
+
+# Set to yes if using DIR/libNAME during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=no
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=no
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=unsupported
+
+# Set to yes if building a shared library automatically hardcodes DIR into the library
+# and all subsequent libraries and executables linked against it.
+hardcode_automatic=no
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="PATH PATH LD_RUN_PATH GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=unknown
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+
+# Fix the shell variable $srcfile for the compiler.
+fix_srcfile_path=""
+
+# Set to yes if exported symbols are required.
+always_export_symbols=no
+
+# The commands to list exported symbols.
+export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | \$SED -e '/^[BCDGRS] /s/.* \\\\([^ ]*\\\\)/\\\\1 DATA/' | \$SED -e '/^[AITW] /s/.* //' | sort | uniq > \$export_symbols"
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=""
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+
+# Symbols that must always be exported.
+include_expsyms=""
+
+# ### END LIBTOOL TAG CONFIG: F77
+
diff --git a/utils/iaxclient/lib/portaudio/ltmain.sh b/utils/iaxclient/lib/portaudio/ltmain.sh
new file mode 100644 (file)
index 0000000..8f7a6ac
--- /dev/null
@@ -0,0 +1,6971 @@
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun configure.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 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 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.
+
+basename="s,^.*/,,g"
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+# define SED for historic ltconfig's generated by Libtool 1.3
+test -z "$SED" && SED=sed
+
+# The name of this program:
+progname=`echo "$progpath" | $SED $basename`
+modename="$progname"
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.5.22
+TIMESTAMP=" (1.1220.2.365 2005/12/18 22:14:06)"
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes.
+if test -n "${ZSH_VERSION+set}" ; then
+  setopt NO_GLOB_SUBST
+fi
+# Same for EGREP, and just to be sure, do LTCC as well
+if test "X$EGREP" = X ; then
+    EGREP=egrep
+fi
+if test "X$LTCC" = X ; then
+    LTCC=${CC-gcc}
+fi
+
+# Check that we have a working $echo.
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+  # Yippee, $echo works!
+  :
+else
+  # Restart under the correct shell, and then maybe $echo will work.
+  exec $SHELL "$progpath" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit $EXIT_SUCCESS
+fi
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  SP2NL='tr \040 \012'
+  NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  SP2NL='tr \100 \n'
+  NL2SP='tr \r\n \100\100'
+  ;;
+esac
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+# We save the old values to restore during execute mode.
+if test "${LC_ALL+set}" = set; then
+  save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
+fi
+if test "${LANG+set}" = set; then
+  save_LANG="$LANG"; LANG=C; export LANG
+fi
+
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS="  $lt_nl"
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+  $echo "$modename: not configured to build any kind of library" 1>&2
+  $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+  exit $EXIT_FAILURE
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+duplicate_deps=no
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+
+if test -z "$max_cmd_len"; then
+  i=0
+  testring="ABCD"
+  new_result=
+  
+  # If test is not a shell built-in, we'll probably end up computing a
+  # maximum length that is only half of the actual maximum length, but
+  # we can't tell.
+  while (test "X"`$SHELL $0 --fallback-echo "X$testring" 2>/dev/null` \
+             = "XX$testring") >/dev/null 2>&1 &&
+          new_result=`expr "X$testring" : ".*" 2>&1` &&
+          max_cmd_len="$new_result" &&
+          test "$i" != 17 # 1/2 MB should be enough
+  do
+    i=`expr $i + 1`
+    testring="$testring$testring"
+  done
+  testring=
+  # Add a significant safety factor because C++ compilers can tack on massive
+  # amounts of additional arguments before passing them to the linker.
+  # It appears as though 1/2 is a usable value.
+  max_cmd_len=`expr $max_cmd_len \/ 2`
+fi
+
+#####################################
+# Shell function definitions:
+# This seems to be the best place for them
+
+# func_mktempdir [string]
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible.  If
+# given, STRING is the basename for that directory.
+func_mktempdir ()
+{
+    my_template="${TMPDIR-/tmp}/${1-$progname}"
+
+    if test "$run" = ":"; then
+      # Return a directory name, but don't create it in dry-run mode
+      my_tmpdir="${my_template}-$$"
+    else
+
+      # If mktemp works, use that first and foremost
+      my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
+
+      if test ! -d "$my_tmpdir"; then
+       # Failing that, at least try and use $RANDOM to avoid a race
+       my_tmpdir="${my_template}-${RANDOM-0}$$"
+
+       save_mktempdir_umask=`umask`
+       umask 0077
+       $mkdir "$my_tmpdir"
+       umask $save_mktempdir_umask
+      fi
+
+      # If we're not in dry-run mode, bomb out on failure
+      test -d "$my_tmpdir" || {
+        $echo "cannot create temporary directory \`$my_tmpdir'" 1>&2
+       exit $EXIT_FAILURE
+      }
+    fi
+
+    $echo "X$my_tmpdir" | $Xsed
+}
+
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+func_win32_libid ()
+{
+  win32_libid_type="unknown"
+  win32_fileres=`file -L $1 2>/dev/null`
+  case $win32_fileres in
+  *ar\ archive\ import\ library*) # definitely import
+    win32_libid_type="x86 archive import"
+    ;;
+  *ar\ archive*) # could be an import, or static
+    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \
+      $EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
+      win32_nmres=`eval $NM -f posix -A $1 | \
+       $SED -n -e '1,100{/ I /{s,.*,import,;p;q;};}'`
+      case $win32_nmres in
+      import*)  win32_libid_type="x86 archive import";;
+      *)        win32_libid_type="x86 archive static";;
+      esac
+    fi
+    ;;
+  *DLL*)
+    win32_libid_type="x86 DLL"
+    ;;
+  *executable*) # but shell scripts are "executable" too...
+    case $win32_fileres in
+    *MS\ Windows\ PE\ Intel*)
+      win32_libid_type="x86 DLL"
+      ;;
+    esac
+    ;;
+  esac
+  $echo $win32_libid_type
+}
+
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+    if test -n "$available_tags" && test -z "$tagname"; then
+      CC_quoted=
+      for arg in $CC; do
+       case $arg in
+         *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+         arg="\"$arg\""
+         ;;
+       esac
+       CC_quoted="$CC_quoted $arg"
+      done
+      case $@ in
+      # Blanks in the command may have been stripped by the calling shell,
+      # but not from the CC environment variable when configure was run.
+      " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*) ;;
+      # Blanks at the start of $base_compile will cause this to fail
+      # if we don't check for them as well.
+      *)
+       for z in $available_tags; do
+         if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+           # Evaluate the configuration.
+           eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+           CC_quoted=
+           for arg in $CC; do
+           # Double-quote args containing other shell metacharacters.
+           case $arg in
+             *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \     ]*|*]*|"")
+             arg="\"$arg\""
+             ;;
+           esac
+           CC_quoted="$CC_quoted $arg"
+         done
+           # user sometimes does CC=<HOST>-gcc so we need to match that to 'gcc'
+           trimedcc=`echo ${CC} | $SED -e "s/${host}-//g"`
+           # and sometimes libtool has CC=<HOST>-gcc but user does CC=gcc
+           extendcc=${host}-${CC}
+           # and sometimes libtool has CC=<OLDHOST>-gcc but user has CC=<NEWHOST>-gcc  
+           # (Gentoo-specific hack because we always export $CHOST)
+           mungedcc=${CHOST-${host}}-${trimedcc}
+           case "$@ " in
+             "cc "* | " cc "* | "${host}-cc "* | " ${host}-cc "*|\
+             "gcc "* | " gcc "* | "${host}-gcc "* | " ${host}-gcc "*)
+             tagname=CC
+             break ;;
+             "$trimedcc "* | " $trimedcc "* | "`$echo $trimedcc` "* | " `$echo $trimedcc` "*|\
+             "$extendcc "* | " $extendcc "* | "`$echo $extendcc` "* | " `$echo $extendcc` "*|\
+             "$mungedcc "* | " $mungedcc "* | "`$echo $mungedcc` "* | " `$echo $mungedcc` "*|\
+             " $CC "* | "$CC "* | " `$echo $CC` "* | "`$echo $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$echo $CC_quoted` "* | "`$echo $CC_quoted` "*)
+             # The compiler in the base compile command matches
+             # the one in the tagged configuration.
+             # Assume this is the tagged configuration we want.
+             tagname=$z
+             break
+             ;;
+           esac
+         fi
+       done
+       # If $tagname still isn't set, then no tagged configuration
+       # was found and let the user know that the "--tag" command
+       # line option must be used.
+       if test -z "$tagname"; then
+         $echo "$modename: unable to infer tagged configuration"
+         $echo "$modename: specify a tag with \`--tag'" 1>&2
+         exit $EXIT_FAILURE
+#        else
+#          $echo "$modename: using $tagname tagged configuration"
+       fi
+       ;;
+      esac
+    fi
+}
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+    f_ex_an_ar_dir="$1"; shift
+    f_ex_an_ar_oldlib="$1"
+
+    $show "(cd $f_ex_an_ar_dir && $AR x $f_ex_an_ar_oldlib)"
+    $run eval "(cd \$f_ex_an_ar_dir && $AR x \$f_ex_an_ar_oldlib)" || exit $?
+    if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+     :
+    else
+      $echo "$modename: ERROR: object name conflicts: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" 1>&2
+      exit $EXIT_FAILURE
+    fi
+}
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+    my_gentop="$1"; shift
+    my_oldlibs=${1+"$@"}
+    my_oldobjs=""
+    my_xlib=""
+    my_xabs=""
+    my_xdir=""
+    my_status=""
+
+    $show "${rm}r $my_gentop"
+    $run ${rm}r "$my_gentop"
+    $show "$mkdir $my_gentop"
+    $run $mkdir "$my_gentop"
+    my_status=$?
+    if test "$my_status" -ne 0 && test ! -d "$my_gentop"; then
+      exit $my_status
+    fi
+
+    for my_xlib in $my_oldlibs; do
+      # Extract the objects.
+      case $my_xlib in
+       [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+       *) my_xabs=`pwd`"/$my_xlib" ;;
+      esac
+      my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'`
+      my_xdir="$my_gentop/$my_xlib"
+
+      $show "${rm}r $my_xdir"
+      $run ${rm}r "$my_xdir"
+      $show "$mkdir $my_xdir"
+      $run $mkdir "$my_xdir"
+      exit_status=$?
+      if test "$exit_status" -ne 0 && test ! -d "$my_xdir"; then
+       exit $exit_status
+      fi
+      case $host in
+      *-darwin*)
+       $show "Extracting $my_xabs"
+       # Do not bother doing anything if just a dry run
+       if test -z "$run"; then
+         darwin_orig_dir=`pwd`
+         cd $my_xdir || exit $?
+         darwin_archive=$my_xabs
+         darwin_curdir=`pwd`
+         darwin_base_archive=`$echo "X$darwin_archive" | $Xsed -e 's%^.*/%%'`
+         darwin_arches=`lipo -info "$darwin_archive" 2>/dev/null | $EGREP Architectures 2>/dev/null`
+         if test -n "$darwin_arches"; then 
+           darwin_arches=`echo "$darwin_arches" | $SED -e 's/.*are://'`
+           darwin_arch=
+           $show "$darwin_base_archive has multiple architectures $darwin_arches"
+           for darwin_arch in  $darwin_arches ; do
+             mkdir -p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+             lipo -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+             cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+             func_extract_an_archive "`pwd`" "${darwin_base_archive}"
+             cd "$darwin_curdir"
+             $rm "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
+           done # $darwin_arches
+      ## Okay now we have a bunch of thin objects, gotta fatten them up :)
+           darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print| xargs basename | sort -u | $NL2SP`
+           darwin_file=
+           darwin_files=
+           for darwin_file in $darwin_filelist; do
+             darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP`
+             lipo -create -output "$darwin_file" $darwin_files
+           done # $darwin_filelist
+           ${rm}r unfat-$$
+           cd "$darwin_orig_dir"
+         else
+           cd "$darwin_orig_dir"
+           func_extract_an_archive "$my_xdir" "$my_xabs"
+         fi # $darwin_arches
+       fi # $run
+       ;;
+      *)
+        func_extract_an_archive "$my_xdir" "$my_xabs"
+        ;;
+      esac
+      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
+    done
+    func_extract_archives_result="$my_oldobjs"
+}
+# End of Shell function definitions
+#####################################
+
+# Darwin sucks
+eval std_shrext=\"$shrext_cmds\"
+
+disable_libs=no
+
+# Parse our command line options once, thoroughly.
+while test "$#" -gt 0
+do
+  arg="$1"
+  shift
+
+  case $arg in
+  -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$prev"; then
+    case $prev in
+    execute_dlfiles)
+      execute_dlfiles="$execute_dlfiles $arg"
+      ;;
+    tag)
+      tagname="$arg"
+      preserve_args="${preserve_args}=$arg"
+
+      # Check whether tagname contains only valid characters
+      case $tagname in
+      *[!-_A-Za-z0-9,/]*)
+       $echo "$progname: invalid tag name: $tagname" 1>&2
+       exit $EXIT_FAILURE
+       ;;
+      esac
+
+      case $tagname in
+      CC)
+       # Don't test for the "default" C tag, as we know, it's there, but
+       # not specially marked.
+       ;;
+      *)
+       if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "$progpath" > /dev/null; then
+         taglist="$taglist $tagname"
+         # Evaluate the configuration.
+         eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$tagname'$/,/^# ### END LIBTOOL TAG CONFIG: '$tagname'$/p' < $progpath`"
+       else
+         $echo "$progname: ignoring unknown tag $tagname" 1>&2
+       fi
+       ;;
+      esac
+      ;;
+    *)
+      eval "$prev=\$arg"
+      ;;
+    esac
+
+    prev=
+    prevopt=
+    continue
+  fi
+
+  # Have we seen a non-optional argument yet?
+  case $arg in
+  --help)
+    show_help=yes
+    ;;
+
+  --version)
+    $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
+    $echo
+    $echo "Copyright (C) 2005  Free Software Foundation, Inc."
+    $echo "This is free software; see the source for copying conditions.  There is NO"
+    $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+    exit $?
+    ;;
+
+  --config)
+    ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $progpath
+    # Now print the configurations for the tags.
+    for tagname in $taglist; do
+      ${SED} -n -e "/^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$/,/^# ### END LIBTOOL TAG CONFIG: $tagname$/p" < "$progpath"
+    done
+    exit $?
+    ;;
+
+  --debug)
+    $echo "$progname: enabling shell trace mode"
+    set -x
+    preserve_args="$preserve_args $arg"
+    ;;
+
+  --dry-run | -n)
+    run=:
+    ;;
+
+  --features)
+    $echo "host: $host"
+    if test "$build_libtool_libs" = yes; then
+      $echo "enable shared libraries"
+    else
+      $echo "disable shared libraries"
+    fi
+    if test "$build_old_libs" = yes; then
+      $echo "enable static libraries"
+    else
+      $echo "disable static libraries"
+    fi
+    exit $?
+    ;;
+
+  --finish) mode="finish" ;;
+
+  --mode) prevopt="--mode" prev=mode ;;
+  --mode=*) mode="$optarg" ;;
+
+  --preserve-dup-deps) duplicate_deps="yes" ;;
+
+  --quiet | --silent)
+    show=:
+    preserve_args="$preserve_args $arg"
+    ;;
+
+  --tag)
+    prevopt="--tag"
+    prev=tag
+    preserve_args="$preserve_args --tag"
+    ;;
+  --tag=*)
+    set tag "$optarg" ${1+"$@"}
+    shift
+    prev=tag
+    preserve_args="$preserve_args --tag"
+    ;;
+
+  -dlopen)
+    prevopt="-dlopen"
+    prev=execute_dlfiles
+    ;;
+
+  -*)
+    $echo "$modename: unrecognized option \`$arg'" 1>&2
+    $echo "$help" 1>&2
+    exit $EXIT_FAILURE
+    ;;
+
+  *)
+    nonopt="$arg"
+    break
+    ;;
+  esac
+done
+
+if test -n "$prevopt"; then
+  $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+  $echo "$help" 1>&2
+  exit $EXIT_FAILURE
+fi
+
+case $disable_libs in
+no) 
+  ;;
+shared)
+  build_libtool_libs=no
+  build_old_libs=yes
+  ;;
+static)
+  build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+  ;;
+esac
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end.  This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+if test -z "$show_help"; then
+
+  # Infer the operation mode.
+  if test -z "$mode"; then
+    $echo "*** Warning: inferring the mode of operation is deprecated." 1>&2
+    $echo "*** Future versions of Libtool will require --mode=MODE be specified." 1>&2
+    case $nonopt in
+    *cc | cc* | *++ | gcc* | *-gcc* | g++* | xlc*)
+      mode=link
+      for arg
+      do
+       case $arg in
+       -c)
+          mode=compile
+          break
+          ;;
+       esac
+      done
+      ;;
+    *db | *dbx | *strace | *truss)
+      mode=execute
+      ;;
+    *install*|cp|mv)
+      mode=install
+      ;;
+    *rm)
+      mode=uninstall
+      ;;
+    *)
+      # If we have no mode, but dlfiles were specified, then do execute mode.
+      test -n "$execute_dlfiles" && mode=execute
+
+      # Just use the default operation mode.
+      if test -z "$mode"; then
+       if test -n "$nonopt"; then
+         $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+       else
+         $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+       fi
+      fi
+      ;;
+    esac
+  fi
+
+  # Only execute mode is allowed to have -dlopen flags.
+  if test -n "$execute_dlfiles" && test "$mode" != execute; then
+    $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+    $echo "$help" 1>&2
+    exit $EXIT_FAILURE
+  fi
+
+  # Change the help message to a mode-specific one.
+  generic_help="$help"
+  help="Try \`$modename --help --mode=$mode' for more information."
+
+  # These modes are in order of execution frequency so that they run quickly.
+  case $mode in
+  # libtool compile mode
+  compile)
+    modename="$modename: compile"
+    # Get the compilation command and the source file.
+    base_compile=
+    srcfile="$nonopt"  #  always keep a non-empty value in "srcfile"
+    suppress_opt=yes
+    suppress_output=
+    arg_mode=normal
+    libobj=
+    later=
+
+    for arg
+    do
+      case $arg_mode in
+      arg  )
+       # do not "continue".  Instead, add this to base_compile
+       lastarg="$arg"
+       arg_mode=normal
+       ;;
+
+      target )
+       libobj="$arg"
+       arg_mode=normal
+       continue
+       ;;
+
+      normal )
+       # Accept any command-line options.
+       case $arg in
+       -o)
+         if test -n "$libobj" ; then
+           $echo "$modename: you cannot specify \`-o' more than once" 1>&2
+           exit $EXIT_FAILURE
+         fi
+         arg_mode=target
+         continue
+         ;;
+
+       -static | -prefer-pic | -prefer-non-pic)
+         later="$later $arg"
+         continue
+         ;;
+
+       -no-suppress)
+         suppress_opt=no
+         continue
+         ;;
+
+       -Xcompiler)
+         arg_mode=arg  #  the next one goes into the "base_compile" arg list
+         continue      #  The current "srcfile" will either be retained or
+         ;;            #  replaced later.  I would guess that would be a bug.
+
+       -Wc,*)
+         args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"`
+         lastarg=
+         save_ifs="$IFS"; IFS=','
+         for arg in $args; do
+           IFS="$save_ifs"
+
+           # Double-quote args containing other shell metacharacters.
+           # Many Bourne shells cannot handle close brackets correctly
+           # in scan sets, so we specify it separately.
+           case $arg in
+             *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \     ]*|*]*|"")
+             arg="\"$arg\""
+             ;;
+           esac
+           lastarg="$lastarg $arg"
+         done
+         IFS="$save_ifs"
+         lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"`
+
+         # Add the arguments to base_compile.
+         base_compile="$base_compile $lastarg"
+         continue
+         ;;
+
+       * )
+         # Accept the current argument as the source file.
+         # The previous "srcfile" becomes the current argument.
+         #
+         lastarg="$srcfile"
+         srcfile="$arg"
+         ;;
+       esac  #  case $arg
+       ;;
+      esac    #  case $arg_mode
+
+      # Aesthetically quote the previous argument.
+      lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+      case $lastarg in
+      # Double-quote args containing other shell metacharacters.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, and some SunOS ksh mistreat backslash-escaping
+      # in scan sets (worked around with variable expansion),
+      # and furthermore cannot handle '|' '&' '(' ')' in scan sets 
+      # at all, so we specify them separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
+       lastarg="\"$lastarg\""
+       ;;
+      esac
+
+      base_compile="$base_compile $lastarg"
+    done # for arg
+
+    case $arg_mode in
+    arg)
+      $echo "$modename: you must specify an argument for -Xcompile"
+      exit $EXIT_FAILURE
+      ;;
+    target)
+      $echo "$modename: you must specify a target with \`-o'" 1>&2
+      exit $EXIT_FAILURE
+      ;;
+    *)
+      # Get the name of the library object.
+      [ -z "$libobj" ] && libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+      ;;
+    esac
+
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    xform='[cCFSifmso]'
+    case $libobj in
+    *.ada) xform=ada ;;
+    *.adb) xform=adb ;;
+    *.ads) xform=ads ;;
+    *.asm) xform=asm ;;
+    *.c++) xform=c++ ;;
+    *.cc) xform=cc ;;
+    *.ii) xform=ii ;;
+    *.class) xform=class ;;
+    *.cpp) xform=cpp ;;
+    *.cxx) xform=cxx ;;
+    *.f90) xform=f90 ;;
+    *.for) xform=for ;;
+    *.java) xform=java ;;
+    esac
+
+    libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+    case $libobj in
+    *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
+    *)
+      $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
+      exit $EXIT_FAILURE
+      ;;
+    esac
+
+    func_infer_tag $base_compile
+
+    for arg in $later; do
+      case $arg in
+      -static)
+       build_old_libs=yes
+       continue
+       ;;
+
+      -prefer-pic)
+       pic_mode=yes
+       continue
+       ;;
+
+      -prefer-non-pic)
+       pic_mode=no
+       continue
+       ;;
+      esac
+    done
+
+    qlibobj=`$echo "X$libobj" | $Xsed -e "$sed_quote_subst"`
+    case $qlibobj in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
+       qlibobj="\"$qlibobj\"" ;;
+    esac
+    test "X$libobj" != "X$qlibobj" \
+       && $echo "X$libobj" | grep '[]~#^*{};<>?"'"'"'  &()|`$[]' \
+       && $echo "$modename: libobj name \`$libobj' may not contain shell special characters."
+    objname=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
+    xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+    if test "X$xdir" = "X$obj"; then
+      xdir=
+    else
+      xdir=$xdir/
+    fi
+    lobj=${xdir}$objdir/$objname
+
+    if test -z "$base_compile"; then
+      $echo "$modename: you must specify a compilation command" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      removelist="$obj $lobj $libobj ${libobj}T"
+    else
+      removelist="$lobj $libobj ${libobj}T"
+    fi
+
+    $run $rm $removelist
+    trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15
+
+    # On Cygwin there's no "real" PIC flag so we must build both object types
+    case $host_os in
+    cygwin* | mingw* | pw32* | os2*)
+      pic_mode=default
+      ;;
+    esac
+    if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+      # non-PIC code in shared libraries is not supported
+      pic_mode=default
+    fi
+
+    # Calculate the filename of the output object if compiler does
+    # not support -o with -c
+    if test "$compiler_c_o" = no; then
+      output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
+      lockfile="$output_obj.lock"
+      removelist="$removelist $output_obj $lockfile"
+      trap "$run $rm $removelist; exit $EXIT_FAILURE" 1 2 15
+    else
+      output_obj=
+      need_locks=no
+      lockfile=
+    fi
+
+    # Lock this critical section if it is needed
+    # We use this script file to make the link, it avoids creating a new file
+    if test "$need_locks" = yes; then
+      until $run ln "$srcfile" "$lockfile" 2>/dev/null; do
+       $show "Waiting for $lockfile to be removed"
+       sleep 2
+      done
+    elif test "$need_locks" = warn; then
+      if test -f "$lockfile"; then
+       $echo "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+       $run $rm $removelist
+       exit $EXIT_FAILURE
+      fi
+      $echo "$srcfile" > "$lockfile"
+    fi
+
+    if test -n "$fix_srcfile_path"; then
+      eval srcfile=\"$fix_srcfile_path\"
+    fi
+    qsrcfile=`$echo "X$srcfile" | $Xsed -e "$sed_quote_subst"`
+    case $qsrcfile in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
+      qsrcfile="\"$qsrcfile\"" ;;
+    esac
+
+    $run $rm "$libobj" "${libobj}T"
+
+    # Create a libtool object file (analogous to a ".la" file),
+    # but don't create it if we're doing a dry run.
+    test -z "$run" && cat > ${libobj}T <<EOF
+# $libobj - a libtool object file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+EOF
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      if test "$pic_mode" != no; then
+       command="$base_compile $qsrcfile $pic_flag"
+      else
+       # Don't build PIC code
+       command="$base_compile $qsrcfile"
+      fi
+
+      if test ! -d "${xdir}$objdir"; then
+       $show "$mkdir ${xdir}$objdir"
+       $run $mkdir ${xdir}$objdir
+       exit_status=$?
+       if test "$exit_status" -ne 0 && test ! -d "${xdir}$objdir"; then
+         exit $exit_status
+       fi
+      fi
+
+      if test -z "$output_obj"; then
+       # Place PIC objects in $objdir
+       command="$command -o $lobj"
+      fi
+
+      $run $rm "$lobj" "$output_obj"
+
+      $show "$command"
+      if $run eval "$command"; then :
+      else
+       test -n "$output_obj" && $run $rm $removelist
+       exit $EXIT_FAILURE
+      fi
+
+      if test "$need_locks" = warn &&
+        test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+       $echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+       $run $rm $removelist
+       exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed, then go on to compile the next one
+      if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+       $show "$mv $output_obj $lobj"
+       if $run $mv $output_obj $lobj; then :
+       else
+         error=$?
+         $run $rm $removelist
+         exit $error
+       fi
+      fi
+
+      # Append the name of the PIC object to the libtool object file.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+pic_object='$objdir/$objname'
+
+EOF
+
+      # Allow error messages only from the first compilation.
+      if test "$suppress_opt" = yes; then
+        suppress_output=' >/dev/null 2>&1'
+      fi
+    else
+      # No PIC object so indicate it doesn't exist in the libtool
+      # object file.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+pic_object=none
+
+EOF
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      if test "$pic_mode" != yes; then
+       # Don't build PIC code
+       command="$base_compile $qsrcfile"
+      else
+       command="$base_compile $qsrcfile $pic_flag"
+      fi
+      if test "$compiler_c_o" = yes; then
+       command="$command -o $obj"
+      fi
+
+      # Suppress compiler output if we already did a PIC compilation.
+      command="$command$suppress_output"
+      $run $rm "$obj" "$output_obj"
+      $show "$command"
+      if $run eval "$command"; then :
+      else
+       $run $rm $removelist
+       exit $EXIT_FAILURE
+      fi
+
+      if test "$need_locks" = warn &&
+        test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+       $echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+       $run $rm $removelist
+       exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed
+      if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+       $show "$mv $output_obj $obj"
+       if $run $mv $output_obj $obj; then :
+       else
+         error=$?
+         $run $rm $removelist
+         exit $error
+       fi
+      fi
+
+      # Append the name of the non-PIC object the libtool object file.
+      # Only append if the libtool object file exists.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+# Name of the non-PIC object.
+non_pic_object='$objname'
+
+EOF
+    else
+      # Append the name of the non-PIC object the libtool object file.
+      # Only append if the libtool object file exists.
+      test -z "$run" && cat >> ${libobj}T <<EOF
+# Name of the non-PIC object.
+non_pic_object=none
+
+EOF
+    fi
+
+    $run $mv "${libobj}T" "${libobj}"
+
+    # Unlock the critical section if it was locked
+    if test "$need_locks" != no; then
+      $run $rm "$lockfile"
+    fi
+
+    exit $EXIT_SUCCESS
+    ;;
+
+  # libtool link mode
+  link | relink)
+    modename="$modename: link"
+    case $host in
+    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+      # It is impossible to link a dll without this setting, and
+      # we shouldn't force the makefile maintainer to figure out
+      # which system we are compiling for in order to pass an extra
+      # flag for every libtool invocation.
+      # allow_undefined=no
+
+      # FIXME: Unfortunately, there are problems with the above when trying
+      # to make a dll which has undefined symbols, in which case not
+      # even a static library is built.  For now, we need to specify
+      # -no-undefined on the libtool link line when we can be certain
+      # that all symbols are satisfied, otherwise we get a static library.
+      allow_undefined=yes
+      ;;
+    *)
+      allow_undefined=yes
+      ;;
+    esac
+    libtool_args="$nonopt"
+    base_compile="$nonopt $@"
+    compile_command="$nonopt"
+    finalize_command="$nonopt"
+
+    compile_rpath=
+    finalize_rpath=
+    compile_shlibpath=
+    finalize_shlibpath=
+    convenience=
+    old_convenience=
+    deplibs=
+    old_deplibs=
+    compiler_flags=
+    linker_flags=
+    dllsearchpath=
+    lib_search_path=`pwd`
+    inst_prefix_dir=
+
+    avoid_version=no
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    ltlibs=
+    module=no
+    no_install=no
+    objs=
+    non_pic_objects=
+    notinst_path= # paths that contain not-installed libtool libraries
+    precious_files_regex=
+    prefer_static_libs=no
+    preload=no
+    prev=
+    prevarg=
+    release=
+    rpath=
+    xrpath=
+    perm_rpath=
+    temp_rpath=
+    thread_safe=no
+    vinfo=
+    vinfo_number=no
+
+    func_infer_tag $base_compile
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case $arg in
+      -all-static | -static)
+       if test "X$arg" = "X-all-static"; then
+         if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+           $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+         fi
+         if test -n "$link_static_flag"; then
+           dlopen_self=$dlopen_self_static
+         fi
+         prefer_static_libs=yes
+       else
+         if test -z "$pic_flag" && test -n "$link_static_flag"; then
+           dlopen_self=$dlopen_self_static
+         fi
+         prefer_static_libs=built
+       fi
+       build_libtool_libs=no
+       build_old_libs=yes
+       break
+       ;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    while test "$#" -gt 0; do
+      arg="$1"
+      shift
+      case $arg in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
+       qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test
+       ;;
+      *) qarg=$arg ;;
+      esac
+      libtool_args="$libtool_args $qarg"
+
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+       case $prev in
+       output)
+         compile_command="$compile_command @OUTPUT@"
+         finalize_command="$finalize_command @OUTPUT@"
+         ;;
+       esac
+
+       case $prev in
+       dlfiles|dlprefiles)
+         if test "$preload" = no; then
+           # Add the symbol object into the linking commands.
+           compile_command="$compile_command @SYMFILE@"
+           finalize_command="$finalize_command @SYMFILE@"
+           preload=yes
+         fi
+         case $arg in
+         *.la | *.lo) ;;  # We handle these cases below.
+         force)
+           if test "$dlself" = no; then
+             dlself=needless
+             export_dynamic=yes
+           fi
+           prev=
+           continue
+           ;;
+         self)
+           if test "$prev" = dlprefiles; then
+             dlself=yes
+           elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+             dlself=yes
+           else
+             dlself=needless
+             export_dynamic=yes
+           fi
+           prev=
+           continue
+           ;;
+         *)
+           if test "$prev" = dlfiles; then
+             dlfiles="$dlfiles $arg"
+           else
+             dlprefiles="$dlprefiles $arg"
+           fi
+           prev=
+           continue
+           ;;
+         esac
+         ;;
+       expsyms)
+         export_symbols="$arg"
+         if test ! -f "$arg"; then
+           $echo "$modename: symbol file \`$arg' does not exist"
+           exit $EXIT_FAILURE
+         fi
+         prev=
+         continue
+         ;;
+       expsyms_regex)
+         export_symbols_regex="$arg"
+         prev=
+         continue
+         ;;
+       inst_prefix)
+         inst_prefix_dir="$arg"
+         prev=
+         continue
+         ;;
+       precious_regex)
+         precious_files_regex="$arg"
+         prev=
+         continue
+         ;;
+       release)
+         release="-$arg"
+         prev=
+         continue
+         ;;
+       objectlist)
+         if test -f "$arg"; then
+           save_arg=$arg
+           moreargs=
+           for fil in `cat $save_arg`
+           do
+#            moreargs="$moreargs $fil"
+             arg=$fil
+             # A libtool-controlled object.
+
+             # Check to see that this really is a libtool object.
+             if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+               pic_object=
+               non_pic_object=
+
+               # Read the .lo file
+               # If there is no directory component, then add one.
+               case $arg in
+               */* | *\\*) . $arg ;;
+               *) . ./$arg ;;
+               esac
+
+               if test -z "$pic_object" || \
+                  test -z "$non_pic_object" ||
+                  test "$pic_object" = none && \
+                  test "$non_pic_object" = none; then
+                 $echo "$modename: cannot find name of object for \`$arg'" 1>&2
+                 exit $EXIT_FAILURE
+               fi
+
+               # Extract subdirectory from the argument.
+               xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+               if test "X$xdir" = "X$arg"; then
+                 xdir=
+               else
+                 xdir="$xdir/"
+               fi
+
+               if test "$pic_object" != none; then
+                 # Prepend the subdirectory the object is found in.
+                 pic_object="$xdir$pic_object"
+
+                 if test "$prev" = dlfiles; then
+                   if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+                     dlfiles="$dlfiles $pic_object"
+                     prev=
+                     continue
+                   else
+                     # If libtool objects are unsupported, then we need to preload.
+                     prev=dlprefiles
+                   fi
+                 fi
+
+                 # CHECK ME:  I think I busted this.  -Ossama
+                 if test "$prev" = dlprefiles; then
+                   # Preload the old-style object.
+                   dlprefiles="$dlprefiles $pic_object"
+                   prev=
+                 fi
+
+                 # A PIC object.
+                 libobjs="$libobjs $pic_object"
+                 arg="$pic_object"
+               fi
+
+               # Non-PIC object.
+               if test "$non_pic_object" != none; then
+                 # Prepend the subdirectory the object is found in.
+                 non_pic_object="$xdir$non_pic_object"
+
+                 # A standard non-PIC object
+                 non_pic_objects="$non_pic_objects $non_pic_object"
+                 if test -z "$pic_object" || test "$pic_object" = none ; then
+                   arg="$non_pic_object"
+                 fi
+               else
+                 # If the PIC object exists, use it instead.
+                 # $xdir was prepended to $pic_object above.
+                 non_pic_object="$pic_object"
+                 non_pic_objects="$non_pic_objects $non_pic_object"
+               fi
+             else
+               # Only an error if not doing a dry-run.
+               if test -z "$run"; then
+                 $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
+                 exit $EXIT_FAILURE
+               else
+                 # Dry-run case.
+
+                 # Extract subdirectory from the argument.
+                 xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+                 if test "X$xdir" = "X$arg"; then
+                   xdir=
+                 else
+                   xdir="$xdir/"
+                 fi
+
+                 pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
+                 non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
+                 libobjs="$libobjs $pic_object"
+                 non_pic_objects="$non_pic_objects $non_pic_object"
+               fi
+             fi
+           done
+         else
+           $echo "$modename: link input file \`$save_arg' does not exist"
+           exit $EXIT_FAILURE
+         fi
+         arg=$save_arg
+         prev=
+         continue
+         ;;
+       rpath | xrpath)
+         # We need an absolute path.
+         case $arg in
+         [\\/]* | [A-Za-z]:[\\/]*) ;;
+         *)
+           $echo "$modename: only absolute run-paths are allowed" 1>&2
+           exit $EXIT_FAILURE
+           ;;
+         esac
+         if test "$prev" = rpath; then
+           case "$rpath " in
+           *" $arg "*) ;;
+           *) rpath="$rpath $arg" ;;
+           esac
+         else
+           case "$xrpath " in
+           *" $arg "*) ;;
+           *) xrpath="$xrpath $arg" ;;
+           esac
+         fi
+         prev=
+         continue
+         ;;
+       xcompiler)
+         compiler_flags="$compiler_flags $qarg"
+         prev=
+         compile_command="$compile_command $qarg"
+         finalize_command="$finalize_command $qarg"
+         continue
+         ;;
+       xlinker)
+         linker_flags="$linker_flags $qarg"
+         compiler_flags="$compiler_flags $wl$qarg"
+         prev=
+         compile_command="$compile_command $wl$qarg"
+         finalize_command="$finalize_command $wl$qarg"
+         continue
+         ;;
+       xcclinker)
+         linker_flags="$linker_flags $qarg"
+         compiler_flags="$compiler_flags $qarg"
+         prev=
+         compile_command="$compile_command $qarg"
+         finalize_command="$finalize_command $qarg"
+         continue
+         ;;
+       shrext)
+         shrext_cmds="$arg"
+         prev=
+         continue
+         ;;
+       darwin_framework|darwin_framework_skip)
+         test "$prev" = "darwin_framework" && compiler_flags="$compiler_flags $arg"
+         compile_command="$compile_command $arg"
+         finalize_command="$finalize_command $arg"
+         prev=
+         continue
+         ;;
+       *)
+         eval "$prev=\"\$arg\""
+         prev=
+         continue
+         ;;
+       esac
+      fi # test -n "$prev"
+
+      prevarg="$arg"
+
+      case $arg in
+      -all-static)
+       if test -n "$link_static_flag"; then
+         compile_command="$compile_command $link_static_flag"
+         finalize_command="$finalize_command $link_static_flag"
+       fi
+       continue
+       ;;
+
+      -allow-undefined)
+       # FIXME: remove this flag sometime in the future.
+       $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+       continue
+       ;;
+
+      -avoid-version)
+       avoid_version=yes
+       continue
+       ;;
+
+      -dlopen)
+       prev=dlfiles
+       continue
+       ;;
+
+      -dlpreopen)
+       prev=dlprefiles
+       continue
+       ;;
+
+      -export-dynamic)
+       export_dynamic=yes
+       continue
+       ;;
+
+      -export-symbols | -export-symbols-regex)
+       if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+         $echo "$modename: more than one -exported-symbols argument is not allowed"
+         exit $EXIT_FAILURE
+       fi
+       if test "X$arg" = "X-export-symbols"; then
+         prev=expsyms
+       else
+         prev=expsyms_regex
+       fi
+       continue
+       ;;
+
+      -framework|-arch|-isysroot)
+       case " $CC " in
+         *" ${arg} ${1} "* | *" ${arg} ${1} "*) 
+               prev=darwin_framework_skip ;;
+         *) compiler_flags="$compiler_flags $arg"
+            prev=darwin_framework ;;
+       esac
+       compile_command="$compile_command $arg"
+       finalize_command="$finalize_command $arg"
+       continue
+       ;;
+
+      -inst-prefix-dir)
+       prev=inst_prefix
+       continue
+       ;;
+
+      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+      # so, if we see these flags be careful not to treat them like -L
+      -L[A-Z][A-Z]*:*)
+       case $with_gcc/$host in
+       no/*-*-irix* | /*-*-irix*)
+         compile_command="$compile_command $arg"
+         finalize_command="$finalize_command $arg"
+         ;;
+       esac
+       continue
+       ;;
+
+      -L*)
+       dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
+       # We need an absolute path.
+       case $dir in
+       [\\/]* | [A-Za-z]:[\\/]*) ;;
+       *)
+         absdir=`cd "$dir" && pwd`
+         if test -z "$absdir"; then
+           $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
+           absdir="$dir"
+           notinst_path="$notinst_path $dir"
+         fi
+         dir="$absdir"
+         ;;
+       esac
+       case "$deplibs " in
+       *" -L$dir "*) ;;
+       *)
+         deplibs="$deplibs -L$dir"
+         lib_search_path="$lib_search_path $dir"
+         ;;
+       esac
+       case $host in
+       *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+         testbindir=`$echo "X$dir" | $Xsed -e 's*/lib$*/bin*'`
+         case :$dllsearchpath: in
+         *":$dir:"*) ;;
+         *) dllsearchpath="$dllsearchpath:$dir";;
+         esac
+         case :$dllsearchpath: in
+         *":$testbindir:"*) ;;
+         *) dllsearchpath="$dllsearchpath:$testbindir";;
+         esac
+         ;;
+       esac
+       continue
+       ;;
+
+      -l*)
+       if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+         case $host in
+         *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos*)
+           # These systems don't actually have a C or math library (as such)
+           continue
+           ;;
+         *-*-os2*)
+           # These systems don't actually have a C library (as such)
+           test "X$arg" = "X-lc" && continue
+           ;;
+         *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+           # Do not include libc due to us having libc/libc_r.
+           test "X$arg" = "X-lc" && continue
+           ;;
+         *-*-rhapsody* | *-*-darwin1.[012])
+           # Rhapsody C and math libraries are in the System framework
+           deplibs="$deplibs -framework System"
+           continue
+           ;;
+         *-*-sco3.2v5* | *-*-sco5v6*)
+           # Causes problems with __ctype
+           test "X$arg" = "X-lc" && continue
+           ;;
+         *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+           # Compiler inserts libc in the correct place for threads to work
+           test "X$arg" = "X-lc" && continue
+           ;;
+         esac
+       elif test "X$arg" = "X-lc_r"; then
+        case $host in
+        *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+          # Do not include libc_r directly, use -pthread flag.
+          continue
+          ;;
+        esac
+       fi
+       deplibs="$deplibs $arg"
+       continue
+       ;;
+
+      # Tru64 UNIX uses -model [arg] to determine the layout of C++
+      # classes, name mangling, and exception handling.
+      -model)
+       compile_command="$compile_command $arg"
+       compiler_flags="$compiler_flags $arg"
+       finalize_command="$finalize_command $arg"
+       prev=xcompiler
+       continue
+       ;;
+
+     -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe)
+       compiler_flags="$compiler_flags $arg"
+       compile_command="$compile_command $arg"
+       finalize_command="$finalize_command $arg"
+       continue
+       ;;
+
+      -module)
+       module=yes
+       continue
+       ;;
+
+      # -64, -mips[0-9] enable 64-bit mode on the SGI compiler
+      # -r[0-9][0-9]* specifies the processor on the SGI compiler
+      # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler
+      # +DA*, +DD* enable 64-bit mode on the HP compiler
+      # -q* pass through compiler args for the IBM compiler
+      # -m* pass through architecture-specific compiler args for GCC
+      # -m*, -t[45]*, -txscale* pass through architecture-specific
+      # compiler args for GCC
+      # -pg pass through profiling flag for GCC
+      # @file GCC response files
+      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*|-pg| \
+      -t[45]*|-txscale*|@*)
+
+       # Unknown arguments in both finalize_command and compile_command need
+       # to be aesthetically quoted because they are evaled later.
+       arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+       case $arg in
+       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*|"")
+         arg="\"$arg\""
+         ;;
+       esac
+        compile_command="$compile_command $arg"
+        finalize_command="$finalize_command $arg"
+        compiler_flags="$compiler_flags $arg"
+        continue
+        ;;
+
+      -shrext)
+       prev=shrext
+       continue
+       ;;
+
+      -no-fast-install)
+       fast_install=no
+       continue
+       ;;
+
+      -no-install)
+       case $host in
+       *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+         # The PATH hackery in wrapper scripts is required on Windows
+         # in order for the loader to find any dlls it needs.
+         $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2
+         $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2
+         fast_install=no
+         ;;
+       *) no_install=yes ;;
+       esac
+       continue
+       ;;
+
+      -no-undefined)
+       allow_undefined=no
+       continue
+       ;;
+
+      -objectlist)
+       prev=objectlist
+       continue
+       ;;
+
+      -o) prev=output ;;
+
+      -precious-files-regex)
+       prev=precious_regex
+       continue
+       ;;
+
+      -release)
+       prev=release
+       continue
+       ;;
+
+      -rpath)
+       prev=rpath
+       continue
+       ;;
+
+      -R)
+       prev=xrpath
+       continue
+       ;;
+
+      -R*)
+       dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
+       # We need an absolute path.
+       case $dir in
+       [\\/]* | [A-Za-z]:[\\/]*) ;;
+       *)
+         $echo "$modename: only absolute run-paths are allowed" 1>&2
+         exit $EXIT_FAILURE
+         ;;
+       esac
+       case "$xrpath " in
+       *" $dir "*) ;;
+       *) xrpath="$xrpath $dir" ;;
+       esac
+       continue
+       ;;
+
+      -static)
+       # The effects of -static are defined in a previous loop.
+       # We used to do the same as -all-static on platforms that
+       # didn't have a PIC flag, but the assumption that the effects
+       # would be equivalent was wrong.  It would break on at least
+       # Digital Unix and AIX.
+       continue
+       ;;
+
+      -thread-safe)
+       thread_safe=yes
+       continue
+       ;;
+
+      -version-info)
+       prev=vinfo
+       continue
+       ;;
+      -version-number)
+       prev=vinfo
+       vinfo_number=yes
+       continue
+       ;;
+
+      -Wc,*)
+       args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'`
+       arg=
+       save_ifs="$IFS"; IFS=','
+       for flag in $args; do
+         IFS="$save_ifs"
+         case $flag in
+           *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \       ]*|*]*|"")
+           flag="\"$flag\""
+           ;;
+         esac
+         arg="$arg $wl$flag"
+         compiler_flags="$compiler_flags $flag"
+       done
+       IFS="$save_ifs"
+       arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
+       ;;
+
+      -Wl,*)
+       args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'`
+       arg=
+       save_ifs="$IFS"; IFS=','
+       for flag in $args; do
+         IFS="$save_ifs"
+         case $flag in
+           *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \       ]*|*]*|"")
+           flag="\"$flag\""
+           ;;
+         esac
+         arg="$arg $wl$flag"
+         compiler_flags="$compiler_flags $wl$flag"
+         linker_flags="$linker_flags $flag"
+       done
+       IFS="$save_ifs"
+       arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
+       ;;
+
+      -Xcompiler)
+       prev=xcompiler
+       continue
+       ;;
+
+      -Xlinker)
+       prev=xlinker
+       continue
+       ;;
+
+      -XCClinker)
+       prev=xcclinker
+       continue
+       ;;
+
+      # Some other compiler flag.
+      -* | +*)
+       # Unknown arguments in both finalize_command and compile_command need
+       # to be aesthetically quoted because they are evaled later.
+       arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+       case $arg in
+       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*|"")
+         arg="\"$arg\""
+         ;;
+       esac
+       ;;
+
+      *.$objext)
+       # A standard object.
+       objs="$objs $arg"
+       ;;
+
+      *.lo)
+       # A libtool-controlled object.
+
+       # Check to see that this really is a libtool object.
+       if (${SED} -e '2q' $arg | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+         pic_object=
+         non_pic_object=
+
+         # Read the .lo file
+         # If there is no directory component, then add one.
+         case $arg in
+         */* | *\\*) . $arg ;;
+         *) . ./$arg ;;
+         esac
+
+         if test -z "$pic_object" || \
+            test -z "$non_pic_object" ||
+            test "$pic_object" = none && \
+            test "$non_pic_object" = none; then
+           $echo "$modename: cannot find name of object for \`$arg'" 1>&2
+           exit $EXIT_FAILURE
+         fi
+
+         # Extract subdirectory from the argument.
+         xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+         if test "X$xdir" = "X$arg"; then
+           xdir=
+         else
+           xdir="$xdir/"
+         fi
+
+         if test "$pic_object" != none; then
+           # Prepend the subdirectory the object is found in.
+           pic_object="$xdir$pic_object"
+
+           if test "$prev" = dlfiles; then
+             if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+               dlfiles="$dlfiles $pic_object"
+               prev=
+               continue
+             else
+               # If libtool objects are unsupported, then we need to preload.
+               prev=dlprefiles
+             fi
+           fi
+
+           # CHECK ME:  I think I busted this.  -Ossama
+           if test "$prev" = dlprefiles; then
+             # Preload the old-style object.
+             dlprefiles="$dlprefiles $pic_object"
+             prev=
+           fi
+
+           # A PIC object.
+           libobjs="$libobjs $pic_object"
+           arg="$pic_object"
+         fi
+
+         # Non-PIC object.
+         if test "$non_pic_object" != none; then
+           # Prepend the subdirectory the object is found in.
+           non_pic_object="$xdir$non_pic_object"
+
+           # A standard non-PIC object
+           non_pic_objects="$non_pic_objects $non_pic_object"
+           if test -z "$pic_object" || test "$pic_object" = none ; then
+             arg="$non_pic_object"
+           fi
+         else
+           # If the PIC object exists, use it instead.
+           # $xdir was prepended to $pic_object above.
+           non_pic_object="$pic_object"
+           non_pic_objects="$non_pic_objects $non_pic_object"
+         fi
+       else
+         # Only an error if not doing a dry-run.
+         if test -z "$run"; then
+           $echo "$modename: \`$arg' is not a valid libtool object" 1>&2
+           exit $EXIT_FAILURE
+         else
+           # Dry-run case.
+
+           # Extract subdirectory from the argument.
+           xdir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+           if test "X$xdir" = "X$arg"; then
+             xdir=
+           else
+             xdir="$xdir/"
+           fi
+
+           pic_object=`$echo "X${xdir}${objdir}/${arg}" | $Xsed -e "$lo2o"`
+           non_pic_object=`$echo "X${xdir}${arg}" | $Xsed -e "$lo2o"`
+           libobjs="$libobjs $pic_object"
+           non_pic_objects="$non_pic_objects $non_pic_object"
+         fi
+       fi
+       ;;
+
+      *.$libext)
+       # An archive.
+       deplibs="$deplibs $arg"
+       old_deplibs="$old_deplibs $arg"
+       continue
+       ;;
+
+      *.la)
+       # A libtool-controlled library.
+
+       if test "$prev" = dlfiles; then
+         # This library was specified with -dlopen.
+         dlfiles="$dlfiles $arg"
+         prev=
+       elif test "$prev" = dlprefiles; then
+         # The library was specified with -dlpreopen.
+         dlprefiles="$dlprefiles $arg"
+         prev=
+       else
+         deplibs="$deplibs $arg"
+       fi
+       continue
+       ;;
+
+      # Some other compiler argument.
+      *)
+       # Unknown arguments in both finalize_command and compile_command need
+       # to be aesthetically quoted because they are evaled later.
+       arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+       case $arg in
+       *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \   ]*|*]*|"")
+         arg="\"$arg\""
+         ;;
+       esac
+       ;;
+      esac # arg
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+       compile_command="$compile_command $arg"
+       finalize_command="$finalize_command $arg"
+      fi
+    done # argument parsing loop
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+      eval arg=\"$export_dynamic_flag_spec\"
+      compile_command="$compile_command $arg"
+      finalize_command="$finalize_command $arg"
+    fi
+
+    oldlibs=
+    # calculate the name of the file, without its directory
+    outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
+    libobjs_save="$libobjs"
+
+    if test -n "$shlibpath_var"; then
+      # get the directories listed in $shlibpath_var
+      eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+    else
+      shlib_search_path=
+    fi
+    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+    output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+    if test "X$output_objdir" = "X$output"; then
+      output_objdir="$objdir"
+    else
+      output_objdir="$output_objdir/$objdir"
+    fi
+    # Create the object directory.
+    if test ! -d "$output_objdir"; then
+      $show "$mkdir $output_objdir"
+      $run $mkdir $output_objdir
+      exit_status=$?
+      if test "$exit_status" -ne 0 && test ! -d "$output_objdir"; then
+       exit $exit_status
+      fi
+    fi
+
+    # Determine the type of output
+    case $output in
+    "")
+      $echo "$modename: you must specify an output file" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+      ;;
+    *.$libext) linkmode=oldlib ;;
+    *.lo | *.$objext) linkmode=obj ;;
+    *.la) linkmode=lib ;;
+    *) linkmode=prog ;; # Anything else should be a program.
+    esac
+
+    case $host in
+    *cygwin* | *mingw* | *pw32*)
+      # don't eliminate duplications in $postdeps and $predeps
+      duplicate_compiler_generated_deps=yes
+      ;;
+    *)
+      duplicate_compiler_generated_deps=$duplicate_deps
+      ;;
+    esac
+    specialdeplibs=
+
+    libs=
+    # Find all interdependent deplibs by searching for libraries
+    # that are linked more than once (e.g. -la -lb -la)
+    for deplib in $deplibs; do
+      if test "X$duplicate_deps" = "Xyes" ; then
+       case "$libs " in
+       *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+       esac
+      fi
+      libs="$libs $deplib"
+    done
+
+    if test "$linkmode" = lib; then
+      libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+      # Compute libraries that are listed more than once in $predeps
+      # $postdeps and mark them as special (i.e., whose duplicates are
+      # not to be eliminated).
+      pre_post_deps=
+      if test "X$duplicate_compiler_generated_deps" = "Xyes" ; then
+       for pre_post_dep in $predeps $postdeps; do
+         case "$pre_post_deps " in
+         *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;;
+         esac
+         pre_post_deps="$pre_post_deps $pre_post_dep"
+       done
+      fi
+      pre_post_deps=
+    fi
+
+    deplibs=
+    newdependency_libs=
+    newlib_search_path=
+    need_relink=no # whether we're linking any uninstalled libtool libraries
+    notinst_deplibs= # not-installed libtool libraries
+    case $linkmode in
+    lib)
+       passes="conv link"
+       for file in $dlfiles $dlprefiles; do
+         case $file in
+         *.la) ;;
+         *)
+           $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2
+           exit $EXIT_FAILURE
+           ;;
+         esac
+       done
+       ;;
+    prog)
+       compile_deplibs=
+       finalize_deplibs=
+       alldeplibs=no
+       newdlfiles=
+       newdlprefiles=
+       passes="conv scan dlopen dlpreopen link"
+       ;;
+    *)  passes="conv"
+       ;;
+    esac
+    for pass in $passes; do
+      if test "$linkmode,$pass" = "lib,link" ||
+        test "$linkmode,$pass" = "prog,scan"; then
+       libs="$deplibs"
+       deplibs=
+      fi
+      if test "$linkmode" = prog; then
+       case $pass in
+       dlopen) libs="$dlfiles" ;;
+       dlpreopen) libs="$dlprefiles" ;;
+       link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+       esac
+      fi
+      if test "$pass" = dlopen; then
+       # Collect dlpreopened libraries
+       save_deplibs="$deplibs"
+       deplibs=
+      fi
+      for deplib in $libs; do
+       lib=
+       found=no
+       case $deplib in
+       -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe)
+         if test "$linkmode,$pass" = "prog,link"; then
+           compile_deplibs="$deplib $compile_deplibs"
+           finalize_deplibs="$deplib $finalize_deplibs"
+         else
+           compiler_flags="$compiler_flags $deplib"
+         fi
+         continue
+         ;;
+       -l*)
+         if test "$linkmode" != lib && test "$linkmode" != prog; then
+           $echo "$modename: warning: \`-l' is ignored for archives/objects" 1>&2
+           continue
+         fi
+         name=`$echo "X$deplib" | $Xsed -e 's/^-l//'`
+         for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do
+           for search_ext in .la $std_shrext .so .a; do
+             # Search the libtool library
+             lib="$searchdir/lib${name}${search_ext}"
+             if test -f "$lib"; then
+               if test "$search_ext" = ".la"; then
+                 found=yes
+               else
+                 found=no
+               fi
+               break 2
+             fi
+           done
+         done
+         if test "$found" != yes; then
+           # deplib doesn't seem to be a libtool library
+           if test "$linkmode,$pass" = "prog,link"; then
+             compile_deplibs="$deplib $compile_deplibs"
+             finalize_deplibs="$deplib $finalize_deplibs"
+           else
+             deplibs="$deplib $deplibs"
+             test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+           fi
+           continue
+         else # deplib is a libtool library
+           # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+           # We need to do some special things here, and not later.
+           if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+             case " $predeps $postdeps " in
+             *" $deplib "*)
+               if (${SED} -e '2q' $lib |
+                    grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+                 library_names=
+                 old_library=
+                 case $lib in
+                 */* | *\\*) . $lib ;;
+                 *) . ./$lib ;;
+                 esac
+                 for l in $old_library $library_names; do
+                   ll="$l"
+                 done
+                 if test "X$ll" = "X$old_library" ; then # only static version available
+                   found=no
+                   ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
+                   test "X$ladir" = "X$lib" && ladir="."
+                   lib=$ladir/$old_library
+                   if test "$linkmode,$pass" = "prog,link"; then
+                     compile_deplibs="$deplib $compile_deplibs"
+                     finalize_deplibs="$deplib $finalize_deplibs"
+                   else
+                     deplibs="$deplib $deplibs"
+                     test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+                   fi
+                   continue
+                 fi
+               fi
+               ;;
+             *) ;;
+             esac
+           fi
+         fi
+         ;; # -l
+       -L*)
+         case $linkmode in
+         lib)
+           deplibs="$deplib $deplibs"
+           test "$pass" = conv && continue
+           newdependency_libs="$deplib $newdependency_libs"
+           newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+           ;;
+         prog)
+           if test "$pass" = conv; then
+             deplibs="$deplib $deplibs"
+             continue
+           fi
+           if test "$pass" = scan; then
+             deplibs="$deplib $deplibs"
+           else
+             compile_deplibs="$deplib $compile_deplibs"
+             finalize_deplibs="$deplib $finalize_deplibs"
+           fi
+           newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+           ;;
+         *)
+           $echo "$modename: warning: \`-L' is ignored for archives/objects" 1>&2
+           ;;
+         esac # linkmode
+         continue
+         ;; # -L
+       -R*)
+         if test "$pass" = link; then
+           dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
+           # Make sure the xrpath contains only unique directories.
+           case "$xrpath " in
+           *" $dir "*) ;;
+           *) xrpath="$xrpath $dir" ;;
+           esac
+         fi
+         deplibs="$deplib $deplibs"
+         continue
+         ;;
+       *.la) lib="$deplib" ;;
+       *.$libext)
+         if test "$pass" = conv; then
+           deplibs="$deplib $deplibs"
+           continue
+         fi
+         case $linkmode in
+         lib)
+           valid_a_lib=no
+           case $deplibs_check_method in
+             match_pattern*)
+               set dummy $deplibs_check_method
+               match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+               if eval $echo \"$deplib\" 2>/dev/null \
+                   | $SED 10q \
+                   | $EGREP "$match_pattern_regex" > /dev/null; then
+                 valid_a_lib=yes
+               fi
+               ;;
+             pass_all)
+               valid_a_lib=yes
+               ;;
+            esac
+           if test "$valid_a_lib" != yes; then
+             $echo
+             $echo "*** Warning: Trying to link with static lib archive $deplib."
+             $echo "*** I have the capability to make that library automatically link in when"
+             $echo "*** you link to this library.  But I can only do this if you have a"
+             $echo "*** shared version of the library, which you do not appear to have"
+             $echo "*** because the file extensions .$libext of this argument makes me believe"
+             $echo "*** that it is just a static archive that I should not used here."
+           else
+             $echo
+             $echo "*** Warning: Linking the shared library $output against the"
+             $echo "*** static library $deplib is not portable!"
+             deplibs="$deplib $deplibs"
+           fi
+           continue
+           ;;
+         prog)
+           if test "$pass" != link; then
+             deplibs="$deplib $deplibs"
+           else
+             compile_deplibs="$deplib $compile_deplibs"
+             finalize_deplibs="$deplib $finalize_deplibs"
+           fi
+           continue
+           ;;
+         esac # linkmode
+         ;; # *.$libext
+       *.lo | *.$objext)
+         if test "$pass" = conv; then
+           deplibs="$deplib $deplibs"
+         elif test "$linkmode" = prog; then
+           if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+             # If there is no dlopen support or we're linking statically,
+             # we need to preload.
+             newdlprefiles="$newdlprefiles $deplib"
+             compile_deplibs="$deplib $compile_deplibs"
+             finalize_deplibs="$deplib $finalize_deplibs"
+           else
+             newdlfiles="$newdlfiles $deplib"
+           fi
+         fi
+         continue
+         ;;
+       %DEPLIBS%)
+         alldeplibs=yes
+         continue
+         ;;
+       esac # case $deplib
+       if test "$found" = yes || test -f "$lib"; then :
+       else
+         $echo "$modename: cannot find the library \`$lib' or unhandled argument \`$deplib'" 1>&2
+         exit $EXIT_FAILURE
+       fi
+
+       # Check to see that this really is a libtool archive.
+       if (${SED} -e '2q' $lib | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+       else
+         $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+         exit $EXIT_FAILURE
+       fi
+
+       ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
+       test "X$ladir" = "X$lib" && ladir="."
+
+       dlname=
+       dlopen=
+       dlpreopen=
+       libdir=
+       library_names=
+       old_library=
+       # If the library was installed with an old release of libtool,
+       # it will not redefine variables installed, or shouldnotlink
+       installed=yes
+       shouldnotlink=no
+       avoidtemprpath=
+
+
+       # Read the .la file
+       case $lib in
+       */* | *\\*) . $lib ;;
+       *) . ./$lib ;;
+       esac
+
+       if test "$linkmode,$pass" = "lib,link" ||
+          test "$linkmode,$pass" = "prog,scan" ||
+          { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+         test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
+         test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
+       fi
+
+       if test "$pass" = conv; then
+         # Only check for convenience libraries
+         deplibs="$lib $deplibs"
+         if test -z "$libdir"; then
+           if test -z "$old_library"; then
+             $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
+             exit $EXIT_FAILURE
+           fi
+           # It is a libtool convenience library, so add in its objects.
+           convenience="$convenience $ladir/$objdir/$old_library"
+           old_convenience="$old_convenience $ladir/$objdir/$old_library"
+           tmp_libs=
+           for deplib in $dependency_libs; do
+             deplibs="$deplib $deplibs"
+              if test "X$duplicate_deps" = "Xyes" ; then
+               case "$tmp_libs " in
+               *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+               esac
+              fi
+             tmp_libs="$tmp_libs $deplib"
+           done
+         elif test "$linkmode" != prog && test "$linkmode" != lib; then
+           $echo "$modename: \`$lib' is not a convenience library" 1>&2
+           exit $EXIT_FAILURE
+         fi
+         continue
+       fi # $pass = conv
+
+
+       # Get the name of the library we link against.
+       linklib=
+       for l in $old_library $library_names; do
+         linklib="$l"
+       done
+       if test -z "$linklib"; then
+         $echo "$modename: cannot find name of link library for \`$lib'" 1>&2
+         exit $EXIT_FAILURE
+       fi
+
+       # This library was specified with -dlopen.
+       if test "$pass" = dlopen; then
+         if test -z "$libdir"; then
+           $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2
+           exit $EXIT_FAILURE
+         fi
+         if test -z "$dlname" ||
+            test "$dlopen_support" != yes ||
+            test "$build_libtool_libs" = no; then
+           # If there is no dlname, no dlopen support or we're linking
+           # statically, we need to preload.  We also need to preload any
+           # dependent libraries so libltdl's deplib preloader doesn't
+           # bomb out in the load deplibs phase.
+           dlprefiles="$dlprefiles $lib $dependency_libs"
+         else
+           newdlfiles="$newdlfiles $lib"
+         fi
+         continue
+       fi # $pass = dlopen
+
+       # We need an absolute path.
+       case $ladir in
+       [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+       *)
+         abs_ladir=`cd "$ladir" && pwd`
+         if test -z "$abs_ladir"; then
+           $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2
+           $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+           abs_ladir="$ladir"
+         fi
+         ;;
+       esac
+       laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+
+       # Find the relevant object directory and library name.
+       if test "X$installed" = Xyes; then
+         if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+           $echo "$modename: warning: library \`$lib' was moved." 1>&2
+           dir="$ladir"
+           absdir="$abs_ladir"
+           libdir="$abs_ladir"
+         else
+           dir="$libdir"
+           absdir="$libdir"
+         fi
+         test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
+       else
+         if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+           dir="$ladir"
+           absdir="$abs_ladir"
+           # Remove this search path later
+           notinst_path="$notinst_path $abs_ladir"
+         else
+           dir="$ladir/$objdir"
+           absdir="$abs_ladir/$objdir"
+           # Remove this search path later
+           notinst_path="$notinst_path $abs_ladir"
+         fi
+       fi # $installed = yes
+       name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+
+       # This library was specified with -dlpreopen.
+       if test "$pass" = dlpreopen; then
+         if test -z "$libdir"; then
+           $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2
+           exit $EXIT_FAILURE
+         fi
+         # Prefer using a static library (so that no silly _DYNAMIC symbols
+         # are required to link).
+         if test -n "$old_library"; then
+           newdlprefiles="$newdlprefiles $dir/$old_library"
+         # Otherwise, use the dlname, so that lt_dlopen finds it.
+         elif test -n "$dlname"; then
+           newdlprefiles="$newdlprefiles $dir/$dlname"
+         else
+           newdlprefiles="$newdlprefiles $dir/$linklib"
+         fi
+       fi # $pass = dlpreopen
+
+       if test -z "$libdir"; then
+         # Link the convenience library
+         if test "$linkmode" = lib; then
+           deplibs="$dir/$old_library $deplibs"
+         elif test "$linkmode,$pass" = "prog,link"; then
+           compile_deplibs="$dir/$old_library $compile_deplibs"
+           finalize_deplibs="$dir/$old_library $finalize_deplibs"
+         else
+           deplibs="$lib $deplibs" # used for prog,scan pass
+         fi
+         continue
+       fi
+
+
+       if test "$linkmode" = prog && test "$pass" != link; then
+         newlib_search_path="$newlib_search_path $ladir"
+         deplibs="$lib $deplibs"
+
+         linkalldeplibs=no
+         if test "$link_all_deplibs" != no || test -z "$library_names" ||
+            test "$build_libtool_libs" = no; then
+           linkalldeplibs=yes
+         fi
+
+         tmp_libs=
+         for deplib in $dependency_libs; do
+           case $deplib in
+           -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test
+           esac
+           # Need to link against all dependency_libs?
+           if test "$linkalldeplibs" = yes; then
+             deplibs="$deplib $deplibs"
+           else
+             # Need to hardcode shared library paths
+             # or/and link against static libraries
+             newdependency_libs="$deplib $newdependency_libs"
+           fi
+           if test "X$duplicate_deps" = "Xyes" ; then
+             case "$tmp_libs " in
+             *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+             esac
+           fi
+           tmp_libs="$tmp_libs $deplib"
+         done # for deplib
+         continue
+       fi # $linkmode = prog...
+
+       if test "$linkmode,$pass" = "prog,link"; then
+         if test -n "$library_names" &&
+            { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+           # We need to hardcode the library path
+           if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
+             # Make sure the rpath contains only unique directories.
+             case "$temp_rpath " in
+             *" $dir "*) ;;
+             *" $absdir "*) ;;
+             *) temp_rpath="$temp_rpath $absdir" ;;
+             esac
+           fi
+
+           # Hardcode the library path.
+           # Skip directories that are in the system default run-time
+           # search path.
+           case " $sys_lib_dlsearch_path " in
+           *" $absdir "*) ;;
+           *)
+             case "$compile_rpath " in
+             *" $absdir "*) ;;
+             *) compile_rpath="$compile_rpath $absdir"
+             esac
+             ;;
+           esac
+           case " $sys_lib_dlsearch_path " in
+           *" $libdir "*) ;;
+           *)
+             case "$finalize_rpath " in
+             *" $libdir "*) ;;
+             *) finalize_rpath="$finalize_rpath $libdir"
+             esac
+             ;;
+           esac
+         fi # $linkmode,$pass = prog,link...
+
+         if test "$alldeplibs" = yes &&
+            { test "$deplibs_check_method" = pass_all ||
+              { test "$build_libtool_libs" = yes &&
+                test -n "$library_names"; }; }; then
+           # We only need to search for static libraries
+           continue
+         fi
+       fi
+
+       link_static=no # Whether the deplib will be linked statically
+       use_static_libs=$prefer_static_libs
+       if test "$use_static_libs" = built && test "$installed" = yes ; then
+         use_static_libs=no
+       fi
+       if test -n "$library_names" &&
+          { test "$use_static_libs" = no || test -z "$old_library"; }; then
+         if test "$installed" = no; then
+           notinst_deplibs="$notinst_deplibs $lib"
+           need_relink=yes
+         fi
+         # This is a shared library
+
+         # Warn about portability, can't link against -module's on
+         # some systems (darwin)
+         if test "$shouldnotlink" = yes && test "$pass" = link ; then
+           $echo
+           if test "$linkmode" = prog; then
+             $echo "*** Warning: Linking the executable $output against the loadable module"
+           else
+             $echo "*** Warning: Linking the shared library $output against the loadable module"
+           fi
+           $echo "*** $linklib is not portable!"
+         fi
+         if test "$linkmode" = lib &&
+            test "$hardcode_into_libs" = yes; then
+           # Hardcode the library path.
+           # Skip directories that are in the system default run-time
+           # search path.
+           case " $sys_lib_dlsearch_path " in
+           *" $absdir "*) ;;
+           *)
+             case "$compile_rpath " in
+             *" $absdir "*) ;;
+             *) compile_rpath="$compile_rpath $absdir"
+             esac
+             ;;
+           esac
+           case " $sys_lib_dlsearch_path " in
+           *" $libdir "*) ;;
+           *)
+             case "$finalize_rpath " in
+             *" $libdir "*) ;;
+             *) finalize_rpath="$finalize_rpath $libdir"
+             esac
+             ;;
+           esac
+         fi
+
+         if test -n "$old_archive_from_expsyms_cmds"; then
+           # figure out the soname
+           set dummy $library_names
+           realname="$2"
+           shift; shift
+           libname=`eval \\$echo \"$libname_spec\"`
+           # use dlname if we got it. it's perfectly good, no?
+           if test -n "$dlname"; then
+             soname="$dlname"
+           elif test -n "$soname_spec"; then
+             # bleh windows
+             case $host in
+             *cygwin* | mingw*)
+               major=`expr $current - $age`
+               versuffix="-$major"
+               ;;
+             esac
+             eval soname=\"$soname_spec\"
+           else
+             soname="$realname"
+           fi
+
+           # Make a new name for the extract_expsyms_cmds to use
+           soroot="$soname"
+           soname=`$echo $soroot | ${SED} -e 's/^.*\///'`
+           newlib="libimp-`$echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a"
+
+           # If the library has no export list, then create one now
+           if test -f "$output_objdir/$soname-def"; then :
+           else
+             $show "extracting exported symbol list from \`$soname'"
+             save_ifs="$IFS"; IFS='~'
+             cmds=$extract_expsyms_cmds
+             for cmd in $cmds; do
+               IFS="$save_ifs"
+               eval cmd=\"$cmd\"
+               $show "$cmd"
+               $run eval "$cmd" || exit $?
+             done
+             IFS="$save_ifs"
+           fi
+
+           # Create $newlib
+           if test -f "$output_objdir/$newlib"; then :; else
+             $show "generating import library for \`$soname'"
+             save_ifs="$IFS"; IFS='~'
+             cmds=$old_archive_from_expsyms_cmds
+             for cmd in $cmds; do
+               IFS="$save_ifs"
+               eval cmd=\"$cmd\"
+               $show "$cmd"
+               $run eval "$cmd" || exit $?
+             done
+             IFS="$save_ifs"
+           fi
+           # make sure the library variables are pointing to the new library
+           dir=$output_objdir
+           linklib=$newlib
+         fi # test -n "$old_archive_from_expsyms_cmds"
+
+         if test "$linkmode" = prog || test "$mode" != relink; then
+           add_shlibpath=
+           add_dir=
+           add=
+           lib_linked=yes
+           case $hardcode_action in
+           immediate | unsupported)
+             if test "$hardcode_direct" = no; then
+               add="$dir/$linklib"
+               case $host in
+                 *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+                 *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+                 *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+                   *-*-unixware7*) add_dir="-L$dir" ;;
+                 *-*-darwin* )
+                   # if the lib is a module then we can not link against
+                   # it, someone is ignoring the new warnings I added
+                   if /usr/bin/file -L $add 2> /dev/null |
+                      $EGREP ": [^:]* bundle" >/dev/null ; then
+                     $echo "** Warning, lib $linklib is a module, not a shared library"
+                     if test -z "$old_library" ; then
+                       $echo
+                       $echo "** And there doesn't seem to be a static archive available"
+                       $echo "** The link will probably fail, sorry"
+                     else
+                       add="$dir/$old_library"
+                     fi
+                   fi
+               esac
+             elif test "$hardcode_minus_L" = no; then
+               case $host in
+               *-*-sunos*) add_shlibpath="$dir" ;;
+               esac
+               add_dir="-L$dir"
+               add="-l$name"
+             elif test "$hardcode_shlibpath_var" = no; then
+               add_shlibpath="$dir"
+               add="-l$name"
+             else
+               lib_linked=no
+             fi
+             ;;
+           relink)
+             if test "$hardcode_direct" = yes; then
+               add="$dir/$linklib"
+             elif test "$hardcode_minus_L" = yes; then
+               add_dir="-L$dir"
+               # Try looking first in the location we're being installed to.
+               if test -n "$inst_prefix_dir"; then
+                 case $libdir in
+                   [\\/]*)
+                     add_dir="$add_dir -L$inst_prefix_dir$libdir"
+                     ;;
+                 esac
+               fi
+               add="-l$name"
+             elif test "$hardcode_shlibpath_var" = yes; then
+               add_shlibpath="$dir"
+               add="-l$name"
+             else
+               lib_linked=no
+             fi
+             ;;
+           *) lib_linked=no ;;
+           esac
+
+           if test "$lib_linked" != yes; then
+             $echo "$modename: configuration error: unsupported hardcode properties"
+             exit $EXIT_FAILURE
+           fi
+
+           if test -n "$add_shlibpath"; then
+             case :$compile_shlibpath: in
+             *":$add_shlibpath:"*) ;;
+             *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
+             esac
+           fi
+           if test "$linkmode" = prog; then
+             test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+             test -n "$add" && compile_deplibs="$add $compile_deplibs"
+           else
+             test -n "$add_dir" && deplibs="$add_dir $deplibs"
+             test -n "$add" && deplibs="$add $deplibs"
+             if test "$hardcode_direct" != yes && \
+                test "$hardcode_minus_L" != yes && \
+                test "$hardcode_shlibpath_var" = yes; then
+               case :$finalize_shlibpath: in
+               *":$libdir:"*) ;;
+               *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+               esac
+             fi
+           fi
+         fi
+
+         if test "$linkmode" = prog || test "$mode" = relink; then
+           add_shlibpath=
+           add_dir=
+           add=
+           # Finalize command for both is simple: just hardcode it.
+           if test "$hardcode_direct" = yes; then
+             add="$libdir/$linklib"
+           elif test "$hardcode_minus_L" = yes; then
+             add_dir="-L$libdir"
+             add="-l$name"
+           elif test "$hardcode_shlibpath_var" = yes; then
+             case :$finalize_shlibpath: in
+             *":$libdir:"*) ;;
+             *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+             esac
+             add="-l$name"
+           elif test "$hardcode_automatic" = yes; then
+             if test -n "$inst_prefix_dir" &&
+                test -f "$inst_prefix_dir$libdir/$linklib" ; then
+               add="$inst_prefix_dir$libdir/$linklib"
+             else
+               add="$libdir/$linklib"
+             fi
+           else
+             # We cannot seem to hardcode it, guess we'll fake it.
+             add_dir="-L$libdir"
+             # Try looking first in the location we're being installed to.
+             if test -n "$inst_prefix_dir"; then
+               case $libdir in
+                 [\\/]*)
+                   add_dir="$add_dir -L$inst_prefix_dir$libdir"
+                   ;;
+               esac
+             fi
+             add="-l$name"
+           fi
+
+           if test "$linkmode" = prog; then
+             test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+             test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+           else
+             test -n "$add_dir" && deplibs="$add_dir $deplibs"
+             test -n "$add" && deplibs="$add $deplibs"
+           fi
+         fi
+       elif test "$linkmode" = prog; then
+         # Here we assume that one of hardcode_direct or hardcode_minus_L
+         # is not unsupported.  This is valid on all known static and
+         # shared platforms.
+         if test "$hardcode_direct" != unsupported; then
+           test -n "$old_library" && linklib="$old_library"
+           compile_deplibs="$dir/$linklib $compile_deplibs"
+           finalize_deplibs="$dir/$linklib $finalize_deplibs"
+         else
+           compile_deplibs="-l$name -L$dir $compile_deplibs"
+           finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+         fi
+       elif test "$build_libtool_libs" = yes; then
+         # Not a shared library
+         if test "$deplibs_check_method" != pass_all; then
+           # We're trying link a shared library against a static one
+           # but the system doesn't support it.
+
+           # Just print a warning and add the library to dependency_libs so
+           # that the program can be linked against the static library.
+           $echo
+           $echo "*** Warning: This system can not link to static lib archive $lib."
+           $echo "*** I have the capability to make that library automatically link in when"
+           $echo "*** you link to this library.  But I can only do this if you have a"
+           $echo "*** shared version of the library, which you do not appear to have."
+           if test "$module" = yes; then
+             $echo "*** But as you try to build a module library, libtool will still create "
+             $echo "*** a static module, that should work as long as the dlopening application"
+             $echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
+             if test -z "$global_symbol_pipe"; then
+               $echo
+               $echo "*** However, this would only work if libtool was able to extract symbol"
+               $echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+               $echo "*** not find such a program.  So, this module is probably useless."
+               $echo "*** \`nm' from GNU binutils and a full rebuild may help."
+             fi
+             if test "$build_old_libs" = no; then
+               build_libtool_libs=module
+               build_old_libs=yes
+             else
+               build_libtool_libs=no
+             fi
+           fi
+         else
+           deplibs="$dir/$old_library $deplibs"
+           link_static=yes
+         fi
+       fi # link shared/static library?
+
+       if test "$linkmode" = lib; then
+         if test -n "$dependency_libs" &&
+            { test "$hardcode_into_libs" != yes ||
+              test "$build_old_libs" = yes ||
+              test "$link_static" = yes; }; then
+           # Extract -R from dependency_libs
+           temp_deplibs=
+           for libdir in $dependency_libs; do
+             case $libdir in
+             -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'`
+                  case " $xrpath " in
+                  *" $temp_xrpath "*) ;;
+                  *) xrpath="$xrpath $temp_xrpath";;
+                  esac;;
+             *) temp_deplibs="$temp_deplibs $libdir";;
+             esac
+           done
+           dependency_libs="$temp_deplibs"
+         fi
+
+         newlib_search_path="$newlib_search_path $absdir"
+         # Link against this library
+         test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+         # ... and its dependency_libs
+         tmp_libs=
+         for deplib in $dependency_libs; do
+           newdependency_libs="$deplib $newdependency_libs"
+           if test "X$duplicate_deps" = "Xyes" ; then
+             case "$tmp_libs " in
+             *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+             esac
+           fi
+           tmp_libs="$tmp_libs $deplib"
+         done
+
+         if test "$link_all_deplibs" != no; then
+           # Add the search paths of all dependency libraries
+           for deplib in $dependency_libs; do
+             case $deplib in
+             -L*) path="$deplib" ;;
+             *.la)
+               dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'`
+               test "X$dir" = "X$deplib" && dir="."
+               # We need an absolute path.
+               case $dir in
+               [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+               *)
+                 absdir=`cd "$dir" && pwd`
+                 if test -z "$absdir"; then
+                   $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+                   absdir="$dir"
+                 fi
+                 ;;
+               esac
+               if grep "^installed=no" $deplib > /dev/null; then
+                 path="$absdir/$objdir"
+               else
+                 eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+                 if test -z "$libdir"; then
+                   $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
+                   exit $EXIT_FAILURE
+                 fi
+                 if test "$absdir" != "$libdir"; then
+                   $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2
+                 fi
+                 path="$absdir"
+               fi
+               depdepl=
+               case $host in
+               *-*-darwin*)
+                 # we do not want to link against static libs,
+                 # but need to link against shared
+                 eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+                 if test -n "$deplibrary_names" ; then
+                   for tmp in $deplibrary_names ; do
+                     depdepl=$tmp
+                   done
+                   if test -f "$path/$depdepl" ; then
+                     depdepl="$path/$depdepl"
+                   fi
+                   # do not add paths which are already there
+                   case " $newlib_search_path " in
+                   *" $path "*) ;;
+                   *) newlib_search_path="$newlib_search_path $path";;
+                   esac
+                 fi
+                 path=""
+                 ;;
+               *)
+                 path="-L$path"
+                 ;;
+               esac
+               ;;
+             -l*)
+               case $host in
+               *-*-darwin*)
+                 # Again, we only want to link against shared libraries
+                 eval tmp_libs=`$echo "X$deplib" | $Xsed -e "s,^\-l,,"`
+                 for tmp in $newlib_search_path ; do
+                   if test -f "$tmp/lib$tmp_libs.dylib" ; then
+                     eval depdepl="$tmp/lib$tmp_libs.dylib"
+                     break
+                   fi
+                 done
+                 path=""
+                 ;;
+               *) continue ;;
+               esac
+               ;;
+             *) continue ;;
+             esac
+             case " $deplibs " in
+             *" $path "*) ;;
+             *) deplibs="$path $deplibs" ;;
+             esac
+             case " $deplibs " in
+             *" $depdepl "*) ;;
+             *) deplibs="$depdepl $deplibs" ;;
+             esac
+           done
+         fi # link_all_deplibs != no
+       fi # linkmode = lib
+      done # for deplib in $libs
+      dependency_libs="$newdependency_libs"
+      if test "$pass" = dlpreopen; then
+       # Link the dlpreopened libraries before other libraries
+       for deplib in $save_deplibs; do
+         deplibs="$deplib $deplibs"
+       done
+      fi
+      if test "$pass" != dlopen; then
+       if test "$pass" != conv; then
+         # Make sure lib_search_path contains only unique directories.
+         lib_search_path=
+         for dir in $newlib_search_path; do
+           case "$lib_search_path " in
+           *" $dir "*) ;;
+           *) lib_search_path="$lib_search_path $dir" ;;
+           esac
+         done
+         newlib_search_path=
+       fi
+
+       if test "$linkmode,$pass" != "prog,link"; then
+         vars="deplibs"
+       else
+         vars="compile_deplibs finalize_deplibs"
+       fi
+       for var in $vars dependency_libs; do
+         # Add libraries to $var in reverse order
+         eval tmp_libs=\"\$$var\"
+         new_libs=
+         for deplib in $tmp_libs; do
+           # FIXME: Pedantically, this is the right thing to do, so
+           #        that some nasty dependency loop isn't accidentally
+           #        broken:
+           #new_libs="$deplib $new_libs"
+           # Pragmatically, this seems to cause very few problems in
+           # practice:
+           case $deplib in
+           -L*) new_libs="$deplib $new_libs" ;;
+           -R*) ;;
+           *)
+             # And here is the reason: when a library appears more
+             # than once as an explicit dependence of a library, or
+             # is implicitly linked in more than once by the
+             # compiler, it is considered special, and multiple
+             # occurrences thereof are not removed.  Compare this
+             # with having the same library being listed as a
+             # dependency of multiple other libraries: in this case,
+             # we know (pedantically, we assume) the library does not
+             # need to be listed more than once, so we keep only the
+             # last copy.  This is not always right, but it is rare
+             # enough that we require users that really mean to play
+             # such unportable linking tricks to link the library
+             # using -Wl,-lname, so that libtool does not consider it
+             # for duplicate removal.
+             case " $specialdeplibs " in
+             *" $deplib "*) new_libs="$deplib $new_libs" ;;
+             *)
+               case " $new_libs " in
+               *" $deplib "*) ;;
+               *) new_libs="$deplib $new_libs" ;;
+               esac
+               ;;
+             esac
+             ;;
+           esac
+         done
+         tmp_libs=
+         for deplib in $new_libs; do
+           case $deplib in
+           -L*)
+             case " $tmp_libs " in
+             *" $deplib "*) ;;
+             *) tmp_libs="$tmp_libs $deplib" ;;
+             esac
+             ;;
+           *) tmp_libs="$tmp_libs $deplib" ;;
+           esac
+         done
+         eval $var=\"$tmp_libs\"
+       done # for var
+      fi
+      # Last step: remove runtime libs from dependency_libs
+      # (they stay in deplibs)
+      tmp_libs=
+      for i in $dependency_libs ; do
+       case " $predeps $postdeps $compiler_lib_search_path " in
+       *" $i "*)
+         i=""
+         ;;
+       esac
+       if test -n "$i" ; then
+         tmp_libs="$tmp_libs $i"
+       fi
+      done
+      dependency_libs=$tmp_libs
+    done # for pass
+    if test "$linkmode" = prog; then
+      dlfiles="$newdlfiles"
+      dlprefiles="$newdlprefiles"
+    fi
+
+    case $linkmode in
+    oldlib)
+      if test -n "$deplibs"; then
+       $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+       $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+       $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$xrpath"; then
+       $echo "$modename: warning: \`-R' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+       $echo "$modename: warning: \`-version-info/-version-number' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$release"; then
+       $echo "$modename: warning: \`-release' is ignored for archives" 1>&2
+      fi
+
+      if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+       $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
+      fi
+
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      oldlibs="$output"
+      objs="$objs$old_deplibs"
+      ;;
+
+    lib)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case $outputname in
+      lib*)
+       name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+       eval shared_ext=\"$shrext_cmds\"
+       eval libname=\"$libname_spec\"
+       ;;
+      *)
+       if test "$module" = no; then
+         $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
+         $echo "$help" 1>&2
+         exit $EXIT_FAILURE
+       fi
+       if test "$need_lib_prefix" != no; then
+         # Add the "lib" prefix for modules if required
+         name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+         eval shared_ext=\"$shrext_cmds\"
+         eval libname=\"$libname_spec\"
+       else
+         libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+       fi
+       ;;
+      esac
+
+      if test -n "$objs"; then
+       if test "$deplibs_check_method" != pass_all; then
+         $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1
+         exit $EXIT_FAILURE
+       else
+         $echo
+         $echo "*** Warning: Linking the shared library $output against the non-libtool"
+         $echo "*** objects $objs is not portable!"
+         libobjs="$libobjs $objs"
+       fi
+      fi
+
+      if test "$dlself" != no; then
+       $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2
+      fi
+
+      set dummy $rpath
+      if test "$#" -gt 2; then
+       $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+      fi
+      install_libdir="$2"
+
+      oldlibs=
+      if test -z "$rpath"; then
+       if test "$build_libtool_libs" = yes; then
+         # Building a libtool convenience library.
+         # Some compilers have problems with a `.al' extension so
+         # convenience libraries should have the same extension an
+         # archive normally would.
+         oldlibs="$output_objdir/$libname.$libext $oldlibs"
+         build_libtool_libs=convenience
+         build_old_libs=yes
+       fi
+
+       if test -n "$vinfo"; then
+         $echo "$modename: warning: \`-version-info/-version-number' is ignored for convenience libraries" 1>&2
+       fi
+
+       if test -n "$release"; then
+         $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
+       fi
+      else
+
+       # Parse the version information argument.
+       save_ifs="$IFS"; IFS=':'
+       set dummy $vinfo 0 0 0
+       IFS="$save_ifs"
+
+       if test -n "$8"; then
+         $echo "$modename: too many parameters to \`-version-info'" 1>&2
+         $echo "$help" 1>&2
+         exit $EXIT_FAILURE
+       fi
+
+       # convert absolute version numbers to libtool ages
+       # this retains compatibility with .la files and attempts
+       # to make the code below a bit more comprehensible
+
+       case $vinfo_number in
+       yes)
+         number_major="$2"
+         number_minor="$3"
+         number_revision="$4"
+         #
+         # There are really only two kinds -- those that
+         # use the current revision as the major version
+         # and those that subtract age and use age as
+         # a minor version.  But, then there is irix
+         # which has an extra 1 added just for fun
+         #
+         case $version_type in
+         darwin|linux|osf|windows)
+           current=`expr $number_major + $number_minor`
+           age="$number_minor"
+           revision="$number_revision"
+           ;;
+         freebsd-aout|freebsd-elf|sunos)
+           current="$number_major"
+           revision="$number_minor"
+           age="0"
+           ;;
+         irix|nonstopux)
+           current=`expr $number_major + $number_minor - 1`
+           age="$number_minor"
+           revision="$number_minor"
+           ;;
+         esac
+         ;;
+       no)
+         current="$2"
+         revision="$3"
+         age="$4"
+         ;;
+       esac
+
+       # Check that each of the things are valid numbers.
+       case $current in
+       0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+       *)
+         $echo "$modename: CURRENT \`$current' must be a nonnegative integer" 1>&2
+         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+         exit $EXIT_FAILURE
+         ;;
+       esac
+
+       case $revision in
+       0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+       *)
+         $echo "$modename: REVISION \`$revision' must be a nonnegative integer" 1>&2
+         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+         exit $EXIT_FAILURE
+         ;;
+       esac
+
+       case $age in
+       0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+       *)
+         $echo "$modename: AGE \`$age' must be a nonnegative integer" 1>&2
+         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+         exit $EXIT_FAILURE
+         ;;
+       esac
+
+       if test "$age" -gt "$current"; then
+         $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+         $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+         exit $EXIT_FAILURE
+       fi
+
+       # Calculate the version variables.
+       major=
+       versuffix=
+       verstring=
+       case $version_type in
+       none) ;;
+
+       darwin)
+         # Like Linux, but with the current version available in
+         # verstring for coding it into the library header
+         major=.`expr $current - $age`
+         versuffix="$major.$age.$revision"
+         # Darwin ld doesn't like 0 for these options...
+         minor_current=`expr $current + 1`
+         verstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
+         ;;
+
+       freebsd-aout)
+         major=".$current"
+         versuffix=".$current.$revision";
+         ;;
+
+       freebsd-elf)
+         major=".$current"
+         versuffix=".$current";
+         ;;
+
+       irix | nonstopux)
+         major=`expr $current - $age + 1`
+
+         case $version_type in
+           nonstopux) verstring_prefix=nonstopux ;;
+           *)         verstring_prefix=sgi ;;
+         esac
+         verstring="$verstring_prefix$major.$revision"
+
+         # Add in all the interfaces that we are compatible with.
+         loop=$revision
+         while test "$loop" -ne 0; do
+           iface=`expr $revision - $loop`
+           loop=`expr $loop - 1`
+           verstring="$verstring_prefix$major.$iface:$verstring"
+         done
+
+         # Before this point, $major must not contain `.'.
+         major=.$major
+         versuffix="$major.$revision"
+         ;;
+
+       linux)
+         major=.`expr $current - $age`
+         versuffix="$major.$age.$revision"
+         ;;
+
+       osf)
+         major=.`expr $current - $age`
+         versuffix=".$current.$age.$revision"
+         verstring="$current.$age.$revision"
+
+         # Add in all the interfaces that we are compatible with.
+         loop=$age
+         while test "$loop" -ne 0; do
+           iface=`expr $current - $loop`
+           loop=`expr $loop - 1`
+           verstring="$verstring:${iface}.0"
+         done
+
+         # Make executables depend on our current version.
+         verstring="$verstring:${current}.0"
+         ;;
+
+       sunos)
+         major=".$current"
+         versuffix=".$current.$revision"
+         ;;
+
+       windows)
+         # Use '-' rather than '.', since we only want one
+         # extension on DOS 8.3 filesystems.
+         major=`expr $current - $age`
+         versuffix="-$major"
+         ;;
+
+       *)
+         $echo "$modename: unknown library version type \`$version_type'" 1>&2
+         $echo "Fatal configuration error.  See the $PACKAGE docs for more information." 1>&2
+         exit $EXIT_FAILURE
+         ;;
+       esac
+
+       # Clear the version info if we defaulted, and they specified a release.
+       if test -z "$vinfo" && test -n "$release"; then
+         major=
+         case $version_type in
+         darwin)
+           # we can't check for "0.0" in archive_cmds due to quoting
+           # problems, so we reset it completely
+           verstring=
+           ;;
+         *)
+           verstring="0.0"
+           ;;
+         esac
+         if test "$need_version" = no; then
+           versuffix=
+         else
+           versuffix=".0.0"
+         fi
+       fi
+
+       # Remove version info from name if versioning should be avoided
+       if test "$avoid_version" = yes && test "$need_version" = no; then
+         major=
+         versuffix=
+         verstring=""
+       fi
+
+       # Check to see if the archive will have undefined symbols.
+       if test "$allow_undefined" = yes; then
+         if test "$allow_undefined_flag" = unsupported; then
+           $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+           build_libtool_libs=no
+           build_old_libs=yes
+         fi
+       else
+         # Don't allow undefined symbols.
+         allow_undefined_flag="$no_undefined_flag"
+       fi
+      fi
+
+      if test "$mode" != relink; then
+       # Remove our outputs, but don't remove object files since they
+       # may have been created when compiling PIC objects.
+       removelist=
+       tempremovelist=`$echo "$output_objdir/*"`
+       for p in $tempremovelist; do
+         case $p in
+           *.$objext)
+              ;;
+           $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+              if test "X$precious_files_regex" != "X"; then
+                if echo $p | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+                then
+                  continue
+                fi
+              fi
+              removelist="$removelist $p"
+              ;;
+           *) ;;
+         esac
+       done
+       if test -n "$removelist"; then
+         $show "${rm}r $removelist"
+         $run ${rm}r $removelist
+       fi
+      fi
+
+      # Now set the variables for building old libraries.
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+       oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+       # Transform .lo files to .o files.
+       oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+      fi
+
+      # Eliminate all temporary directories.
+      for path in $notinst_path; do
+       lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"`
+       deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"`
+       dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"`
+      done
+
+      if test -n "$xrpath"; then
+       # If the user specified any rpath flags, then add them.
+       temp_xrpath=
+       for libdir in $xrpath; do
+         temp_xrpath="$temp_xrpath -R$libdir"
+         case "$finalize_rpath " in
+         *" $libdir "*) ;;
+         *) finalize_rpath="$finalize_rpath $libdir" ;;
+         esac
+       done
+       if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+         dependency_libs="$temp_xrpath $dependency_libs"
+       fi
+      fi
+
+      # Make sure dlfiles contains only unique files that won't be dlpreopened
+      old_dlfiles="$dlfiles"
+      dlfiles=
+      for lib in $old_dlfiles; do
+       case " $dlprefiles $dlfiles " in
+       *" $lib "*) ;;
+       *) dlfiles="$dlfiles $lib" ;;
+       esac
+      done
+
+      # Make sure dlprefiles contains only unique files
+      old_dlprefiles="$dlprefiles"
+      dlprefiles=
+      for lib in $old_dlprefiles; do
+       case "$dlprefiles " in
+       *" $lib "*) ;;
+       *) dlprefiles="$dlprefiles $lib" ;;
+       esac
+      done
+
+      if test "$build_libtool_libs" = yes; then
+       if test -n "$rpath"; then
+         case $host in
+         *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*)
+           # these systems don't actually have a c library (as such)!
+           ;;
+         *-*-rhapsody* | *-*-darwin1.[012])
+           # Rhapsody C library is in the System framework
+           deplibs="$deplibs -framework System"
+           ;;
+         *-*-netbsd*)
+           # Don't link with libc until the a.out ld.so is fixed.
+           ;;
+         *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+           # Do not include libc due to us having libc/libc_r.
+           ;;
+         *-*-sco3.2v5* | *-*-sco5v6*)
+           # Causes problems with __ctype
+           ;;
+         *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+           # Compiler inserts libc in the correct place for threads to work
+           ;;
+         *)
+           # Add libc to deplibs on all other systems if necessary.
+           if test "$build_libtool_need_lc" = "yes"; then
+             deplibs="$deplibs -lc"
+           fi
+           ;;
+         esac
+       fi
+
+       # Transform deplibs into only deplibs that can be linked in shared.
+       name_save=$name
+       libname_save=$libname
+       release_save=$release
+       versuffix_save=$versuffix
+       major_save=$major
+       # I'm not sure if I'm treating the release correctly.  I think
+       # release should show up in the -l (ie -lgmp5) so we don't want to
+       # add it in twice.  Is that correct?
+       release=""
+       versuffix=""
+       major=""
+       newdeplibs=
+       droppeddeps=no
+       case $deplibs_check_method in
+       pass_all)
+         # Don't check for shared/static.  Everything works.
+         # This might be a little naive.  We might want to check
+         # whether the library exists or not.  But this is on
+         # osf3 & osf4 and I'm not really sure... Just
+         # implementing what was already the behavior.
+         newdeplibs=$deplibs
+         ;;
+       test_compile)
+         # This code stresses the "libraries are programs" paradigm to its
+         # limits. Maybe even breaks it.  We compile a program, linking it
+         # against the deplibs as a proxy for the library.  Then we can check
+         # whether they linked in statically or dynamically with ldd.
+         $rm conftest.c
+         cat > conftest.c <<EOF
+         int main() { return 0; }
+EOF
+         $rm conftest
+         $LTCC $LTCFLAGS -o conftest conftest.c $deplibs
+         if test "$?" -eq 0 ; then
+           ldd_output=`ldd conftest`
+           for i in $deplibs; do
+             name=`expr $i : '-l\(.*\)'`
+             # If $name is empty we are operating on a -L argument.
+              if test "$name" != "" && test "$name" -ne "0"; then
+               if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+                 case " $predeps $postdeps " in
+                 *" $i "*)
+                   newdeplibs="$newdeplibs $i"
+                   i=""
+                   ;;
+                 esac
+               fi
+               if test -n "$i" ; then
+                 libname=`eval \\$echo \"$libname_spec\"`
+                 deplib_matches=`eval \\$echo \"$library_names_spec\"`
+                 set dummy $deplib_matches
+                 deplib_match=$2
+                 if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+                   newdeplibs="$newdeplibs $i"
+                 else
+                   droppeddeps=yes
+                   $echo
+                   $echo "*** Warning: dynamic linker does not accept needed library $i."
+                   $echo "*** I have the capability to make that library automatically link in when"
+                   $echo "*** you link to this library.  But I can only do this if you have a"
+                   $echo "*** shared version of the library, which I believe you do not have"
+                   $echo "*** because a test_compile did reveal that the linker did not use it for"
+                   $echo "*** its dynamic dependency list that programs get resolved with at runtime."
+                 fi
+               fi
+             else
+               newdeplibs="$newdeplibs $i"
+             fi
+           done
+         else
+           # Error occurred in the first compile.  Let's try to salvage
+           # the situation: Compile a separate program for each library.
+           for i in $deplibs; do
+             name=`expr $i : '-l\(.*\)'`
+             # If $name is empty we are operating on a -L argument.
+              if test "$name" != "" && test "$name" != "0"; then
+               $rm conftest
+               $LTCC $LTCFLAGS -o conftest conftest.c $i
+               # Did it work?
+               if test "$?" -eq 0 ; then
+                 ldd_output=`ldd conftest`
+                 if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+                   case " $predeps $postdeps " in
+                   *" $i "*)
+                     newdeplibs="$newdeplibs $i"
+                     i=""
+                     ;;
+                   esac
+                 fi
+                 if test -n "$i" ; then
+                   libname=`eval \\$echo \"$libname_spec\"`
+                   deplib_matches=`eval \\$echo \"$library_names_spec\"`
+                   set dummy $deplib_matches
+                   deplib_match=$2
+                   if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+                     newdeplibs="$newdeplibs $i"
+                   else
+                     droppeddeps=yes
+                     $echo
+                     $echo "*** Warning: dynamic linker does not accept needed library $i."
+                     $echo "*** I have the capability to make that library automatically link in when"
+                     $echo "*** you link to this library.  But I can only do this if you have a"
+                     $echo "*** shared version of the library, which you do not appear to have"
+                     $echo "*** because a test_compile did reveal that the linker did not use this one"
+                     $echo "*** as a dynamic dependency that programs can get resolved with at runtime."
+                   fi
+                 fi
+               else
+                 droppeddeps=yes
+                 $echo
+                 $echo "*** Warning!  Library $i is needed by this library but I was not able to"
+                 $echo "***  make it link in!  You will probably need to install it or some"
+                 $echo "*** library that it depends on before this library will be fully"
+                 $echo "*** functional.  Installing it before continuing would be even better."
+               fi
+             else
+               newdeplibs="$newdeplibs $i"
+             fi
+           done
+         fi
+         ;;
+       file_magic*)
+         set dummy $deplibs_check_method
+         file_magic_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+         for a_deplib in $deplibs; do
+           name=`expr $a_deplib : '-l\(.*\)'`
+           # If $name is empty we are operating on a -L argument.
+            if test "$name" != "" && test  "$name" != "0"; then
+             if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+               case " $predeps $postdeps " in
+               *" $a_deplib "*)
+                 newdeplibs="$newdeplibs $a_deplib"
+                 a_deplib=""
+                 ;;
+               esac
+             fi
+             if test -n "$a_deplib" ; then
+               libname=`eval \\$echo \"$libname_spec\"`
+               for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+                 potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+                 for potent_lib in $potential_libs; do
+                     # Follow soft links.
+                     if ls -lLd "$potent_lib" 2>/dev/null \
+                        | grep " -> " >/dev/null; then
+                       continue
+                     fi
+                     # The statement above tries to avoid entering an
+                     # endless loop below, in case of cyclic links.
+                     # We might still enter an endless loop, since a link
+                     # loop can be closed while we follow links,
+                     # but so what?
+                     potlib="$potent_lib"
+                     while test -h "$potlib" 2>/dev/null; do
+                       potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+                       case $potliblink in
+                       [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+                       *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+                       esac
+                     done
+                     # It is ok to link against an archive when
+                     # building a shared library.
+                     if $AR -t $potlib > /dev/null 2>&1; then
+                       newdeplibs="$newdeplibs $a_deplib"
+                       a_deplib=""
+                       break 2
+                     fi
+                     if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
+                        | ${SED} 10q \
+                        | $EGREP "$file_magic_regex" > /dev/null; then
+                       newdeplibs="$newdeplibs $a_deplib"
+                       a_deplib=""
+                       break 2
+                     fi
+                 done
+               done
+             fi
+             if test -n "$a_deplib" ; then
+               droppeddeps=yes
+               $echo
+               $echo "*** Warning: linker path does not have real file for library $a_deplib."
+               $echo "*** I have the capability to make that library automatically link in when"
+               $echo "*** you link to this library.  But I can only do this if you have a"
+               $echo "*** shared version of the library, which you do not appear to have"
+               $echo "*** because I did check the linker path looking for a file starting"
+               if test -z "$potlib" ; then
+                 $echo "*** with $libname but no candidates were found. (...for file magic test)"
+               else
+                 $echo "*** with $libname and none of the candidates passed a file format test"
+                 $echo "*** using a file magic. Last file checked: $potlib"
+               fi
+             fi
+           else
+             # Add a -L argument.
+             newdeplibs="$newdeplibs $a_deplib"
+           fi
+         done # Gone through all deplibs.
+         ;;
+       match_pattern*)
+         set dummy $deplibs_check_method
+         match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+         for a_deplib in $deplibs; do
+           name=`expr $a_deplib : '-l\(.*\)'`
+           # If $name is empty we are operating on a -L argument.
+           if test -n "$name" && test "$name" != "0"; then
+             if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+               case " $predeps $postdeps " in
+               *" $a_deplib "*)
+                 newdeplibs="$newdeplibs $a_deplib"
+                 a_deplib=""
+                 ;;
+               esac
+             fi
+             if test -n "$a_deplib" ; then
+               libname=`eval \\$echo \"$libname_spec\"`
+               for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+                 potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+                 for potent_lib in $potential_libs; do
+                   potlib="$potent_lib" # see symlink-check above in file_magic test
+                   if eval $echo \"$potent_lib\" 2>/dev/null \
+                       | ${SED} 10q \
+                       | $EGREP "$match_pattern_regex" > /dev/null; then
+                     newdeplibs="$newdeplibs $a_deplib"
+                     a_deplib=""
+                     break 2
+                   fi
+                 done
+               done
+             fi
+             if test -n "$a_deplib" ; then
+               droppeddeps=yes
+               $echo
+               $echo "*** Warning: linker path does not have real file for library $a_deplib."
+               $echo "*** I have the capability to make that library automatically link in when"
+               $echo "*** you link to this library.  But I can only do this if you have a"
+               $echo "*** shared version of the library, which you do not appear to have"
+               $echo "*** because I did check the linker path looking for a file starting"
+               if test -z "$potlib" ; then
+                 $echo "*** with $libname but no candidates were found. (...for regex pattern test)"
+               else
+                 $echo "*** with $libname and none of the candidates passed a file format test"
+                 $echo "*** using a regex pattern. Last file checked: $potlib"
+               fi
+             fi
+           else
+             # Add a -L argument.
+             newdeplibs="$newdeplibs $a_deplib"
+           fi
+         done # Gone through all deplibs.
+         ;;
+       none | unknown | *)
+         newdeplibs=""
+         tmp_deplibs=`$echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
+           -e 's/ -[LR][^ ]*//g'`
+         if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+           for i in $predeps $postdeps ; do
+             # can't use Xsed below, because $i might contain '/'
+             tmp_deplibs=`$echo "X $tmp_deplibs" | ${SED} -e "1s,^X,," -e "s,$i,,"`
+           done
+         fi
+         if $echo "X $tmp_deplibs" | $Xsed -e 's/[     ]//g' \
+           | grep . >/dev/null; then
+           $echo
+           if test "X$deplibs_check_method" = "Xnone"; then
+             $echo "*** Warning: inter-library dependencies are not supported in this platform."
+           else
+             $echo "*** Warning: inter-library dependencies are not known to be supported."
+           fi
+           $echo "*** All declared inter-library dependencies are being dropped."
+           droppeddeps=yes
+         fi
+         ;;
+       esac
+       versuffix=$versuffix_save
+       major=$major_save
+       release=$release_save
+       libname=$libname_save
+       name=$name_save
+
+       case $host in
+       *-*-rhapsody* | *-*-darwin1.[012])
+         # On Rhapsody replace the C library is the System framework
+         newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'`
+         ;;
+       esac
+
+       if test "$droppeddeps" = yes; then
+         if test "$module" = yes; then
+           $echo
+           $echo "*** Warning: libtool could not satisfy all declared inter-library"
+           $echo "*** dependencies of module $libname.  Therefore, libtool will create"
+           $echo "*** a static module, that should work as long as the dlopening"
+           $echo "*** application is linked with the -dlopen flag."
+           if test -z "$global_symbol_pipe"; then
+             $echo
+             $echo "*** However, this would only work if libtool was able to extract symbol"
+             $echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+             $echo "*** not find such a program.  So, this module is probably useless."
+             $echo "*** \`nm' from GNU binutils and a full rebuild may help."
+           fi
+           if test "$build_old_libs" = no; then
+             oldlibs="$output_objdir/$libname.$libext"
+             build_libtool_libs=module
+             build_old_libs=yes
+           else
+             build_libtool_libs=no
+           fi
+         else
+           $echo "*** The inter-library dependencies that have been dropped here will be"
+           $echo "*** automatically added whenever a program is linked with this library"
+           $echo "*** or is declared to -dlopen it."
+
+           if test "$allow_undefined" = no; then
+             $echo
+             $echo "*** Since this library must not contain undefined symbols,"
+             $echo "*** because either the platform does not support them or"
+             $echo "*** it was explicitly requested with -no-undefined,"
+             $echo "*** libtool will only create a static version of it."
+             if test "$build_old_libs" = no; then
+               oldlibs="$output_objdir/$libname.$libext"
+               build_libtool_libs=module
+               build_old_libs=yes
+             else
+               build_libtool_libs=no
+             fi
+           fi
+         fi
+       fi
+       # Done checking deplibs!
+       deplibs=$newdeplibs
+      fi
+
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+       case " $new_libs " in
+       *" -L$path/$objdir "*) ;;
+       *)
+         case " $deplibs " in
+         *" -L$path/$objdir "*)
+           new_libs="$new_libs -L$path/$objdir" ;;
+         esac
+         ;;
+       esac
+      done
+      for deplib in $deplibs; do
+       case $deplib in
+       -L*)
+         case " $new_libs " in
+         *" $deplib "*) ;;
+         *) new_libs="$new_libs $deplib" ;;
+         esac
+         ;;
+       *) new_libs="$new_libs $deplib" ;;
+       esac
+      done
+      deplibs="$new_libs"
+
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+
+      # Test again, we may have decided not to build it any more
+      if test "$build_libtool_libs" = yes; then
+       if test "$hardcode_into_libs" = yes; then
+         # Hardcode the library paths
+         hardcode_libdirs=
+         dep_rpath=
+         rpath="$finalize_rpath"
+         test "$mode" != relink && rpath="$compile_rpath$rpath"
+         for libdir in $rpath; do
+           if test -n "$hardcode_libdir_flag_spec"; then
+             if test -n "$hardcode_libdir_separator"; then
+               if test -z "$hardcode_libdirs"; then
+                 hardcode_libdirs="$libdir"
+               else
+                 # Just accumulate the unique libdirs.
+                 case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+                 *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+                   ;;
+                 *)
+                   hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+                   ;;
+                 esac
+               fi
+             else
+               eval flag=\"$hardcode_libdir_flag_spec\"
+               dep_rpath="$dep_rpath $flag"
+             fi
+           elif test -n "$runpath_var"; then
+             case "$perm_rpath " in
+             *" $libdir "*) ;;
+             *) perm_rpath="$perm_rpath $libdir" ;;
+             esac
+           fi
+         done
+         # Substitute the hardcoded libdirs into the rpath.
+         if test -n "$hardcode_libdir_separator" &&
+            test -n "$hardcode_libdirs"; then
+           libdir="$hardcode_libdirs"
+           if test -n "$hardcode_libdir_flag_spec_ld"; then
+             eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\"
+           else
+             eval dep_rpath=\"$hardcode_libdir_flag_spec\"
+           fi
+         fi
+         if test -n "$runpath_var" && test -n "$perm_rpath"; then
+           # We should set the runpath_var.
+           rpath=
+           for dir in $perm_rpath; do
+             rpath="$rpath$dir:"
+           done
+           eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+         fi
+         test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+       fi
+
+       shlibpath="$finalize_shlibpath"
+       test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+       if test -n "$shlibpath"; then
+         eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+       fi
+
+       # Get the real and link names of the library.
+       eval shared_ext=\"$shrext_cmds\"
+       eval library_names=\"$library_names_spec\"
+       set dummy $library_names
+       realname="$2"
+       shift; shift
+
+       if test -n "$soname_spec"; then
+         eval soname=\"$soname_spec\"
+       else
+         soname="$realname"
+       fi
+       if test -z "$dlname"; then
+         dlname=$soname
+       fi
+
+       lib="$output_objdir/$realname"
+       linknames=
+       for link
+       do
+         linknames="$linknames $link"
+       done
+
+       # Use standard objects if they are pic
+       test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+
+       # Prepare the list of exported symbols
+       if test -z "$export_symbols"; then
+         if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+           $show "generating symbol list for \`$libname.la'"
+           export_symbols="$output_objdir/$libname.exp"
+           $run $rm $export_symbols
+           cmds=$export_symbols_cmds
+           save_ifs="$IFS"; IFS='~'
+           for cmd in $cmds; do
+             IFS="$save_ifs"
+             eval cmd=\"$cmd\"
+             if len=`expr "X$cmd" : ".*"` &&
+              test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+               $show "$cmd"
+               $run eval "$cmd" || exit $?
+               skipped_export=false
+             else
+               # The command line is too long to execute in one step.
+               $show "using reloadable object file for export list..."
+               skipped_export=:
+               # Break out early, otherwise skipped_export may be
+               # set to false by a later but shorter cmd.
+               break
+             fi
+           done
+           IFS="$save_ifs"
+           if test -n "$export_symbols_regex"; then
+             $show "$EGREP -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
+             $run eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+             $show "$mv \"${export_symbols}T\" \"$export_symbols\""
+             $run eval '$mv "${export_symbols}T" "$export_symbols"'
+           fi
+         fi
+       fi
+
+       if test -n "$export_symbols" && test -n "$include_expsyms"; then
+         $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
+       fi
+
+       tmp_deplibs=
+       for test_deplib in $deplibs; do
+               case " $convenience " in
+               *" $test_deplib "*) ;;
+               *)
+                       tmp_deplibs="$tmp_deplibs $test_deplib"
+                       ;;
+               esac
+       done
+       deplibs="$tmp_deplibs"
+
+       if test -n "$convenience"; then
+         if test -n "$whole_archive_flag_spec"; then
+           save_libobjs=$libobjs
+           eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+         else
+           gentop="$output_objdir/${outputname}x"
+           generated="$generated $gentop"
+
+           func_extract_archives $gentop $convenience
+           libobjs="$libobjs $func_extract_archives_result"
+         fi
+       fi
+       
+       if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+         eval flag=\"$thread_safe_flag_spec\"
+         linker_flags="$linker_flags $flag"
+       fi
+
+       # Make a backup of the uninstalled library when relinking
+       if test "$mode" = relink; then
+         $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $?
+       fi
+
+       # Do each of the archive commands.
+       if test "$module" = yes && test -n "$module_cmds" ; then
+         if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+           eval test_cmds=\"$module_expsym_cmds\"
+           cmds=$module_expsym_cmds
+         else
+           eval test_cmds=\"$module_cmds\"
+           cmds=$module_cmds
+         fi
+       else
+       if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+         eval test_cmds=\"$archive_expsym_cmds\"
+         cmds=$archive_expsym_cmds
+       else
+         eval test_cmds=\"$archive_cmds\"
+         cmds=$archive_cmds
+         fi
+       fi
+
+       if test "X$skipped_export" != "X:" &&
+          len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
+          test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+         :
+       else
+         # The command line is too long to link in one step, link piecewise.
+         $echo "creating reloadable object files..."
+
+         # Save the value of $output and $libobjs because we want to
+         # use them later.  If we have whole_archive_flag_spec, we
+         # want to use save_libobjs as it was before
+         # whole_archive_flag_spec was expanded, because we can't
+         # assume the linker understands whole_archive_flag_spec.
+         # This may have to be revisited, in case too many
+         # convenience libraries get linked in and end up exceeding
+         # the spec.
+         if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+           save_libobjs=$libobjs
+         fi
+         save_output=$output
+         output_la=`$echo "X$output" | $Xsed -e "$basename"`
+
+         # Clear the reloadable object creation command queue and
+         # initialize k to one.
+         test_cmds=
+         concat_cmds=
+         objlist=
+         delfiles=
+         last_robj=
+         k=1
+         output=$output_objdir/$output_la-${k}.$objext
+         # Loop over the list of objects to be linked.
+         for obj in $save_libobjs
+         do
+           eval test_cmds=\"$reload_cmds $objlist $last_robj\"
+           if test "X$objlist" = X ||
+              { len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
+                test "$len" -le "$max_cmd_len"; }; then
+             objlist="$objlist $obj"
+           else
+             # The command $test_cmds is almost too long, add a
+             # command to the queue.
+             if test "$k" -eq 1 ; then
+               # The first file doesn't have a previous command to add.
+               eval concat_cmds=\"$reload_cmds $objlist $last_robj\"
+             else
+               # All subsequent reloadable object files will link in
+               # the last one created.
+               eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj\"
+             fi
+             last_robj=$output_objdir/$output_la-${k}.$objext
+             k=`expr $k + 1`
+             output=$output_objdir/$output_la-${k}.$objext
+             objlist=$obj
+             len=1
+           fi
+         done
+         # Handle the remaining objects by creating one last
+         # reloadable object file.  All subsequent reloadable object
+         # files will link in the last one created.
+         test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+         eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\"
+
+         if ${skipped_export-false}; then
+           $show "generating symbol list for \`$libname.la'"
+           export_symbols="$output_objdir/$libname.exp"
+           $run $rm $export_symbols
+           libobjs=$output
+           # Append the command to create the export file.
+           eval concat_cmds=\"\$concat_cmds~$export_symbols_cmds\"
+          fi
+
+         # Set up a command to remove the reloadable object files
+         # after they are used.
+         i=0
+         while test "$i" -lt "$k"
+         do
+           i=`expr $i + 1`
+           delfiles="$delfiles $output_objdir/$output_la-${i}.$objext"
+         done
+
+         $echo "creating a temporary reloadable object file: $output"
+
+         # Loop through the commands generated above and execute them.
+         save_ifs="$IFS"; IFS='~'
+         for cmd in $concat_cmds; do
+           IFS="$save_ifs"
+           $show "$cmd"
+           $run eval "$cmd" || exit $?
+         done
+         IFS="$save_ifs"
+
+         libobjs=$output
+         # Restore the value of output.
+         output=$save_output
+
+         if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+           eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+         fi
+         # Expand the library linking commands again to reset the
+         # value of $libobjs for piecewise linking.
+
+         # Do each of the archive commands.
+         if test "$module" = yes && test -n "$module_cmds" ; then
+           if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+             cmds=$module_expsym_cmds
+           else
+             cmds=$module_cmds
+           fi
+         else
+         if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+           cmds=$archive_expsym_cmds
+         else
+           cmds=$archive_cmds
+           fi
+         fi
+
+         # Append the command to remove the reloadable object files
+         # to the just-reset $cmds.
+         eval cmds=\"\$cmds~\$rm $delfiles\"
+       fi
+       save_ifs="$IFS"; IFS='~'
+       for cmd in $cmds; do
+         IFS="$save_ifs"
+         eval cmd=\"$cmd\"
+         $show "$cmd"
+         $run eval "$cmd" || {
+           lt_exit=$?
+
+           # Restore the uninstalled library and exit
+           if test "$mode" = relink; then
+             $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)'
+           fi
+
+           exit $lt_exit
+         }
+       done
+       IFS="$save_ifs"
+
+       # Restore the uninstalled library and exit
+       if test "$mode" = relink; then
+         $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $?
+
+         if test -n "$convenience"; then
+           if test -z "$whole_archive_flag_spec"; then
+             $show "${rm}r $gentop"
+             $run ${rm}r "$gentop"
+           fi
+         fi
+
+         exit $EXIT_SUCCESS
+       fi
+
+       # Create links to the real library.
+       for linkname in $linknames; do
+         if test "$realname" != "$linkname"; then
+           $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
+           $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
+         fi
+       done
+
+       # If -module or -export-dynamic was specified, set the dlname.
+       if test "$module" = yes || test "$export_dynamic" = yes; then
+         # On all known operating systems, these are identical.
+         dlname="$soname"
+       fi
+      fi
+      ;;
+
+    obj)
+      if test -n "$deplibs"; then
+       $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
+      fi
+
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+       $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$rpath"; then
+       $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$xrpath"; then
+       $echo "$modename: warning: \`-R' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$vinfo"; then
+       $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
+      fi
+
+      if test -n "$release"; then
+       $echo "$modename: warning: \`-release' is ignored for objects" 1>&2
+      fi
+
+      case $output in
+      *.lo)
+       if test -n "$objs$old_deplibs"; then
+         $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
+         exit $EXIT_FAILURE
+       fi
+       libobj="$output"
+       obj=`$echo "X$output" | $Xsed -e "$lo2o"`
+       ;;
+      *)
+       libobj=
+       obj="$output"
+       ;;
+      esac
+
+      # Delete the old objects.
+      $run $rm $obj $libobj
+
+      # Objects from convenience libraries.  This assumes
+      # single-version convenience libraries.  Whenever we create
+      # different ones for PIC/non-PIC, this we'll have to duplicate
+      # the extraction.
+      reload_conv_objs=
+      gentop=
+      # reload_cmds runs $LD directly, so let us get rid of
+      # -Wl from whole_archive_flag_spec
+      wl=
+
+      if test -n "$convenience"; then
+       if test -n "$whole_archive_flag_spec"; then
+         eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\"
+       else
+         gentop="$output_objdir/${obj}x"
+         generated="$generated $gentop"
+
+         func_extract_archives $gentop $convenience
+         reload_conv_objs="$reload_objs $func_extract_archives_result"
+       fi
+      fi
+
+      # Create the old-style object.
+      reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+      output="$obj"
+      cmds=$reload_cmds
+      save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+       IFS="$save_ifs"
+       eval cmd=\"$cmd\"
+       $show "$cmd"
+       $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+
+      # Exit if we aren't doing a library object file.
+      if test -z "$libobj"; then
+       if test -n "$gentop"; then
+         $show "${rm}r $gentop"
+         $run ${rm}r $gentop
+       fi
+
+       exit $EXIT_SUCCESS
+      fi
+
+      if test "$build_libtool_libs" != yes; then
+       if test -n "$gentop"; then
+         $show "${rm}r $gentop"
+         $run ${rm}r $gentop
+       fi
+
+       # Create an invalid libtool object if no PIC, so that we don't
+       # accidentally link it into a program.
+       # $show "echo timestamp > $libobj"
+       # $run eval "echo timestamp > $libobj" || exit $?
+       exit $EXIT_SUCCESS
+      fi
+
+      if test -n "$pic_flag" || test "$pic_mode" != default; then
+       # Only do commands if we really have different PIC objects.
+       reload_objs="$libobjs $reload_conv_objs"
+       output="$libobj"
+       cmds=$reload_cmds
+       save_ifs="$IFS"; IFS='~'
+       for cmd in $cmds; do
+         IFS="$save_ifs"
+         eval cmd=\"$cmd\"
+         $show "$cmd"
+         $run eval "$cmd" || exit $?
+       done
+       IFS="$save_ifs"
+      fi
+
+      if test -n "$gentop"; then
+       $show "${rm}r $gentop"
+       $run ${rm}r $gentop
+      fi
+
+      exit $EXIT_SUCCESS
+      ;;
+
+    prog)
+      case $host in
+       *cygwin*) output=`$echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;;
+      esac
+      if test -n "$vinfo"; then
+       $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
+      fi
+
+      if test -n "$release"; then
+       $echo "$modename: warning: \`-release' is ignored for programs" 1>&2
+      fi
+
+      if test "$preload" = yes; then
+       if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown &&
+          test "$dlopen_self_static" = unknown; then
+         $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
+       fi
+      fi
+
+      case $host in
+      *-*-rhapsody* | *-*-darwin1.[012])
+       # On Rhapsody replace the C library is the System framework
+       compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
+       finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
+       ;;
+      esac
+
+      case $host in
+      *darwin*)
+        # Don't allow lazy linking, it breaks C++ global constructors
+        if test "$tagname" = CXX ; then
+        compile_command="$compile_command ${wl}-bind_at_load"
+        finalize_command="$finalize_command ${wl}-bind_at_load"
+        fi
+        ;;
+      esac
+
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+       case " $new_libs " in
+       *" -L$path/$objdir "*) ;;
+       *)
+         case " $compile_deplibs " in
+         *" -L$path/$objdir "*)
+           new_libs="$new_libs -L$path/$objdir" ;;
+         esac
+         ;;
+       esac
+      done
+      for deplib in $compile_deplibs; do
+       case $deplib in
+       -L*)
+         case " $new_libs " in
+         *" $deplib "*) ;;
+         *) new_libs="$new_libs $deplib" ;;
+         esac
+         ;;
+       *) new_libs="$new_libs $deplib" ;;
+       esac
+      done
+      compile_deplibs="$new_libs"
+
+
+      compile_command="$compile_command $compile_deplibs"
+      finalize_command="$finalize_command $finalize_deplibs"
+
+      if test -n "$rpath$xrpath"; then
+       # If the user specified any rpath flags, then add them.
+       for libdir in $rpath $xrpath; do
+         # This is the magic to use -rpath.
+         case "$finalize_rpath " in
+         *" $libdir "*) ;;
+         *) finalize_rpath="$finalize_rpath $libdir" ;;
+         esac
+       done
+      fi
+
+      # Now hardcode the library paths
+      rpath=
+      hardcode_libdirs=
+      for libdir in $compile_rpath $finalize_rpath; do
+       if test -n "$hardcode_libdir_flag_spec"; then
+         if test -n "$hardcode_libdir_separator"; then
+           if test -z "$hardcode_libdirs"; then
+             hardcode_libdirs="$libdir"
+           else
+             # Just accumulate the unique libdirs.
+             case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+             *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+               ;;
+             *)
+               hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+               ;;
+             esac
+           fi
+         else
+           eval flag=\"$hardcode_libdir_flag_spec\"
+           rpath="$rpath $flag"
+         fi
+       elif test -n "$runpath_var"; then
+         case "$perm_rpath " in
+         *" $libdir "*) ;;
+         *) perm_rpath="$perm_rpath $libdir" ;;
+         esac
+       fi
+       case $host in
+       *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+         testbindir=`$echo "X$libdir" | $Xsed -e 's*/lib$*/bin*'`
+         case :$dllsearchpath: in
+         *":$libdir:"*) ;;
+         *) dllsearchpath="$dllsearchpath:$libdir";;
+         esac
+         case :$dllsearchpath: in
+         *":$testbindir:"*) ;;
+         *) dllsearchpath="$dllsearchpath:$testbindir";;
+         esac
+         ;;
+       esac
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+        test -n "$hardcode_libdirs"; then
+       libdir="$hardcode_libdirs"
+       eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      compile_rpath="$rpath"
+
+      rpath=
+      hardcode_libdirs=
+      for libdir in $finalize_rpath; do
+       if test -n "$hardcode_libdir_flag_spec"; then
+         if test -n "$hardcode_libdir_separator"; then
+           if test -z "$hardcode_libdirs"; then
+             hardcode_libdirs="$libdir"
+           else
+             # Just accumulate the unique libdirs.
+             case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+             *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+               ;;
+             *)
+               hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+               ;;
+             esac
+           fi
+         else
+           eval flag=\"$hardcode_libdir_flag_spec\"
+           rpath="$rpath $flag"
+         fi
+       elif test -n "$runpath_var"; then
+         case "$finalize_perm_rpath " in
+         *" $libdir "*) ;;
+         *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+         esac
+       fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+        test -n "$hardcode_libdirs"; then
+       libdir="$hardcode_libdirs"
+       eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      finalize_rpath="$rpath"
+
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
+       # Transform all the library objects into standard objects.
+       compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+       finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+      fi
+
+      dlsyms=
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+       if test -n "$NM" && test -n "$global_symbol_pipe"; then
+         dlsyms="${outputname}S.c"
+       else
+         $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+       fi
+      fi
+
+      if test -n "$dlsyms"; then
+       case $dlsyms in
+       "") ;;
+       *.c)
+         # Discover the nlist of each of the dlfiles.
+         nlist="$output_objdir/${outputname}.nm"
+
+         $show "$rm $nlist ${nlist}S ${nlist}T"
+         $run $rm "$nlist" "${nlist}S" "${nlist}T"
+
+         # Parse the name list into a source file.
+         $show "creating $output_objdir/$dlsyms"
+
+         test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
+/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define lt_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */\
+"
+
+         if test "$dlself" = yes; then
+           $show "generating symbol list for \`$output'"
+
+           test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
+
+           # Add our own program objects to the symbol list.
+           progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+           for arg in $progfiles; do
+             $show "extracting global C symbols from \`$arg'"
+             $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+           done
+
+           if test -n "$exclude_expsyms"; then
+             $run eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+             $run eval '$mv "$nlist"T "$nlist"'
+           fi
+
+           if test -n "$export_symbols_regex"; then
+             $run eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+             $run eval '$mv "$nlist"T "$nlist"'
+           fi
+
+           # Prepare the list of exported symbols
+           if test -z "$export_symbols"; then
+             export_symbols="$output_objdir/$outputname.exp"
+             $run $rm $export_symbols
+             $run eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+              case $host in
+              *cygwin* | *mingw* )
+               $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+               $run eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+                ;;
+              esac
+           else
+             $run eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+             $run eval 'grep -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+             $run eval 'mv "$nlist"T "$nlist"'
+              case $host in
+              *cygwin* | *mingw* )
+               $run eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+               $run eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+                ;;
+              esac
+           fi
+         fi
+
+         for arg in $dlprefiles; do
+           $show "extracting global C symbols from \`$arg'"
+           name=`$echo "$arg" | ${SED} -e 's%^.*/%%'`
+           $run eval '$echo ": $name " >> "$nlist"'
+           $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+         done
+
+         if test -z "$run"; then
+           # Make sure we have at least an empty file.
+           test -f "$nlist" || : > "$nlist"
+
+           if test -n "$exclude_expsyms"; then
+             $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+             $mv "$nlist"T "$nlist"
+           fi
+
+           # Try sorting and uniquifying the output.
+           if grep -v "^: " < "$nlist" |
+               if sort -k 3 </dev/null >/dev/null 2>&1; then
+                 sort -k 3
+               else
+                 sort +2
+               fi |
+               uniq > "$nlist"S; then
+             :
+           else
+             grep -v "^: " < "$nlist" > "$nlist"S
+           fi
+
+           if test -f "$nlist"S; then
+             eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
+           else
+             $echo '/* NONE */' >> "$output_objdir/$dlsyms"
+           fi
+
+           $echo >> "$output_objdir/$dlsyms" "\
+
+#undef lt_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define lt_ptr void *
+#else
+# define lt_ptr char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+"
+
+           case $host in
+           *cygwin* | *mingw* )
+         $echo >> "$output_objdir/$dlsyms" "\
+/* DATA imports from DLLs on WIN32 can't be const, because
+   runtime relocations are performed -- see ld's documentation
+   on pseudo-relocs */
+struct {
+"
+             ;;
+           * )
+         $echo >> "$output_objdir/$dlsyms" "\
+const struct {
+"
+             ;;
+           esac
+
+
+         $echo >> "$output_objdir/$dlsyms" "\
+  const char *name;
+  lt_ptr address;
+}
+lt_preloaded_symbols[] =
+{\
+"
+
+           eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms"
+
+           $echo >> "$output_objdir/$dlsyms" "\
+  {0, (lt_ptr) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+         fi
+
+         pic_flag_for_symtable=
+         case $host in
+         # compiling the symbol table file with pic_flag works around
+         # a FreeBSD bug that causes programs to crash when -lm is
+         # linked before any other PIC object.  But we must not use
+         # pic_flag when linking with -static.  The problem exists in
+         # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+         *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+           case "$compile_command " in
+           *" -static "*) ;;
+           *) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND";;
+           esac;;
+         *-*-hpux*)
+           case "$compile_command " in
+           *" -static "*) ;;
+           *) pic_flag_for_symtable=" $pic_flag";;
+           esac
+         esac
+
+         # Now compile the dynamic symbol file.
+         $show "(cd $output_objdir && $LTCC  $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
+         $run eval '(cd $output_objdir && $LTCC  $LTCFLAGS -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+
+         # Clean up the generated files.
+         $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
+         $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
+
+         # Transform the symbol file into the correct name.
+          case $host in
+          *cygwin* | *mingw* )
+            if test -f "$output_objdir/${outputname}.def" ; then
+              compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%"`
+              finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%"`
+            else
+              compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+              finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+             fi
+            ;;
+          * )
+            compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+            finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+            ;;
+          esac
+         ;;
+       *)
+         $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
+         exit $EXIT_FAILURE
+         ;;
+       esac
+      else
+       # We keep going just in case the user didn't refer to
+       # lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
+       # really was required.
+
+       # Nullify the symbol file.
+       compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+       finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+      fi
+
+      if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+       # Replace the output file specification.
+       compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+       link_command="$compile_command$compile_rpath"
+
+       # We have no uninstalled library dependencies, so finalize right now.
+       $show "$link_command"
+       $run eval "$link_command"
+       exit_status=$?
+
+       # Delete the generated files.
+       if test -n "$dlsyms"; then
+         $show "$rm $output_objdir/${outputname}S.${objext}"
+         $run $rm "$output_objdir/${outputname}S.${objext}"
+       fi
+
+       exit $exit_status
+      fi
+
+      if test -n "$shlibpath_var"; then
+       # We should set the shlibpath_var
+       rpath=
+       for dir in $temp_rpath; do
+         case $dir in
+         [\\/]* | [A-Za-z]:[\\/]*)
+           # Absolute path.
+           rpath="$rpath$dir:"
+           ;;
+         *)
+           # Relative path: add a thisdir entry.
+           rpath="$rpath\$thisdir/$dir:"
+           ;;
+         esac
+       done
+       temp_rpath="$rpath"
+      fi
+
+      if test -n "$compile_shlibpath$finalize_shlibpath"; then
+       compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+       finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      compile_var=
+      finalize_var=
+      if test -n "$runpath_var"; then
+       if test -n "$perm_rpath"; then
+         # We should set the runpath_var.
+         rpath=
+         for dir in $perm_rpath; do
+           rpath="$rpath$dir:"
+         done
+         compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+       fi
+       if test -n "$finalize_perm_rpath"; then
+         # We should set the runpath_var.
+         rpath=
+         for dir in $finalize_perm_rpath; do
+           rpath="$rpath$dir:"
+         done
+         finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+       fi
+      fi
+
+      if test "$no_install" = yes; then
+       # We don't need to create a wrapper script.
+       link_command="$compile_var$compile_command$compile_rpath"
+       # Replace the output file specification.
+       link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+       # Delete the old output file.
+       $run $rm $output
+       # Link the executable and exit
+       $show "$link_command"
+       $run eval "$link_command" || exit $?
+       exit $EXIT_SUCCESS
+      fi
+
+      if test "$hardcode_action" = relink; then
+       # Fast installation is not supported
+       link_command="$compile_var$compile_command$compile_rpath"
+       relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+       $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
+       $echo "$modename: \`$output' will be relinked during installation" 1>&2
+      else
+       if test "$fast_install" != no; then
+         link_command="$finalize_var$compile_command$finalize_rpath"
+         if test "$fast_install" = yes; then
+           relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+         else
+           # fast_install is set to needless
+           relink_command=
+         fi
+       else
+         link_command="$compile_var$compile_command$compile_rpath"
+         relink_command="$finalize_var$finalize_command$finalize_rpath"
+       fi
+      fi
+
+      # Replace the output file specification.
+      link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+      # Delete the old output files.
+      $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+      $show "$link_command"
+      $run eval "$link_command" || exit $?
+
+      # Now create the wrapper script.
+      $show "creating $output"
+
+      # Quote the relink command for shipping.
+      if test -n "$relink_command"; then
+       # Preserve any variables that may affect compiler behavior
+       for var in $variables_saved_for_relink; do
+         if eval test -z \"\${$var+set}\"; then
+           relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
+         elif eval var_value=\$$var; test -z "$var_value"; then
+           relink_command="$var=; export $var; $relink_command"
+         else
+           var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
+           relink_command="$var=\"$var_value\"; export $var; $relink_command"
+         fi
+       done
+       relink_command="(cd `pwd`; $relink_command)"
+       relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Quote $echo for shipping.
+      if test "X$echo" = "X$SHELL $progpath --fallback-echo"; then
+       case $progpath in
+       [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";;
+       *) qecho="$SHELL `pwd`/$progpath --fallback-echo";;
+       esac
+       qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
+      else
+       qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Only actually do things if our run command is non-null.
+      if test -z "$run"; then
+       # win32 will think the script is a binary if it has
+       # a .exe suffix, so we strip it off here.
+       case $output in
+         *.exe) output=`$echo $output|${SED} 's,.exe$,,'` ;;
+       esac
+       # test for cygwin because mv fails w/o .exe extensions
+       case $host in
+         *cygwin*)
+           exeext=.exe
+           outputname=`$echo $outputname|${SED} 's,.exe$,,'` ;;
+         *) exeext= ;;
+       esac
+       case $host in
+         *cygwin* | *mingw* )
+            output_name=`basename $output`
+            output_path=`dirname $output`
+            cwrappersource="$output_path/$objdir/lt-$output_name.c"
+            cwrapper="$output_path/$output_name.exe"
+            $rm $cwrappersource $cwrapper
+            trap "$rm $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+           cat > $cwrappersource <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+   Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+
+   The $output program cannot be directly executed until all the libtool
+   libraries that it depends on are installed.
+
+   This wrapper executable should never be moved out of the build directory.
+   If it is, it will not operate correctly.
+
+   Currently, it simply execs the wrapper *script* "/bin/sh $output",
+   but could eventually absorb all of the scripts functionality and
+   exec $objdir/$outputname directly.
+*/
+EOF
+           cat >> $cwrappersource<<"EOF"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/stat.h>
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+  defined (__OS2__)
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# ifndef DIR_SEPARATOR_2
+#  define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+#  define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+        (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+  if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+/* -DDEBUG is fairly common in CFLAGS.  */
+#undef DEBUG
+#if defined DEBUGWRAPPER
+# define DEBUG(format, ...) fprintf(stderr, format, __VA_ARGS__)
+#else
+# define DEBUG(format, ...)
+#endif
+
+const char *program_name = NULL;
+
+void * xmalloc (size_t num);
+char * xstrdup (const char *string);
+const char * base_name (const char *name);
+char * find_executable(const char *wrapper);
+int    check_executable(const char *path);
+char * strendzap(char *str, const char *pat);
+void lt_fatal (const char *message, ...);
+
+int
+main (int argc, char *argv[])
+{
+  char **newargz;
+  int i;
+
+  program_name = (char *) xstrdup (base_name (argv[0]));
+  DEBUG("(main) argv[0]      : %s\n",argv[0]);
+  DEBUG("(main) program_name : %s\n",program_name);
+  newargz = XMALLOC(char *, argc+2);
+EOF
+
+            cat >> $cwrappersource <<EOF
+  newargz[0] = (char *) xstrdup("$SHELL");
+EOF
+
+            cat >> $cwrappersource <<"EOF"
+  newargz[1] = find_executable(argv[0]);
+  if (newargz[1] == NULL)
+    lt_fatal("Couldn't find %s", argv[0]);
+  DEBUG("(main) found exe at : %s\n",newargz[1]);
+  /* we know the script has the same name, without the .exe */
+  /* so make sure newargz[1] doesn't end in .exe */
+  strendzap(newargz[1],".exe");
+  for (i = 1; i < argc; i++)
+    newargz[i+1] = xstrdup(argv[i]);
+  newargz[argc+1] = NULL;
+
+  for (i=0; i<argc+1; i++)
+  {
+    DEBUG("(main) newargz[%d]   : %s\n",i,newargz[i]);
+    ;
+  }
+
+EOF
+
+            case $host_os in
+              mingw*)
+                cat >> $cwrappersource <<EOF
+  execv("$SHELL",(char const **)newargz);
+EOF
+              ;;
+              *)
+                cat >> $cwrappersource <<EOF
+  execv("$SHELL",newargz);
+EOF
+              ;;
+            esac
+
+            cat >> $cwrappersource <<"EOF"
+  return 127;
+}
+
+void *
+xmalloc (size_t num)
+{
+  void * p = (void *) malloc (num);
+  if (!p)
+    lt_fatal ("Memory exhausted");
+
+  return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+  return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL
+;
+}
+
+const char *
+base_name (const char *name)
+{
+  const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  /* Skip over the disk name in MSDOS pathnames. */
+  if (isalpha ((unsigned char)name[0]) && name[1] == ':')
+    name += 2;
+#endif
+
+  for (base = name; *name; name++)
+    if (IS_DIR_SEPARATOR (*name))
+      base = name + 1;
+  return base;
+}
+
+int
+check_executable(const char * path)
+{
+  struct stat st;
+
+  DEBUG("(check_executable)  : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!");
+  if ((!path) || (!*path))
+    return 0;
+
+  if ((stat (path, &st) >= 0) &&
+      (
+        /* MinGW & native WIN32 do not support S_IXOTH or S_IXGRP */
+#if defined (S_IXOTH)
+       ((st.st_mode & S_IXOTH) == S_IXOTH) ||
+#endif
+#if defined (S_IXGRP)
+       ((st.st_mode & S_IXGRP) == S_IXGRP) ||
+#endif
+       ((st.st_mode & S_IXUSR) == S_IXUSR))
+      )
+    return 1;
+  else
+    return 0;
+}
+
+/* Searches for the full path of the wrapper.  Returns
+   newly allocated full path name if found, NULL otherwise */
+char *
+find_executable (const char* wrapper)
+{
+  int has_slash = 0;
+  const char* p;
+  const char* p_next;
+  /* static buffer for getcwd */
+  char tmp[LT_PATHMAX + 1];
+  int tmp_len;
+  char* concat_name;
+
+  DEBUG("(find_executable)  : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!");
+
+  if ((wrapper == NULL) || (*wrapper == '\0'))
+    return NULL;
+
+  /* Absolute path? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  if (isalpha ((unsigned char)wrapper[0]) && wrapper[1] == ':')
+  {
+    concat_name = xstrdup (wrapper);
+    if (check_executable(concat_name))
+      return concat_name;
+    XFREE(concat_name);
+  }
+  else
+  {
+#endif
+    if (IS_DIR_SEPARATOR (wrapper[0]))
+    {
+      concat_name = xstrdup (wrapper);
+      if (check_executable(concat_name))
+        return concat_name;
+      XFREE(concat_name);
+    }
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  }
+#endif
+
+  for (p = wrapper; *p; p++)
+    if (*p == '/')
+    {
+      has_slash = 1;
+      break;
+    }
+  if (!has_slash)
+  {
+    /* no slashes; search PATH */
+    const char* path = getenv ("PATH");
+    if (path != NULL)
+    {
+      for (p = path; *p; p = p_next)
+      {
+        const char* q;
+        size_t p_len;
+        for (q = p; *q; q++)
+          if (IS_PATH_SEPARATOR(*q))
+            break;
+        p_len = q - p;
+        p_next = (*q == '\0' ? q : q + 1);
+        if (p_len == 0)
+        {
+          /* empty path: current directory */
+          if (getcwd (tmp, LT_PATHMAX) == NULL)
+            lt_fatal ("getcwd failed");
+          tmp_len = strlen(tmp);
+          concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1);
+          memcpy (concat_name, tmp, tmp_len);
+          concat_name[tmp_len] = '/';
+          strcpy (concat_name + tmp_len + 1, wrapper);
+        }
+        else
+        {
+          concat_name = XMALLOC(char, p_len + 1 + strlen(wrapper) + 1);
+          memcpy (concat_name, p, p_len);
+          concat_name[p_len] = '/';
+          strcpy (concat_name + p_len + 1, wrapper);
+        }
+        if (check_executable(concat_name))
+          return concat_name;
+        XFREE(concat_name);
+      }
+    }
+    /* not found in PATH; assume curdir */
+  }
+  /* Relative path | not found in path: prepend cwd */
+  if (getcwd (tmp, LT_PATHMAX) == NULL)
+    lt_fatal ("getcwd failed");
+  tmp_len = strlen(tmp);
+  concat_name = XMALLOC(char, tmp_len + 1 + strlen(wrapper) + 1);
+  memcpy (concat_name, tmp, tmp_len);
+  concat_name[tmp_len] = '/';
+  strcpy (concat_name + tmp_len + 1, wrapper);
+
+  if (check_executable(concat_name))
+    return concat_name;
+  XFREE(concat_name);
+  return NULL;
+}
+
+char *
+strendzap(char *str, const char *pat)
+{
+  size_t len, patlen;
+
+  assert(str != NULL);
+  assert(pat != NULL);
+
+  len = strlen(str);
+  patlen = strlen(pat);
+
+  if (patlen <= len)
+  {
+    str += len - patlen;
+    if (strcmp(str, pat) == 0)
+      *str = '\0';
+  }
+  return str;
+}
+
+static void
+lt_error_core (int exit_status, const char * mode,
+          const char * message, va_list ap)
+{
+  fprintf (stderr, "%s: %s: ", program_name, mode);
+  vfprintf (stderr, message, ap);
+  fprintf (stderr, ".\n");
+
+  if (exit_status >= 0)
+    exit (exit_status);
+}
+
+void
+lt_fatal (const char *message, ...)
+{
+  va_list ap;
+  va_start (ap, message);
+  lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
+  va_end (ap);
+}
+EOF
+          # we should really use a build-platform specific compiler
+          # here, but OTOH, the wrappers (shell script and this C one)
+          # are only useful if you want to execute the "real" binary.
+          # Since the "real" binary is built for $host, then this
+          # wrapper might as well be built for $host, too.
+          $run $LTCC $LTCFLAGS -s -o $cwrapper $cwrappersource
+          ;;
+        esac
+        $rm $output
+        trap "$rm $output; exit $EXIT_FAILURE" 1 2 15
+
+       $echo > $output "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='${SED} -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variable:
+  notinst_deplibs='$notinst_deplibs'
+else
+  # When we are sourced in execute mode, \$file and \$echo are already set.
+  if test \"\$libtool_execute_magic\" != \"$magic\"; then
+    echo=\"$qecho\"
+    file=\"\$0\"
+    # Make sure echo works.
+    if test \"X\$1\" = X--no-reexec; then
+      # Discard the --no-reexec flag, and continue.
+      shift
+    elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
+      # Yippee, \$echo works!
+      :
+    else
+      # Restart under the correct shell, and then maybe \$echo will work.
+      exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+    fi
+  fi\
+"
+       $echo >> $output "\
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
+
+    file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
+  done
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+       if test "$fast_install" = yes; then
+         $echo >> $output "\
+  program=lt-'$outputname'$exeext
+  progdir=\"\$thisdir/$objdir\"
+
+  if test ! -f \"\$progdir/\$program\" || \\
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+    file=\"\$\$-\$program\"
+
+    if test ! -d \"\$progdir\"; then
+      $mkdir \"\$progdir\"
+    else
+      $rm \"\$progdir/\$file\"
+    fi"
+
+         $echo >> $output "\
+
+    # relink executable if necessary
+    if test -n \"\$relink_command\"; then
+      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+      else
+       $echo \"\$relink_command_output\" >&2
+       $rm \"\$progdir/\$file\"
+       exit $EXIT_FAILURE
+      fi
+    fi
+
+    $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+    { $rm \"\$progdir/\$program\";
+      $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+    $rm \"\$progdir/\$file\"
+  fi"
+       else
+         $echo >> $output "\
+  program='$outputname'
+  progdir=\"\$thisdir/$objdir\"
+"
+       fi
+
+       $echo >> $output "\
+
+  if test -f \"\$progdir/\$program\"; then"
+
+       # Export our shlibpath_var if we have one.
+       if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+         $echo >> $output "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    # The second colon is a workaround for a bug in BeOS R4 sed
+    $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+    export $shlibpath_var
+"
+       fi
+
+       # fixup the dll searchpath if we need to.
+       if test -n "$dllsearchpath"; then
+         $echo >> $output "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
+       fi
+
+       $echo >> $output "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+
+      # Make sure env LD_LIBRARY_PATH does not mess us up
+      if test -n \"\${LD_LIBRARY_PATH+set}\"; then
+        export LD_LIBRARY_PATH=\$progdir:\$LD_LIBRARY_PATH
+      fi
+"
+       case $host in
+       # Backslashes separate directories on plain windows
+       *-*-mingw | *-*-os2*)
+         $echo >> $output "\
+      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+         ;;
+
+       *)
+         $echo >> $output "\
+      exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+         ;;
+       esac
+       $echo >> $output "\
+      \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+      exit $EXIT_FAILURE
+    fi
+  else
+    # The program doesn't exist.
+    \$echo \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
+    \$echo \"This script is just a wrapper for \$program.\" 1>&2
+    $echo \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit $EXIT_FAILURE
+  fi
+fi\
+"
+       chmod +x $output
+      fi
+      exit $EXIT_SUCCESS
+      ;;
+    esac
+
+    # See if we need to build an old-fashioned archive.
+    for oldlib in $oldlibs; do
+
+      if test "$build_libtool_libs" = convenience; then
+       oldobjs="$libobjs_save"
+       addlibs="$convenience"
+       build_libtool_libs=no
+      else
+       if test "$build_libtool_libs" = module; then
+         oldobjs="$libobjs_save"
+         build_libtool_libs=no
+       else
+         oldobjs="$old_deplibs $non_pic_objects"
+       fi
+       addlibs="$old_convenience"
+      fi
+
+      if test -n "$addlibs"; then
+       gentop="$output_objdir/${outputname}x"
+       generated="$generated $gentop"
+
+       func_extract_archives $gentop $addlibs
+       oldobjs="$oldobjs $func_extract_archives_result"
+      fi
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+       cmds=$old_archive_from_new_cmds
+      else
+       # POSIX demands no paths to be encoded in archives.  We have
+       # to avoid creating archives with duplicate basenames if we
+       # might have to extract them afterwards, e.g., when creating a
+       # static archive out of a convenience library, or when linking
+       # the entirety of a libtool archive into another (currently
+       # not supported by libtool).
+       if (for obj in $oldobjs
+           do
+             $echo "X$obj" | $Xsed -e 's%^.*/%%'
+           done | sort | sort -uc >/dev/null 2>&1); then
+         :
+       else
+         $echo "copying selected object files to avoid basename conflicts..."
+
+         if test -z "$gentop"; then
+           gentop="$output_objdir/${outputname}x"
+           generated="$generated $gentop"
+
+           $show "${rm}r $gentop"
+           $run ${rm}r "$gentop"
+           $show "$mkdir $gentop"
+           $run $mkdir "$gentop"
+           exit_status=$?
+           if test "$exit_status" -ne 0 && test ! -d "$gentop"; then
+             exit $exit_status
+           fi
+         fi
+
+         save_oldobjs=$oldobjs
+         oldobjs=
+         counter=1
+         for obj in $save_oldobjs
+         do
+           objbase=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
+           case " $oldobjs " in
+           " ") oldobjs=$obj ;;
+           *[\ /]"$objbase "*)
+             while :; do
+               # Make sure we don't pick an alternate name that also
+               # overlaps.
+               newobj=lt$counter-$objbase
+               counter=`expr $counter + 1`
+               case " $oldobjs " in
+               *[\ /]"$newobj "*) ;;
+               *) if test ! -f "$gentop/$newobj"; then break; fi ;;
+               esac
+             done
+             $show "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+             $run ln "$obj" "$gentop/$newobj" ||
+             $run cp "$obj" "$gentop/$newobj"
+             oldobjs="$oldobjs $gentop/$newobj"
+             ;;
+           *) oldobjs="$oldobjs $obj" ;;
+           esac
+         done
+       fi
+
+       eval cmds=\"$old_archive_cmds\"
+
+       if len=`expr "X$cmds" : ".*"` &&
+            test "$len" -le "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+         cmds=$old_archive_cmds
+       else
+         # the command line is too long to link in one step, link in parts
+         $echo "using piecewise archive linking..."
+         save_RANLIB=$RANLIB
+         RANLIB=:
+         objlist=
+         concat_cmds=
+         save_oldobjs=$oldobjs
+
+         # Is there a better way of finding the last object in the list?
+         for obj in $save_oldobjs
+         do
+           last_oldobj=$obj
+         done
+         for obj in $save_oldobjs
+         do
+           oldobjs="$objlist $obj"
+           objlist="$objlist $obj"
+           eval test_cmds=\"$old_archive_cmds\"
+           if len=`expr "X$test_cmds" : ".*" 2>/dev/null` &&
+              test "$len" -le "$max_cmd_len"; then
+             :
+           else
+             # the above command should be used before it gets too long
+             oldobjs=$objlist
+             if test "$obj" = "$last_oldobj" ; then
+               RANLIB=$save_RANLIB
+             fi
+             test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+             eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+             objlist=
+           fi
+         done
+         RANLIB=$save_RANLIB
+         oldobjs=$objlist
+         if test "X$oldobjs" = "X" ; then
+           eval cmds=\"\$concat_cmds\"
+         else
+           eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+         fi
+       fi
+      fi
+      save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+        eval cmd=\"$cmd\"
+       IFS="$save_ifs"
+       $show "$cmd"
+       $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$generated"; then
+      $show "${rm}r$generated"
+      $run ${rm}r$generated
+    fi
+
+    # Now create the libtool archive.
+    case $output in
+    *.la)
+      old_library=
+      test "$build_old_libs" = yes && old_library="$libname.$libext"
+      $show "creating $output"
+
+      # Preserve any variables that may affect compiler behavior
+      for var in $variables_saved_for_relink; do
+       if eval test -z \"\${$var+set}\"; then
+         relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
+       elif eval var_value=\$$var; test -z "$var_value"; then
+         relink_command="$var=; export $var; $relink_command"
+       else
+         var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
+         relink_command="$var=\"$var_value\"; export $var; $relink_command"
+       fi
+      done
+      # Quote the link command for shipping.
+      relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+      relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+      if test "$hardcode_automatic" = yes ; then
+       relink_command=
+      fi
+
+
+      # Only create the output if not a dry run.
+      if test -z "$run"; then
+       for installed in no yes; do
+         if test "$installed" = yes; then
+           if test -z "$install_libdir"; then
+             break
+           fi
+           output="$output_objdir/$outputname"i
+           # Replace all uninstalled libtool libraries with the installed ones
+           newdependency_libs=
+           for deplib in $dependency_libs; do
+             case $deplib in
+             *.la)
+               name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'`
+               eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+               if test -z "$libdir"; then
+                 $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
+                 exit $EXIT_FAILURE
+               fi
+               if test "X$EGREP" = X ; then
+                       EGREP=egrep
+               fi
+               # We do not want portage's install root ($D) present.  Check only for
+               # this if the .la is being installed.
+               if test "$installed" = yes && test "$D"; then
+                 eval mynewdependency_lib=`echo "$libdir/$name" |sed -e "s:$D:/:g" -e 's:/\+:/:g'`
+               else
+                 mynewdependency_lib="$libdir/$name"
+               fi
+               # Do not add duplicates
+               if test "$mynewdependency_lib"; then
+                 my_little_ninja_foo_1=`echo $newdependency_libs |$EGREP -e "$mynewdependency_lib"`
+                 if test -z "$my_little_ninja_foo_1"; then
+                   newdependency_libs="$newdependency_libs $mynewdependency_lib"
+                 fi
+               fi
+               ;;
+                 *)
+               if test "$installed" = yes; then
+                 # Rather use S=WORKDIR if our version of portage supports it.
+                 # This is because some ebuild (gcc) do not use $S as buildroot.
+                 if test "$PWORKDIR"; then
+                   S="$PWORKDIR"
+                 fi
+                 # We do not want portage's build root ($S) present.
+                 my_little_ninja_foo_2=`echo $deplib |$EGREP -e "$S"`
+                 # We do not want portage's install root ($D) present.
+                 my_little_ninja_foo_3=`echo $deplib |$EGREP -e "$D"`
+                 if test -n "$my_little_ninja_foo_2" && test "$S"; then
+                   mynewdependency_lib=""
+                 elif test -n "$my_little_ninja_foo_3" && test "$D"; then
+                   eval mynewdependency_lib=`echo "$deplib" |sed -e "s:$D:/:g" -e 's:/\+:/:g'`
+                 else
+                   mynewdependency_lib="$deplib"
+                 fi
+               else
+                 mynewdependency_lib="$deplib"
+               fi
+               # Do not add duplicates
+               if test "$mynewdependency_lib"; then
+                 my_little_ninja_foo_4=`echo $newdependency_libs |$EGREP -e "$mynewdependency_lib"`
+                 if test -z "$my_little_ninja_foo_4"; then
+                       newdependency_libs="$newdependency_libs $mynewdependency_lib"
+                 fi
+               fi
+               ;;
+             esac
+           done
+           dependency_libs="$newdependency_libs"
+           newdlfiles=
+           for lib in $dlfiles; do
+             name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+             eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+             if test -z "$libdir"; then
+               $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+               exit $EXIT_FAILURE
+             fi
+             newdlfiles="$newdlfiles $libdir/$name"
+           done
+           dlfiles="$newdlfiles"
+           newdlprefiles=
+           for lib in $dlprefiles; do
+             name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+             eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+             if test -z "$libdir"; then
+               $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+               exit $EXIT_FAILURE
+             fi
+             newdlprefiles="$newdlprefiles $libdir/$name"
+           done
+           dlprefiles="$newdlprefiles"
+         else
+           newdlfiles=
+           for lib in $dlfiles; do
+             case $lib in
+               [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+               *) abs=`pwd`"/$lib" ;;
+             esac
+             newdlfiles="$newdlfiles $abs"
+           done
+           dlfiles="$newdlfiles"
+           newdlprefiles=
+           for lib in $dlprefiles; do
+             case $lib in
+               [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+               *) abs=`pwd`"/$lib" ;;
+             esac
+             newdlprefiles="$newdlprefiles $abs"
+           done
+           dlprefiles="$newdlprefiles"
+         fi
+         $rm $output
+         # place dlname in correct position for cygwin
+         tdlname=$dlname
+         case $host,$output,$installed,$module,$dlname in
+           *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
+         esac
+         # Do not add duplicates
+         if test "$installed" = yes && test "$D"; then
+           install_libdir=`echo "$install_libdir" |sed -e "s:$D:/:g" -e 's:/\+:/:g'`
+         fi
+         $echo > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+         if test "$installed" = no && test "$need_relink" = yes; then
+           $echo >> $output "\
+relink_command=\"$relink_command\""
+         fi
+       done
+      fi
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
+      $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $?
+      ;;
+    esac
+    exit $EXIT_SUCCESS
+    ;;
+
+  # libtool install mode
+  install)
+    modename="$modename: install"
+
+    # There may be an optional sh(1) argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+       # Allow the use of GNU shtool's install command.
+       $echo "X$nonopt" | grep shtool > /dev/null; then
+      # Aesthetically quote it.
+      arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
+      case $arg in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
+       arg="\"$arg\""
+       ;;
+      esac
+      install_prog="$arg "
+      arg="$1"
+      shift
+    else
+      install_prog=
+      arg=$nonopt
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+    case $arg in
+    *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \      ]*|*]*|"")
+      arg="\"$arg\""
+      ;;
+    esac
+    install_prog="$install_prog$arg"
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=no
+    stripme=
+    for arg
+    do
+      if test -n "$dest"; then
+       files="$files $dest"
+       dest=$arg
+       continue
+      fi
+
+      case $arg in
+      -d) isdir=yes ;;
+      -f) 
+       case " $install_prog " in
+       *[\\\ /]cp\ *) ;;
+       *) prev=$arg ;;
+       esac
+       ;;
+      -g | -m | -o) prev=$arg ;;
+      -s)
+       stripme=" -s"
+       continue
+       ;;
+      -*)
+       ;;
+      *)
+       # If the previous option needed an argument, then skip it.
+       if test -n "$prev"; then
+         prev=
+       else
+         dest=$arg
+         continue
+       fi
+       ;;
+      esac
+
+      # Aesthetically quote the argument.
+      arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+      case $arg in
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \    ]*|*]*|"")
+       arg="\"$arg\""
+       ;;
+      esac
+      install_prog="$install_prog $arg"
+    done
+
+    if test -z "$install_prog"; then
+      $echo "$modename: you must specify an install program" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    if test -n "$prev"; then
+      $echo "$modename: the \`$prev' option requires an argument" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+       $echo "$modename: no file or destination specified" 1>&2
+      else
+       $echo "$modename: you must specify a destination" 1>&2
+      fi
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    # Strip any trailing slash from the destination.
+    dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test "$isdir" = yes; then
+      destdir="$dest"
+      destname=
+    else
+      destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
+      test "X$destdir" = "X$dest" && destdir=.
+      destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files
+      if test "$#" -gt 2; then
+       $echo "$modename: \`$dest' is not a directory" 1>&2
+       $echo "$help" 1>&2
+       exit $EXIT_FAILURE
+      fi
+    fi
+    case $destdir in
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
+    *)
+      for file in $files; do
+       case $file in
+       *.lo) ;;
+       *)
+         $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
+         $echo "$help" 1>&2
+         exit $EXIT_FAILURE
+         ;;
+       esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case $file in
+      *.$libext)
+       # Do the static libraries later.
+       staticlibs="$staticlibs $file"
+       ;;
+
+      *.la)
+       # Check to see that this really is a libtool archive.
+       if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+       else
+         $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
+         $echo "$help" 1>&2
+         exit $EXIT_FAILURE
+       fi
+
+       library_names=
+       old_library=
+       relink_command=
+       # If there is no directory component, then add one.
+       case $file in
+       */* | *\\*) . $file ;;
+       *) . ./$file ;;
+       esac
+
+       # Add the libdir to current_libdirs if it is the destination.
+       if test "X$destdir" = "X$libdir"; then
+         case "$current_libdirs " in
+         *" $libdir "*) ;;
+         *) current_libdirs="$current_libdirs $libdir" ;;
+         esac
+       else
+         # Note the libdir as a future libdir.
+         case "$future_libdirs " in
+         *" $libdir "*) ;;
+         *) future_libdirs="$future_libdirs $libdir" ;;
+         esac
+       fi
+
+       dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/
+       test "X$dir" = "X$file/" && dir=
+       dir="$dir$objdir"
+
+       if test -n "$relink_command"; then
+         # Determine the prefix the user has applied to our future dir.
+         inst_prefix_dir=`$echo "$destdir" | $SED "s%$libdir\$%%"`
+
+         # Don't allow the user to place us outside of our expected
+         # location b/c this prevents finding dependent libraries that
+         # are installed to the same prefix.
+         # At present, this check doesn't affect windows .dll's that
+         # are installed into $libdir/../bin (currently, that works fine)
+         # but it's something to keep an eye on.
+         if test "$inst_prefix_dir" = "$destdir"; then
+           $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2
+           exit $EXIT_FAILURE
+         fi
+
+         if test -n "$inst_prefix_dir"; then
+           # Stick the inst_prefix_dir data into the link command.
+           relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+         else
+           relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+         fi
+
+         $echo "$modename: warning: relinking \`$file'" 1>&2
+         $show "$relink_command"
+         if $run eval "$relink_command"; then :
+         else
+           $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+           exit $EXIT_FAILURE
+         fi
+       fi
+
+       # See the names of the shared library.
+       set dummy $library_names
+       if test -n "$2"; then
+         realname="$2"
+         shift
+         shift
+
+         srcname="$realname"
+         test -n "$relink_command" && srcname="$realname"T
+
+         # Install the shared library and build the symlinks.
+         $show "$install_prog $dir/$srcname $destdir/$realname"
+         $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $?
+         if test -n "$stripme" && test -n "$striplib"; then
+           $show "$striplib $destdir/$realname"
+           $run eval "$striplib $destdir/$realname" || exit $?
+         fi
+
+         if test "$#" -gt 0; then
+           # Delete the old symlinks, and create new ones.
+           # Try `ln -sf' first, because the `ln' binary might depend on
+           # the symlink we replace!  Solaris /bin/ln does not understand -f,
+           # so we also need to try rm && ln -s.
+           for linkname
+           do
+             if test "$linkname" != "$realname"; then
+                $show "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })"
+                $run eval "(cd $destdir && { $LN_S -f $realname $linkname || { $rm $linkname && $LN_S $realname $linkname; }; })"
+             fi
+           done
+         fi
+
+         # Do each command in the postinstall commands.
+         lib="$destdir/$realname"
+         cmds=$postinstall_cmds
+         save_ifs="$IFS"; IFS='~'
+         for cmd in $cmds; do
+           IFS="$save_ifs"
+           eval cmd=\"$cmd\"
+           $show "$cmd"
+           $run eval "$cmd" || {
+             lt_exit=$?
+
+             # Restore the uninstalled library and exit
+             if test "$mode" = relink; then
+               $run eval '(cd $output_objdir && $rm ${realname}T && $mv ${realname}U $realname)'
+             fi
+
+             exit $lt_exit
+           }
+         done
+         IFS="$save_ifs"
+       fi
+
+       # Install the pseudo-library for information purposes.
+       name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+       instname="$dir/$name"i
+       $show "$install_prog $instname $destdir/$name"
+       $run eval "$install_prog $instname $destdir/$name" || exit $?
+
+       # Maybe install the static library, too.
+       test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+       ;;
+
+      *.lo)
+       # Install (i.e. copy) a libtool object.
+
+       # Figure out destination file name, if it wasn't already specified.
+       if test -n "$destname"; then
+         destfile="$destdir/$destname"
+       else
+         destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+         destfile="$destdir/$destfile"
+       fi
+
+       # Deduce the name of the destination old-style object file.
+       case $destfile in
+       *.lo)
+         staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
+         ;;
+       *.$objext)
+         staticdest="$destfile"
+         destfile=
+         ;;
+       *)
+         $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
+         $echo "$help" 1>&2
+         exit $EXIT_FAILURE
+         ;;
+       esac
+
+       # Install the libtool object if requested.
+       if test -n "$destfile"; then
+         $show "$install_prog $file $destfile"
+         $run eval "$install_prog $file $destfile" || exit $?
+       fi
+
+       # Install the old object if enabled.
+       if test "$build_old_libs" = yes; then
+         # Deduce the name of the old-style object file.
+         staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
+
+         $show "$install_prog $staticobj $staticdest"
+         $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+       fi
+       exit $EXIT_SUCCESS
+       ;;
+
+      *)
+       # Figure out destination file name, if it wasn't already specified.
+       if test -n "$destname"; then
+         destfile="$destdir/$destname"
+       else
+         destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+         destfile="$destdir/$destfile"
+       fi
+
+       # If the file is missing, and there is a .exe on the end, strip it
+       # because it is most likely a libtool script we actually want to
+       # install
+       stripped_ext=""
+       case $file in
+         *.exe)
+           if test ! -f "$file"; then
+             file=`$echo $file|${SED} 's,.exe$,,'`
+             stripped_ext=".exe"
+           fi
+           ;;
+       esac
+
+       # Do a test to see if this is really a libtool program.
+       case $host in
+       *cygwin*|*mingw*)
+           wrapper=`$echo $file | ${SED} -e 's,.exe$,,'`
+           ;;
+       *)
+           wrapper=$file
+           ;;
+       esac
+       if (${SED} -e '4q' $wrapper | grep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then
+         notinst_deplibs=
+         relink_command=
+
+         # Note that it is not necessary on cygwin/mingw to append a dot to
+         # foo even if both foo and FILE.exe exist: automatic-append-.exe
+         # behavior happens only for exec(3), not for open(2)!  Also, sourcing
+         # `FILE.' does not work on cygwin managed mounts.
+         #
+         # If there is no directory component, then add one.
+         case $wrapper in
+         */* | *\\*) . ${wrapper} ;;
+         *) . ./${wrapper} ;;
+         esac
+
+         # Check the variables that should have been set.
+         if test -z "$notinst_deplibs"; then
+           $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2
+           exit $EXIT_FAILURE
+         fi
+
+         finalize=yes
+         for lib in $notinst_deplibs; do
+           # Check to see that each library is installed.
+           libdir=
+           if test -f "$lib"; then
+             # If there is no directory component, then add one.
+             case $lib in
+             */* | *\\*) . $lib ;;
+             *) . ./$lib ;;
+             esac
+           fi
+           libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test
+           if test -n "$libdir" && test ! -f "$libfile"; then
+             $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+             finalize=no
+           fi
+         done
+
+         relink_command=
+         # Note that it is not necessary on cygwin/mingw to append a dot to
+         # foo even if both foo and FILE.exe exist: automatic-append-.exe
+         # behavior happens only for exec(3), not for open(2)!  Also, sourcing
+         # `FILE.' does not work on cygwin managed mounts.
+         #
+         # If there is no directory component, then add one.
+         case $wrapper in
+         */* | *\\*) . ${wrapper} ;;
+         *) . ./${wrapper} ;;
+         esac
+
+         outputname=
+         if test "$fast_install" = no && test -n "$relink_command"; then
+           if test "$finalize" = yes && test -z "$run"; then
+             tmpdir=`func_mktempdir`
+             file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'`
+             outputname="$tmpdir/$file"
+             # Replace the output file specification.
+             relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+             $show "$relink_command"
+             if $run eval "$relink_command"; then :
+             else
+               $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+               ${rm}r "$tmpdir"
+               continue
+             fi
+             file="$outputname"
+           else
+             $echo "$modename: warning: cannot relink \`$file'" 1>&2
+           fi
+         else
+           # Install the binary that we compiled earlier.
+           file=`$echo "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+         fi
+       fi
+
+       # remove .exe since cygwin /usr/bin/install will append another
+       # one anyway 
+       case $install_prog,$host in
+       */usr/bin/install*,*cygwin*)
+         case $file:$destfile in
+         *.exe:*.exe)
+           # this is ok
+           ;;
+         *.exe:*)
+           destfile=$destfile.exe
+           ;;
+         *:*.exe)
+           destfile=`$echo $destfile | ${SED} -e 's,.exe$,,'`
+           ;;
+         esac
+         ;;
+       esac
+       $show "$install_prog$stripme $file $destfile"
+       $run eval "$install_prog\$stripme \$file \$destfile" || exit $?
+       test -n "$outputname" && ${rm}r "$tmpdir"
+       ;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+
+      $show "$install_prog $file $oldlib"
+      $run eval "$install_prog \$file \$oldlib" || exit $?
+
+      if test -n "$stripme" && test -n "$old_striplib"; then
+       $show "$old_striplib $oldlib"
+       $run eval "$old_striplib $oldlib" || exit $?
+      fi
+
+      # Do each command in the postinstall commands.
+      cmds=$old_postinstall_cmds
+      save_ifs="$IFS"; IFS='~'
+      for cmd in $cmds; do
+       IFS="$save_ifs"
+       eval cmd=\"$cmd\"
+       $show "$cmd"
+       $run eval "$cmd" || exit $?
+      done
+      IFS="$save_ifs"
+    done
+
+    if test -n "$future_libdirs"; then
+      $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+    fi
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      test -n "$run" && current_libdirs=" -n$current_libdirs"
+      exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+    else
+      exit $EXIT_SUCCESS
+    fi
+    ;;
+
+  # libtool finish mode
+  finish)
+    modename="$modename: finish"
+    libdirs="$nonopt"
+    admincmds=
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for dir
+      do
+       libdirs="$libdirs $dir"
+      done
+
+      for libdir in $libdirs; do
+       if test -n "$finish_cmds"; then
+         # Do each command in the finish commands.
+         cmds=$finish_cmds
+         save_ifs="$IFS"; IFS='~'
+         for cmd in $cmds; do
+           IFS="$save_ifs"
+           eval cmd=\"$cmd\"
+           $show "$cmd"
+           $run eval "$cmd" || admincmds="$admincmds
+       $cmd"
+         done
+         IFS="$save_ifs"
+       fi
+       if test -n "$finish_eval"; then
+         # Do the single finish_eval.
+         eval cmds=\"$finish_eval\"
+         $run eval "$cmds" || admincmds="$admincmds
+       $cmds"
+       fi
+      done
+    fi
+
+    # Exit here if they wanted silent mode.
+    test "$show" = : && exit $EXIT_SUCCESS
+
+    $echo "X----------------------------------------------------------------------" | $Xsed
+    $echo "Libraries have been installed in:"
+    for libdir in $libdirs; do
+      $echo "   $libdir"
+    done
+    $echo
+    $echo "If you ever happen to want to link against installed libraries"
+    $echo "in a given directory, LIBDIR, you must either use libtool, and"
+    $echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+    $echo "flag during linking and do at least one of the following:"
+    if test -n "$shlibpath_var"; then
+      $echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
+      $echo "     during execution"
+    fi
+    if test -n "$runpath_var"; then
+      $echo "   - add LIBDIR to the \`$runpath_var' environment variable"
+      $echo "     during linking"
+    fi
+    if test -n "$hardcode_libdir_flag_spec"; then
+      libdir=LIBDIR
+      eval flag=\"$hardcode_libdir_flag_spec\"
+
+      $echo "   - use the \`$flag' linker flag"
+    fi
+    if test -n "$admincmds"; then
+      $echo "   - have your system administrator run these commands:$admincmds"
+    fi
+    if test -f /etc/ld.so.conf; then
+      $echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+    fi
+    $echo
+    $echo "See any operating system documentation about shared libraries for"
+    $echo "more information, such as the ld(1) and ld.so(8) manual pages."
+    $echo "X----------------------------------------------------------------------" | $Xsed
+    exit $EXIT_SUCCESS
+    ;;
+
+  # libtool execute mode
+  execute)
+    modename="$modename: execute"
+
+    # The first argument is the command name.
+    cmd="$nonopt"
+    if test -z "$cmd"; then
+      $echo "$modename: you must specify a COMMAND" 1>&2
+      $echo "$help"
+      exit $EXIT_FAILURE
+    fi
+
+    # Handle -dlopen flags immediately.
+    for file in $execute_dlfiles; do
+      if test ! -f "$file"; then
+       $echo "$modename: \`$file' is not a file" 1>&2
+       $echo "$help" 1>&2
+       exit $EXIT_FAILURE
+      fi
+
+      dir=
+      case $file in
+      *.la)
+       # Check to see that this really is a libtool archive.
+       if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+       else
+         $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+         $echo "$help" 1>&2
+         exit $EXIT_FAILURE
+       fi
+
+       # Read the libtool library.
+       dlname=
+       library_names=
+
+       # If there is no directory component, then add one.
+       case $file in
+       */* | *\\*) . $file ;;
+       *) . ./$file ;;
+       esac
+
+       # Skip this library if it cannot be dlopened.
+       if test -z "$dlname"; then
+         # Warn if it was a shared library.
+         test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
+         continue
+       fi
+
+       dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+       test "X$dir" = "X$file" && dir=.
+
+       if test -f "$dir/$objdir/$dlname"; then
+         dir="$dir/$objdir"
+       else
+         $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+         exit $EXIT_FAILURE
+       fi
+       ;;
+
+      *.lo)
+       # Just add the directory containing the .lo file.
+       dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+       test "X$dir" = "X$file" && dir=.
+       ;;
+
+      *)
+       $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+       continue
+       ;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir="$absdir"
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+       eval "$shlibpath_var=\"\$dir\""
+      else
+       eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic="$magic"
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case $file in
+      -*) ;;
+      *)
+       # Do a test to see if this is really a libtool program.
+       if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+         # If there is no directory component, then add one.
+         case $file in
+         */* | *\\*) . $file ;;
+         *) . ./$file ;;
+         esac
+
+         # Transform arg to wrapped name.
+         file="$progdir/$program"
+       fi
+       ;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
+      args="$args \"$file\""
+    done
+
+    if test -z "$run"; then
+      if test -n "$shlibpath_var"; then
+       # Export the shlibpath_var.
+       eval "export $shlibpath_var"
+      fi
+
+      # Restore saved environment variables
+      if test "${save_LC_ALL+set}" = set; then
+       LC_ALL="$save_LC_ALL"; export LC_ALL
+      fi
+      if test "${save_LANG+set}" = set; then
+       LANG="$save_LANG"; export LANG
+      fi
+
+      # Now prepare to actually exec the command.
+      exec_cmd="\$cmd$args"
+    else
+      # Display what would be done.
+      if test -n "$shlibpath_var"; then
+       eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+       $echo "export $shlibpath_var"
+      fi
+      $echo "$cmd$args"
+      exit $EXIT_SUCCESS
+    fi
+    ;;
+
+  # libtool clean and uninstall mode
+  clean | uninstall)
+    modename="$modename: $mode"
+    rm="$nonopt"
+    files=
+    rmforce=
+    exit_status=0
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    for arg
+    do
+      case $arg in
+      -f) rm="$rm $arg"; rmforce=yes ;;
+      -*) rm="$rm $arg" ;;
+      *) files="$files $arg" ;;
+      esac
+    done
+
+    if test -z "$rm"; then
+      $echo "$modename: you must specify an RM program" 1>&2
+      $echo "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
+
+    rmdirs=
+
+    origobjdir="$objdir"
+    for file in $files; do
+      dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+      if test "X$dir" = "X$file"; then
+       dir=.
+       objdir="$origobjdir"
+      else
+       objdir="$dir/$origobjdir"
+      fi
+      name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+      test "$mode" = uninstall && objdir="$dir"
+
+      # Remember objdir for removal later, being careful to avoid duplicates
+      if test "$mode" = clean; then
+       case " $rmdirs " in
+         *" $objdir "*) ;;
+         *) rmdirs="$rmdirs $objdir" ;;
+       esac
+      fi
+
+      # Don't error if the file doesn't exist and rm -f was used.
+      if (test -L "$file") >/dev/null 2>&1 \
+       || (test -h "$file") >/dev/null 2>&1 \
+       || test -f "$file"; then
+       :
+      elif test -d "$file"; then
+       exit_status=1
+       continue
+      elif test "$rmforce" = yes; then
+       continue
+      fi
+
+      rmfiles="$file"
+
+      case $name in
+      *.la)
+       # Possibly a libtool archive, so verify it.
+       if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+         . $dir/$name
+
+         # Delete the libtool libraries and symlinks.
+         for n in $library_names; do
+           rmfiles="$rmfiles $objdir/$n"
+         done
+         test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
+
+         case "$mode" in
+         clean)
+           case "  $library_names " in
+           # "  " in the beginning catches empty $dlname
+           *" $dlname "*) ;;
+           *) rmfiles="$rmfiles $objdir/$dlname" ;;
+           esac
+            test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
+           ;;
+         uninstall)
+           if test -n "$library_names"; then
+             # Do each command in the postuninstall commands.
+             cmds=$postuninstall_cmds
+             save_ifs="$IFS"; IFS='~'
+             for cmd in $cmds; do
+               IFS="$save_ifs"
+               eval cmd=\"$cmd\"
+               $show "$cmd"
+               $run eval "$cmd"
+               if test "$?" -ne 0 && test "$rmforce" != yes; then
+                 exit_status=1
+               fi
+             done
+             IFS="$save_ifs"
+           fi
+
+           if test -n "$old_library"; then
+             # Do each command in the old_postuninstall commands.
+             cmds=$old_postuninstall_cmds
+             save_ifs="$IFS"; IFS='~'
+             for cmd in $cmds; do
+               IFS="$save_ifs"
+               eval cmd=\"$cmd\"
+               $show "$cmd"
+               $run eval "$cmd"
+               if test "$?" -ne 0 && test "$rmforce" != yes; then
+                 exit_status=1
+               fi
+             done
+             IFS="$save_ifs"
+           fi
+           # FIXME: should reinstall the best remaining shared library.
+           ;;
+         esac
+       fi
+       ;;
+
+      *.lo)
+       # Possibly a libtool object, so verify it.
+       if (${SED} -e '2q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+
+         # Read the .lo file
+         . $dir/$name
+
+         # Add PIC object to the list of files to remove.
+         if test -n "$pic_object" \
+            && test "$pic_object" != none; then
+           rmfiles="$rmfiles $dir/$pic_object"
+         fi
+
+         # Add non-PIC object to the list of files to remove.
+         if test -n "$non_pic_object" \
+            && test "$non_pic_object" != none; then
+           rmfiles="$rmfiles $dir/$non_pic_object"
+         fi
+       fi
+       ;;
+
+      *)
+       if test "$mode" = clean ; then
+         noexename=$name
+         case $file in
+         *.exe)
+           file=`$echo $file|${SED} 's,.exe$,,'`
+           noexename=`$echo $name|${SED} 's,.exe$,,'`
+           # $file with .exe has already been added to rmfiles,
+           # add $file without .exe
+           rmfiles="$rmfiles $file"
+           ;;
+         esac
+         # Do a test to see if this is a libtool program.
+         if (${SED} -e '4q' $file | grep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+           relink_command=
+           . $dir/$noexename
+
+           # note $name still contains .exe if it was in $file originally
+           # as does the version of $file that was added into $rmfiles
+           rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
+           if test "$fast_install" = yes && test -n "$relink_command"; then
+             rmfiles="$rmfiles $objdir/lt-$name"
+           fi
+           if test "X$noexename" != "X$name" ; then
+             rmfiles="$rmfiles $objdir/lt-${noexename}.c"
+           fi
+         fi
+       fi
+       ;;
+      esac
+      $show "$rm $rmfiles"
+      $run $rm $rmfiles || exit_status=1
+    done
+    objdir="$origobjdir"
+
+    # Try to remove the ${objdir}s in the directories where we deleted files
+    for dir in $rmdirs; do
+      if test -d "$dir"; then
+       $show "rmdir $dir"
+       $run rmdir $dir >/dev/null 2>&1
+      fi
+    done
+
+    exit $exit_status
+    ;;
+
+  "")
+    $echo "$modename: you must specify a MODE" 1>&2
+    $echo "$generic_help" 1>&2
+    exit $EXIT_FAILURE
+    ;;
+  esac
+
+  if test -z "$exec_cmd"; then
+    $echo "$modename: invalid operation mode \`$mode'" 1>&2
+    $echo "$generic_help" 1>&2
+    exit $EXIT_FAILURE
+  fi
+fi # test -z "$show_help"
+
+if test -n "$exec_cmd"; then
+  eval exec $exec_cmd
+  exit $EXIT_FAILURE
+fi
+
+# We need to display help for each of the modes.
+case $mode in
+"") $echo \
+"Usage: $modename [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+    --config          show all configuration variables
+    --debug           enable verbose shell tracing
+-n, --dry-run         display commands without modifying any files
+    --features        display basic configuration information and exit
+    --finish          same as \`--mode=finish'
+    --help            display this help message and exit
+    --mode=MODE       use operation mode MODE [default=inferred from MODE-ARGS]
+    --quiet           same as \`--silent'
+    --silent          don't print informational messages
+    --tag=TAG         use configuration variables from tag TAG
+    --version         print version information
+
+MODE must be one of the following:
+
+      clean           remove files from the build directory
+      compile         compile a source file into a libtool object
+      execute         automatically set library path, then run a program
+      finish          complete the installation of libtool libraries
+      install         install libraries or executables
+      link            create a library or an executable
+      uninstall       remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE.  Try \`$modename --help --mode=MODE' for
+a more detailed description of MODE.
+
+Report bugs to <bug-libtool@gnu.org>."
+  exit $EXIT_SUCCESS
+  ;;
+
+clean)
+  $echo \
+"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+  ;;
+
+compile)
+  $echo \
+"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
+  -prefer-pic       try to building PIC objects only
+  -prefer-non-pic   try to building non-PIC objects only
+  -static           always build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+  ;;
+
+execute)
+  $echo \
+"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+  ;;
+
+finish)
+  $echo \
+"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the \`--dry-run' option if you just want to see what would be executed."
+  ;;
+
+install)
+  $echo \
+"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+  ;;
+
+link)
+  $echo \
+"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -avoid-version    do not add a version suffix if possible
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -export-symbols SYMFILE
+                   try to export only the symbols listed in SYMFILE
+  -export-symbols-regex REGEX
+                   try to export only the symbols matching REGEX
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -module           build a library that can dlopened
+  -no-fast-install  disable the fast-install mode
+  -no-install       link a not-installable executable
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -objectlist FILE  Use a list of object files found in FILE to specify objects
+  -precious-files-regex REGEX
+                    don't remove output files matching REGEX
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
+  -static           do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+                   specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+  ;;
+
+uninstall)
+  $echo \
+"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+  ;;
+
+*)
+  $echo "$modename: invalid operation mode \`$mode'" 1>&2
+  $echo "$help" 1>&2
+  exit $EXIT_FAILURE
+  ;;
+esac
+
+$echo
+$echo "Try \`$modename --help' for more information about other modes."
+
+exit $?
+
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries.  Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them.  This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration.  But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+disable_libs=shared
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+disable_libs=static
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/utils/iaxclient/lib/portaudio/pa_tests/patest_in_overflow.c b/utils/iaxclient/lib/portaudio/pa_tests/patest_in_overflow.c
new file mode 100644 (file)
index 0000000..05a27b0
--- /dev/null
@@ -0,0 +1,224 @@
+/** @file patest_in_overflow.c
+       @brief Count input overflows (using paInputOverflow flag) under 
+       overloaded and normal conditions.
+    This test uses the same method to overload the stream as does
+    patest_out_underflow.c -- it generates sine waves until the cpu load
+    exceeds a certain level. However this test is only concerned with
+    input and so doesn't ouput any sound.
+    
+    @author Ross Bencina <rossb@audiomulch.com>
+       @author Phil Burk <philburk@softsynth.com>
+*/
+/*
+ * $Id: patest_in_overflow.c,v 1.2 2006/03/28 14:05:07 msmeyer Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2004 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define MAX_SINES     (500)
+#define MAX_LOAD      (1.2)
+#define SAMPLE_RATE   (44100)
+#define FRAMES_PER_BUFFER  (512)
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+#define TWOPI (M_PI * 2.0)
+
+typedef struct paTestData
+{
+    int sineCount;
+    double phases[MAX_SINES];
+    int countOverflows;
+    int inputOverflowCount;
+}
+paTestData;
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( const void *inputBuffer, void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                           const PaStreamCallbackTimeInfo* timeInfo,
+                           PaStreamCallbackFlags statusFlags,
+                           void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    float out;          /* variable to hold dummy output */
+    unsigned long i;
+    int j;
+    int finished = paContinue;
+    (void) timeInfo;    /* Prevent unused variable warning. */
+    (void) inputBuffer; /* Prevent unused variable warning. */
+    (void) outputBuffer; /* Prevent unused variable warning. */
+
+    if( data->countOverflows && (statusFlags & paInputOverflow) )
+        data->inputOverflowCount++;
+
+    for( i=0; i<framesPerBuffer; i++ )
+    {
+        float output = 0.0;
+        double phaseInc = 0.02;
+        double phase;
+
+        for( j=0; j<data->sineCount; j++ )
+        {
+            /* Advance phase of next oscillator. */
+            phase = data->phases[j];
+            phase += phaseInc;
+            if( phase > TWOPI ) phase -= TWOPI;
+
+            phaseInc *= 1.02;
+            if( phaseInc > 0.5 ) phaseInc *= 0.5;
+
+            /* This is not a very efficient way to calc sines. */
+            output += (float) sin( phase );
+            data->phases[j] = phase;
+        }
+        /* this is an input-only stream so we don't actually use the output */
+        out = (float) (output / data->sineCount);
+        (void) out; /* suppress unused variable warning*/
+    }
+
+    return finished;
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaStreamParameters inputParameters;
+    PaStream *stream;
+    PaError err;
+    int safeSineCount, stressedSineCount;
+    int safeOverflowCount, stressedOverflowCount;
+    paTestData data = {0};
+    double load;
+
+
+    printf("PortAudio Test: input only, no sound output. Load callback by performing calculations, count input overflows. SR = %d, BufSize = %d. MAX_LOAD = %f\n",
+        SAMPLE_RATE, FRAMES_PER_BUFFER, (float)MAX_LOAD );
+
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    inputParameters.device = Pa_GetDefaultInputDevice();  /* default input device */
+    inputParameters.channelCount = 1;                      /* mono output */
+    inputParameters.sampleFormat = paFloat32;              /* 32 bit floating point output */
+    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
+    inputParameters.hostApiSpecificStreamInfo = NULL;
+
+    err = Pa_OpenStream(
+              &stream,
+              &inputParameters,
+              NULL,    /* no output */
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              paClipOff,    /* we won't output out of range samples so don't bother clipping them */
+              patestCallback,
+              &data );    
+    if( err != paNoError ) goto error;
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+    printf("Establishing load conditions...\n" );
+
+    /* Determine number of sines required to get to 50% */
+    do
+    {
+        data.sineCount++;
+        Pa_Sleep( 100 );
+
+        load = Pa_GetStreamCpuLoad( stream );
+        printf("sineCount = %d, CPU load = %f\n", data.sineCount, load );
+    }
+    while( load < 0.5 && data.sineCount < (MAX_SINES-1));
+
+    safeSineCount = data.sineCount;
+
+    /* Calculate target stress value then ramp up to that level*/
+    stressedSineCount = (int) (2.0 * data.sineCount * MAX_LOAD );
+    if( stressedSineCount > MAX_SINES )
+        stressedSineCount = MAX_SINES;
+    for( ; data.sineCount < stressedSineCount; data.sineCount++ )
+    {
+        Pa_Sleep( 100 );
+        load = Pa_GetStreamCpuLoad( stream );
+        printf("STRESSING: sineCount = %d, CPU load = %f\n", data.sineCount, load );
+    }
+    
+    printf("Counting overflows for 5 seconds.\n");
+    data.countOverflows = 1;
+    Pa_Sleep( 5000 );
+
+    stressedOverflowCount = data.inputOverflowCount;
+
+    data.countOverflows = 0;
+    data.sineCount = safeSineCount;
+
+    printf("Resuming safe load...\n");
+    Pa_Sleep( 1500 );
+    data.inputOverflowCount = 0;
+    Pa_Sleep( 1500 );
+    load = Pa_GetStreamCpuLoad( stream );
+    printf("sineCount = %d, CPU load = %f\n", data.sineCount, load );
+
+    printf("Counting overflows for 5 seconds.\n");
+    data.countOverflows = 1;
+    Pa_Sleep( 5000 );
+
+    safeOverflowCount = data.inputOverflowCount;
+    
+    printf("Stop stream.\n");
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+    
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+    
+    Pa_Terminate();
+
+    if( stressedOverflowCount == 0 )
+        printf("Test failed, no input overflows detected under stress.\n");
+    else if( safeOverflowCount != 0 )
+        printf("Test failed, %d unexpected overflows detected under safe load.\n", safeOverflowCount);
+    else
+        printf("Test passed, %d expected input overflows detected under stress, 0 unexpected overflows detected under safe load.\n", stressedOverflowCount );
+
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/pablio/README.txt b/utils/iaxclient/lib/portaudio/pablio/README.txt
new file mode 100644 (file)
index 0000000..99c7d14
--- /dev/null
@@ -0,0 +1,39 @@
+README for PABLIO
+Portable Audio Blocking I/O Library
+Author: Phil Burk
+
+PABLIO is a simplified interface to PortAudio that provide
+read/write style blocking I/O.
+
+Please see the .DOC file for documentation.
+
+/*
+ * More information on PortAudio at: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+
diff --git a/utils/iaxclient/lib/portaudio/pablio/pablio.c b/utils/iaxclient/lib/portaudio/pablio/pablio.c
new file mode 100644 (file)
index 0000000..895616f
--- /dev/null
@@ -0,0 +1,307 @@
+/*
+ * $Id: pablio.c,v 1.3 2006/06/10 21:30:55 dmazzoni Exp $
+ * pablio.c
+ * Portable Audio Blocking Input/Output utility.
+ *
+ * Author: Phil Burk, http://www.softsynth.com
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "portaudio.h"
+#include "ringbuffer.h"
+#include "pablio.h"
+#include <string.h>
+
+/************************************************************************/
+/******** Constants *****************************************************/
+/************************************************************************/
+
+#define FRAMES_PER_BUFFER    (256)
+
+/************************************************************************/
+/******** Prototypes ****************************************************/
+/************************************************************************/
+
+static int blockingIOCallback( void *inputBuffer, void *outputBuffer,
+                               unsigned long framesPerBuffer,
+                               PaTimestamp outTime, void *userData );
+static PaError PABLIO_InitFIFO( RingBuffer *rbuf, long numFrames, long bytesPerFrame );
+static PaError PABLIO_TermFIFO( RingBuffer *rbuf );
+
+/************************************************************************/
+/******** Functions *****************************************************/
+/************************************************************************/
+
+/* Called from PortAudio.
+ * Read and write data only if there is room in FIFOs.
+ */
+static int blockingIOCallback( void *inputBuffer, void *outputBuffer,
+                               unsigned long framesPerBuffer,
+                               PaTimestamp outTime, void *userData )
+{
+    PABLIO_Stream *data = (PABLIO_Stream*)userData;
+    long numBytes = data->bytesPerFrame * framesPerBuffer;
+    (void) outTime;
+
+    /* This may get called with NULL inputBuffer during initial setup. */
+    if( inputBuffer != NULL )
+    {
+        RingBuffer_Write( &data->inFIFO, inputBuffer, numBytes );
+    }
+    if( outputBuffer != NULL )
+    {
+        int i;
+        int numRead = RingBuffer_Read( &data->outFIFO, outputBuffer, numBytes );
+        /* Zero out remainder of buffer if we run out of data. */
+        for( i=numRead; i<numBytes; i++ )
+        {
+            ((char *)outputBuffer)[i] = 0;
+        }
+    }
+
+    return 0;
+}
+
+/* Allocate buffer. */
+static PaError PABLIO_InitFIFO( RingBuffer *rbuf, long numFrames, long bytesPerFrame )
+{
+    long numBytes = numFrames * bytesPerFrame;
+    char *buffer = (char *) malloc( numBytes );
+    if( buffer == NULL ) return paInsufficientMemory;
+    memset( buffer, 0, numBytes );
+    return (PaError) RingBuffer_Init( rbuf, numBytes, buffer );
+}
+
+/* Free buffer. */
+static PaError PABLIO_TermFIFO( RingBuffer *rbuf )
+{
+    if( rbuf->buffer ) free( rbuf->buffer );
+    rbuf->buffer = NULL;
+    return paNoError;
+}
+
+/************************************************************
+ * Write data to ring buffer.
+ * Will not return until all the data has been written.
+ */
+long WriteAudioStream( PABLIO_Stream *aStream, void *data, long numFrames )
+{
+    long bytesWritten;
+    char *p = (char *) data;
+    long numBytes = aStream->bytesPerFrame * numFrames;
+    while( numBytes > 0)
+    {
+        bytesWritten = RingBuffer_Write( &aStream->outFIFO, p, numBytes );
+        numBytes -= bytesWritten;
+        p += bytesWritten;
+        if( numBytes > 0) Pa_Sleep(10);
+    }
+    return numFrames;
+}
+
+/************************************************************
+ * Read data from ring buffer.
+ * Will not return until all the data has been read.
+ */
+long ReadAudioStream( PABLIO_Stream *aStream, void *data, long numFrames )
+{
+    long bytesRead;
+    char *p = (char *) data;
+    long numBytes = aStream->bytesPerFrame * numFrames;
+    while( numBytes > 0)
+    {
+        bytesRead = RingBuffer_Read( &aStream->inFIFO, p, numBytes );
+        numBytes -= bytesRead;
+        p += bytesRead;
+        if( numBytes > 0) Pa_Sleep(10);
+    }
+    return numFrames;
+}
+
+/************************************************************
+ * Return the number of frames that could be written to the stream without
+ * having to wait.
+ */
+long GetAudioStreamWriteable( PABLIO_Stream *aStream )
+{
+    int bytesEmpty = RingBuffer_GetWriteAvailable( &aStream->outFIFO );
+    return bytesEmpty / aStream->bytesPerFrame;
+}
+
+/************************************************************
+ * Return the number of frames that are available to be read from the
+ * stream without having to wait.
+ */
+long GetAudioStreamReadable( PABLIO_Stream *aStream )
+{
+    int bytesFull = RingBuffer_GetReadAvailable( &aStream->inFIFO );
+    return bytesFull / aStream->bytesPerFrame;
+}
+
+/************************************************************/
+static unsigned long RoundUpToNextPowerOf2( unsigned long n )
+{
+    long numBits = 0;
+    if( ((n-1) & n) == 0) return n; /* Already Power of two. */
+    while( n > 0 )
+    {
+        n= n>>1;
+        numBits++;
+    }
+    return (1<<numBits);
+}
+
+/************************************************************
+ * Opens a PortAudio stream with default characteristics.
+ * Allocates PABLIO_Stream structure.
+ *
+ * flags parameter can be an ORed combination of:
+ *    PABLIO_READ, PABLIO_WRITE, or PABLIO_READ_WRITE,
+ *    and either PABLIO_MONO or PABLIO_STEREO
+ */
+PaError OpenAudioStream( PABLIO_Stream **rwblPtr, double sampleRate,
+                         PaSampleFormat format, long flags )
+{
+    long   bytesPerSample;
+    long   doRead = 0;
+    long   doWrite = 0;
+    PaError err;
+    PABLIO_Stream *aStream;
+    long   minNumBuffers;
+    long   numFrames;
+
+    /* Allocate PABLIO_Stream structure for caller. */
+    aStream = (PABLIO_Stream *) malloc( sizeof(PABLIO_Stream) );
+    if( aStream == NULL ) return paInsufficientMemory;
+    memset( aStream, 0, sizeof(PABLIO_Stream) );
+
+    /* Determine size of a sample. */
+    bytesPerSample = Pa_GetSampleSize( format );
+    if( bytesPerSample < 0 )
+    {
+        err = (PaError) bytesPerSample;
+        goto error;
+    }
+    aStream->samplesPerFrame = ((flags&PABLIO_MONO) != 0) ? 1 : 2;
+    aStream->bytesPerFrame = bytesPerSample * aStream->samplesPerFrame;
+
+    /* Initialize PortAudio  */
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    /* Warning: numFrames must be larger than amount of data processed per interrupt
+     *    inside PA to prevent glitches. Just to be safe, adjust size upwards.
+     */
+    minNumBuffers = 2 * Pa_GetMinNumBuffers( FRAMES_PER_BUFFER, sampleRate );
+    numFrames = minNumBuffers * FRAMES_PER_BUFFER;
+    numFrames = RoundUpToNextPowerOf2( numFrames );
+
+    /* Initialize Ring Buffers */
+    doRead = ((flags & PABLIO_READ) != 0);
+    doWrite = ((flags & PABLIO_WRITE) != 0);
+    if(doRead)
+    {
+        err = PABLIO_InitFIFO( &aStream->inFIFO, numFrames, aStream->bytesPerFrame );
+        if( err != paNoError ) goto error;
+    }
+    if(doWrite)
+    {
+        long numBytes;
+        err = PABLIO_InitFIFO( &aStream->outFIFO, numFrames, aStream->bytesPerFrame );
+        if( err != paNoError ) goto error;
+        /* Make Write FIFO appear full initially. */
+        numBytes = RingBuffer_GetWriteAvailable( &aStream->outFIFO );
+        RingBuffer_AdvanceWriteIndex( &aStream->outFIFO, numBytes );
+    }
+
+    /* Open a PortAudio stream that we will use to communicate with the underlying
+     * audio drivers. */
+    err = Pa_OpenStream(
+              &aStream->stream,
+              (doRead ? Pa_GetDefaultInputDeviceID() : paNoDevice),
+              (doRead ? aStream->samplesPerFrame : 0 ),
+              format,
+              NULL,
+              (doWrite ? Pa_GetDefaultOutputDeviceID() : paNoDevice),
+              (doWrite ? aStream->samplesPerFrame : 0 ),
+              format,
+              NULL,
+              sampleRate,
+              FRAMES_PER_BUFFER,
+              minNumBuffers,
+              paClipOff,       /* we won't output out of range samples so don't bother clipping them */
+              blockingIOCallback,
+              aStream );
+    if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( aStream->stream );
+    if( err != paNoError ) goto error;
+
+    *rwblPtr = aStream;
+    return paNoError;
+
+error:
+    CloseAudioStream( aStream );
+    *rwblPtr = NULL;
+    return err;
+}
+
+/************************************************************/
+PaError CloseAudioStream( PABLIO_Stream *aStream )
+{
+    PaError err;
+    int bytesEmpty;
+    int byteSize = aStream->outFIFO.bufferSize;
+
+    /* If we are writing data, make sure we play everything written. */
+    if( byteSize > 0 )
+    {
+        bytesEmpty = RingBuffer_GetWriteAvailable( &aStream->outFIFO );
+        while( bytesEmpty < byteSize )
+        {
+            Pa_Sleep( 10 );
+            bytesEmpty = RingBuffer_GetWriteAvailable( &aStream->outFIFO );
+        }
+    }
+
+    err = Pa_StopStream( aStream->stream );
+    if( err != paNoError ) goto error;
+    err = Pa_CloseStream( aStream->stream );
+    if( err != paNoError ) goto error;
+    Pa_Terminate();
+
+error:
+    PABLIO_TermFIFO( &aStream->inFIFO );
+    PABLIO_TermFIFO( &aStream->outFIFO );
+    free( aStream );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/pablio/pablio.def b/utils/iaxclient/lib/portaudio/pablio/pablio.def
new file mode 100644 (file)
index 0000000..a10f952
--- /dev/null
@@ -0,0 +1,35 @@
+LIBRARY      PABLIO
+DESCRIPTION  'PABLIO   Portable Audio Blocking I/O'
+
+EXPORTS
+    ; Explicit exports can go here
+       Pa_Initialize                   @1
+       Pa_Terminate                    @2
+       Pa_GetHostError                 @3
+       Pa_GetErrorText                 @4
+       Pa_CountDevices                 @5
+       Pa_GetDefaultInputDeviceID      @6
+       Pa_GetDefaultOutputDeviceID     @7
+       Pa_GetDeviceInfo                @8
+       Pa_OpenStream                   @9
+       Pa_OpenDefaultStream            @10
+       Pa_CloseStream                  @11
+       Pa_StartStream                  @12
+       Pa_StopStream                   @13
+       Pa_StreamActive                 @14
+       Pa_StreamTime                   @15
+       Pa_GetCPULoad                   @16
+       Pa_GetMinNumBuffers             @17
+       Pa_Sleep                        @18
+
+       OpenAudioStream                 @19
+       CloseAudioStream                @20
+       WriteAudioStream                @21
+       ReadAudioStream                 @22
+
+       Pa_GetSampleSize                @23
+
+   ;123456789012345678901234567890123456
+   ;000000000111111111122222222223333333
+
+
diff --git a/utils/iaxclient/lib/portaudio/pablio/pablio.h b/utils/iaxclient/lib/portaudio/pablio/pablio.h
new file mode 100644 (file)
index 0000000..b5aa6db
--- /dev/null
@@ -0,0 +1,109 @@
+#ifndef _PABLIO_H
+#define _PABLIO_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/*
+ * $Id: pablio.h,v 1.3 2006/06/10 21:30:55 dmazzoni Exp $
+ * PABLIO.h
+ * Portable Audio Blocking read/write utility.
+ *
+ * Author: Phil Burk, http://www.softsynth.com/portaudio/
+ *
+ * Include file for PABLIO, the Portable Audio Blocking I/O Library.
+ * PABLIO is built on top of PortAudio, the Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "portaudio.h"
+#include "ringbuffer.h"
+#include <string.h>
+
+typedef struct
+{
+    RingBuffer   inFIFO;
+    RingBuffer   outFIFO;
+    PaStream     *stream;
+    int          bytesPerFrame;
+    int          samplesPerFrame;
+}
+PABLIO_Stream;
+
+/* Values for flags for OpenAudioStream(). */
+#define PABLIO_READ     (1<<0)
+#define PABLIO_WRITE    (1<<1)
+#define PABLIO_READ_WRITE    (PABLIO_READ|PABLIO_WRITE)
+#define PABLIO_MONO     (1<<2)
+#define PABLIO_STEREO   (1<<3)
+
+/************************************************************
+ * Write data to ring buffer.
+ * Will not return until all the data has been written.
+ */
+long WriteAudioStream( PABLIO_Stream *aStream, void *data, long numFrames );
+
+/************************************************************
+ * Read data from ring buffer.
+ * Will not return until all the data has been read.
+ */
+long ReadAudioStream( PABLIO_Stream *aStream, void *data, long numFrames );
+
+/************************************************************
+ * Return the number of frames that could be written to the stream without
+ * having to wait.
+ */
+long GetAudioStreamWriteable( PABLIO_Stream *aStream );
+
+/************************************************************
+ * Return the number of frames that are available to be read from the
+ * stream without having to wait.
+ */
+long GetAudioStreamReadable( PABLIO_Stream *aStream );
+
+/************************************************************
+ * Opens a PortAudio stream with default characteristics.
+ * Allocates PABLIO_Stream structure.
+ *
+ * flags parameter can be an ORed combination of:
+ *    PABLIO_READ, PABLIO_WRITE, or PABLIO_READ_WRITE,
+ *    and either PABLIO_MONO or PABLIO_STEREO
+ */
+PaError OpenAudioStream( PABLIO_Stream **aStreamPtr, double sampleRate,
+                         PaSampleFormat format, long flags );
+
+PaError CloseAudioStream( PABLIO_Stream *aStream );
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* _PABLIO_H */
diff --git a/utils/iaxclient/lib/portaudio/pablio/ringbuffer.c b/utils/iaxclient/lib/portaudio/pablio/ringbuffer.c
new file mode 100644 (file)
index 0000000..67fe82a
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * $Id: ringbuffer.c,v 1.3 2006/06/10 21:30:55 dmazzoni Exp $
+ * ringbuffer.c
+ * Ring Buffer utility..
+ *
+ * Author: Phil Burk, http://www.softsynth.com
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "ringbuffer.h"
+#include <string.h>
+
+/***************************************************************************
+ * Initialize FIFO.
+ * numBytes must be power of 2, returns -1 if not.
+ */
+long RingBuffer_Init( RingBuffer *rbuf, long numBytes, void *dataPtr )
+{
+    if( ((numBytes-1) & numBytes) != 0) return -1; /* Not Power of two. */
+    rbuf->bufferSize = numBytes;
+    rbuf->buffer = (char *)dataPtr;
+    RingBuffer_Flush( rbuf );
+    rbuf->bigMask = (numBytes*2)-1;
+    rbuf->smallMask = (numBytes)-1;
+    return 0;
+}
+/***************************************************************************
+** Return number of bytes available for reading. */
+long RingBuffer_GetReadAvailable( RingBuffer *rbuf )
+{
+    return ( (rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask );
+}
+/***************************************************************************
+** Return number of bytes available for writing. */
+long RingBuffer_GetWriteAvailable( RingBuffer *rbuf )
+{
+    return ( rbuf->bufferSize - RingBuffer_GetReadAvailable(rbuf));
+}
+
+/***************************************************************************
+** Clear buffer. Should only be called when buffer is NOT being read. */
+void RingBuffer_Flush( RingBuffer *rbuf )
+{
+    rbuf->writeIndex = rbuf->readIndex = 0;
+}
+
+/***************************************************************************
+** Get address of region(s) to which we can write data.
+** If the region is contiguous, size2 will be zero.
+** If non-contiguous, size2 will be the size of second region.
+** Returns room available to be written or numBytes, whichever is smaller.
+*/
+long RingBuffer_GetWriteRegions( RingBuffer *rbuf, long numBytes,
+                                 void **dataPtr1, long *sizePtr1,
+                                 void **dataPtr2, long *sizePtr2 )
+{
+    long   index;
+    long   available = RingBuffer_GetWriteAvailable( rbuf );
+    if( numBytes > available ) numBytes = available;
+    /* Check to see if write is not contiguous. */
+    index = rbuf->writeIndex & rbuf->smallMask;
+    if( (index + numBytes) > rbuf->bufferSize )
+    {
+        /* Write data in two blocks that wrap the buffer. */
+        long   firstHalf = rbuf->bufferSize - index;
+        *dataPtr1 = &rbuf->buffer[index];
+        *sizePtr1 = firstHalf;
+        *dataPtr2 = &rbuf->buffer[0];
+        *sizePtr2 = numBytes - firstHalf;
+    }
+    else
+    {
+        *dataPtr1 = &rbuf->buffer[index];
+        *sizePtr1 = numBytes;
+        *dataPtr2 = NULL;
+        *sizePtr2 = 0;
+    }
+    return numBytes;
+}
+
+
+/***************************************************************************
+*/
+long RingBuffer_AdvanceWriteIndex( RingBuffer *rbuf, long numBytes )
+{
+    return rbuf->writeIndex = (rbuf->writeIndex + numBytes) & rbuf->bigMask;
+}
+
+/***************************************************************************
+** Get address of region(s) from which we can read data.
+** If the region is contiguous, size2 will be zero.
+** If non-contiguous, size2 will be the size of second region.
+** Returns room available to be written or numBytes, whichever is smaller.
+*/
+long RingBuffer_GetReadRegions( RingBuffer *rbuf, long numBytes,
+                                void **dataPtr1, long *sizePtr1,
+                                void **dataPtr2, long *sizePtr2 )
+{
+    long   index;
+    long   available = RingBuffer_GetReadAvailable( rbuf );
+    if( numBytes > available ) numBytes = available;
+    /* Check to see if read is not contiguous. */
+    index = rbuf->readIndex & rbuf->smallMask;
+    if( (index + numBytes) > rbuf->bufferSize )
+    {
+        /* Write data in two blocks that wrap the buffer. */
+        long firstHalf = rbuf->bufferSize - index;
+        *dataPtr1 = &rbuf->buffer[index];
+        *sizePtr1 = firstHalf;
+        *dataPtr2 = &rbuf->buffer[0];
+        *sizePtr2 = numBytes - firstHalf;
+    }
+    else
+    {
+        *dataPtr1 = &rbuf->buffer[index];
+        *sizePtr1 = numBytes;
+        *dataPtr2 = NULL;
+        *sizePtr2 = 0;
+    }
+    return numBytes;
+}
+/***************************************************************************
+*/
+long RingBuffer_AdvanceReadIndex( RingBuffer *rbuf, long numBytes )
+{
+    return rbuf->readIndex = (rbuf->readIndex + numBytes) & rbuf->bigMask;
+}
+
+/***************************************************************************
+** Return bytes written. */
+long RingBuffer_Write( RingBuffer *rbuf, void *data, long numBytes )
+{
+    long size1, size2, numWritten;
+    void *data1, *data2;
+    numWritten = RingBuffer_GetWriteRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 );
+    if( size2 > 0 )
+    {
+
+        memcpy( data1, data, size1 );
+        data = ((char *)data) + size1;
+        memcpy( data2, data, size2 );
+    }
+    else
+    {
+        memcpy( data1, data, size1 );
+    }
+    RingBuffer_AdvanceWriteIndex( rbuf, numWritten );
+    return numWritten;
+}
+
+/***************************************************************************
+** Return bytes read. */
+long RingBuffer_Read( RingBuffer *rbuf, void *data, long numBytes )
+{
+    long size1, size2, numRead;
+    void *data1, *data2;
+    numRead = RingBuffer_GetReadRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 );
+    if( size2 > 0 )
+    {
+        memcpy( data, data1, size1 );
+        data = ((char *)data) + size1;
+        memcpy( data, data2, size2 );
+    }
+    else
+    {
+        memcpy( data, data1, size1 );
+    }
+    RingBuffer_AdvanceReadIndex( rbuf, numRead );
+    return numRead;
+}
diff --git a/utils/iaxclient/lib/portaudio/pablio/ringbuffer.h b/utils/iaxclient/lib/portaudio/pablio/ringbuffer.h
new file mode 100644 (file)
index 0000000..b24d0b9
--- /dev/null
@@ -0,0 +1,114 @@
+#ifndef _RINGBUFFER_H
+#define _RINGBUFFER_H
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/*
+ * $Id: ringbuffer.h,v 1.3 2006/06/10 21:30:55 dmazzoni Exp $
+ * ringbuffer.h
+ * Ring Buffer utility..
+ *
+ * Author: Phil Burk, http://www.softsynth.com
+ *
+ * This program is distributed with the PortAudio Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "ringbuffer.h"
+#include <string.h>
+
+#ifdef USE_IAXC_RINGBUFFER_PREFIX
+#define RingBuffer_Init _iaxc_RingBuffer_Init
+#define RingBuffer_Flush _iaxc_RingBuffer_Flush
+#define RingBuffer_GetWriteAvailable _iaxc_RingBuffer_GetWriteAvailable
+#define RingBuffer_GetReadAvailable _iaxc_RingBuffer_GetReadAvailable
+#define RingBuffer_Write _iaxc_RingBuffer_Write
+#define RingBuffer_Read _iaxc_RingBuffer_Read
+#define RingBuffer_GetWriteRegions _iaxc_RingBuffer_GetWriteRegions
+#define RingBuffer_AdvanceWriteIndex _iaxc_RingBuffer_AdvanceWriteIndex
+#define RingBuffer_GetReadRegions _iaxc_RingBuffer_GetReadRegions
+#define RingBuffer_AdvanceReadIndex _iaxc_RingBuffer_AdvanceReadIndex
+#endif
+
+typedef struct
+{
+    long   bufferSize; /* Number of bytes in FIFO. Power of 2. Set by RingBuffer_Init. */
+    long   writeIndex; /* Index of next writable byte. Set by RingBuffer_AdvanceWriteIndex. */
+    long   readIndex;  /* Index of next readable byte. Set by RingBuffer_AdvanceReadIndex. */
+    long   bigMask;    /* Used for wrapping indices with extra bit to distinguish full/empty. */
+    long   smallMask;  /* Used for fitting indices to buffer. */
+    char *buffer;
+}
+RingBuffer;
+/*
+ * Initialize Ring Buffer.
+ * numBytes must be power of 2, returns -1 if not.
+ */
+long RingBuffer_Init( RingBuffer *rbuf, long numBytes, void *dataPtr );
+
+/* Clear buffer. Should only be called when buffer is NOT being read. */
+void RingBuffer_Flush( RingBuffer *rbuf );
+
+/* Return number of bytes available for writing. */
+long RingBuffer_GetWriteAvailable( RingBuffer *rbuf );
+/* Return number of bytes available for read. */
+long RingBuffer_GetReadAvailable( RingBuffer *rbuf );
+/* Return bytes written. */
+long RingBuffer_Write( RingBuffer *rbuf, void *data, long numBytes );
+/* Return bytes read. */
+long RingBuffer_Read( RingBuffer *rbuf, void *data, long numBytes );
+
+/* Get address of region(s) to which we can write data.
+** If the region is contiguous, size2 will be zero.
+** If non-contiguous, size2 will be the size of second region.
+** Returns room available to be written or numBytes, whichever is smaller.
+*/
+long RingBuffer_GetWriteRegions( RingBuffer *rbuf, long numBytes,
+                                 void **dataPtr1, long *sizePtr1,
+                                 void **dataPtr2, long *sizePtr2 );
+long RingBuffer_AdvanceWriteIndex( RingBuffer *rbuf, long numBytes );
+
+/* Get address of region(s) from which we can read data.
+** If the region is contiguous, size2 will be zero.
+** If non-contiguous, size2 will be the size of second region.
+** Returns room available to be written or numBytes, whichever is smaller.
+*/
+long RingBuffer_GetReadRegions( RingBuffer *rbuf, long numBytes,
+                                void **dataPtr1, long *sizePtr1,
+                                void **dataPtr2, long *sizePtr2 );
+
+long RingBuffer_AdvanceReadIndex( RingBuffer *rbuf, long numBytes );
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* _RINGBUFFER_H */
diff --git a/utils/iaxclient/lib/portaudio/pablio/test_rw.c b/utils/iaxclient/lib/portaudio/pablio/test_rw.c
new file mode 100644 (file)
index 0000000..18482fd
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * $Id: test_rw.c,v 1.3 2006/06/10 21:30:55 dmazzoni Exp $
+ * test_rw.c
+ * Read input from one stream and write it to another.
+ *
+ * Author: Phil Burk, http://www.softsynth.com/portaudio/
+ *
+ * This program uses PABLIO, the Portable Audio Blocking I/O Library.
+ * PABLIO is built on top of PortAudio, the Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "pablio.h"
+
+/*
+** Note that many of the older ISA sound cards on PCs do NOT support
+** full duplex audio (simultaneous record and playback).
+** And some only support full duplex at lower sample rates.
+*/
+#define SAMPLE_RATE          (44100)
+#define NUM_SECONDS              (5)
+#define SAMPLES_PER_FRAME        (2)
+#define FRAMES_PER_BLOCK        (64)
+
+/* Select whether we will use floats or shorts. */
+#if 1
+#define SAMPLE_TYPE  paFloat32
+typedef float SAMPLE;
+#else
+#define SAMPLE_TYPE  paInt16
+typedef short SAMPLE;
+#endif
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    int      i;
+    SAMPLE   samples[SAMPLES_PER_FRAME * FRAMES_PER_BLOCK];
+    PaError  err;
+    PABLIO_Stream     *aStream;
+
+    printf("Full duplex sound test using PortAudio and RingBuffers\n");
+    fflush(stdout);
+
+    /* Open simplified blocking I/O layer on top of PortAudio. */
+    err = OpenAudioStream( &aStream, SAMPLE_RATE, SAMPLE_TYPE,
+                           (PABLIO_READ_WRITE | PABLIO_STEREO) );
+    if( err != paNoError ) goto error;
+
+    /* Process samples in the foreground. */
+    for( i=0; i<(NUM_SECONDS * SAMPLE_RATE); i += FRAMES_PER_BLOCK )
+    {
+        /* Read one block of data into sample array from audio input. */
+        ReadAudioStream( aStream, samples, FRAMES_PER_BLOCK );
+        /* Write that same block of data to output. */
+        WriteAudioStream( aStream, samples, FRAMES_PER_BLOCK );
+    }
+
+    CloseAudioStream( aStream );
+
+    printf("Full duplex sound test complete.\n" );
+    fflush(stdout);
+    return 0;
+
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return -1;
+}
diff --git a/utils/iaxclient/lib/portaudio/pablio/test_rw_echo.c b/utils/iaxclient/lib/portaudio/pablio/test_rw_echo.c
new file mode 100644 (file)
index 0000000..d56c96d
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * $Id: test_rw_echo.c,v 1.3 2006/06/10 21:30:55 dmazzoni Exp $
+ * test_rw_echo.c
+ * Echo delayed input to output.
+ *
+ * Author: Phil Burk, http://www.softsynth.com/portaudio/
+ *
+ * This program uses PABLIO, the Portable Audio Blocking I/O Library.
+ * PABLIO is built on top of PortAudio, the Portable Audio Library.
+ *
+ * Note that if you need low latency, you should not use PABLIO.
+ * Use the PA_OpenStream callback technique which is lower level
+ * than PABLIO.
+ *
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "pablio.h"
+#include <string.h>
+
+/*
+** Note that many of the older ISA sound cards on PCs do NOT support
+** full duplex audio (simultaneous record and playback).
+** And some only support full duplex at lower sample rates.
+*/
+#define SAMPLE_RATE         (22050)
+#define NUM_SECONDS            (20)
+#define SAMPLES_PER_FRAME       (2)
+
+/* Select whether we will use floats or shorts. */
+#if 1
+#define SAMPLE_TYPE  paFloat32
+typedef float SAMPLE;
+#else
+#define SAMPLE_TYPE  paInt16
+typedef short SAMPLE;
+#endif
+
+#define NUM_ECHO_FRAMES   (2*SAMPLE_RATE)
+SAMPLE   samples[NUM_ECHO_FRAMES][SAMPLES_PER_FRAME] = {0.0};
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    int      i;
+    PaError  err;
+    PABLIO_Stream     *aInStream;
+    PABLIO_Stream     *aOutStream;
+    int      index;
+
+    printf("Full duplex sound test using PABLIO\n");
+    fflush(stdout);
+
+    /* Open simplified blocking I/O layer on top of PortAudio. */
+    /* Open input first so it can start to fill buffers. */
+    err = OpenAudioStream( &aInStream, SAMPLE_RATE, SAMPLE_TYPE,
+                           (PABLIO_READ | PABLIO_STEREO) );
+    if( err != paNoError ) goto error;
+    /* printf("opened input\n");  fflush(stdout); /**/
+
+    err = OpenAudioStream( &aOutStream, SAMPLE_RATE, SAMPLE_TYPE,
+                           (PABLIO_WRITE | PABLIO_STEREO) );
+    if( err != paNoError ) goto error;
+    /* printf("opened output\n");  fflush(stdout); /**/
+
+    /* Process samples in the foreground. */
+    index = 0;
+    for( i=0; i<(NUM_SECONDS * SAMPLE_RATE); i++ )
+    {
+        /* Write old frame of data to output. */
+        /* samples[index][1] = (i&256) * (1.0f/256.0f); /* sawtooth */
+        WriteAudioStream( aOutStream, &samples[index][0], 1 );
+
+        /* Read one frame of data into sample array for later output. */
+        ReadAudioStream( aInStream, &samples[index][0], 1 );
+        index += 1;
+        if( index >= NUM_ECHO_FRAMES ) index = 0;
+
+        if( (i & 0xFFFF) == 0 ) printf("i = %d\n", i ); fflush(stdout); /**/
+    }
+
+    CloseAudioStream( aOutStream );
+    CloseAudioStream( aInStream );
+
+    printf("R/W echo sound test complete.\n" );
+    fflush(stdout);
+    return 0;
+
+error:
+    fprintf( stderr, "An error occured while using PortAudio\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return -1;
+}
diff --git a/utils/iaxclient/lib/portaudio/pablio/test_w_saw.c b/utils/iaxclient/lib/portaudio/pablio/test_w_saw.c
new file mode 100644 (file)
index 0000000..b663280
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * $Id: test_w_saw.c,v 1.3 2006/06/10 21:30:55 dmazzoni Exp $
+ * test_w_saw.c
+ * Generate stereo sawtooth waveforms.
+ *
+ * Author: Phil Burk, http://www.softsynth.com
+ *
+ * This program uses PABLIO, the Portable Audio Blocking I/O Library.
+ * PABLIO is built on top of PortAudio, the Portable Audio Library.
+ *
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "pablio.h"
+#include <string.h>
+
+#define SAMPLE_RATE         (44100)
+#define NUM_SECONDS             (6)
+#define SAMPLES_PER_FRAME       (2)
+
+#define FREQUENCY           (220.0f)
+#define PHASE_INCREMENT     (2.0f * FREQUENCY / SAMPLE_RATE)
+#define FRAMES_PER_BLOCK    (100)
+
+float   samples[FRAMES_PER_BLOCK][SAMPLES_PER_FRAME];
+float   phases[SAMPLES_PER_FRAME];
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    int             i,j;
+    PaError         err;
+    PABLIO_Stream  *aOutStream;
+
+    printf("Generate sawtooth waves using PABLIO.\n");
+    fflush(stdout);
+
+    /* Open simplified blocking I/O layer on top of PortAudio. */
+    err = OpenAudioStream( &aOutStream, SAMPLE_RATE, paFloat32,
+                           (PABLIO_WRITE | PABLIO_STEREO) );
+    if( err != paNoError ) goto error;
+
+    /* Initialize oscillator phases. */
+    phases[0] = 0.0;
+    phases[1] = 0.0;
+
+    for( i=0; i<(NUM_SECONDS * SAMPLE_RATE); i += FRAMES_PER_BLOCK )
+    {
+        /* Generate sawtooth waveforms in a block for efficiency. */
+        for( j=0; j<FRAMES_PER_BLOCK; j++ )
+        {
+            /* Generate a sawtooth wave by incrementing a variable. */
+            phases[0] += PHASE_INCREMENT;
+            /* The signal range is -1.0 to +1.0 so wrap around if we go over. */
+            if( phases[0] > 1.0f ) phases[0] -= 2.0f;
+            samples[j][0] = phases[0];
+
+            /* On the second channel, generate a sawtooth wave a fifth higher. */
+            phases[1] += PHASE_INCREMENT * (3.0f / 2.0f);
+            if( phases[1] > 1.0f ) phases[1] -= 2.0f;
+            samples[j][1] = phases[1];
+        }
+
+        /* Write samples to output. */
+        WriteAudioStream( aOutStream, samples, FRAMES_PER_BLOCK );
+    }
+
+    CloseAudioStream( aOutStream );
+
+    printf("Sawtooth sound test complete.\n" );
+    fflush(stdout);
+    return 0;
+
+error:
+    fprintf( stderr, "An error occured while using PABLIO\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return -1;
+}
diff --git a/utils/iaxclient/lib/portaudio/pablio/test_w_saw8.c b/utils/iaxclient/lib/portaudio/pablio/test_w_saw8.c
new file mode 100644 (file)
index 0000000..962341c
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * $Id: test_w_saw8.c,v 1.3 2006/06/10 21:30:55 dmazzoni Exp $
+ * test_w_saw8.c
+ * Generate stereo 8 bit sawtooth waveforms.
+ *
+ * Author: Phil Burk, http://www.softsynth.com
+ *
+ * This program uses PABLIO, the Portable Audio Blocking I/O Library.
+ * PABLIO is built on top of PortAudio, the Portable Audio Library.
+ *
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "pablio.h"
+#include <string.h>
+
+#define SAMPLE_RATE         (22050)
+#define NUM_SECONDS             (6)
+#define SAMPLES_PER_FRAME       (2)
+
+
+#define FRAMES_PER_BLOCK    (100)
+
+unsigned char   samples[FRAMES_PER_BLOCK][SAMPLES_PER_FRAME];
+unsigned char   phases[SAMPLES_PER_FRAME];
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    int             i,j;
+    PaError         err;
+    PABLIO_Stream  *aOutStream;
+
+    printf("Generate unsigned 8 bit sawtooth waves using PABLIO.\n");
+    fflush(stdout);
+
+    /* Open simplified blocking I/O layer on top of PortAudio. */
+    err = OpenAudioStream( &aOutStream, SAMPLE_RATE, paUInt8,
+                           (PABLIO_WRITE | PABLIO_STEREO) );
+    if( err != paNoError ) goto error;
+
+    /* Initialize oscillator phases to "ground" level for paUInt8. */
+    phases[0] = 128;
+    phases[1] = 128;
+
+    for( i=0; i<(NUM_SECONDS * SAMPLE_RATE); i += FRAMES_PER_BLOCK )
+    {
+        /* Generate sawtooth waveforms in a block for efficiency. */
+        for( j=0; j<FRAMES_PER_BLOCK; j++ )
+        {
+            /* Generate a sawtooth wave by incrementing a variable. */
+            phases[0] += 1;
+            /* We don't have to do anything special to wrap when using paUint8 because
+             * 8 bit arithmetic automatically wraps. */
+            samples[j][0] = phases[0];
+
+            /* On the second channel, generate a higher sawtooth wave. */
+            phases[1] += 3;
+            samples[j][1] = phases[1];
+        }
+
+        /* Write samples to output. */
+        WriteAudioStream( aOutStream, samples, FRAMES_PER_BLOCK );
+    }
+
+    CloseAudioStream( aOutStream );
+
+    printf("Sawtooth sound test complete.\n" );
+    fflush(stdout);
+    return 0;
+
+error:
+    fprintf( stderr, "An error occured while using PABLIO\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return -1;
+}
diff --git a/utils/iaxclient/lib/portaudio/portaudio-2.0.pc b/utils/iaxclient/lib/portaudio/portaudio-2.0.pc
new file mode 100644 (file)
index 0000000..5f2921e
--- /dev/null
@@ -0,0 +1,12 @@
+prefix=/usr/local
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+Name: PortAudio
+Description: Portable audio I/O
+Requires:
+Version: 19
+
+Libs: -L${libdir} -lportaudio -lwinmm -lm
+Cflags: -I${includedir} -mthreads
diff --git a/utils/iaxclient/lib/portaudio/portaudio-2.0.pc.in b/utils/iaxclient/lib/portaudio/portaudio-2.0.pc.in
new file mode 100644 (file)
index 0000000..f5c1969
--- /dev/null
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: PortAudio
+Description: Portable audio I/O
+Requires:
+Version: 19
+
+Libs: -L${libdir} -lportaudio @LIBS@
+Cflags: -I${includedir} @THREAD_CFLAGS@
diff --git a/utils/iaxclient/lib/portaudio/src/SConscript b/utils/iaxclient/lib/portaudio/src/SConscript
new file mode 100644 (file)
index 0000000..a4929a0
--- /dev/null
@@ -0,0 +1,193 @@
+import os.path, copy, sys
+
+def checkSymbol(conf, header, library=None, symbol=None, autoAdd=True, critical=False, pkgName=None):
+    """ Check for symbol in library, optionally look only for header.
+    @param conf: Configure instance.
+    @param header: The header file where the symbol is declared.
+    @param library: The library in which the symbol exists, if None it is taken to be the standard C library.
+    @param symbol: The symbol to look for, if None only the header will be looked up.
+    @param autoAdd: Automatically link with this library if check is positive.
+    @param critical: Raise on error?
+    @param pkgName: Optional name of pkg-config entry for library, to determine build parameters.
+    @return: True/False
+    """
+    origEnv = conf.env.Copy() # Copy unmodified environment so we can restore it upon error
+    env = conf.env
+    if library is None:
+        library = "c"   # Standard library
+        autoAdd = False
+
+    if pkgName is not None:
+        origLibs = copy.copy(env.get("LIBS", None))
+
+        try: env.ParseConfig("pkg-config --silence-errors %s --cflags --libs" % pkgName)
+        except: pass
+        else:
+            # I see no other way of checking that the parsing succeeded, if it did add no more linking parameters
+            if env.get("LIBS", None) != origLibs:
+                autoAdd = False
+
+    try:
+        if not conf.CheckCHeader(header, include_quotes="<>"):
+            raise ConfigurationError("missing header %s" % header)
+        if symbol is not None and not conf.CheckLib(library, symbol, language="C", autoadd=autoAdd):
+            raise ConfigurationError("missing symbol %s in library %s" % (symbol, library))
+    except ConfigurationError:
+        conf.env = origEnv
+        if not critical:
+            return False
+        raise
+
+    return True
+
+import SCons.Errors
+
+# Import common variables
+
+# Could use '#' to refer to top-level SConstruct directory, but looks like env.SConsignFile doesn't interpret this at least :(
+sconsDir = os.path.abspath(os.path.join("build", "scons"))
+
+try:
+    Import("Platform", "Posix", "ConfigurationError", "ApiVer")
+except SCons.Errors.UserError:
+    # The common objects must be exported first
+    SConscript(os.path.join(sconsDir, "SConscript_common"))
+    Import("Platform", "Posix", "ConfigurationError", "ApiVer")
+
+Import("env")
+
+# This will be manipulated
+env = env.Copy()
+
+# We operate with a set of needed libraries and optional libraries, the latter stemming from host API implementations.
+# For libraries of both types we record a set of values that is used to look for the library in question, during
+# configuration. If the corresponding library for a host API implementation isn't found, the implementation is left out.
+neededLibs = []
+optionalImpls = {}
+if Platform in Posix:
+    env.Append(CPPPATH=os.path.join("os", "unix"))
+    neededLibs += [("pthread", "pthread.h", "pthread_create"), ("m", "math.h", "sin")]
+    if env["useALSA"]:
+        optionalImpls["ALSA"] = ("asound", "alsa/asoundlib.h", "snd_pcm_open")
+    if env["useJACK"]:
+        optionalImpls["JACK"] = ("jack", "jack/jack.h", "jack_client_new")
+    if env["useOSS"]:
+        # TODO: It looks like the prefix for soundcard.h depends on the platform
+        optionalImpls["OSS"] = ("oss", "sys/soundcard.h", None)
+else:
+    raise ConfigurationError("unknown platform %s" % Platform)
+
+if Platform == "darwin":
+    env.Append(LINKFLAGS=["-framework CoreAudio", "-framework AudioToolBox"])
+    env.Append(CPPDEFINES=["PA_USE_COREAUDIO"])
+elif Platform == "cygwin":
+    env.Append(LIBS=["winmm"])
+elif Platform == "irix":
+    neededLibs +=  [("audio", "dmedia/audio.h", "alOpenPort"), ("dmedia", "dmedia/dmedia.h", "dmGetUST")]
+    env.Append(CPPDEFINES=["PA_USE_SGI"])
+
+def CheckCTypeSize(context, tp):
+    """ Check size of C type.
+    @param context: A configuration context.
+    @param tp: The type to check.
+    @return: Size of type, in bytes.
+    """
+    context.Message("Checking the size of C type %s..." % tp)
+    ret = context.TryRun("""
+#include <stdio.h>
+
+int main() {
+    printf("%%d", sizeof(%s));
+    return 0;
+}
+""" % tp, ".c")
+    if not ret[0]:
+        context.Result(" Couldn't obtain size of type %s!" % tp)
+        return None
+
+    assert ret[1]
+    sz = int(ret[1])
+    context.Result("%d" % sz)
+    return sz
+
+"""
+if sys.byteorder == "little":
+    env.Append(CPPDEFINES=["PA_LITTLE_ENDIAN"])
+elif sys.byteorder == "big":
+    env.Append(CPPDEFINES=["PA_BIG_ENDIAN"])
+else:
+    raise ConfigurationError("unknown byte order: %s" % sys.byteorder)
+"""
+if env["enableDebugOutput"]:
+    env.Append(CPPDEFINES=["PA_ENABLE_DEBUG_OUTPUT"])
+
+# Start configuration
+
+# Use an absolute path for conf_dir, otherwise it gets created both relative to current directory and build directory
+conf = env.Configure(log_file=os.path.join(sconsDir, "sconf.log"), custom_tests={"CheckCTypeSize": CheckCTypeSize},
+        conf_dir=os.path.join(sconsDir, ".sconf_temp"))
+env.Append(CPPDEFINES=["SIZEOF_SHORT=%d" % conf.CheckCTypeSize("short")])
+env.Append(CPPDEFINES=["SIZEOF_INT=%d" % conf.CheckCTypeSize("int")])
+env.Append(CPPDEFINES=["SIZEOF_LONG=%d" % conf.CheckCTypeSize("long")])
+if checkSymbol(conf, "time.h", "rt", "clock_gettime"):
+    env.Append(CPPDEFINES=["HAVE_CLOCK_GETTIME"])
+if checkSymbol(conf, "time.h", symbol="nanosleep"):
+    env.Append(CPPDEFINES=["HAVE_NANOSLEEP"])
+
+# Look for needed libraries and link with them
+for lib, hdr, sym in neededLibs:
+    checkSymbol(conf, hdr, lib, sym, critical=True)
+# Look for host API libraries, if a library isn't found disable corresponding host API implementation.
+for name, val in optionalImpls.items():
+    lib, hdr, sym = val
+    if checkSymbol(conf, hdr, lib, sym, critical=False, pkgName=name.lower()):
+        env.Append(CPPDEFINES=["PA_USE_%s=1" % name.upper()])
+    else:
+        del optionalImpls[name]
+
+# Configuration finished
+env = conf.Finish()
+
+# PA infrastructure
+CommonSources = [os.path.join("common", f) for f in "pa_allocation.c pa_converters.c pa_cpuload.c pa_dither.c pa_front.c \
+        pa_process.c pa_skeleton.c pa_stream.c pa_trace.c".split()]
+
+# Host API implementations
+ImplSources = []
+if Platform in Posix:
+    ImplSources += [os.path.join("os", "unix", f) for f in "pa_unix_hostapis.c pa_unix_util.c".split()]
+
+if "ALSA" in optionalImpls:
+    ImplSources.append(os.path.join("hostapi", "alsa", "pa_linux_alsa.c"))
+if "JACK" in optionalImpls:
+    ImplSources.append(os.path.join("hostapi", "jack", "pa_jack.c"))
+if "OSS" in optionalImpls:
+    ImplSources.append(os.path.join("hostapi", "oss", "pa_unix_oss.c"))
+
+sources = CommonSources + ImplSources
+
+sharedLibEnv = env.Copy()
+if Platform in Posix:
+    # Add soname to library, this is so a reference is made to the versioned library in programs linking against libportaudio.so
+    sharedLibEnv.AppendUnique(SHLINKFLAGS="-Wl,-soname=libportaudio.so.%d" % int(ApiVer.split(".")[0]))
+sharedLib = sharedLibEnv.SharedLibrary(target="portaudio", source=sources)
+
+staticLib = env.StaticLibrary(target="portaudio", source=sources)
+
+if Platform in Posix:
+    prefix = env["prefix"]
+    includeDir = os.path.join(prefix, "include")
+    libDir = os.path.join(prefix, "lib")
+
+testNames = ["patest_sine", "paqa_devs", "paqa_errs", "patest1", "patest_buffer", "patest_callbackstop", "patest_clip", \
+        "patest_dither", "patest_hang", "patest_in_overflow", "patest_latency", "patest_leftright", "patest_longsine", \
+        "patest_many", "patest_maxsines", "patest_multi_sine", "patest_out_underflow", "patest_pink", "patest_prime", \
+        "patest_read_record", "patest_record", "patest_ringmix", "patest_saw", "patest_sine8", "patest_sine", \
+        "patest_sine_time", "patest_start_stop", "patest_stop", "patest_sync", \
+        "patest_toomanysines", "patest_underflow", "patest_wire", "patest_write_sine", "pa_devs", "pa_fuzz", "pa_minlat"]
+
+# The test directory ("bin") should be in the top-level PA directory
+tests = [env.Program(target=os.path.join("#", "bin", name), source=[os.path.join("#", "test", name + ".c"),
+        staticLib]) for name in testNames]
+
+Return("sources", "sharedLib", "staticLib", "tests", "env")
diff --git a/utils/iaxclient/lib/portaudio/src/common/pa_allocation.c b/utils/iaxclient/lib/portaudio/src/common/pa_allocation.c
new file mode 100644 (file)
index 0000000..ee5d41c
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ * $Id: pa_allocation.c,v 1.1 2006/06/10 21:30:55 dmazzoni Exp $
+ * Portable Audio I/O Library allocation group implementation
+ * memory allocation group for tracking allocation groups
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2002 Ross Bencina, Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file
+ @brief Allocation Group implementation.
+*/
+
+
+#include "pa_allocation.h"
+#include "pa_util.h"
+
+
+/*
+    Maintain 3 singly linked lists...
+    linkBlocks: the buffers used to allocate the links
+    spareLinks: links available for use in the allocations list
+    allocations: the buffers currently allocated using PaUtil_ContextAllocateMemory()
+
+    Link block size is doubled every time new links are allocated.
+*/
+
+
+#define PA_INITIAL_LINK_COUNT_    16
+
+struct PaUtilAllocationGroupLink
+{
+    struct PaUtilAllocationGroupLink *next;
+    void *buffer;
+};
+
+/*
+    Allocate a block of links. The first link will have it's buffer member
+    pointing to the block, and it's next member set to <nextBlock>. The remaining
+    links will have NULL buffer members, and each link will point to
+    the next link except the last, which will point to <nextSpare>
+*/
+static struct PaUtilAllocationGroupLink *AllocateLinks( long count,
+        struct PaUtilAllocationGroupLink *nextBlock,
+        struct PaUtilAllocationGroupLink *nextSpare )
+{
+    struct PaUtilAllocationGroupLink *result;
+    int i;
+    
+    result = (struct PaUtilAllocationGroupLink *)PaUtil_AllocateMemory(
+            sizeof(struct PaUtilAllocationGroupLink) * count );
+    if( result )
+    {
+        /* the block link */
+        result[0].buffer = result;
+        result[0].next = nextBlock;
+
+        /* the spare links */
+        for( i=1; i<count; ++i )
+        {
+            result[i].buffer = 0;
+            result[i].next = &result[i+1];
+        }
+        result[count-1].next = nextSpare;
+    }
+    
+    return result;
+}
+
+
+PaUtilAllocationGroup* PaUtil_CreateAllocationGroup( void )
+{
+    PaUtilAllocationGroup* result = 0;
+    struct PaUtilAllocationGroupLink *links;
+
+
+    links = AllocateLinks( PA_INITIAL_LINK_COUNT_, 0, 0 );
+    if( links != 0 )
+    {
+        result = (PaUtilAllocationGroup*)PaUtil_AllocateMemory( sizeof(PaUtilAllocationGroup) );
+        if( result )
+        {
+            result->linkCount = PA_INITIAL_LINK_COUNT_;
+            result->linkBlocks = &links[0];
+            result->spareLinks = &links[1];
+            result->allocations = 0;
+        }
+        else
+        {
+            PaUtil_FreeMemory( links );
+        }
+    }
+
+    return result;
+}
+
+
+void PaUtil_DestroyAllocationGroup( PaUtilAllocationGroup* group )
+{
+    struct PaUtilAllocationGroupLink *current = group->linkBlocks;
+    struct PaUtilAllocationGroupLink *next;
+
+    while( current )
+    {
+        next = current->next;
+        PaUtil_FreeMemory( current->buffer );
+        current = next;
+    }
+
+    PaUtil_FreeMemory( group );
+}
+
+
+void* PaUtil_GroupAllocateMemory( PaUtilAllocationGroup* group, long size )
+{
+    struct PaUtilAllocationGroupLink *links, *link;
+    void *result = 0;
+    
+    /* allocate more links if necessary */
+    if( !group->spareLinks )
+    {
+        /* double the link count on each block allocation */
+        links = AllocateLinks( group->linkCount, group->linkBlocks, group->spareLinks );
+        if( links )
+        {
+            group->linkCount += group->linkCount;
+            group->linkBlocks = &links[0];
+            group->spareLinks = &links[1];
+        }
+    }
+
+    if( group->spareLinks )
+    {
+        result = PaUtil_AllocateMemory( size );
+        if( result )
+        {
+            link = group->spareLinks;
+            group->spareLinks = link->next;
+
+            link->buffer = result;
+            link->next = group->allocations;
+
+            group->allocations = link;
+        }
+    }
+
+    return result;    
+}
+
+
+void PaUtil_GroupFreeMemory( PaUtilAllocationGroup* group, void *buffer )
+{
+    struct PaUtilAllocationGroupLink *current = group->allocations;
+    struct PaUtilAllocationGroupLink *previous = 0;
+
+    if( buffer == 0 )
+        return;
+
+    /* find the right link and remove it */
+    while( current )
+    {
+        if( current->buffer == buffer )
+        {
+            if( previous )
+            {
+                previous->next = current->next;
+            }
+            else
+            {
+                group->allocations = current->next;
+            }
+
+            current->buffer = 0;
+            current->next = group->spareLinks;
+            group->spareLinks = current;
+
+            break;
+        }
+        
+        previous = current;
+        current = current->next;
+    }
+
+    PaUtil_FreeMemory( buffer ); /* free the memory whether we found it in the list or not */
+}
+
+
+void PaUtil_FreeAllAllocations( PaUtilAllocationGroup* group )
+{
+    struct PaUtilAllocationGroupLink *current = group->allocations;
+    struct PaUtilAllocationGroupLink *previous = 0;
+
+    /* free all buffers in the allocations list */
+    while( current )
+    {
+        PaUtil_FreeMemory( current->buffer );
+        current->buffer = 0;
+
+        previous = current;
+        current = current->next;
+    }
+
+    /* link the former allocations list onto the front of the spareLinks list */
+    if( previous )
+    {
+        previous->next = group->spareLinks;
+        group->spareLinks = group->allocations;
+        group->allocations = 0;
+    }
+}
+
diff --git a/utils/iaxclient/lib/portaudio/src/common/pa_allocation.h b/utils/iaxclient/lib/portaudio/src/common/pa_allocation.h
new file mode 100644 (file)
index 0000000..4eab3d6
--- /dev/null
@@ -0,0 +1,95 @@
+#ifndef PA_ALLOCATION_H
+#define PA_ALLOCATION_H
+/*
+ * $Id: pa_allocation.h,v 1.1 2006/06/10 21:30:55 dmazzoni Exp $
+ * Portable Audio I/O Library allocation context header
+ * memory allocation context for tracking allocation groups
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2002 Ross Bencina, Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file
+ @brief Allocation Group prototypes. An Allocation Group makes it easy to
+ allocate multiple blocks of memory and free them all simultanously.
+ An allocation group is useful for keeping track of multiple blocks
+ of memory which are allocated at the same time (such as during initialization)
+ and need to be deallocated at the same time. The allocation group maintains
+ a list of allocated blocks, and can deallocate them all simultaneously which
+ can be usefull for cleaning up after a partially initialized object fails.
+
+ The allocation group implementation is built on top of the lower
+ level allocation functions defined in pa_util.h
+*/
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+
+typedef struct
+{
+    long linkCount;
+    struct PaUtilAllocationGroupLink *linkBlocks;
+    struct PaUtilAllocationGroupLink *spareLinks;
+    struct PaUtilAllocationGroupLink *allocations;
+}PaUtilAllocationGroup;
+
+
+
+/** Create an allocation group.
+*/
+PaUtilAllocationGroup* PaUtil_CreateAllocationGroup( void );
+
+/** Destroy an allocation group, but not the memory allocated through the group.
+*/
+void PaUtil_DestroyAllocationGroup( PaUtilAllocationGroup* group );
+
+/** Allocate a block of memory though an allocation group.
+*/
+void* PaUtil_GroupAllocateMemory( PaUtilAllocationGroup* group, long size );
+
+/** Free a block of memory that was previously allocated though an allocation
+ group. Calling this function is a relatively time consuming operation.
+ Under normal circumstances clients should call PaUtil_FreeAllAllocations to
+ free all allocated blocks simultaneously.
+ @see PaUtil_FreeAllAllocations
+*/
+void PaUtil_GroupFreeMemory( PaUtilAllocationGroup* group, void *buffer );
+
+/** Free all blocks of memory which have been allocated through the allocation
+ group. This function doesn't destroy the group itself.
+*/
+void PaUtil_FreeAllAllocations( PaUtilAllocationGroup* group );
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* PA_ALLOCATION_H */
diff --git a/utils/iaxclient/lib/portaudio/src/common/pa_converters.c b/utils/iaxclient/lib/portaudio/src/common/pa_converters.c
new file mode 100644 (file)
index 0000000..4c7828b
--- /dev/null
@@ -0,0 +1,1926 @@
+/*
+ * $Id: pa_converters.c,v 1.1 2006/06/10 21:30:55 dmazzoni Exp $
+ * Portable Audio I/O Library sample conversion mechanism
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2002 Phil Burk, Ross Bencina
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file
+ @brief Conversion functions implementations.
+ If the C9x function lrintf() is available, define PA_USE_C99_LRINTF to use it
+
+ @todo Consider whether functions which dither but don't clip should exist,
+ V18 automatically enabled clipping whenever dithering was selected. Perhaps
+ we should do the same.
+
+ @todo implement the converters marked IMPLEMENT ME: Float32_To_UInt8_Dither,
+ Float32_To_UInt8_Clip, Float32_To_UInt8_DitherClip, Int32_To_Int24_Dither,
+ Int32_To_UInt8_Dither, Int24_To_Int16_Dither, Int24_To_Int8_Dither, 
+ Int24_To_UInt8_Dither, Int16_To_Int8_Dither, Int16_To_UInt8_Dither,
+
+ @todo review the converters marked REVIEW: Float32_To_Int32,
+ Float32_To_Int32_Dither, Float32_To_Int32_Clip, Float32_To_Int32_DitherClip,
+ Int32_To_Int16_Dither, Int32_To_Int8_Dither, Int16_To_Int32
+*/
+
+
+#include "pa_converters.h"
+#include "pa_dither.h"
+#include "pa_endianness.h"
+#include "pa_types.h"
+
+
+PaSampleFormat PaUtil_SelectClosestAvailableFormat(
+        PaSampleFormat availableFormats, PaSampleFormat format )
+{
+    PaSampleFormat result;
+
+    format &= ~paNonInterleaved;
+    availableFormats &= ~paNonInterleaved;
+    
+    if( (format & availableFormats) == 0 )
+    {
+        /* NOTE: this code depends on the sample format constants being in
+            descending order of quality - ie best quality is 0
+            FIXME: should write an assert which checks that all of the
+            known constants conform to that requirement.
+        */
+
+        if( format != 0x01 )
+        {
+            /* scan for better formats */
+            result = format;
+            do
+            {
+                result >>= 1;
+            }
+            while( (result & availableFormats) == 0 && result != 0 );
+        }
+        else
+        {
+            result = 0;
+        }
+        
+        if( result == 0 ){
+            /* scan for worse formats */
+            result = format;
+            do
+            {
+                result <<= 1;
+            }
+            while( (result & availableFormats) == 0 && result != paCustomFormat );
+
+            if( (result & availableFormats) == 0 )
+                result = paSampleFormatNotSupported;
+        }
+        
+    }else{
+        result = format;
+    }
+
+    return result;
+}
+
+/* -------------------------------------------------------------------------- */
+
+#define PA_SELECT_FORMAT_( format, float32, int32, int24, int16, int8, uint8 ) \
+    switch( format & ~paNonInterleaved ){                                      \
+    case paFloat32:                                                            \
+        float32                                                                \
+    case paInt32:                                                              \
+        int32                                                                  \
+    case paInt24:                                                              \
+        int24                                                                  \
+    case paInt16:                                                              \
+        int16                                                                  \
+    case paInt8:                                                               \
+        int8                                                                   \
+    case paUInt8:                                                              \
+        uint8                                                                  \
+    default: return 0;                                                         \
+    }
+
+/* -------------------------------------------------------------------------- */
+
+#define PA_SELECT_CONVERTER_DITHER_CLIP_( flags, source, destination )         \
+    if( flags & paClipOff ){ /* no clip */                                     \
+        if( flags & paDitherOff ){ /* no dither */                             \
+            return paConverters. source ## _To_ ## destination;                \
+        }else{ /* dither */                                                    \
+            return paConverters. source ## _To_ ## destination ## _Dither;     \
+        }                                                                      \
+    }else{ /* clip */                                                          \
+        if( flags & paDitherOff ){ /* no dither */                             \
+            return paConverters. source ## _To_ ## destination ## _Clip;       \
+        }else{ /* dither */                                                    \
+            return paConverters. source ## _To_ ## destination ## _DitherClip; \
+        }                                                                      \
+    }
+
+/* -------------------------------------------------------------------------- */
+
+#define PA_SELECT_CONVERTER_DITHER_( flags, source, destination )              \
+    if( flags & paDitherOff ){ /* no dither */                                 \
+        return paConverters. source ## _To_ ## destination;                    \
+    }else{ /* dither */                                                        \
+        return paConverters. source ## _To_ ## destination ## _Dither;         \
+    }
+
+/* -------------------------------------------------------------------------- */
+
+#define PA_USE_CONVERTER_( source, destination )\
+    return paConverters. source ## _To_ ## destination;
+
+/* -------------------------------------------------------------------------- */
+
+#define PA_UNITY_CONVERSION_( wordlength )\
+    return paConverters. Copy_ ## wordlength ## _To_ ## wordlength;
+
+/* -------------------------------------------------------------------------- */
+
+PaUtilConverter* PaUtil_SelectConverter( PaSampleFormat sourceFormat,
+        PaSampleFormat destinationFormat, PaStreamFlags flags )
+{
+    PA_SELECT_FORMAT_( sourceFormat,
+                       /* paFloat32: */
+                       PA_SELECT_FORMAT_( destinationFormat,
+                                          /* paFloat32: */        PA_UNITY_CONVERSION_( 32 ),
+                                          /* paInt32: */          PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, Int32 ),
+                                          /* paInt24: */          PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, Int24 ),
+                                          /* paInt16: */          PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, Int16 ),
+                                          /* paInt8: */           PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, Int8 ),
+                                          /* paUInt8: */          PA_SELECT_CONVERTER_DITHER_CLIP_( flags, Float32, UInt8 )
+                                        ),
+                       /* paInt32: */
+                       PA_SELECT_FORMAT_( destinationFormat,
+                                          /* paFloat32: */        PA_USE_CONVERTER_( Int32, Float32 ),
+                                          /* paInt32: */          PA_UNITY_CONVERSION_( 32 ),
+                                          /* paInt24: */          PA_SELECT_CONVERTER_DITHER_( flags, Int32, Int24 ),
+                                          /* paInt16: */          PA_SELECT_CONVERTER_DITHER_( flags, Int32, Int16 ),
+                                          /* paInt8: */           PA_SELECT_CONVERTER_DITHER_( flags, Int32, Int8 ),
+                                          /* paUInt8: */          PA_SELECT_CONVERTER_DITHER_( flags, Int32, UInt8 )
+                                        ),
+                       /* paInt24: */
+                       PA_SELECT_FORMAT_( destinationFormat,
+                                          /* paFloat32: */        PA_USE_CONVERTER_( Int24, Float32 ),
+                                          /* paInt32: */          PA_USE_CONVERTER_( Int24, Int32 ),
+                                          /* paInt24: */          PA_UNITY_CONVERSION_( 24 ),
+                                          /* paInt16: */          PA_SELECT_CONVERTER_DITHER_( flags, Int24, Int16 ),
+                                          /* paInt8: */           PA_SELECT_CONVERTER_DITHER_( flags, Int24, Int8 ),
+                                          /* paUInt8: */          PA_SELECT_CONVERTER_DITHER_( flags, Int24, UInt8 )
+                                        ),
+                       /* paInt16: */
+                       PA_SELECT_FORMAT_( destinationFormat,
+                                          /* paFloat32: */        PA_USE_CONVERTER_( Int16, Float32 ),
+                                          /* paInt32: */          PA_USE_CONVERTER_( Int16, Int32 ),
+                                          /* paInt24: */          PA_USE_CONVERTER_( Int16, Int24 ),
+                                          /* paInt16: */          PA_UNITY_CONVERSION_( 16 ),
+                                          /* paInt8: */           PA_SELECT_CONVERTER_DITHER_( flags, Int16, Int8 ),
+                                          /* paUInt8: */          PA_SELECT_CONVERTER_DITHER_( flags, Int16, UInt8 )
+                                        ),
+                       /* paInt8: */
+                       PA_SELECT_FORMAT_( destinationFormat,
+                                          /* paFloat32: */        PA_USE_CONVERTER_( Int8, Float32 ),
+                                          /* paInt32: */          PA_USE_CONVERTER_( Int8, Int32 ),
+                                          /* paInt24: */          PA_USE_CONVERTER_( Int8, Int24 ),
+                                          /* paInt16: */          PA_USE_CONVERTER_( Int8, Int16 ),
+                                          /* paInt8: */           PA_UNITY_CONVERSION_( 8 ),
+                                          /* paUInt8: */          PA_USE_CONVERTER_( Int8, UInt8 )
+                                        ),
+                       /* paUInt8: */
+                       PA_SELECT_FORMAT_( destinationFormat,
+                                          /* paFloat32: */        PA_USE_CONVERTER_( UInt8, Float32 ),
+                                          /* paInt32: */          PA_USE_CONVERTER_( UInt8, Int32 ),
+                                          /* paInt24: */          PA_USE_CONVERTER_( UInt8, Int24 ),
+                                          /* paInt16: */          PA_USE_CONVERTER_( UInt8, Int16 ),
+                                          /* paInt8: */           PA_USE_CONVERTER_( UInt8, Int8 ),
+                                          /* paUInt8: */          PA_UNITY_CONVERSION_( 8 )
+                                        )
+                     )
+}
+
+/* -------------------------------------------------------------------------- */
+
+#ifdef PA_NO_STANDARD_CONVERTERS
+
+/* -------------------------------------------------------------------------- */
+
+PaUtilConverterTable paConverters = {
+    0, /* PaUtilConverter *Float32_To_Int32; */
+    0, /* PaUtilConverter *Float32_To_Int32_Dither; */
+    0, /* PaUtilConverter *Float32_To_Int32_Clip; */
+    0, /* PaUtilConverter *Float32_To_Int32_DitherClip; */
+
+    0, /* PaUtilConverter *Float32_To_Int24; */
+    0, /* PaUtilConverter *Float32_To_Int24_Dither; */
+    0, /* PaUtilConverter *Float32_To_Int24_Clip; */
+    0, /* PaUtilConverter *Float32_To_Int24_DitherClip; */
+
+    0, /* PaUtilConverter *Float32_To_Int16; */
+    0, /* PaUtilConverter *Float32_To_Int16_Dither; */
+    0, /* PaUtilConverter *Float32_To_Int16_Clip; */
+    0, /* PaUtilConverter *Float32_To_Int16_DitherClip; */
+
+    0, /* PaUtilConverter *Float32_To_Int8; */
+    0, /* PaUtilConverter *Float32_To_Int8_Dither; */
+    0, /* PaUtilConverter *Float32_To_Int8_Clip; */
+    0, /* PaUtilConverter *Float32_To_Int8_DitherClip; */
+
+    0, /* PaUtilConverter *Float32_To_UInt8; */
+    0, /* PaUtilConverter *Float32_To_UInt8_Dither; */
+    0, /* PaUtilConverter *Float32_To_UInt8_Clip; */
+    0, /* PaUtilConverter *Float32_To_UInt8_DitherClip; */
+
+    0, /* PaUtilConverter *Int32_To_Float32; */
+    0, /* PaUtilConverter *Int32_To_Int24; */
+    0, /* PaUtilConverter *Int32_To_Int24_Dither; */
+    0, /* PaUtilConverter *Int32_To_Int16; */
+    0, /* PaUtilConverter *Int32_To_Int16_Dither; */
+    0, /* PaUtilConverter *Int32_To_Int8; */
+    0, /* PaUtilConverter *Int32_To_Int8_Dither; */
+    0, /* PaUtilConverter *Int32_To_UInt8; */
+    0, /* PaUtilConverter *Int32_To_UInt8_Dither; */
+
+    0, /* PaUtilConverter *Int24_To_Float32; */
+    0, /* PaUtilConverter *Int24_To_Int32; */
+    0, /* PaUtilConverter *Int24_To_Int16; */
+    0, /* PaUtilConverter *Int24_To_Int16_Dither; */
+    0, /* PaUtilConverter *Int24_To_Int8; */
+    0, /* PaUtilConverter *Int24_To_Int8_Dither; */
+    0, /* PaUtilConverter *Int24_To_UInt8; */
+    0, /* PaUtilConverter *Int24_To_UInt8_Dither; */
+    
+    0, /* PaUtilConverter *Int16_To_Float32; */
+    0, /* PaUtilConverter *Int16_To_Int32; */
+    0, /* PaUtilConverter *Int16_To_Int24; */
+    0, /* PaUtilConverter *Int16_To_Int8; */
+    0, /* PaUtilConverter *Int16_To_Int8_Dither; */
+    0, /* PaUtilConverter *Int16_To_UInt8; */
+    0, /* PaUtilConverter *Int16_To_UInt8_Dither; */
+
+    0, /* PaUtilConverter *Int8_To_Float32; */
+    0, /* PaUtilConverter *Int8_To_Int32; */
+    0, /* PaUtilConverter *Int8_To_Int24 */
+    0, /* PaUtilConverter *Int8_To_Int16; */
+    0, /* PaUtilConverter *Int8_To_UInt8; */
+
+    0, /* PaUtilConverter *UInt8_To_Float32; */
+    0, /* PaUtilConverter *UInt8_To_Int32; */
+    0, /* PaUtilConverter *UInt8_To_Int24; */
+    0, /* PaUtilConverter *UInt8_To_Int16; */
+    0, /* PaUtilConverter *UInt8_To_Int8; */
+
+    0, /* PaUtilConverter *Copy_8_To_8; */
+    0, /* PaUtilConverter *Copy_16_To_16; */
+    0, /* PaUtilConverter *Copy_24_To_24; */
+    0  /* PaUtilConverter *Copy_32_To_32; */
+};
+
+/* -------------------------------------------------------------------------- */
+
+#else /* PA_NO_STANDARD_CONVERTERS is not defined */
+
+/* -------------------------------------------------------------------------- */
+
+#define PA_CLIP_( val, min, max )\
+    { val = ((val) < (min)) ? (min) : (((val) > (max)) ? (max) : (val)); }
+
+
+static const float const_1_div_128_ = 1.0f / 128.0f;  /* 8 bit multiplier */
+
+static const float const_1_div_32768_ = 1.0f / 32768.f; /* 16 bit multiplier */
+
+static const double const_1_div_2147483648_ = 1.0 / 2147483648.0; /* 32 bit multiplier */
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int32(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    float *src = (float*)sourceBuffer;
+    PaInt32 *dest =  (PaInt32*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        /* REVIEW */
+#ifdef PA_USE_C99_LRINTF
+        float scaled = *src * 0x7FFFFFFF;
+        *dest = lrintf(scaled-0.5f);
+#else
+        double scaled = *src * 0x7FFFFFFF;
+        *dest = (PaInt32) scaled;        
+#endif
+        
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int32_Dither(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    float *src = (float*)sourceBuffer;
+    PaInt32 *dest =  (PaInt32*)destinationBuffer;
+
+    while( count-- )
+    {
+        /* REVIEW */
+#ifdef PA_USE_C99_LRINTF
+        float dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
+        /* use smaller scaler to prevent overflow when we add the dither */
+        float dithered = ((float)*src * (2147483646.0f)) + dither;
+        *dest = lrintf(dithered - 0.5f);
+#else
+        double dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
+        /* use smaller scaler to prevent overflow when we add the dither */
+        double dithered = ((double)*src * (2147483646.0)) + dither;
+        *dest = (PaInt32) dithered;
+#endif
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int32_Clip(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    float *src = (float*)sourceBuffer;
+    PaInt32 *dest =  (PaInt32*)destinationBuffer;
+    (void) ditherGenerator; /* unused parameter */
+    
+    while( count-- )
+    {
+        /* REVIEW */
+#ifdef PA_USE_C99_LRINTF
+        float scaled = *src * 0x7FFFFFFF;
+        PA_CLIP_( scaled, -2147483648.f, 2147483647.f  );
+        *dest = lrintf(scaled-0.5f);
+#else
+        double scaled = *src * 0x7FFFFFFF;
+        PA_CLIP_( scaled, -2147483648., 2147483647.  );
+        *dest = (PaInt32) scaled;
+#endif
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int32_DitherClip(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    float *src = (float*)sourceBuffer;
+    PaInt32 *dest =  (PaInt32*)destinationBuffer;
+
+    while( count-- )
+    {
+        /* REVIEW */
+#ifdef PA_USE_C99_LRINTF
+        float dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
+        /* use smaller scaler to prevent overflow when we add the dither */
+        float dithered = ((float)*src * (2147483646.0f)) + dither;
+        PA_CLIP_( dithered, -2147483648.f, 2147483647.f  );
+        *dest = lrintf(dithered-0.5f);
+#else
+        double dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
+        /* use smaller scaler to prevent overflow when we add the dither */
+        double dithered = ((double)*src * (2147483646.0)) + dither;
+        PA_CLIP_( dithered, -2147483648., 2147483647.  );
+        *dest = (PaInt32) dithered;
+#endif
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int24(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    float *src = (float*)sourceBuffer;
+    unsigned char *dest = (unsigned char*)destinationBuffer;
+    PaInt32 temp;
+
+    (void) ditherGenerator; /* unused parameter */
+    
+    while( count-- )
+    {
+        /* convert to 32 bit and drop the low 8 bits */
+        double scaled = *src * 0x7FFFFFFF;
+        temp = (PaInt32) scaled;
+        
+#if defined(PA_LITTLE_ENDIAN)
+        dest[0] = (unsigned char)(temp >> 8);
+        dest[1] = (unsigned char)(temp >> 16);
+        dest[2] = (unsigned char)(temp >> 24);
+#elif defined(PA_BIG_ENDIAN)
+        dest[0] = (unsigned char)(temp >> 24);
+        dest[1] = (unsigned char)(temp >> 16);
+        dest[2] = (unsigned char)(temp >> 8);
+#endif
+
+        src += sourceStride;
+        dest += destinationStride * 3;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int24_Dither(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    float *src = (float*)sourceBuffer;
+    unsigned char *dest = (unsigned char*)destinationBuffer;
+    PaInt32 temp;
+
+    while( count-- )
+    {
+        /* convert to 32 bit and drop the low 8 bits */
+
+        double dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
+        /* use smaller scaler to prevent overflow when we add the dither */
+        double dithered = ((double)*src * (2147483646.0)) + dither;
+        
+        temp = (PaInt32) dithered;
+
+#if defined(PA_LITTLE_ENDIAN)
+        dest[0] = (unsigned char)(temp >> 8);
+        dest[1] = (unsigned char)(temp >> 16);
+        dest[2] = (unsigned char)(temp >> 24);
+#elif defined(PA_BIG_ENDIAN)
+        dest[0] = (unsigned char)(temp >> 24);
+        dest[1] = (unsigned char)(temp >> 16);
+        dest[2] = (unsigned char)(temp >> 8);
+#endif
+
+        src += sourceStride;
+        dest += destinationStride * 3;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int24_Clip(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    float *src = (float*)sourceBuffer;
+    unsigned char *dest = (unsigned char*)destinationBuffer;
+    PaInt32 temp;
+
+    (void) ditherGenerator; /* unused parameter */
+    
+    while( count-- )
+    {
+        /* convert to 32 bit and drop the low 8 bits */
+        double scaled = *src * 0x7FFFFFFF;
+        PA_CLIP_( scaled, -2147483648., 2147483647.  );
+        temp = (PaInt32) scaled;
+
+#if defined(PA_LITTLE_ENDIAN)
+        dest[0] = (unsigned char)(temp >> 8);
+        dest[1] = (unsigned char)(temp >> 16);
+        dest[2] = (unsigned char)(temp >> 24);
+#elif defined(PA_BIG_ENDIAN)
+        dest[0] = (unsigned char)(temp >> 24);
+        dest[1] = (unsigned char)(temp >> 16);
+        dest[2] = (unsigned char)(temp >> 8);
+#endif
+
+        src += sourceStride;
+        dest += destinationStride * 3;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int24_DitherClip(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    float *src = (float*)sourceBuffer;
+    unsigned char *dest = (unsigned char*)destinationBuffer;
+    PaInt32 temp;
+    
+    while( count-- )
+    {
+        /* convert to 32 bit and drop the low 8 bits */
+        
+        double dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
+        /* use smaller scaler to prevent overflow when we add the dither */
+        double dithered = ((double)*src * (2147483646.0)) + dither;
+        PA_CLIP_( dithered, -2147483648., 2147483647.  );
+        
+        temp = (PaInt32) dithered;
+
+#if defined(PA_LITTLE_ENDIAN)
+        dest[0] = (unsigned char)(temp >> 8);
+        dest[1] = (unsigned char)(temp >> 16);
+        dest[2] = (unsigned char)(temp >> 24);
+#elif defined(PA_BIG_ENDIAN)
+        dest[0] = (unsigned char)(temp >> 24);
+        dest[1] = (unsigned char)(temp >> 16);
+        dest[2] = (unsigned char)(temp >> 8);
+#endif
+
+        src += sourceStride;
+        dest += destinationStride * 3;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int16(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    float *src = (float*)sourceBuffer;
+    PaInt16 *dest =  (PaInt16*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+#ifdef PA_USE_C99_LRINTF
+        float tempf = (*src * (32767.0f)) ;
+        *dest = lrintf(tempf-0.5f);
+#else
+        short samp = (short) (*src * (32767.0f));
+        *dest = samp;
+#endif
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int16_Dither(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    float *src = (float*)sourceBuffer;
+    PaInt16 *dest = (PaInt16*)destinationBuffer;
+
+    while( count-- )
+    {
+
+        float dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
+        /* use smaller scaler to prevent overflow when we add the dither */
+        float dithered = (*src * (32766.0f)) + dither;
+
+#ifdef PA_USE_C99_LRINTF
+        *dest = lrintf(dithered-0.5f);
+#else
+        *dest = (PaInt16) dithered;
+#endif
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int16_Clip(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    float *src = (float*)sourceBuffer;
+    PaInt16 *dest =  (PaInt16*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+#ifdef PA_USE_C99_LRINTF
+        long samp = lrintf((*src * (32767.0f)) -0.5f);
+#else
+        long samp = (PaInt32) (*src * (32767.0f));
+#endif
+        PA_CLIP_( samp, -0x8000, 0x7FFF );
+        *dest = (PaInt16) samp;
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int16_DitherClip(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    float *src = (float*)sourceBuffer;
+    PaInt16 *dest =  (PaInt16*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+
+        float dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
+        /* use smaller scaler to prevent overflow when we add the dither */
+        float dithered = (*src * (32766.0f)) + dither;
+        PaInt32 samp = (PaInt32) dithered;
+        PA_CLIP_( samp, -0x8000, 0x7FFF );
+#ifdef PA_USE_C99_LRINTF
+        *dest = lrintf(samp-0.5f);
+#else
+        *dest = (PaInt16) samp;
+#endif
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int8(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    float *src = (float*)sourceBuffer;
+    signed char *dest =  (signed char*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        signed char samp = (signed char) (*src * (127.0f));
+        *dest = samp;
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int8_Dither(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    float *src = (float*)sourceBuffer;
+    signed char *dest =  (signed char*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        float dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
+        /* use smaller scaler to prevent overflow when we add the dither */
+        float dithered = (*src * (126.0f)) + dither;
+        PaInt32 samp = (PaInt32) dithered;
+        *dest = (signed char) samp;
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int8_Clip(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    float *src = (float*)sourceBuffer;
+    signed char *dest =  (signed char*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        PaInt32 samp = (PaInt32)(*src * (127.0f));
+        PA_CLIP_( samp, -0x80, 0x7F );
+        *dest = (signed char) samp;
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int8_DitherClip(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    float *src = (float*)sourceBuffer;
+    signed char *dest =  (signed char*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        float dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
+        /* use smaller scaler to prevent overflow when we add the dither */
+        float dithered = (*src * (126.0f)) + dither;
+        PaInt32 samp = (PaInt32) dithered;
+        PA_CLIP_( samp, -0x80, 0x7F );
+        *dest = (signed char) samp;
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_UInt8(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    float *src = (float*)sourceBuffer;
+    unsigned char *dest =  (unsigned char*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        unsigned char samp = (unsigned char)(128 + ((unsigned char) (*src * (127.0f))));
+        *dest = samp;
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_UInt8_Dither(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    float *src = (float*)sourceBuffer;
+    unsigned char *dest =  (unsigned char*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        /* IMPLEMENT ME */
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_UInt8_Clip(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    float *src = (float*)sourceBuffer;
+    unsigned char *dest =  (unsigned char*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        /* IMPLEMENT ME */
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_UInt8_DitherClip(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    float *src = (float*)sourceBuffer;
+    unsigned char *dest =  (unsigned char*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        /* IMPLEMENT ME */
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int32_To_Float32(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    PaInt32 *src = (PaInt32*)sourceBuffer;
+    float *dest =  (float*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        *dest = (float) ((double)*src * const_1_div_2147483648_);
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int32_To_Int24(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    PaInt32 *src    = (PaInt32*)sourceBuffer;
+    unsigned char *dest = (unsigned char*)destinationBuffer;
+    (void) ditherGenerator; /* unused parameter */
+    
+       while( count-- )
+    {
+               /* REVIEW */
+#if defined(PA_LITTLE_ENDIAN)
+        dest[0] = (unsigned char)(*src >> 8);
+        dest[1] = (unsigned char)(*src >> 16);
+        dest[2] = (unsigned char)(*src >> 24);
+#elif defined(PA_BIG_ENDIAN)
+        dest[0] = (unsigned char)(*src >> 24);
+        dest[1] = (unsigned char)(*src >> 16);
+        dest[2] = (unsigned char)(*src >> 8);
+#endif
+        src += sourceStride;
+        dest += destinationStride * 3;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int32_To_Int24_Dither(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    (void) destinationBuffer; /* unused parameters */
+    (void) destinationStride; /* unused parameters */
+    (void) sourceBuffer; /* unused parameters */
+    (void) sourceStride; /* unused parameters */
+    (void) count; /* unused parameters */
+    (void) ditherGenerator; /* unused parameters */
+    /* IMPLEMENT ME */
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int32_To_Int16(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    PaInt32 *src = (PaInt32*)sourceBuffer;
+    PaInt16 *dest =  (PaInt16*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        *dest = (PaInt16) ((*src) >> 16);
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int32_To_Int16_Dither(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    PaInt32 *src = (PaInt32*)sourceBuffer;
+    PaInt16 *dest =  (PaInt16*)destinationBuffer;
+    PaInt32 dither;
+
+    while( count-- )
+    {
+        /* REVIEW */
+        dither = PaUtil_Generate16BitTriangularDither( ditherGenerator );
+        *dest = (PaInt16) ((((*src)>>1) + dither) >> 15);
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int32_To_Int8(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    PaInt32 *src = (PaInt32*)sourceBuffer;
+    signed char *dest =  (signed char*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        *dest = (signed char) ((*src) >> 24);
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int32_To_Int8_Dither(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    PaInt32 *src = (PaInt32*)sourceBuffer;
+    signed char *dest =  (signed char*)destinationBuffer;
+    PaInt32 dither;
+
+    while( count-- )
+    {
+        /* REVIEW */
+        dither = PaUtil_Generate16BitTriangularDither( ditherGenerator );
+        *dest = (signed char) ((((*src)>>1) + dither) >> 23);
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int32_To_UInt8(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    PaInt32 *src = (PaInt32*)sourceBuffer;
+    unsigned char *dest =  (unsigned char*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+               (*dest) = (unsigned char)(((*src) >> 24) + 128); 
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int32_To_UInt8_Dither(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    PaInt32 *src = (PaInt32*)sourceBuffer;
+    unsigned char *dest =  (unsigned char*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        /* IMPLEMENT ME */
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int24_To_Float32(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    unsigned char *src = (unsigned char*)sourceBuffer;
+    float *dest = (float*)destinationBuffer;
+    PaInt32 temp;
+
+    (void) ditherGenerator; /* unused parameter */
+    
+    while( count-- )
+    {
+
+#if defined(PA_LITTLE_ENDIAN)
+        temp = (((long)src[0]) << 8);  
+        temp = temp | (((long)src[1]) << 16);
+        temp = temp | (((long)src[2]) << 24);
+#elif defined(PA_BIG_ENDIAN)
+        temp = (((long)src[0]) << 24);
+        temp = temp | (((long)src[1]) << 16);
+        temp = temp | (((long)src[2]) << 8);
+#endif
+
+        *dest = (float) ((double)temp * const_1_div_2147483648_);
+
+        src += sourceStride * 3;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int24_To_Int32(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    unsigned char *src  = (unsigned char*)sourceBuffer;
+    PaInt32 *dest = (PaInt32*)  destinationBuffer;
+    PaInt32 temp;
+
+    (void) ditherGenerator; /* unused parameter */
+    
+    while( count-- )
+    {
+
+#if defined(PA_LITTLE_ENDIAN)
+        temp = (((long)src[0]) << 8);  
+        temp = temp | (((long)src[1]) << 16);
+        temp = temp | (((long)src[2]) << 24);
+#elif defined(PA_BIG_ENDIAN)
+        temp = (((long)src[0]) << 24);
+        temp = temp | (((long)src[1]) << 16);
+        temp = temp | (((long)src[2]) << 8);
+#endif
+
+        *dest = temp;
+
+        src += sourceStride * 3;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int24_To_Int16(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    unsigned char *src = (unsigned char*)sourceBuffer;
+    PaInt16 *dest = (PaInt16*)destinationBuffer;
+    
+    PaInt16 temp;
+
+    (void) ditherGenerator; /* unused parameter */
+        
+    while( count-- )
+    {
+               
+#if defined(PA_LITTLE_ENDIAN)
+               /* src[0] is discarded */
+        temp = (((PaInt16)src[1]));
+        temp = temp | (PaInt16)(((PaInt16)src[2]) << 8);
+#elif defined(PA_BIG_ENDIAN)
+               /* src[2] is discarded */
+        temp = (PaInt16)(((PaInt16)src[0]) << 8);
+        temp = temp | (((PaInt16)src[1]));
+#endif
+
+        *dest = temp;
+
+        src += sourceStride * 3;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int24_To_Int16_Dither(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    (void) destinationBuffer; /* unused parameters */
+    (void) destinationStride; /* unused parameters */
+    (void) sourceBuffer; /* unused parameters */
+    (void) sourceStride; /* unused parameters */
+    (void) count; /* unused parameters */
+    (void) ditherGenerator; /* unused parameters */
+    /* IMPLEMENT ME */
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int24_To_Int8(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    unsigned char *src = (unsigned char*)sourceBuffer;
+    signed char  *dest = (signed char*)destinationBuffer;
+    
+    (void) ditherGenerator; /* unused parameter */
+        
+    while( count-- )
+    {  
+       
+#if defined(PA_LITTLE_ENDIAN)
+               /* src[0] is discarded */
+               /* src[1] is discarded */
+        *dest = src[2];
+#elif defined(PA_BIG_ENDIAN)
+               /* src[2] is discarded */
+               /* src[1] is discarded */
+               *dest = src[0];
+#endif
+
+        src += sourceStride * 3;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int24_To_Int8_Dither(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    (void) destinationBuffer; /* unused parameters */
+    (void) destinationStride; /* unused parameters */
+    (void) sourceBuffer; /* unused parameters */
+    (void) sourceStride; /* unused parameters */
+    (void) count; /* unused parameters */
+    (void) ditherGenerator; /* unused parameters */
+    /* IMPLEMENT ME */
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int24_To_UInt8(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    unsigned char *src = (unsigned char*)sourceBuffer;
+    unsigned char *dest = (unsigned char*)destinationBuffer;
+    
+    (void) ditherGenerator; /* unused parameter */
+        
+    while( count-- )
+    {
+               
+#if defined(PA_LITTLE_ENDIAN)
+               /* src[0] is discarded */
+               /* src[1] is discarded */
+        *dest = (unsigned char)(src[2] + 128);
+#elif defined(PA_BIG_ENDIAN)
+        *dest = (unsigned char)(src[0] + 128);
+               /* src[1] is discarded */
+               /* src[2] is discarded */               
+#endif
+
+        src += sourceStride * 3;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int24_To_UInt8_Dither(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    (void) destinationBuffer; /* unused parameters */
+    (void) destinationStride; /* unused parameters */
+    (void) sourceBuffer; /* unused parameters */
+    (void) sourceStride; /* unused parameters */
+    (void) count; /* unused parameters */
+    (void) ditherGenerator; /* unused parameters */
+    /* IMPLEMENT ME */
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int16_To_Float32(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    PaInt16 *src = (PaInt16*)sourceBuffer;
+    float *dest =  (float*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        float samp = *src * const_1_div_32768_; /* FIXME: i'm concerned about this being asymetrical with float->int16 -rb */
+        *dest = samp;
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int16_To_Int32(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    PaInt16 *src = (PaInt16*)sourceBuffer;
+    PaInt32 *dest =  (PaInt32*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        /* REVIEW: we should consider something like
+            (*src << 16) | (*src & 0xFFFF)
+        */
+        
+        *dest = *src << 16;
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int16_To_Int24(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    PaInt16 *src   = (PaInt16*) sourceBuffer;
+    unsigned char *dest = (unsigned char*)destinationBuffer;
+    PaInt16 temp;
+
+    (void) ditherGenerator; /* unused parameter */
+    
+    while( count-- )
+    {
+        temp = *src;
+        
+#if defined(PA_LITTLE_ENDIAN)
+        dest[0] = 0;
+        dest[1] = (unsigned char)(temp);
+        dest[2] = (unsigned char)(temp >> 8);
+#elif defined(PA_BIG_ENDIAN)
+        dest[0] = (unsigned char)(temp >> 8);
+        dest[1] = (unsigned char)(temp);
+        dest[2] = 0;
+#endif
+
+        src += sourceStride;
+        dest += destinationStride * 3;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int16_To_Int8(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    PaInt16 *src = (PaInt16*)sourceBuffer;
+    signed char *dest =  (signed char*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        (*dest) = (signed char)((*src) >> 8);
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int16_To_Int8_Dither(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    PaInt16 *src = (PaInt16*)sourceBuffer;
+    signed char *dest =  (signed char*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        /* IMPLEMENT ME */
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int16_To_UInt8(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    PaInt16 *src = (PaInt16*)sourceBuffer;
+    unsigned char *dest =  (unsigned char*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+               (*dest) = (unsigned char)(((*src) >> 8) + 128); 
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int16_To_UInt8_Dither(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    PaInt16 *src = (PaInt16*)sourceBuffer;
+    unsigned char *dest =  (unsigned char*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        /* IMPLEMENT ME */
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int8_To_Float32(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    signed char *src = (signed char*)sourceBuffer;
+    float *dest =  (float*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        float samp = *src * const_1_div_128_;
+        *dest = samp;
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int8_To_Int32(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    signed char *src = (signed char*)sourceBuffer;
+    PaInt32 *dest =  (PaInt32*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+               (*dest) = (*src) << 24;
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int8_To_Int24(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    signed char *src = (signed char*)sourceBuffer;
+    unsigned char *dest =  (unsigned char*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+
+#if defined(PA_LITTLE_ENDIAN)
+        dest[0] = 0;
+        dest[1] = 0;
+        dest[2] = (*src);
+#elif defined(PA_BIG_ENDIAN)
+        dest[0] = (*src);
+        dest[1] = 0;
+        dest[2] = 0;
+#endif
+
+        src += sourceStride;
+        dest += destinationStride * 3;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int8_To_Int16(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    signed char *src = (signed char*)sourceBuffer;
+    PaInt16 *dest =  (PaInt16*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        (*dest) = (PaInt16)((*src) << 8);
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Int8_To_UInt8(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    signed char *src = (signed char*)sourceBuffer;
+    unsigned char *dest =  (unsigned char*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        (*dest) = (unsigned char)(*src + 128);
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void UInt8_To_Float32(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    unsigned char *src = (unsigned char*)sourceBuffer;
+    float *dest =  (float*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        float samp = (*src - 128) * const_1_div_128_;
+        *dest = samp;
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void UInt8_To_Int32(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    unsigned char *src = (unsigned char*)sourceBuffer;
+    PaInt32 *dest = (PaInt32*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+               (*dest) = (*src - 128) << 24;
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void UInt8_To_Int24(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+       unsigned char *src  = (unsigned char*)sourceBuffer;
+    unsigned char *dest = (unsigned char*)destinationBuffer;
+    (void) ditherGenerator; /* unused parameters */
+    
+       while( count-- )
+    {
+
+#if defined(PA_LITTLE_ENDIAN)
+        dest[0] = 0;
+        dest[1] = 0;
+        dest[2] = (unsigned char)(*src - 128);
+#elif defined(PA_BIG_ENDIAN)
+        dest[0] = (unsigned char)(*src - 128);
+        dest[1] = 0;
+        dest[2] = 0;
+#endif
+               
+        src += sourceStride;
+        dest += destinationStride * 3;    
+       }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void UInt8_To_Int16(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    unsigned char *src = (unsigned char*)sourceBuffer;
+    PaInt16 *dest =  (PaInt16*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        (*dest) = (PaInt16)((*src - 128) << 8);
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void UInt8_To_Int8(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    unsigned char *src = (unsigned char*)sourceBuffer;
+    signed char  *dest = (signed char*)destinationBuffer;
+    (void)ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        (*dest) = (signed char)(*src - 128);
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Copy_8_To_8(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    unsigned char *src = (unsigned char*)sourceBuffer;
+    unsigned char *dest = (unsigned char*)destinationBuffer;
+                                                      
+    (void) ditherGenerator; /* unused parameter */
+
+    while( count-- )
+    {
+        *dest = *src;
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Copy_16_To_16(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    PaUint16 *src = (PaUint16 *)sourceBuffer;
+    PaUint16 *dest = (PaUint16 *)destinationBuffer;
+                                                        
+    (void) ditherGenerator; /* unused parameter */
+    
+    while( count-- )
+    {
+        *dest = *src;
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Copy_24_To_24(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    unsigned char *src = (unsigned char*)sourceBuffer;
+    unsigned char *dest = (unsigned char*)destinationBuffer;
+
+    (void) ditherGenerator; /* unused parameter */
+    
+    while( count-- )
+    {
+        dest[0] = src[0];
+        dest[1] = src[1];
+        dest[2] = src[2];
+
+        src += sourceStride * 3;
+        dest += destinationStride * 3;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Copy_32_To_32(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    PaUint32 *dest = (PaUint32 *)destinationBuffer;
+    PaUint32 *src = (PaUint32 *)sourceBuffer;
+
+    (void) ditherGenerator; /* unused parameter */
+    
+    while( count-- )
+    {
+        *dest = *src;
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+PaUtilConverterTable paConverters = {
+    Float32_To_Int32,              /* PaUtilConverter *Float32_To_Int32; */
+    Float32_To_Int32_Dither,       /* PaUtilConverter *Float32_To_Int32_Dither; */
+    Float32_To_Int32_Clip,         /* PaUtilConverter *Float32_To_Int32_Clip; */
+    Float32_To_Int32_DitherClip,   /* PaUtilConverter *Float32_To_Int32_DitherClip; */
+
+    Float32_To_Int24,              /* PaUtilConverter *Float32_To_Int24; */
+    Float32_To_Int24_Dither,       /* PaUtilConverter *Float32_To_Int24_Dither; */
+    Float32_To_Int24_Clip,         /* PaUtilConverter *Float32_To_Int24_Clip; */
+    Float32_To_Int24_DitherClip,   /* PaUtilConverter *Float32_To_Int24_DitherClip; */
+    
+    Float32_To_Int16,              /* PaUtilConverter *Float32_To_Int16; */
+    Float32_To_Int16_Dither,       /* PaUtilConverter *Float32_To_Int16_Dither; */
+    Float32_To_Int16_Clip,         /* PaUtilConverter *Float32_To_Int16_Clip; */
+    Float32_To_Int16_DitherClip,   /* PaUtilConverter *Float32_To_Int16_DitherClip; */
+
+    Float32_To_Int8,               /* PaUtilConverter *Float32_To_Int8; */
+    Float32_To_Int8_Dither,        /* PaUtilConverter *Float32_To_Int8_Dither; */
+    Float32_To_Int8_Clip,          /* PaUtilConverter *Float32_To_Int8_Clip; */
+    Float32_To_Int8_DitherClip,    /* PaUtilConverter *Float32_To_Int8_DitherClip; */
+
+    Float32_To_UInt8,              /* PaUtilConverter *Float32_To_UInt8; */
+    Float32_To_UInt8_Dither,       /* PaUtilConverter *Float32_To_UInt8_Dither; */
+    Float32_To_UInt8_Clip,         /* PaUtilConverter *Float32_To_UInt8_Clip; */
+    Float32_To_UInt8_DitherClip,   /* PaUtilConverter *Float32_To_UInt8_DitherClip; */
+
+    Int32_To_Float32,              /* PaUtilConverter *Int32_To_Float32; */
+    Int32_To_Int24,                /* PaUtilConverter *Int32_To_Int24; */
+    Int32_To_Int24_Dither,         /* PaUtilConverter *Int32_To_Int24_Dither; */
+    Int32_To_Int16,                /* PaUtilConverter *Int32_To_Int16; */
+    Int32_To_Int16_Dither,         /* PaUtilConverter *Int32_To_Int16_Dither; */
+    Int32_To_Int8,                 /* PaUtilConverter *Int32_To_Int8; */
+    Int32_To_Int8_Dither,          /* PaUtilConverter *Int32_To_Int8_Dither; */
+    Int32_To_UInt8,                /* PaUtilConverter *Int32_To_UInt8; */
+    Int32_To_UInt8_Dither,         /* PaUtilConverter *Int32_To_UInt8_Dither; */
+
+    Int24_To_Float32,              /* PaUtilConverter *Int24_To_Float32; */
+    Int24_To_Int32,                /* PaUtilConverter *Int24_To_Int32; */
+    Int24_To_Int16,                /* PaUtilConverter *Int24_To_Int16; */
+    Int24_To_Int16_Dither,         /* PaUtilConverter *Int24_To_Int16_Dither; */
+    Int24_To_Int8,                 /* PaUtilConverter *Int24_To_Int8; */
+    Int24_To_Int8_Dither,          /* PaUtilConverter *Int24_To_Int8_Dither; */
+    Int24_To_UInt8,                /* PaUtilConverter *Int24_To_UInt8; */
+    Int24_To_UInt8_Dither,         /* PaUtilConverter *Int24_To_UInt8_Dither; */
+
+    Int16_To_Float32,              /* PaUtilConverter *Int16_To_Float32; */
+    Int16_To_Int32,                /* PaUtilConverter *Int16_To_Int32; */
+    Int16_To_Int24,                /* PaUtilConverter *Int16_To_Int24; */
+    Int16_To_Int8,                 /* PaUtilConverter *Int16_To_Int8; */
+    Int16_To_Int8_Dither,          /* PaUtilConverter *Int16_To_Int8_Dither; */
+    Int16_To_UInt8,                /* PaUtilConverter *Int16_To_UInt8; */
+    Int16_To_UInt8_Dither,         /* PaUtilConverter *Int16_To_UInt8_Dither; */
+
+    Int8_To_Float32,               /* PaUtilConverter *Int8_To_Float32; */
+    Int8_To_Int32,                 /* PaUtilConverter *Int8_To_Int32; */
+    Int8_To_Int24,                 /* PaUtilConverter *Int8_To_Int24 */
+    Int8_To_Int16,                 /* PaUtilConverter *Int8_To_Int16; */
+    Int8_To_UInt8,                 /* PaUtilConverter *Int8_To_UInt8; */
+
+    UInt8_To_Float32,              /* PaUtilConverter *UInt8_To_Float32; */
+    UInt8_To_Int32,                /* PaUtilConverter *UInt8_To_Int32; */
+    UInt8_To_Int24,                /* PaUtilConverter *UInt8_To_Int24; */
+    UInt8_To_Int16,                /* PaUtilConverter *UInt8_To_Int16; */
+    UInt8_To_Int8,                 /* PaUtilConverter *UInt8_To_Int8; */
+
+    Copy_8_To_8,                   /* PaUtilConverter *Copy_8_To_8; */
+    Copy_16_To_16,                 /* PaUtilConverter *Copy_16_To_16; */
+    Copy_24_To_24,                 /* PaUtilConverter *Copy_24_To_24; */
+    Copy_32_To_32                  /* PaUtilConverter *Copy_32_To_32; */
+};
+
+/* -------------------------------------------------------------------------- */
+
+#endif /* PA_NO_STANDARD_CONVERTERS */
+
+/* -------------------------------------------------------------------------- */
+
+PaUtilZeroer* PaUtil_SelectZeroer( PaSampleFormat destinationFormat )
+{
+    switch( destinationFormat & ~paNonInterleaved ){
+    case paFloat32:
+        return paZeroers.Zero32;
+    case paInt32:
+        return paZeroers.Zero32;
+    case paInt24:
+        return paZeroers.Zero24;
+    case paInt16:
+        return paZeroers.Zero16;
+    case paInt8:
+        return paZeroers.Zero8;
+    case paUInt8:
+        return paZeroers.ZeroU8;
+    default: return 0;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+#ifdef PA_NO_STANDARD_ZEROERS
+
+/* -------------------------------------------------------------------------- */
+
+PaUtilZeroerTable paZeroers = {
+    0,  /* PaUtilZeroer *ZeroU8; */
+    0,  /* PaUtilZeroer *Zero8; */
+    0,  /* PaUtilZeroer *Zero16; */
+    0,  /* PaUtilZeroer *Zero24; */
+    0,  /* PaUtilZeroer *Zero32; */
+};
+
+/* -------------------------------------------------------------------------- */
+
+#else /* PA_NO_STANDARD_ZEROERS is not defined */
+
+/* -------------------------------------------------------------------------- */
+
+static void ZeroU8( void *destinationBuffer, signed int destinationStride,
+        unsigned int count )
+{
+    unsigned char *dest = (unsigned char*)destinationBuffer;
+
+    while( count-- )
+    {
+        *dest = 128;
+
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Zero8( void *destinationBuffer, signed int destinationStride,
+        unsigned int count )
+{
+    unsigned char *dest = (unsigned char*)destinationBuffer;
+
+    while( count-- )
+    {
+        *dest = 0;
+
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Zero16( void *destinationBuffer, signed int destinationStride,
+        unsigned int count )
+{
+    PaUint16 *dest = (PaUint16 *)destinationBuffer;
+
+    while( count-- )
+    {
+        *dest = 0;
+
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Zero24( void *destinationBuffer, signed int destinationStride,
+        unsigned int count )
+{
+    unsigned char *dest = (unsigned char*)destinationBuffer;
+
+    while( count-- )
+    {
+        dest[0] = 0;
+        dest[1] = 0;
+        dest[2] = 0;
+
+        dest += destinationStride * 3;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Zero32( void *destinationBuffer, signed int destinationStride,
+        unsigned int count )
+{
+    PaUint32 *dest = (PaUint32 *)destinationBuffer;
+
+    while( count-- )
+    {
+        *dest = 0;
+
+        dest += destinationStride;
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+PaUtilZeroerTable paZeroers = {
+    ZeroU8,  /* PaUtilZeroer *ZeroU8; */
+    Zero8,  /* PaUtilZeroer *Zero8; */
+    Zero16,  /* PaUtilZeroer *Zero16; */
+    Zero24,  /* PaUtilZeroer *Zero24; */
+    Zero32,  /* PaUtilZeroer *Zero32; */
+};
+
+/* -------------------------------------------------------------------------- */
+
+#endif /* PA_NO_STANDARD_ZEROERS */
diff --git a/utils/iaxclient/lib/portaudio/src/common/pa_converters.h b/utils/iaxclient/lib/portaudio/src/common/pa_converters.h
new file mode 100644 (file)
index 0000000..51b10bb
--- /dev/null
@@ -0,0 +1,254 @@
+#ifndef PA_CONVERTERS_H
+#define PA_CONVERTERS_H
+/*
+ * $Id: pa_converters.h,v 1.1 2006/06/10 21:30:55 dmazzoni Exp $
+ * Portable Audio I/O Library sample conversion mechanism
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2002 Phil Burk, Ross Bencina
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file
+ @brief Conversion functions used to convert buffers of samples from one
+ format to another.
+*/
+
+
+#include "portaudio.h"  /* for PaSampleFormat */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+
+struct PaUtilTriangularDitherGenerator;
+
+
+/** Choose an available sample format which is most appropriate for
+ representing the requested format. If the requested format is not available
+ higher quality formats are considered before lower quality formates.
+ @param availableFormats A variable containing the logical OR of all available
+ formats.
+ @param format The desired format.
+ @return The most appropriate available format for representing the requested
+ format.
+*/
+PaSampleFormat PaUtil_SelectClosestAvailableFormat(
+        PaSampleFormat availableFormats, PaSampleFormat format );
+
+
+/* high level conversions functions for use by implementations */
+
+
+/** The generic sample converter prototype. Sample converters convert count
+    samples from sourceBuffer to destinationBuffer. The actual type of the data
+    pointed to by these parameters varys for different converter functions.
+    @param destinationBuffer A pointer to the first sample of the destination.
+    @param destinationStride An offset between successive destination samples
+    expressed in samples (not bytes.) It may be negative.
+    @param sourceBuffer A pointer to the first sample of the source.
+    @param sourceStride An offset between successive source samples
+    expressed in samples (not bytes.) It may be negative.
+    @param count The number of samples to convert.
+    @param ditherState State information used to calculate dither. Converters
+    that do not perform dithering will ignore this parameter, in which case
+    NULL or invalid dither state may be passed.
+*/
+typedef void PaUtilConverter(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator );
+
+
+/** Find a sample converter function for the given source and destinations
+    formats and flags (clip and dither.)
+    @return
+    A pointer to a PaUtilConverter which will perform the requested
+    conversion, or NULL if the given format conversion is not supported.
+    For conversions where clipping or dithering is not necessary, the
+    clip and dither flags are ignored and a non-clipping or dithering
+    version is returned.
+    If the source and destination formats are the same, a function which
+    copies data of the appropriate size will be returned.
+*/
+PaUtilConverter* PaUtil_SelectConverter( PaSampleFormat sourceFormat,
+        PaSampleFormat destinationFormat, PaStreamFlags flags );
+
+
+/** The generic buffer zeroer prototype. Buffer zeroers copy count zeros to
+    destinationBuffer. The actual type of the data pointed to varys for
+    different zeroer functions.
+    @param destinationBuffer A pointer to the first sample of the destination.
+    @param destinationStride An offset between successive destination samples
+    expressed in samples (not bytes.) It may be negative.
+    @param count The number of samples to zero.
+*/
+typedef void PaUtilZeroer(
+    void *destinationBuffer, signed int destinationStride, unsigned int count );
+
+    
+/** Find a buffer zeroer function for the given destination format.
+    @return
+    A pointer to a PaUtilZeroer which will perform the requested
+    zeroing.
+*/
+PaUtilZeroer* PaUtil_SelectZeroer( PaSampleFormat destinationFormat );
+
+/*----------------------------------------------------------------------------*/
+/* low level functions and data structures which may be used for
+    substituting conversion functions */
+
+
+/** The type used to store all sample conversion functions.
+    @see paConverters;
+*/
+typedef struct{
+    PaUtilConverter *Float32_To_Int32;
+    PaUtilConverter *Float32_To_Int32_Dither;
+    PaUtilConverter *Float32_To_Int32_Clip;
+    PaUtilConverter *Float32_To_Int32_DitherClip;
+
+    PaUtilConverter *Float32_To_Int24;
+    PaUtilConverter *Float32_To_Int24_Dither;
+    PaUtilConverter *Float32_To_Int24_Clip;
+    PaUtilConverter *Float32_To_Int24_DitherClip;
+    
+    PaUtilConverter *Float32_To_Int16;
+    PaUtilConverter *Float32_To_Int16_Dither;
+    PaUtilConverter *Float32_To_Int16_Clip;
+    PaUtilConverter *Float32_To_Int16_DitherClip;
+
+    PaUtilConverter *Float32_To_Int8;
+    PaUtilConverter *Float32_To_Int8_Dither;
+    PaUtilConverter *Float32_To_Int8_Clip;
+    PaUtilConverter *Float32_To_Int8_DitherClip;
+
+    PaUtilConverter *Float32_To_UInt8;
+    PaUtilConverter *Float32_To_UInt8_Dither;
+    PaUtilConverter *Float32_To_UInt8_Clip;
+    PaUtilConverter *Float32_To_UInt8_DitherClip;
+
+    PaUtilConverter *Int32_To_Float32;
+    PaUtilConverter *Int32_To_Int24;
+    PaUtilConverter *Int32_To_Int24_Dither;
+    PaUtilConverter *Int32_To_Int16;
+    PaUtilConverter *Int32_To_Int16_Dither;
+    PaUtilConverter *Int32_To_Int8;
+    PaUtilConverter *Int32_To_Int8_Dither;
+    PaUtilConverter *Int32_To_UInt8;
+    PaUtilConverter *Int32_To_UInt8_Dither;
+
+    PaUtilConverter *Int24_To_Float32;
+    PaUtilConverter *Int24_To_Int32;
+    PaUtilConverter *Int24_To_Int16;
+    PaUtilConverter *Int24_To_Int16_Dither;
+    PaUtilConverter *Int24_To_Int8;
+    PaUtilConverter *Int24_To_Int8_Dither;
+    PaUtilConverter *Int24_To_UInt8;
+    PaUtilConverter *Int24_To_UInt8_Dither;
+
+    PaUtilConverter *Int16_To_Float32;
+    PaUtilConverter *Int16_To_Int32;
+    PaUtilConverter *Int16_To_Int24;
+    PaUtilConverter *Int16_To_Int8;
+    PaUtilConverter *Int16_To_Int8_Dither;
+    PaUtilConverter *Int16_To_UInt8;
+    PaUtilConverter *Int16_To_UInt8_Dither;
+
+    PaUtilConverter *Int8_To_Float32;
+    PaUtilConverter *Int8_To_Int32;
+    PaUtilConverter *Int8_To_Int24;
+    PaUtilConverter *Int8_To_Int16;
+    PaUtilConverter *Int8_To_UInt8;
+    
+    PaUtilConverter *UInt8_To_Float32;
+    PaUtilConverter *UInt8_To_Int32;
+    PaUtilConverter *UInt8_To_Int24;
+    PaUtilConverter *UInt8_To_Int16;
+    PaUtilConverter *UInt8_To_Int8;
+
+    PaUtilConverter *Copy_8_To_8;       /* copy without any conversion */
+    PaUtilConverter *Copy_16_To_16;     /* copy without any conversion */
+    PaUtilConverter *Copy_24_To_24;     /* copy without any conversion */
+    PaUtilConverter *Copy_32_To_32;     /* copy without any conversion */
+} PaUtilConverterTable;
+
+
+/** A table of pointers to all required converter functions.
+    PaUtil_SelectConverter() uses this table to lookup the appropriate
+    conversion functions. The fields of this structure are initialized
+    with default conversion functions. Fields may be NULL, indicating that
+    no conversion function is available. User code may substitue optimised
+    conversion functions by assigning different function pointers to
+    these fields.
+
+    @note
+    If the PA_NO_STANDARD_CONVERTERS preprocessor variable is defined,
+    PortAudio's standard converters will not be compiled, and all fields
+    of this structure will be initialized to NULL. In such cases, users
+    should supply their own conversion functions if the require PortAudio
+    to open a stream that requires sample conversion.
+
+    @see PaUtilConverterTable, PaUtilConverter, PaUtil_SelectConverter
+*/
+extern PaUtilConverterTable paConverters;
+
+
+/** The type used to store all buffer zeroing functions.
+    @see paZeroers;
+*/
+typedef struct{
+    PaUtilZeroer *ZeroU8; /* unsigned 8 bit, zero == 128 */
+    PaUtilZeroer *Zero8;
+    PaUtilZeroer *Zero16;
+    PaUtilZeroer *Zero24;
+    PaUtilZeroer *Zero32;
+} PaUtilZeroerTable;
+
+
+/** A table of pointers to all required zeroer functions.
+    PaUtil_SelectZeroer() uses this table to lookup the appropriate
+    conversion functions. The fields of this structure are initialized
+    with default conversion functions. User code may substitue optimised
+    conversion functions by assigning different function pointers to
+    these fields.
+
+    @note
+    If the PA_NO_STANDARD_ZEROERS preprocessor variable is defined,
+    PortAudio's standard zeroers will not be compiled, and all fields
+    of this structure will be initialized to NULL. In such cases, users
+    should supply their own zeroing functions for the sample sizes which
+    they intend to use.
+
+    @see PaUtilZeroerTable, PaUtilZeroer, PaUtil_SelectZeroer
+*/
+extern PaUtilZeroerTable paZeroers;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* PA_CONVERTERS_H */
diff --git a/utils/iaxclient/lib/portaudio/src/common/pa_cpuload.c b/utils/iaxclient/lib/portaudio/src/common/pa_cpuload.c
new file mode 100644 (file)
index 0000000..dfc1f2b
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * $Id: pa_cpuload.c,v 1.1 2006/06/10 21:30:55 dmazzoni Exp $
+ * Portable Audio I/O Library CPU Load measurement functions
+ * Portable CPU load measurement facility.
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 2002 Ross Bencina
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file
+ @brief Functions to assist in measuring the CPU utilization of a callback
+ stream. Used to implement the Pa_GetStreamCpuLoad() function.
+
+ @todo Dynamically calculate the coefficients used to smooth the CPU Load
+ Measurements over time to provide a uniform characterisation of CPU Load
+ independent of rate at which PaUtil_BeginCpuLoadMeasurement /
+ PaUtil_EndCpuLoadMeasurement are called.
+*/
+
+
+#include "pa_cpuload.h"
+
+#include <assert.h>
+
+#include "pa_util.h"   /* for PaUtil_GetTime() */
+
+
+void PaUtil_InitializeCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer, double sampleRate )
+{
+    assert( sampleRate > 0 );
+
+    measurer->samplingPeriod = 1. / sampleRate;
+    measurer->averageLoad = 0.;
+}
+
+void PaUtil_ResetCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer )
+{
+    measurer->averageLoad = 0.;
+}
+
+void PaUtil_BeginCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer )
+{
+    measurer->measurementStartTime = PaUtil_GetTime();
+}
+
+
+void PaUtil_EndCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer, unsigned long framesProcessed )
+{
+    double measurementEndTime, secondsFor100Percent, measuredLoad;
+
+    if( framesProcessed > 0 ){
+        measurementEndTime = PaUtil_GetTime();
+
+        assert( framesProcessed > 0 );
+        secondsFor100Percent = framesProcessed * measurer->samplingPeriod;
+
+        measuredLoad = (measurementEndTime - measurer->measurementStartTime) / secondsFor100Percent;
+
+        /* Low pass filter the calculated CPU load to reduce jitter using a simple IIR low pass filter. */
+        /** FIXME @todo these coefficients shouldn't be hardwired */
+#define LOWPASS_COEFFICIENT_0   (0.9)
+#define LOWPASS_COEFFICIENT_1   (0.99999 - LOWPASS_COEFFICIENT_0)
+
+        measurer->averageLoad = (LOWPASS_COEFFICIENT_0 * measurer->averageLoad) +
+                               (LOWPASS_COEFFICIENT_1 * measuredLoad);
+    }
+}
+
+
+double PaUtil_GetCpuLoad( PaUtilCpuLoadMeasurer* measurer )
+{
+    return measurer->averageLoad;
+}
diff --git a/utils/iaxclient/lib/portaudio/src/common/pa_cpuload.h b/utils/iaxclient/lib/portaudio/src/common/pa_cpuload.h
new file mode 100644 (file)
index 0000000..99a3fd8
--- /dev/null
@@ -0,0 +1,63 @@
+#ifndef PA_CPULOAD_H
+#define PA_CPULOAD_H
+/*
+ * $Id: pa_cpuload.h,v 1.1 2006/06/10 21:30:55 dmazzoni Exp $
+ * Portable Audio I/O Library CPU Load measurement functions
+ * Portable CPU load measurement facility.
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 2002 Ross Bencina
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file
+ @brief Functions to assist in measuring the CPU utilization of a callback
+ stream. Used to implement the Pa_GetStreamCpuLoad() function.
+*/
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+
+typedef struct {
+    double samplingPeriod;
+    double measurementStartTime;
+    double averageLoad;
+} PaUtilCpuLoadMeasurer; /**< @todo need better name than measurer */
+
+void PaUtil_InitializeCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer, double sampleRate );
+void PaUtil_BeginCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer );
+void PaUtil_EndCpuLoadMeasurement( PaUtilCpuLoadMeasurer* measurer, unsigned long framesProcessed );
+void PaUtil_ResetCpuLoadMeasurer( PaUtilCpuLoadMeasurer* measurer );
+double PaUtil_GetCpuLoad( PaUtilCpuLoadMeasurer* measurer );
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */     
+#endif /* PA_CPULOAD_H */
diff --git a/utils/iaxclient/lib/portaudio/src/common/pa_dither.c b/utils/iaxclient/lib/portaudio/src/common/pa_dither.c
new file mode 100644 (file)
index 0000000..f7382cf
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * $Id: pa_dither.c,v 1.1 2006/06/10 21:30:55 dmazzoni Exp $
+ * Portable Audio I/O Library triangular dither generator
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2002 Phil Burk, Ross Bencina
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file
+ @brief Functions for generating dither noise
+*/
+
+
+#include "pa_dither.h"
+#include "pa_types.h"
+
+#define PA_DITHER_BITS_   (15)
+
+
+void PaUtil_InitializeTriangularDitherState( PaUtilTriangularDitherGenerator *state )
+{
+    state->previous = 0;
+    state->randSeed1 = 22222;
+    state->randSeed2 = 5555555;
+}
+
+
+signed long PaUtil_Generate16BitTriangularDither( PaUtilTriangularDitherGenerator *state )
+{
+    signed long current, highPass;
+
+    /* Generate two random numbers. */
+    state->randSeed1 = (state->randSeed1 * 196314165) + 907633515;
+    state->randSeed2 = (state->randSeed2 * 196314165) + 907633515;
+
+    /* Generate triangular distribution about 0.
+     * Shift before adding to prevent overflow which would skew the distribution.
+     * Also shift an extra bit for the high pass filter. 
+     */
+#define DITHER_SHIFT_  ((SIZEOF_LONG*8 - PA_DITHER_BITS_) + 1)
+    current = (((signed long)state->randSeed1)>>DITHER_SHIFT_) +
+              (((signed long)state->randSeed2)>>DITHER_SHIFT_);
+
+    /* High pass filter to reduce audibility. */
+    highPass = current - state->previous;
+    state->previous = current;
+    return highPass;
+}
+
+
+/* Multiply by PA_FLOAT_DITHER_SCALE_ to get a float between -2.0 and +1.99999 */
+#define PA_FLOAT_DITHER_SCALE_  (1.0f / ((1<<PA_DITHER_BITS_)-1))
+static const float const_float_dither_scale_ = PA_FLOAT_DITHER_SCALE_;
+
+float PaUtil_GenerateFloatTriangularDither( PaUtilTriangularDitherGenerator *state )
+{
+    signed long current, highPass;
+
+    /* Generate two random numbers. */
+    state->randSeed1 = (state->randSeed1 * 196314165) + 907633515;
+    state->randSeed2 = (state->randSeed2 * 196314165) + 907633515;
+
+    /* Generate triangular distribution about 0.
+     * Shift before adding to prevent overflow which would skew the distribution.
+     * Also shift an extra bit for the high pass filter. 
+     */
+#define DITHER_SHIFT_  ((SIZEOF_LONG*8 - PA_DITHER_BITS_) + 1)
+    current = (((signed long)state->randSeed1)>>DITHER_SHIFT_) +
+              (((signed long)state->randSeed2)>>DITHER_SHIFT_);
+
+    /* High pass filter to reduce audibility. */
+    highPass = current - state->previous;
+    state->previous = current;
+    return ((float)highPass) * const_float_dither_scale_;
+}
+
+
+/*
+The following alternate dither algorithms (from musicdsp.org) could be
+considered
+*/
+
+/*Noise shaped dither  (March 2000)
+-------------------
+
+This is a simple implementation of highpass triangular-PDF dither with
+2nd-order noise shaping, for use when truncating floating point audio
+data to fixed point.
+
+The noise shaping lowers the noise floor by 11dB below 5kHz (@ 44100Hz
+sample rate) compared to triangular-PDF dither. The code below assumes
+input data is in the range +1 to -1 and doesn't check for overloads!
+
+To save time when generating dither for multiple channels you can do
+things like this:  r3=(r1 & 0x7F)<<8; instead of calling rand() again.
+
+
+
+  int   r1, r2;                //rectangular-PDF random numbers
+  float s1, s2;                //error feedback buffers
+  float s = 0.5f;              //set to 0.0f for no noise shaping
+  float w = pow(2.0,bits-1);   //word length (usually bits=16)
+  float wi= 1.0f/w;            
+  float d = wi / RAND_MAX;     //dither amplitude (2 lsb)
+  float o = wi * 0.5f;         //remove dc offset
+  float in, tmp;
+  int   out;
+
+
+//for each sample...
+
+  r2=r1;                               //can make HP-TRI dither by
+  r1=rand();                           //subtracting previous rand()
+    
+  in += s * (s1 + s1 - s2);            //error feedback
+  tmp = in + o + d * (float)(r1 - r2); //dc offset and dither 
+  
+  out = (int)(w * tmp);                //truncate downwards
+  if(tmp<0.0f) out--;                  //this is faster than floor()
+
+  s2 = s1;                            
+  s1 = in - wi * (float)out;           //error
+
+
+
+-- 
+paul.kellett@maxim.abel.co.uk
+http://www.maxim.abel.co.uk
+*/
+
+
+/*
+16-to-8-bit first-order dither
+
+Type : First order error feedforward dithering code
+References : Posted by Jon Watte
+
+Notes : 
+This is about as simple a dithering algorithm as you can implement, but it's
+likely to sound better than just truncating to N bits.
+
+Note that you might not want to carry forward the full difference for infinity.
+It's probably likely that the worst performance hit comes from the saturation
+conditionals, which can be avoided with appropriate instructions on many DSPs
+and integer SIMD type instructions, or CMOV.
+
+Last, if sound quality is paramount (such as when going from > 16 bits to 16
+bits) you probably want to use a higher-order dither function found elsewhere
+on this site. 
+
+
+Code : 
+// This code will down-convert and dither a 16-bit signed short 
+// mono signal into an 8-bit unsigned char signal, using a first 
+// order forward-feeding error term dither. 
+
+#define uchar unsigned char 
+
+void dither_one_channel_16_to_8( short * input, uchar * output, int count, int * memory ) 
+{ 
+  int m = *memory; 
+  while( count-- > 0 ) { 
+    int i = *input++; 
+    i += m; 
+    int j = i + 32768 - 128; 
+    uchar o; 
+    if( j < 0 ) { 
+      o = 0; 
+    } 
+    else if( j > 65535 ) { 
+      o = 255; 
+    } 
+    else { 
+      o = (uchar)((j>>8)&0xff); 
+    } 
+    m = ((j-32768+128)-i); 
+    *output++ = o; 
+  } 
+  *memory = m; 
+} 
+*/
diff --git a/utils/iaxclient/lib/portaudio/src/common/pa_dither.h b/utils/iaxclient/lib/portaudio/src/common/pa_dither.h
new file mode 100644 (file)
index 0000000..4e14ec0
--- /dev/null
@@ -0,0 +1,91 @@
+#ifndef PA_DITHER_H
+#define PA_DITHER_H
+/*
+ * $Id: pa_dither.h,v 1.1 2006/06/10 21:30:55 dmazzoni Exp $
+ * Portable Audio I/O Library triangular dither generator
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2002 Phil Burk, Ross Bencina
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file
+ @brief Functions for generating dither noise
+*/
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+
+/** @brief State needed to generate a dither signal */
+typedef struct PaUtilTriangularDitherGenerator{
+    unsigned long previous;
+    unsigned long randSeed1;
+    unsigned long randSeed2;
+} PaUtilTriangularDitherGenerator;
+
+
+/** @brief Initialize dither state */
+void PaUtil_InitializeTriangularDitherState( PaUtilTriangularDitherGenerator *ditherState );
+
+
+/**
+ @brief Calculate 2 LSB dither signal with a triangular distribution.
+ Ranged for adding to a 1 bit right-shifted 32 bit integer
+ prior to >>15. eg:
+<pre>
+    signed long in = *
+    signed long dither = PaUtil_Generate16BitTriangularDither( ditherState );
+    signed short out = (signed short)(((in>>1) + dither) >> 15);
+</pre>
+ @return
+ A signed long with a range of +32767 to -32768
+*/
+signed long PaUtil_Generate16BitTriangularDither( PaUtilTriangularDitherGenerator *ditherState );
+
+
+/**
+ @brief Calculate 2 LSB dither signal with a triangular distribution.
+ Ranged for adding to a pre-scaled float.
+<pre>
+    float in = *
+    float dither = PaUtil_GenerateFloatTriangularDither( ditherState );
+    // use smaller scaler to prevent overflow when we add the dither
+    signed short out = (signed short)(in*(32766.0f) + dither );
+</pre>
+ @return
+ A float with a range of -2.0 to +1.99999.
+*/
+float PaUtil_GenerateFloatTriangularDither( PaUtilTriangularDitherGenerator *ditherState );
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* PA_DITHER_H */
diff --git a/utils/iaxclient/lib/portaudio/src/common/pa_endianness.h b/utils/iaxclient/lib/portaudio/src/common/pa_endianness.h
new file mode 100644 (file)
index 0000000..32471ca
--- /dev/null
@@ -0,0 +1,130 @@
+#ifndef PA_ENDIANNESS_H
+#define PA_ENDIANNESS_H
+/*
+ * $Id: pa_endianness.h,v 1.1 2006/06/10 21:30:55 dmazzoni Exp $
+ * Portable Audio I/O Library current platform endianness macros
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2002 Phil Burk, Ross Bencina
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file
+ @brief Configure endianness symbols for the target processor.
+
+ Arrange for either the PA_LITTLE_ENDIAN or PA_BIG_ENDIAN preprocessor symbols
+ to be defined. The one that is defined reflects the endianness of the target
+ platform and may be used to implement conditional compilation of byte-order
+ dependent code.
+
+ If either PA_LITTLE_ENDIAN or PA_BIG_ENDIAN is defined already, then no attempt
+ is made to override that setting. This may be useful if you have a better way
+ of determining the platform's endianness. The autoconf mechanism uses this for
+ example.
+
+ A PA_VALIDATE_ENDIANNESS macro is provided to compare the compile time
+ and runtime endiannes and raise an assertion if they don't match.
+*/
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/* If this is an apple, we need to do detect endianness this way */
+#if defined(__APPLE__)
+    /* we need to do some endian detection that is sensitive to harware arch */
+    #if defined(__LITTLE_ENDIAN__)
+       #if !defined( PA_LITTLE_ENDIAN )
+          #define PA_LITTLE_ENDIAN
+       #endif
+       #if defined( PA_BIG_ENDIAN )
+          #undef PA_BIG_ENDIAN
+       #endif
+    #else
+       #if !defined( PA_BIG_ENDIAN )
+          #define PA_BIG_ENDIAN
+       #endif
+       #if defined( PA_LITTLE_ENDIAN )
+          #undef PA_LITTLE_ENDIAN
+       #endif
+    #endif
+#else
+   /* this is not an apple, so first check the existing defines, and, failing that,
+      detect well-known architechtures. */
+
+   #if defined(PA_LITTLE_ENDIAN) || defined(PA_BIG_ENDIAN)
+       /* endianness define has been set externally, such as by autoconf */
+
+       #if defined(PA_LITTLE_ENDIAN) && defined(PA_BIG_ENDIAN)
+       #error both PA_LITTLE_ENDIAN and PA_BIG_ENDIAN have been defined externally to pa_endianness.h - only one endianness at a time please
+       #endif
+
+   #endif
+   /* endianness define has not been set externally */
+
+   /* set PA_LITTLE_ENDIAN or PA_BIG_ENDIAN by testing well known platform specific defines */
+
+   #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) || defined(LITTLE_ENDIAN) || defined(__i386) || defined(_M_IX86) || (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN)
+      #define PA_LITTLE_ENDIAN /* win32, assume intel byte order */
+   #else
+      #define PA_BIG_ENDIAN
+   #endif
+
+   #if !defined(PA_LITTLE_ENDIAN) && !defined(PA_BIG_ENDIAN)
+   /*
+    If the following error is raised, you either need to modify the code above
+    to automatically determine the endianness from other symbols defined on your
+    platform, or define either PA_LITTLE_ENDIAN or PA_BIG_ENDIAN externally.
+   */
+   #error pa_endianness.h was unable to automatically determine the endianness of the target platform
+   #endif
+
+#endif
+
+/* PA_VALIDATE_ENDIANNESS compares the compile time and runtime endianness,
+ and raises an assertion if they don't match. <assert.h> must be included in
+ the context in which this macro is used.
+*/
+#if defined(PA_LITTLE_ENDIAN)
+    #define PA_VALIDATE_ENDIANNESS \
+    { \
+        const long nativeOne = 1; \
+        assert( "PortAudio: compile time and runtime endianness don't match" && (((char *)&nativeOne)[0]) == 1 ); \
+    }
+#elif defined(PA_BIG_ENDIAN)
+    #define PA_VALIDATE_ENDIANNESS \
+    { \
+        const long nativeOne = 1; \
+        assert( "PortAudio: compile time and runtime endianness don't match" && (((char *)&nativeOne)[0]) == 0 ); \
+    }
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* PA_ENDIANNESS_H */
diff --git a/utils/iaxclient/lib/portaudio/src/common/pa_front.c b/utils/iaxclient/lib/portaudio/src/common/pa_front.c
new file mode 100644 (file)
index 0000000..168cf67
--- /dev/null
@@ -0,0 +1,1981 @@
+/*
+ * $Id: pa_front.c,v 1.1 2006/06/10 21:30:55 dmazzoni Exp $
+ * Portable Audio I/O Library Multi-Host API front end
+ * Validate function parameters and manage multiple host APIs.
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2002 Ross Bencina, Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* doxygen index page */
+/** @mainpage
+
+PortAudio is an open-source cross-platform C library for audio input
+and output. It is designed to simplify the porting of audio applications
+between various platforms, and also to simplify the development of audio
+software in general by hiding the complexities of device interfacing.
+
+See the PortAudio website for further information http://www.portaudio.com/
+
+This documentation pertains to PortAudio V19, API version 2.0 which is
+currently under development. API version 2.0 differs in a number of ways from
+previous versions, please consult the enhancement proposals for further details:
+http://www.portaudio.com/docs/proposals/index.html
+
+This documentation is under construction. Things you might be interested in
+include:
+
+- The PortAudio API 2.0, as documented in portaudio.h
+
+- The <a href="todo.html">TODO List</a>
+
+Feel free to pick an item off TODO list and fix/implement it. You may want to
+enquire about status on the PortAudio mailing list first.
+*/
+
+
+/** @file
+ @brief Implements public PortAudio API, checks some errors, forwards to
+ host API implementations.
+ Implements the functions defined in the PortAudio API, checks for
+ some parameter and state inconsistencies and forwards API requests to
+ specific Host API implementations (via the interface declared in
+ pa_hostapi.h), and Streams (via the interface declared in pa_stream.h).
+
+ This file handles initialization and termination of Host API
+ implementations via initializers stored in the paHostApiInitializers
+ global variable.
+
+ Some utility functions declared in pa_util.h are implemented in this file.
+
+ All PortAudio API functions can be conditionally compiled with logging code.
+ To compile with logging, define the PA_LOG_API_CALLS precompiler symbol.
+
+    @todo Consider adding host API specific error text in Pa_GetErrorText() for
+    paUnanticipatedHostError
+
+    @todo Consider adding a new error code for when (inputParameters == NULL)
+    && (outputParameters == NULL)
+
+    @todo review whether Pa_CloseStream() should call the interface's
+    CloseStream function if aborting the stream returns an error code.
+
+    @todo Create new error codes if a NULL buffer pointer, or a
+    zero frame count is passed to Pa_ReadStream or Pa_WriteStream.
+*/
+
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <memory.h>
+#include <string.h>
+#include <assert.h> /* needed by PA_VALIDATE_ENDIANNESS */
+
+#include "portaudio.h"
+#include "pa_util.h"
+#include "pa_endianness.h"
+#include "pa_types.h"
+#include "pa_hostapi.h"
+#include "pa_stream.h"
+
+#include "pa_trace.h"
+
+
+#define PA_VERSION_  1899
+#define PA_VERSION_TEXT_ "PortAudio V19-devel"
+
+
+
+/* #define PA_LOG_API_CALLS */
+
+/*
+    The basic format for log messages is described below. If you need to
+    add any log messages, please follow this format.
+    Function entry (void function):
+        "FunctionName called.\n"
+    Function entry (non void function):
+        "FunctionName called:\n"
+        "\tParam1Type param1: param1Value\n"
+        "\tParam2Type param2: param2Value\n"      (etc...)
+    Function exit (no return value):
+        "FunctionName returned.\n"
+    Function exit (simple return value):
+        "FunctionName returned:\n"
+        "\tReturnType: returnValue\n\n"
+    If the return type is an error code, the error text is displayed in ()
+    If the return type is not an error code, but has taken a special value
+    because an error occurred, then the reason for the error is shown in []
+    If the return type is a struct ptr, the struct is dumped.
+    See the code below for examples
+*/
+
+
+int Pa_GetVersion( void )
+{
+    return PA_VERSION_;
+}
+
+
+const char* Pa_GetVersionText( void )
+{
+    return PA_VERSION_TEXT_;
+}
+
+
+
+#define PA_LAST_HOST_ERROR_TEXT_LENGTH_  1024
+
+static char lastHostErrorText_[ PA_LAST_HOST_ERROR_TEXT_LENGTH_ + 1 ] = {0};
+
+static PaHostErrorInfo lastHostErrorInfo_ = { (PaHostApiTypeId)-1, 0, lastHostErrorText_ };
+
+
+void PaUtil_SetLastHostErrorInfo( PaHostApiTypeId hostApiType, long errorCode,
+        const char *errorText )
+{
+    lastHostErrorInfo_.hostApiType = hostApiType;
+    lastHostErrorInfo_.errorCode = errorCode;
+
+    strncpy( lastHostErrorText_, errorText, PA_LAST_HOST_ERROR_TEXT_LENGTH_ );
+}
+
+
+void PaUtil_DebugPrint( const char *format, ... )
+{
+    va_list ap;
+
+    va_start( ap, format );
+    vfprintf( stderr, format, ap );
+    va_end( ap );
+
+    fflush( stderr );
+}
+
+
+static PaUtilHostApiRepresentation **hostApis_ = 0;
+static int hostApisCount_ = 0;
+static int initializationCount_ = 0;
+static int deviceCount_ = 0;
+
+PaUtilStreamRepresentation *firstOpenStream_ = NULL;
+
+
+#define PA_IS_INITIALISED_ (initializationCount_ != 0)
+
+
+static int CountHostApiInitializers( void )
+{
+    int result = 0;
+
+    while( paHostApiInitializers[ result ] != 0 )
+        ++result;
+    return result;
+}
+
+
+static void TerminateHostApis( void )
+{
+    /* terminate in reverse order from initialization */
+
+    while( hostApisCount_ > 0 )
+    {
+        --hostApisCount_;
+        hostApis_[hostApisCount_]->Terminate( hostApis_[hostApisCount_] );
+    }
+    hostApisCount_ = 0;
+    deviceCount_ = 0;
+
+    if( hostApis_ != 0 )
+        PaUtil_FreeMemory( hostApis_ );
+    hostApis_ = 0;
+}
+
+
+static PaError InitializeHostApis( void )
+{
+    PaError result = paNoError;
+    int i, initializerCount, baseDeviceIndex;
+
+    initializerCount = CountHostApiInitializers();
+
+    hostApis_ = (PaUtilHostApiRepresentation**)PaUtil_AllocateMemory(
+            sizeof(PaUtilHostApiRepresentation*) * initializerCount );
+    if( !hostApis_ )
+    {
+        result = paInsufficientMemory;
+        goto error; 
+    }
+
+    hostApisCount_ = 0;
+    deviceCount_ = 0;
+    baseDeviceIndex = 0;
+
+    for( i=0; i< initializerCount; ++i )
+    {
+        hostApis_[hostApisCount_] = NULL;
+        result = paHostApiInitializers[i]( &hostApis_[hostApisCount_], hostApisCount_ );
+        if( result != paNoError )
+            goto error;
+
+        if( hostApis_[hostApisCount_] )
+        {
+            PaUtilHostApiRepresentation* hostApi = hostApis_[hostApisCount_];
+            assert( hostApi->info.defaultInputDevice < hostApi->info.deviceCount );
+            assert( hostApi->info.defaultOutputDevice < hostApi->info.deviceCount );
+
+            hostApis_[hostApisCount_]->privatePaFrontInfo.baseDeviceIndex = baseDeviceIndex;
+
+            if( hostApis_[hostApisCount_]->info.defaultInputDevice != paNoDevice )
+                hostApis_[hostApisCount_]->info.defaultInputDevice += baseDeviceIndex;
+
+            if( hostApis_[hostApisCount_]->info.defaultOutputDevice != paNoDevice )
+                hostApis_[hostApisCount_]->info.defaultOutputDevice += baseDeviceIndex;
+
+            baseDeviceIndex += hostApis_[hostApisCount_]->info.deviceCount;
+            deviceCount_ += hostApis_[hostApisCount_]->info.deviceCount;
+
+            ++hostApisCount_;
+        }
+    }
+
+    return result;
+
+error:
+    TerminateHostApis();
+    return result;
+}
+
+
+/*
+    FindHostApi() finds the index of the host api to which
+    <device> belongs and returns it. if <hostSpecificDeviceIndex> is
+    non-null, the host specific device index is returned in it.
+    returns -1 if <device> is out of range.
+*/
+static int FindHostApi( PaDeviceIndex device, int *hostSpecificDeviceIndex )
+{
+    int i=0;
+
+    if( !PA_IS_INITIALISED_ )
+        return -1;
+
+    if( device < 0 )
+        return -1;
+
+    while( i < hostApisCount_
+            && device >= hostApis_[i]->info.deviceCount )
+    {
+
+        device -= hostApis_[i]->info.deviceCount;
+        ++i;
+    }
+
+    if( i >= hostApisCount_ )
+        return -1;
+
+    if( hostSpecificDeviceIndex )
+        *hostSpecificDeviceIndex = device;
+
+    return i;
+}
+
+
+static void AddOpenStream( PaStream* stream )
+{
+    ((PaUtilStreamRepresentation*)stream)->nextOpenStream = firstOpenStream_;
+    firstOpenStream_ = (PaUtilStreamRepresentation*)stream;
+}
+
+
+static void RemoveOpenStream( PaStream* stream )
+{
+    PaUtilStreamRepresentation *previous = NULL;
+    PaUtilStreamRepresentation *current = firstOpenStream_;
+
+    while( current != NULL )
+    {
+        if( ((PaStream*)current) == stream )
+        {
+            if( previous == NULL )
+            {
+                firstOpenStream_ = current->nextOpenStream;
+            }
+            else
+            {
+                previous->nextOpenStream = current->nextOpenStream;
+            }
+            return;
+        }
+        else
+        {
+            previous = current;
+            current = current->nextOpenStream;
+        }
+    }
+}
+
+
+static void CloseOpenStreams( void )
+{
+    /* we call Pa_CloseStream() here to ensure that the same destruction
+        logic is used for automatically closed streams */
+
+    while( firstOpenStream_ != NULL )
+        Pa_CloseStream( firstOpenStream_ );
+}
+
+
+PaError Pa_Initialize( void )
+{
+    PaError result;
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint( "Pa_Initialize called.\n" );
+#endif
+
+    if( PA_IS_INITIALISED_ )
+    {
+        ++initializationCount_;
+        result = paNoError;
+    }
+    else
+    {
+        PA_VALIDATE_TYPE_SIZES;
+        PA_VALIDATE_ENDIANNESS;
+        
+        PaUtil_InitializeClock();
+        PaUtil_ResetTraceMessages();
+
+        result = InitializeHostApis();
+        if( result == paNoError )
+            ++initializationCount_;
+    }
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint( "Pa_Initialize returned:\n" );
+    PaUtil_DebugPrint( "\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+#endif
+
+    return result;
+}
+
+
+PaError Pa_Terminate( void )
+{
+    PaError result;
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_Terminate called.\n" );
+#endif
+
+    if( PA_IS_INITIALISED_ )
+    {
+        if( --initializationCount_ == 0 )
+        {
+            CloseOpenStreams();
+
+            TerminateHostApis();
+
+            PaUtil_DumpTraceMessages();
+        }
+        result = paNoError;
+    }
+    else
+    {
+        result=  paNotInitialized;
+    }
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_Terminate returned:\n" );
+    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+#endif
+
+    return result;
+}
+
+
+const PaHostErrorInfo* Pa_GetLastHostErrorInfo( void )
+{
+    return &lastHostErrorInfo_;
+}
+
+
+const char *Pa_GetErrorText( PaError errorCode )
+{
+    const char *result;
+
+    switch( errorCode )
+    {
+    case paNoError:                  result = "Success"; break;
+    case paNotInitialized:           result = "PortAudio not initialized"; break;
+    /** @todo could catenate the last host error text to result in the case of paUnanticipatedHostError */
+    case paUnanticipatedHostError:   result = "Unanticipated host error"; break;
+    case paInvalidChannelCount:      result = "Invalid number of channels"; break;
+    case paInvalidSampleRate:        result = "Invalid sample rate"; break;
+    case paInvalidDevice:            result = "Invalid device"; break;
+    case paInvalidFlag:              result = "Invalid flag"; break;
+    case paSampleFormatNotSupported: result = "Sample format not supported"; break;
+    case paBadIODeviceCombination:   result = "Illegal combination of I/O devices"; break;
+    case paInsufficientMemory:       result = "Insufficient memory"; break;
+    case paBufferTooBig:             result = "Buffer too big"; break;
+    case paBufferTooSmall:           result = "Buffer too small"; break;
+    case paNullCallback:             result = "No callback routine specified"; break;
+    case paBadStreamPtr:             result = "Invalid stream pointer"; break;
+    case paTimedOut:                 result = "Wait timed out"; break;
+    case paInternalError:            result = "Internal PortAudio error"; break;
+    case paDeviceUnavailable:        result = "Device unavailable"; break;
+    case paIncompatibleHostApiSpecificStreamInfo:   result = "Incompatible host API specific stream info"; break;
+    case paStreamIsStopped:          result = "Stream is stopped"; break;
+    case paStreamIsNotStopped:       result = "Stream is not stopped"; break;
+    case paInputOverflowed:          result = "Input overflowed"; break;
+    case paOutputUnderflowed:        result = "Output underflowed"; break;
+    case paHostApiNotFound:          result = "Host API not found"; break;
+    case paInvalidHostApi:           result = "Invalid host API"; break;
+    case paCanNotReadFromACallbackStream:       result = "Can't read from a callback stream"; break;
+    case paCanNotWriteToACallbackStream:        result = "Can't write to a callback stream"; break;
+    case paCanNotReadFromAnOutputOnlyStream:    result = "Can't read from an output only stream"; break;
+    case paCanNotWriteToAnInputOnlyStream:      result = "Can't write to an input only stream"; break;
+    default:                         result = "Illegal error number"; break;
+    }
+    return result;
+}
+
+
+PaHostApiIndex Pa_HostApiTypeIdToHostApiIndex( PaHostApiTypeId type )
+{
+    PaHostApiIndex result;
+    int i;
+    
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_HostApiTypeIdToHostApiIndex called:\n" );
+    PaUtil_DebugPrint("\tPaHostApiTypeId type: %d\n", type );
+#endif
+
+    if( !PA_IS_INITIALISED_ )
+    {
+        result = paNotInitialized;
+    }
+    else
+    {
+        result = paHostApiNotFound;
+        
+        for( i=0; i < hostApisCount_; ++i )
+        {
+            if( hostApis_[i]->info.type == type )
+            {
+                result = i;
+                break;
+            }         
+        }
+    }
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_HostApiTypeIdToHostApiIndex returned:\n" );
+    if( result < 0 )
+        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+    else
+        PaUtil_DebugPrint("\tPaHostApiIndex: %d\n\n", result );
+#endif
+
+    return result;
+}
+
+
+PaError PaUtil_GetHostApiRepresentation( struct PaUtilHostApiRepresentation **hostApi,
+        PaHostApiTypeId type )
+{
+    PaError result;
+    int i;
+    
+    if( !PA_IS_INITIALISED_ )
+    {
+        result = paNotInitialized;
+    }
+    else
+    {
+        result = paHostApiNotFound;
+                
+        for( i=0; i < hostApisCount_; ++i )
+        {
+            if( hostApis_[i]->info.type == type )
+            {
+                *hostApi = hostApis_[i];
+                result = paNoError;
+                break;
+            }
+        }
+    }
+
+    return result;
+}
+
+
+PaError PaUtil_DeviceIndexToHostApiDeviceIndex(
+        PaDeviceIndex *hostApiDevice, PaDeviceIndex device, struct PaUtilHostApiRepresentation *hostApi )
+{
+    PaError result;
+    PaDeviceIndex x;
+    
+    x = device - hostApi->privatePaFrontInfo.baseDeviceIndex;
+
+    if( x < 0 || x >= hostApi->info.deviceCount )
+    {
+        result = paInvalidDevice;
+    }
+    else
+    {
+        *hostApiDevice = x;
+        result = paNoError;
+    }
+
+    return result;
+}
+
+
+PaHostApiIndex Pa_GetHostApiCount( void )
+{
+    int result;
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_GetHostApiCount called.\n" );
+#endif
+
+    if( !PA_IS_INITIALISED_ )
+    {
+        result = paNotInitialized;
+    }
+    else
+    {
+        result = hostApisCount_;
+    }
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_GetHostApiCount returned:\n" );
+    if( result < 0 )
+        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+    else
+        PaUtil_DebugPrint("\tPaHostApiIndex %d\n\n", result );
+#endif
+
+    return result;
+}
+
+
+PaHostApiIndex Pa_GetDefaultHostApi( void )
+{
+    int result;
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_GetDefaultHostApi called.\n" );
+#endif
+
+    if( !PA_IS_INITIALISED_ )
+    {
+        result = paNotInitialized;
+    }
+    else
+    {
+        result = paDefaultHostApiIndex;
+
+        /* internal consistency check: make sure that the default host api
+         index is within range */
+
+        if( result < 0 || result >= hostApisCount_ )
+        {
+            result = paInternalError;
+        }
+    }
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_GetDefaultHostApi returned:\n" );
+    if( result < 0 )
+        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+    else
+        PaUtil_DebugPrint("\tPaHostApiIndex %d\n\n", result );
+#endif
+
+    return result;
+}
+
+
+const PaHostApiInfo* Pa_GetHostApiInfo( PaHostApiIndex hostApi )
+{
+    PaHostApiInfo *info;
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_GetHostApiInfo called:\n" );
+    PaUtil_DebugPrint("\tPaHostApiIndex hostApi: %d\n", hostApi );
+#endif
+
+    if( !PA_IS_INITIALISED_ )
+    {
+        info = NULL;
+
+#ifdef PA_LOG_API_CALLS
+        PaUtil_DebugPrint("Pa_GetHostApiInfo returned:\n" );
+        PaUtil_DebugPrint("\tPaHostApiInfo*: NULL [ PortAudio not initialized ]\n\n" );
+#endif
+
+    }
+    else if( hostApi < 0 || hostApi >= hostApisCount_ )
+    {
+        info = NULL;
+        
+#ifdef PA_LOG_API_CALLS
+        PaUtil_DebugPrint("Pa_GetHostApiInfo returned:\n" );
+        PaUtil_DebugPrint("\tPaHostApiInfo*: NULL [ hostApi out of range ]\n\n" );
+#endif
+
+    }
+    else
+    {
+        info = &hostApis_[hostApi]->info;
+
+#ifdef PA_LOG_API_CALLS
+        PaUtil_DebugPrint("Pa_GetHostApiInfo returned:\n" );
+        PaUtil_DebugPrint("\tPaHostApiInfo*: 0x%p\n", info );
+        PaUtil_DebugPrint("\t{" );
+        PaUtil_DebugPrint("\t\tint structVersion: %d\n", info->structVersion );
+        PaUtil_DebugPrint("\t\tPaHostApiTypeId type: %d\n", info->type );
+        PaUtil_DebugPrint("\t\tconst char *name: %s\n\n", info->name );
+        PaUtil_DebugPrint("\t}\n\n" );
+#endif
+
+    }
+
+     return info;
+}
+
+
+PaDeviceIndex Pa_HostApiDeviceIndexToDeviceIndex( PaHostApiIndex hostApi, int hostApiDeviceIndex )
+{
+    PaDeviceIndex result;
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_HostApiDeviceIndexToPaDeviceIndex called:\n" );
+    PaUtil_DebugPrint("\tPaHostApiIndex hostApi: %d\n", hostApi );
+    PaUtil_DebugPrint("\tint hostApiDeviceIndex: %d\n", hostApiDeviceIndex );
+#endif
+
+    if( !PA_IS_INITIALISED_ )
+    {
+        result = paNotInitialized;
+    }
+    else
+    {
+        if( hostApi < 0 || hostApi >= hostApisCount_ )
+        {
+            result = paInvalidHostApi;
+        }
+        else
+        {
+            if( hostApiDeviceIndex < 0 ||
+                    hostApiDeviceIndex >= hostApis_[hostApi]->info.deviceCount )
+            {
+                result = paInvalidDevice;
+            }
+            else
+            {
+                result = hostApis_[hostApi]->privatePaFrontInfo.baseDeviceIndex + hostApiDeviceIndex;
+            }
+        }
+    }
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_HostApiDeviceIndexToPaDeviceIndex returned:\n" );
+    if( result < 0 )
+        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+    else
+        PaUtil_DebugPrint("\tPaDeviceIndex: %d\n\n", result );
+#endif
+
+    return result;
+}
+
+
+PaDeviceIndex Pa_GetDeviceCount( void )
+{
+    PaDeviceIndex result;
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_GetDeviceCount called.\n" );
+#endif
+
+    if( !PA_IS_INITIALISED_ )
+    {
+        result = paNotInitialized;
+    }
+    else
+    {
+        result = deviceCount_;
+    }
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_GetDeviceCount returned:\n" );
+    if( result < 0 )
+        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+    else
+        PaUtil_DebugPrint("\tPaDeviceIndex: %d\n\n", result );
+#endif
+
+    return result;
+}
+
+
+PaDeviceIndex Pa_GetDefaultInputDevice( void )
+{
+    PaHostApiIndex hostApi;
+    PaDeviceIndex result;
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_GetDefaultInputDevice called.\n" );
+#endif
+
+    hostApi = Pa_GetDefaultHostApi();
+    if( hostApi < 0 )
+    {
+        result = paNoDevice;
+    }
+    else
+    {
+        result = hostApis_[hostApi]->info.defaultInputDevice;
+    }
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_GetDefaultInputDevice returned:\n" );
+    PaUtil_DebugPrint("\tPaDeviceIndex: %d\n\n", result );
+#endif
+
+    return result;
+}
+
+
+PaDeviceIndex Pa_GetDefaultOutputDevice( void )
+{
+    PaHostApiIndex hostApi;
+    PaDeviceIndex result;
+    
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_GetDefaultOutputDevice called.\n" );
+#endif
+
+    hostApi = Pa_GetDefaultHostApi();
+    if( hostApi < 0 )
+    {
+        result = paNoDevice;
+    }
+    else
+    {
+        result = hostApis_[hostApi]->info.defaultOutputDevice;
+    }
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_GetDefaultOutputDevice returned:\n" );
+    PaUtil_DebugPrint("\tPaDeviceIndex: %d\n\n", result );
+#endif
+
+    return result;
+}
+
+
+const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceIndex device )
+{
+    int hostSpecificDeviceIndex;
+    int hostApiIndex = FindHostApi( device, &hostSpecificDeviceIndex );
+    PaDeviceInfo *result;
+
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_GetDeviceInfo called:\n" );
+    PaUtil_DebugPrint("\tPaDeviceIndex device: %d\n", device );
+#endif
+
+    if( hostApiIndex < 0 )
+    {
+        result = NULL;
+
+#ifdef PA_LOG_API_CALLS
+        PaUtil_DebugPrint("Pa_GetDeviceInfo returned:\n" );
+        PaUtil_DebugPrint("\tPaDeviceInfo* NULL [ invalid device index ]\n\n" );
+#endif
+
+    }
+    else
+    {
+        result = hostApis_[hostApiIndex]->deviceInfos[ hostSpecificDeviceIndex ];
+
+#ifdef PA_LOG_API_CALLS
+        PaUtil_DebugPrint("Pa_GetDeviceInfo returned:\n" );
+        PaUtil_DebugPrint("\tPaDeviceInfo*: 0x%p:\n", result );
+        PaUtil_DebugPrint("\t{\n" );
+
+        PaUtil_DebugPrint("\t\tint structVersion: %d\n", result->structVersion );
+        PaUtil_DebugPrint("\t\tconst char *name: %s\n", result->name );
+        PaUtil_DebugPrint("\t\tPaHostApiIndex hostApi: %d\n", result->hostApi );
+        PaUtil_DebugPrint("\t\tint maxInputChannels: %d\n", result->maxInputChannels );
+        PaUtil_DebugPrint("\t\tint maxOutputChannels: %d\n", result->maxOutputChannels );
+        PaUtil_DebugPrint("\t}\n\n" );
+#endif
+
+    }
+
+    return result;
+}
+
+
+/*
+    SampleFormatIsValid() returns 1 if sampleFormat is a sample format
+    defined in portaudio.h, or 0 otherwise.
+*/
+static int SampleFormatIsValid( PaSampleFormat format )
+{
+    switch( format & ~paNonInterleaved )
+    {
+    case paFloat32: return 1;
+    case paInt16: return 1;
+    case paInt32: return 1;
+    case paInt24: return 1;
+    case paInt8: return 1;
+    case paUInt8: return 1;
+    case paCustomFormat: return 1;
+    default: return 0;
+    }
+}
+
+/*
+    NOTE: make sure this validation list is kept syncronised with the one in
+            pa_hostapi.h
+
+    ValidateOpenStreamParameters() checks that parameters to Pa_OpenStream()
+    conform to the expected values as described below. This function is
+    also designed to be used with the proposed Pa_IsFormatSupported() function.
+    
+    There are basically two types of validation that could be performed:
+    Generic conformance validation, and device capability mismatch
+    validation. This function performs only generic conformance validation.
+    Validation that would require knowledge of device capabilities is
+    not performed because of potentially complex relationships between
+    combinations of parameters - for example, even if the sampleRate
+    seems ok, it might not be for a duplex stream - we have no way of
+    checking this in an API-neutral way, so we don't try.
+    On success the function returns PaNoError and fills in hostApi,
+    hostApiInputDeviceID, and hostApiOutputDeviceID fields. On failure
+    the function returns an error code indicating the first encountered
+    parameter error.
+    If ValidateOpenStreamParameters() returns paNoError, the following
+    assertions are guaranteed to be true.
+    - at least one of inputParameters & outputParmeters is valid (not NULL)
+
+    - if inputParameters & outputParameters are both valid, that
+        inputParameters->device & outputParameters->device  both use the same host api
+    PaDeviceIndex inputParameters->device
+        - is within range (0 to Pa_GetDeviceCount-1) Or:
+        - is paUseHostApiSpecificDeviceSpecification and
+            inputParameters->hostApiSpecificStreamInfo is non-NULL and refers
+            to a valid host api
+
+    int inputParameters->channelCount
+        - if inputParameters->device is not paUseHostApiSpecificDeviceSpecification, channelCount is > 0
+        - upper bound is NOT validated against device capabilities
+    PaSampleFormat inputParameters->sampleFormat
+        - is one of the sample formats defined in portaudio.h
+
+    void *inputParameters->hostApiSpecificStreamInfo
+        - if supplied its hostApi field matches the input device's host Api
+    PaDeviceIndex outputParmeters->device
+        - is within range (0 to Pa_GetDeviceCount-1)
+    int outputParmeters->channelCount
+        - if inputDevice is valid, channelCount is > 0
+        - upper bound is NOT validated against device capabilities
+    PaSampleFormat outputParmeters->sampleFormat
+        - is one of the sample formats defined in portaudio.h
+        
+    void *outputParmeters->hostApiSpecificStreamInfo
+        - if supplied its hostApi field matches the output device's host Api
+    double sampleRate
+        - is not an 'absurd' rate (less than 1000. or greater than 200000.)
+        - sampleRate is NOT validated against device capabilities
+    PaStreamFlags streamFlags
+        - unused platform neutral flags are zero
+        - paNeverDropInput is only used for full-duplex callback streams with
+            variable buffer size (paFramesPerBufferUnspecified)
+*/
+static PaError ValidateOpenStreamParameters(
+    const PaStreamParameters *inputParameters,
+    const PaStreamParameters *outputParameters,
+    double sampleRate,
+    unsigned long framesPerBuffer,
+    PaStreamFlags streamFlags,
+    PaStreamCallback *streamCallback,
+    PaUtilHostApiRepresentation **hostApi,
+    PaDeviceIndex *hostApiInputDevice,
+    PaDeviceIndex *hostApiOutputDevice )
+{
+    int inputHostApiIndex  = -1, /* Surpress uninitialised var warnings: compiler does */
+        outputHostApiIndex = -1; /* not see that if inputParameters and outputParame-  */
+                                 /* ters are both nonzero, these indices are set.      */
+
+    if( (inputParameters == NULL) && (outputParameters == NULL) )
+    {
+        return paInvalidDevice; /** @todo should be a new error code "invalid device parameters" or something */
+    }
+    else
+    {
+        if( inputParameters == NULL )
+        {
+            *hostApiInputDevice = paNoDevice;
+        }
+        else if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
+        {
+            if( inputParameters->hostApiSpecificStreamInfo )
+            {
+                inputHostApiIndex = Pa_HostApiTypeIdToHostApiIndex(
+                        ((PaUtilHostApiSpecificStreamInfoHeader*)inputParameters->hostApiSpecificStreamInfo)->hostApiType );
+
+                if( inputHostApiIndex != -1 )
+                {
+                    *hostApiInputDevice = paUseHostApiSpecificDeviceSpecification;
+                    *hostApi = hostApis_[inputHostApiIndex];
+                }
+                else
+                {
+                    return paInvalidDevice;
+                }
+            }
+            else
+            {
+                return paInvalidDevice;
+            }
+        }
+        else
+        {
+            if( inputParameters->device < 0 || inputParameters->device >= deviceCount_ )
+                return paInvalidDevice;
+
+            inputHostApiIndex = FindHostApi( inputParameters->device, hostApiInputDevice );
+            if( inputHostApiIndex < 0 )
+                return paInternalError;
+
+            *hostApi = hostApis_[inputHostApiIndex];
+
+            if( inputParameters->channelCount <= 0 )
+                return paInvalidChannelCount;
+
+            if( !SampleFormatIsValid( inputParameters->sampleFormat ) )
+                return paSampleFormatNotSupported;
+
+            if( inputParameters->hostApiSpecificStreamInfo != NULL )
+            {
+                if( ((PaUtilHostApiSpecificStreamInfoHeader*)inputParameters->hostApiSpecificStreamInfo)->hostApiType
+                        != (*hostApi)->info.type )
+                    return paIncompatibleHostApiSpecificStreamInfo;
+            }
+        }
+
+        if( outputParameters == NULL )
+        {
+            *hostApiOutputDevice = paNoDevice;
+        }
+        else if( outputParameters->device == paUseHostApiSpecificDeviceSpecification  )
+        {
+            if( outputParameters->hostApiSpecificStreamInfo )
+            {
+                outputHostApiIndex = Pa_HostApiTypeIdToHostApiIndex(
+                        ((PaUtilHostApiSpecificStreamInfoHeader*)outputParameters->hostApiSpecificStreamInfo)->hostApiType );
+
+                if( outputHostApiIndex != -1 )
+                {
+                    *hostApiOutputDevice = paUseHostApiSpecificDeviceSpecification;
+                    *hostApi = hostApis_[outputHostApiIndex];
+                }
+                else
+                {
+                    return paInvalidDevice;
+                }
+            }
+            else
+            {
+                return paInvalidDevice;
+            }
+        }
+        else
+        {
+            if( outputParameters->device < 0 || outputParameters->device >= deviceCount_ )
+                return paInvalidDevice;
+
+            outputHostApiIndex = FindHostApi( outputParameters->device, hostApiOutputDevice );
+            if( outputHostApiIndex < 0 )
+                return paInternalError;
+
+            *hostApi = hostApis_[outputHostApiIndex];
+
+            if( outputParameters->channelCount <= 0 )
+                return paInvalidChannelCount;
+
+            if( !SampleFormatIsValid( outputParameters->sampleFormat ) )
+                return paSampleFormatNotSupported;
+
+            if( outputParameters->hostApiSpecificStreamInfo != NULL )
+            {
+                if( ((PaUtilHostApiSpecificStreamInfoHeader*)outputParameters->hostApiSpecificStreamInfo)->hostApiType
+                        != (*hostApi)->info.type )
+                    return paIncompatibleHostApiSpecificStreamInfo;
+            }
+        }   
+
+        if( (inputParameters != NULL) && (outputParameters != NULL) )
+        {
+            /* ensure that both devices use the same API */
+            if( inputHostApiIndex != outputHostApiIndex )
+                return paBadIODeviceCombination;
+        }
+    }
+    
+    
+    /* Check for absurd sample rates. */
+    if( (sampleRate < 1000.0) || (sampleRate > 200000.0) )
+        return paInvalidSampleRate;
+
+    if( ((streamFlags & ~paPlatformSpecificFlags) & ~(paClipOff | paDitherOff | paNeverDropInput | paPrimeOutputBuffersUsingStreamCallback ) ) != 0 )
+        return paInvalidFlag;
+
+    if( streamFlags & paNeverDropInput )
+    {
+        /* must be a callback stream */
+        if( !streamCallback )
+             return paInvalidFlag;
+
+        /* must be a full duplex stream */
+        if( (inputParameters == NULL) || (outputParameters == NULL) )
+            return paInvalidFlag;
+
+        /* must use paFramesPerBufferUnspecified */
+        if( framesPerBuffer != paFramesPerBufferUnspecified )
+            return paInvalidFlag;
+    }
+    
+    return paNoError;
+}
+
+
+PaError Pa_IsFormatSupported( const PaStreamParameters *inputParameters,
+                              const PaStreamParameters *outputParameters,
+                              double sampleRate )
+{
+    PaError result;
+    PaUtilHostApiRepresentation *hostApi;
+    PaDeviceIndex hostApiInputDevice, hostApiOutputDevice;
+    PaStreamParameters hostApiInputParameters, hostApiOutputParameters;
+    PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr;
+
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_IsFormatSupported called:\n" );
+
+    if( inputParameters == NULL ){
+        PaUtil_DebugPrint("\tPaStreamParameters *inputParameters: NULL\n" );
+    }else{
+        PaUtil_DebugPrint("\tPaStreamParameters *inputParameters: 0x%p\n", inputParameters );
+        PaUtil_DebugPrint("\tPaDeviceIndex inputParameters->device: %d\n", inputParameters->device );
+        PaUtil_DebugPrint("\tint inputParameters->channelCount: %d\n", inputParameters->channelCount );
+        PaUtil_DebugPrint("\tPaSampleFormat inputParameters->sampleFormat: %d\n", inputParameters->sampleFormat );
+        PaUtil_DebugPrint("\tPaTime inputParameters->suggestedLatency: %f\n", inputParameters->suggestedLatency );
+        PaUtil_DebugPrint("\tvoid *inputParameters->hostApiSpecificStreamInfo: 0x%p\n", inputParameters->hostApiSpecificStreamInfo );
+    }
+
+    if( outputParameters == NULL ){
+        PaUtil_DebugPrint("\tPaStreamParameters *outputParameters: NULL\n" );
+    }else{
+        PaUtil_DebugPrint("\tPaStreamParameters *outputParameters: 0x%p\n", outputParameters );
+        PaUtil_DebugPrint("\tPaDeviceIndex outputParameters->device: %d\n", outputParameters->device );
+        PaUtil_DebugPrint("\tint outputParameters->channelCount: %d\n", outputParameters->channelCount );
+        PaUtil_DebugPrint("\tPaSampleFormat outputParameters->sampleFormat: %d\n", outputParameters->sampleFormat );
+        PaUtil_DebugPrint("\tPaTime outputParameters->suggestedLatency: %f\n", outputParameters->suggestedLatency );
+        PaUtil_DebugPrint("\tvoid *outputParameters->hostApiSpecificStreamInfo: 0x%p\n", outputParameters->hostApiSpecificStreamInfo );
+    }
+    
+    PaUtil_DebugPrint("\tdouble sampleRate: %g\n", sampleRate );
+#endif
+
+    if( !PA_IS_INITIALISED_ )
+    {
+        result = paNotInitialized;
+
+#ifdef PA_LOG_API_CALLS
+        PaUtil_DebugPrint("Pa_IsFormatSupported returned:\n" );
+        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+#endif
+        return result;
+    }
+
+    result = ValidateOpenStreamParameters( inputParameters,
+                                           outputParameters,
+                                           sampleRate, 0, paNoFlag, 0,
+                                           &hostApi,
+                                           &hostApiInputDevice,
+                                           &hostApiOutputDevice );
+    if( result != paNoError )
+    {
+#ifdef PA_LOG_API_CALLS
+        PaUtil_DebugPrint("Pa_IsFormatSupported returned:\n" );
+        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+#endif
+        return result;
+    }
+    
+
+    if( inputParameters )
+    {
+        hostApiInputParameters.device = hostApiInputDevice;
+        hostApiInputParameters.channelCount = inputParameters->channelCount;
+        hostApiInputParameters.sampleFormat = inputParameters->sampleFormat;
+        hostApiInputParameters.suggestedLatency = inputParameters->suggestedLatency;
+        hostApiInputParameters.hostApiSpecificStreamInfo = inputParameters->hostApiSpecificStreamInfo;
+        hostApiInputParametersPtr = &hostApiInputParameters;
+    }
+    else
+    {
+        hostApiInputParametersPtr = NULL;
+    }
+
+    if( outputParameters )
+    {
+        hostApiOutputParameters.device = hostApiOutputDevice;
+        hostApiOutputParameters.channelCount = outputParameters->channelCount;
+        hostApiOutputParameters.sampleFormat = outputParameters->sampleFormat;
+        hostApiOutputParameters.suggestedLatency = outputParameters->suggestedLatency;
+        hostApiOutputParameters.hostApiSpecificStreamInfo = outputParameters->hostApiSpecificStreamInfo;
+        hostApiOutputParametersPtr = &hostApiOutputParameters;
+    }
+    else
+    {
+        hostApiOutputParametersPtr = NULL;
+    }
+
+    result = hostApi->IsFormatSupported( hostApi,
+                                  hostApiInputParametersPtr, hostApiOutputParametersPtr,
+                                  sampleRate );
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_OpenStream returned:\n" );
+    if( result == paFormatIsSupported )
+        PaUtil_DebugPrint("\tPaError: 0 [ paFormatIsSupported ]\n\n" );
+    else
+        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+#endif
+
+    return result;
+}
+
+
+PaError Pa_OpenStream( PaStream** stream,
+                       const PaStreamParameters *inputParameters,
+                       const PaStreamParameters *outputParameters,
+                       double sampleRate,
+                       unsigned long framesPerBuffer,
+                       PaStreamFlags streamFlags,
+                       PaStreamCallback *streamCallback,
+                       void *userData )
+{
+    PaError result;
+    PaUtilHostApiRepresentation *hostApi;
+    PaDeviceIndex hostApiInputDevice, hostApiOutputDevice;
+    PaStreamParameters hostApiInputParameters, hostApiOutputParameters;
+    PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr;
+
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_OpenStream called:\n" );
+    PaUtil_DebugPrint("\tPaStream** stream: 0x%p\n", stream );
+
+    if( inputParameters == NULL ){
+        PaUtil_DebugPrint("\tPaStreamParameters *inputParameters: NULL\n" );
+    }else{
+        PaUtil_DebugPrint("\tPaStreamParameters *inputParameters: 0x%p\n", inputParameters );
+        PaUtil_DebugPrint("\tPaDeviceIndex inputParameters->device: %d\n", inputParameters->device );
+        PaUtil_DebugPrint("\tint inputParameters->channelCount: %d\n", inputParameters->channelCount );
+        PaUtil_DebugPrint("\tPaSampleFormat inputParameters->sampleFormat: %d\n", inputParameters->sampleFormat );
+        PaUtil_DebugPrint("\tPaTime inputParameters->suggestedLatency: %f\n", inputParameters->suggestedLatency );
+        PaUtil_DebugPrint("\tvoid *inputParameters->hostApiSpecificStreamInfo: 0x%p\n", inputParameters->hostApiSpecificStreamInfo );
+    }
+
+    if( outputParameters == NULL ){
+        PaUtil_DebugPrint("\tPaStreamParameters *outputParameters: NULL\n" );
+    }else{
+        PaUtil_DebugPrint("\tPaStreamParameters *outputParameters: 0x%p\n", outputParameters );
+        PaUtil_DebugPrint("\tPaDeviceIndex outputParameters->device: %d\n", outputParameters->device );
+        PaUtil_DebugPrint("\tint outputParameters->channelCount: %d\n", outputParameters->channelCount );
+        PaUtil_DebugPrint("\tPaSampleFormat outputParameters->sampleFormat: %d\n", outputParameters->sampleFormat );
+        PaUtil_DebugPrint("\tPaTime outputParameters->suggestedLatency: %f\n", outputParameters->suggestedLatency );
+        PaUtil_DebugPrint("\tvoid *outputParameters->hostApiSpecificStreamInfo: 0x%p\n", outputParameters->hostApiSpecificStreamInfo );
+    }
+    
+    PaUtil_DebugPrint("\tdouble sampleRate: %g\n", sampleRate );
+    PaUtil_DebugPrint("\tunsigned long framesPerBuffer: %d\n", framesPerBuffer );
+    PaUtil_DebugPrint("\tPaStreamFlags streamFlags: 0x%x\n", streamFlags );
+    PaUtil_DebugPrint("\tPaStreamCallback *streamCallback: 0x%p\n", streamCallback );
+    PaUtil_DebugPrint("\tvoid *userData: 0x%p\n", userData );
+#endif
+
+    if( !PA_IS_INITIALISED_ )
+    {
+        result = paNotInitialized;
+
+#ifdef PA_LOG_API_CALLS
+        PaUtil_DebugPrint("Pa_OpenStream returned:\n" );
+        PaUtil_DebugPrint("\t*(PaStream** stream): undefined\n" );
+        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+#endif
+        return result;
+    }
+
+    /* Check for parameter errors.
+        NOTE: make sure this validation list is kept syncronised with the one
+        in pa_hostapi.h
+    */
+
+    if( stream == NULL )
+    {
+        result = paBadStreamPtr;
+
+#ifdef PA_LOG_API_CALLS
+        PaUtil_DebugPrint("Pa_OpenStream returned:\n" );
+        PaUtil_DebugPrint("\t*(PaStream** stream): undefined\n" );
+        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+#endif
+        return result;
+    }
+
+    result = ValidateOpenStreamParameters( inputParameters,
+                                           outputParameters,
+                                           sampleRate, framesPerBuffer,
+                                           streamFlags, streamCallback,
+                                           &hostApi,
+                                           &hostApiInputDevice,
+                                           &hostApiOutputDevice );
+    if( result != paNoError )
+    {
+#ifdef PA_LOG_API_CALLS
+        PaUtil_DebugPrint("Pa_OpenStream returned:\n" );
+        PaUtil_DebugPrint("\t*(PaStream** stream): undefined\n" );
+        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+#endif
+        return result;
+    }
+    
+
+    if( inputParameters )
+    {
+        hostApiInputParameters.device = hostApiInputDevice;
+        hostApiInputParameters.channelCount = inputParameters->channelCount;
+        hostApiInputParameters.sampleFormat = inputParameters->sampleFormat;
+        hostApiInputParameters.suggestedLatency = inputParameters->suggestedLatency;
+        hostApiInputParameters.hostApiSpecificStreamInfo = inputParameters->hostApiSpecificStreamInfo;
+        hostApiInputParametersPtr = &hostApiInputParameters;
+    }
+    else
+    {
+        hostApiInputParametersPtr = NULL;
+    }
+
+    if( outputParameters )
+    {
+        hostApiOutputParameters.device = hostApiOutputDevice;
+        hostApiOutputParameters.channelCount = outputParameters->channelCount;
+        hostApiOutputParameters.sampleFormat = outputParameters->sampleFormat;
+        hostApiOutputParameters.suggestedLatency = outputParameters->suggestedLatency;
+        hostApiOutputParameters.hostApiSpecificStreamInfo = outputParameters->hostApiSpecificStreamInfo;
+        hostApiOutputParametersPtr = &hostApiOutputParameters;
+    }
+    else
+    {
+        hostApiOutputParametersPtr = NULL;
+    }
+
+    result = hostApi->OpenStream( hostApi, stream,
+                                  hostApiInputParametersPtr, hostApiOutputParametersPtr,
+                                  sampleRate, framesPerBuffer, streamFlags, streamCallback, userData );
+
+    if( result == paNoError )
+        AddOpenStream( *stream );
+
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_OpenStream returned:\n" );
+    PaUtil_DebugPrint("\t*(PaStream** stream): 0x%p\n", *stream );
+    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+#endif
+
+    return result;
+}
+
+
+PaError Pa_OpenDefaultStream( PaStream** stream,
+                              int inputChannelCount,
+                              int outputChannelCount,
+                              PaSampleFormat sampleFormat,
+                              double sampleRate,
+                              unsigned long framesPerBuffer,
+                              PaStreamCallback *streamCallback,
+                              void *userData )
+{
+    PaError result;
+    PaStreamParameters hostApiInputParameters, hostApiOutputParameters;
+    PaStreamParameters *hostApiInputParametersPtr, *hostApiOutputParametersPtr;
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_OpenDefaultStream called:\n" );
+    PaUtil_DebugPrint("\tPaStream** stream: 0x%p\n", stream );
+    PaUtil_DebugPrint("\tint inputChannelCount: %d\n", inputChannelCount );
+    PaUtil_DebugPrint("\tint outputChannelCount: %d\n", outputChannelCount );
+    PaUtil_DebugPrint("\tPaSampleFormat sampleFormat: %d\n", sampleFormat );
+    PaUtil_DebugPrint("\tdouble sampleRate: %g\n", sampleRate );
+    PaUtil_DebugPrint("\tunsigned long framesPerBuffer: %d\n", framesPerBuffer );
+    PaUtil_DebugPrint("\tPaStreamCallback *streamCallback: 0x%p\n", streamCallback );
+    PaUtil_DebugPrint("\tvoid *userData: 0x%p\n", userData );
+#endif
+
+
+    if( inputChannelCount > 0 )
+    {
+        hostApiInputParameters.device = Pa_GetDefaultInputDevice();
+        hostApiInputParameters.channelCount = inputChannelCount;
+        hostApiInputParameters.sampleFormat = sampleFormat;
+        /* defaultHighInputLatency is used below instead of
+           defaultLowInputLatency because it is more important for the default
+           stream to work reliably than it is for it to work with the lowest
+           latency.
+         */
+        hostApiInputParameters.suggestedLatency = 
+             Pa_GetDeviceInfo( hostApiInputParameters.device )->defaultHighInputLatency;
+        hostApiInputParameters.hostApiSpecificStreamInfo = NULL;
+        hostApiInputParametersPtr = &hostApiInputParameters;
+    }
+    else
+    {
+        hostApiInputParametersPtr = NULL;
+    }
+
+    if( outputChannelCount > 0 )
+    {
+        hostApiOutputParameters.device = Pa_GetDefaultOutputDevice();
+        hostApiOutputParameters.channelCount = outputChannelCount;
+        hostApiOutputParameters.sampleFormat = sampleFormat;
+        /* defaultHighOutputLatency is used below instead of
+           defaultLowOutputLatency because it is more important for the default
+           stream to work reliably than it is for it to work with the lowest
+           latency.
+         */
+        hostApiOutputParameters.suggestedLatency =
+             Pa_GetDeviceInfo( hostApiOutputParameters.device )->defaultHighOutputLatency;
+        hostApiOutputParameters.hostApiSpecificStreamInfo = NULL;
+        hostApiOutputParametersPtr = &hostApiOutputParameters;
+    }
+    else
+    {
+        hostApiOutputParametersPtr = NULL;
+    }
+
+
+    result = Pa_OpenStream(
+                 stream, hostApiInputParametersPtr, hostApiOutputParametersPtr,
+                 sampleRate, framesPerBuffer, paNoFlag, streamCallback, userData );
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_OpenDefaultStream returned:\n" );
+    PaUtil_DebugPrint("\t*(PaStream** stream): 0x%p", *stream );
+    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+#endif
+
+    return result;
+}
+
+
+PaError PaUtil_ValidateStreamPointer( PaStream* stream )
+{
+    if( !PA_IS_INITIALISED_ ) return paNotInitialized;
+
+    if( stream == NULL ) return paBadStreamPtr;
+
+    if( ((PaUtilStreamRepresentation*)stream)->magic != PA_STREAM_MAGIC )
+        return paBadStreamPtr;
+
+    return paNoError;
+}
+
+
+PaError Pa_CloseStream( PaStream* stream )
+{
+    PaUtilStreamInterface *interface;
+    PaError result = PaUtil_ValidateStreamPointer( stream );
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_CloseStream called:\n" );
+    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
+#endif
+
+    /* always remove the open stream from our list, even if this function
+        eventually returns an error. Otherwise CloseOpenStreams() will
+        get stuck in an infinite loop */
+    RemoveOpenStream( stream ); /* be sure to call this _before_ closing the stream */
+
+    if( result == paNoError )
+    {
+        interface = PA_STREAM_INTERFACE(stream);
+
+        /* abort the stream if it isn't stopped */
+        result = interface->IsStopped( stream );
+        if( result == 1 )
+            result = paNoError;
+        else if( result == 0 )
+            result = interface->Abort( stream );
+
+        if( result == paNoError )                 /** @todo REVIEW: shouldn't we close anyway? */
+            result = interface->Close( stream );
+    }
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_CloseStream returned:\n" );
+    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+#endif
+
+    return result;
+}
+
+
+PaError Pa_SetStreamFinishedCallback( PaStream *stream, PaStreamFinishedCallback* streamFinishedCallback )
+{
+    PaError result = PaUtil_ValidateStreamPointer( stream );
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_SetStreamFinishedCallback called:\n" );
+    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
+    PaUtil_DebugPrint("\tPaStreamFinishedCallback* streamFinishedCallback: 0x%p\n", streamFinishedCallback );
+#endif
+
+    if( result == paNoError )
+    {
+        result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
+        if( result == 0 )
+        {
+            result = paStreamIsNotStopped ;
+        }
+        if( result == 1 )
+        {
+            PA_STREAM_REP( stream )->streamFinishedCallback = streamFinishedCallback;
+            result = paNoError;
+        }
+    }
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_SetStreamFinishedCallback returned:\n" );
+    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+#endif
+
+    return result;
+
+}
+
+
+PaError Pa_StartStream( PaStream *stream )
+{
+    PaError result = PaUtil_ValidateStreamPointer( stream );
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_StartStream called:\n" );
+    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
+#endif
+
+    if( result == paNoError )
+    {
+        result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
+        if( result == 0 )
+        {
+            result = paStreamIsNotStopped ;
+        }
+        else if( result == 1 )
+        {
+            result = PA_STREAM_INTERFACE(stream)->Start( stream );
+        }
+    }
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_StartStream returned:\n" );
+    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+#endif
+
+    return result;
+}
+
+
+PaError Pa_StopStream( PaStream *stream )
+{
+    PaError result = PaUtil_ValidateStreamPointer( stream );
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_StopStream called\n" );
+    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
+#endif
+
+    if( result == paNoError )
+    {
+        result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
+        if( result == 0 )
+        {
+            result = PA_STREAM_INTERFACE(stream)->Stop( stream );
+        }
+        else if( result == 1 )
+        {
+            result = paStreamIsStopped;
+        }
+    }
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_StopStream returned:\n" );
+    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+#endif
+
+    return result;
+}
+
+
+PaError Pa_AbortStream( PaStream *stream )
+{
+    PaError result = PaUtil_ValidateStreamPointer( stream );
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_AbortStream called:\n" );
+    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
+#endif
+
+    if( result == paNoError )
+    {
+        result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
+        if( result == 0 )
+        {
+            result = PA_STREAM_INTERFACE(stream)->Abort( stream );
+        }
+        else if( result == 1 )
+        {
+            result = paStreamIsStopped;
+        }
+    }
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_AbortStream returned:\n" );
+    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+#endif
+
+    return result;
+}
+
+
+PaError Pa_IsStreamStopped( PaStream *stream )
+{
+    PaError result = PaUtil_ValidateStreamPointer( stream );
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_IsStreamStopped called:\n" );
+    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
+#endif
+
+    if( result == paNoError )
+        result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_IsStreamStopped returned:\n" );
+    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+#endif
+
+    return result;
+}
+
+
+PaError Pa_IsStreamActive( PaStream *stream )
+{
+    PaError result = PaUtil_ValidateStreamPointer( stream );
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_IsStreamActive called:\n" );
+    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
+#endif
+
+    if( result == paNoError )
+        result = PA_STREAM_INTERFACE(stream)->IsActive( stream );
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_IsStreamActive returned:\n" );
+    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+#endif
+
+    return result;
+}
+
+
+const PaStreamInfo* Pa_GetStreamInfo( PaStream *stream )
+{
+    PaError error = PaUtil_ValidateStreamPointer( stream );
+    const PaStreamInfo *result;
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_GetStreamInfo called:\n" );
+    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
+#endif
+
+    if( error != paNoError )
+    {
+        result = 0;
+
+#ifdef PA_LOG_API_CALLS
+        PaUtil_DebugPrint("Pa_GetStreamInfo returned:\n" );
+        PaUtil_DebugPrint("\tconst PaStreamInfo*: 0 [PaError error:%d ( %s )]\n\n", result, error, Pa_GetErrorText( error ) );
+#endif
+
+    }
+    else
+    {
+        result = &PA_STREAM_REP( stream )->streamInfo;
+
+#ifdef PA_LOG_API_CALLS
+        PaUtil_DebugPrint("Pa_GetStreamInfo returned:\n" );
+        PaUtil_DebugPrint("\tconst PaStreamInfo*: 0x%p:\n", result );
+        PaUtil_DebugPrint("\t{" );
+
+        PaUtil_DebugPrint("\t\tint structVersion: %d\n", result->structVersion );
+        PaUtil_DebugPrint("\t\tPaTime inputLatency: %f\n", result->inputLatency );
+        PaUtil_DebugPrint("\t\tPaTime outputLatency: %f\n", result->outputLatency );
+        PaUtil_DebugPrint("\t\tdouble sampleRate: %f\n", result->sampleRate );
+        PaUtil_DebugPrint("\t}\n\n" );
+#endif
+
+    }
+
+    return result;
+}
+
+
+PaTime Pa_GetStreamTime( PaStream *stream )
+{
+    PaError error = PaUtil_ValidateStreamPointer( stream );
+    PaTime result;
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_GetStreamTime called:\n" );
+    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
+#endif
+
+    if( error != paNoError )
+    {
+        result = 0;
+
+#ifdef PA_LOG_API_CALLS
+        PaUtil_DebugPrint("Pa_GetStreamTime returned:\n" );
+        PaUtil_DebugPrint("\tPaTime: 0 [PaError error:%d ( %s )]\n\n", result, error, Pa_GetErrorText( error ) );
+#endif
+
+    }
+    else
+    {
+        result = PA_STREAM_INTERFACE(stream)->GetTime( stream );
+
+#ifdef PA_LOG_API_CALLS
+        PaUtil_DebugPrint("Pa_GetStreamTime returned:\n" );
+        PaUtil_DebugPrint("\tPaTime: %g\n\n", result );
+#endif
+
+    }
+
+    return result;
+}
+
+
+double Pa_GetStreamCpuLoad( PaStream* stream )
+{
+    PaError error = PaUtil_ValidateStreamPointer( stream );
+    double result;
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_GetStreamCpuLoad called:\n" );
+    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
+#endif
+
+    if( error != paNoError )
+    {
+
+        result = 0.0;
+
+#ifdef PA_LOG_API_CALLS
+        PaUtil_DebugPrint("Pa_GetStreamCpuLoad returned:\n" );
+        PaUtil_DebugPrint("\tdouble: 0.0 [PaError error: %d ( %s )]\n\n", error, Pa_GetErrorText( error ) );
+#endif
+
+    }
+    else
+    {
+        result = PA_STREAM_INTERFACE(stream)->GetCpuLoad( stream );
+
+#ifdef PA_LOG_API_CALLS
+        PaUtil_DebugPrint("Pa_GetStreamCpuLoad returned:\n" );
+        PaUtil_DebugPrint("\tdouble: %g\n\n", result );
+#endif
+
+    }
+
+    return result;
+}
+
+
+PaError Pa_ReadStream( PaStream* stream,
+                       void *buffer,
+                       unsigned long frames )
+{
+    PaError result = PaUtil_ValidateStreamPointer( stream );
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_ReadStream called:\n" );
+    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
+#endif
+
+    if( result == paNoError )
+    {
+        if( frames == 0 )
+        {
+            /* XXX: Should we not allow the implementation to signal any overflow condition? */
+            result = paNoError;
+        }
+        else if( buffer == 0 )
+        {
+            result = paBadBufferPtr;
+        }
+        else
+        {
+            result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
+            if( result == 0 )
+            {
+                result = PA_STREAM_INTERFACE(stream)->Read( stream, buffer, frames );
+            }
+            else if( result == 1 )
+            {
+                result = paStreamIsStopped;
+            }
+        }
+    }
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_ReadStream returned:\n" );
+    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+#endif
+
+    return result;
+}
+
+
+PaError Pa_WriteStream( PaStream* stream,
+                        const void *buffer,
+                        unsigned long frames )
+{
+    PaError result = PaUtil_ValidateStreamPointer( stream );
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_WriteStream called:\n" );
+    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
+#endif
+
+    if( result == paNoError )
+    {
+        if( frames == 0 )
+        {
+            /* XXX: Should we not allow the implementation to signal any underflow condition? */
+            result = paNoError;
+        }
+        else if( buffer == 0 )
+        {
+            result = paBadBufferPtr;
+        }
+        else
+        {
+            result = PA_STREAM_INTERFACE(stream)->IsStopped( stream );
+            if( result == 0 )
+            {
+                result = PA_STREAM_INTERFACE(stream)->Write( stream, buffer, frames );
+            }
+            else if( result == 1 )
+            {
+                result = paStreamIsStopped;
+            }  
+        }
+    }
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_WriteStream returned:\n" );
+    PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+#endif
+
+    return result;
+}
+
+signed long Pa_GetStreamReadAvailable( PaStream* stream )
+{
+    PaError error = PaUtil_ValidateStreamPointer( stream );
+    signed long result;
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_GetStreamReadAvailable called:\n" );
+    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
+#endif
+
+    if( error != paNoError )
+    {
+        result = 0;
+
+#ifdef PA_LOG_API_CALLS
+        PaUtil_DebugPrint("Pa_GetStreamReadAvailable returned:\n" );
+        PaUtil_DebugPrint("\tunsigned long: 0 [ PaError error: %d ( %s ) ]\n\n", error, Pa_GetErrorText( error ) );
+#endif
+
+    }
+    else
+    {
+        result = PA_STREAM_INTERFACE(stream)->GetReadAvailable( stream );
+
+#ifdef PA_LOG_API_CALLS
+        PaUtil_DebugPrint("Pa_GetStreamReadAvailable returned:\n" );
+        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+#endif
+
+    }
+
+    return result;
+}
+
+
+signed long Pa_GetStreamWriteAvailable( PaStream* stream )
+{
+    PaError error = PaUtil_ValidateStreamPointer( stream );
+    signed long result;
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_GetStreamWriteAvailable called:\n" );
+    PaUtil_DebugPrint("\tPaStream* stream: 0x%p\n", stream );
+#endif
+
+    if( error != paNoError )
+    {
+        result = 0;
+
+#ifdef PA_LOG_API_CALLS
+        PaUtil_DebugPrint("Pa_GetStreamWriteAvailable returned:\n" );
+        PaUtil_DebugPrint("\tunsigned long: 0 [ PaError error: %d ( %s ) ]\n\n", error, Pa_GetErrorText( error ) );
+#endif
+
+    }
+    else
+    {
+        result = PA_STREAM_INTERFACE(stream)->GetWriteAvailable( stream );
+
+#ifdef PA_LOG_API_CALLS
+        PaUtil_DebugPrint("Pa_GetStreamWriteAvailable returned:\n" );
+        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+#endif
+
+    }
+
+    return result;
+}
+
+
+PaError Pa_GetSampleSize( PaSampleFormat format )
+{
+    int result;
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_GetSampleSize called:\n" );
+    PaUtil_DebugPrint("\tPaSampleFormat format: %d\n", format );
+#endif
+
+    switch( format & ~paNonInterleaved )
+    {
+
+    case paUInt8:
+    case paInt8:
+        result = 1;
+        break;
+
+    case paInt16:
+        result = 2;
+        break;
+
+    case paInt24:
+        result = 3;
+        break;
+
+    case paFloat32:
+    case paInt32:
+        result = 4;
+        break;
+
+    default:
+        result = paSampleFormatNotSupported;
+        break;
+    }
+
+#ifdef PA_LOG_API_CALLS
+    PaUtil_DebugPrint("Pa_GetSampleSize returned:\n" );
+    if( result > 0 )
+        PaUtil_DebugPrint("\tint: %d\n\n", result );
+    else
+        PaUtil_DebugPrint("\tPaError: %d ( %s )\n\n", result, Pa_GetErrorText( result ) );
+#endif
+
+    return (PaError) result;
+}
+
diff --git a/utils/iaxclient/lib/portaudio/src/common/pa_hostapi.h b/utils/iaxclient/lib/portaudio/src/common/pa_hostapi.h
new file mode 100644 (file)
index 0000000..231a179
--- /dev/null
@@ -0,0 +1,244 @@
+#ifndef PA_HOSTAPI_H
+#define PA_HOSTAPI_H
+/*
+ * $Id: pa_hostapi.h,v 1.1 2006/06/10 21:30:55 dmazzoni Exp $
+ * Portable Audio I/O Library
+ * host api representation
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2002 Ross Bencina, Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file
+ @brief Interface used by pa_front to virtualize functions which operate on
+ host APIs.
+*/
+
+
+#include "portaudio.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+
+/** **FOR THE USE OF pa_front.c ONLY**
+    Do NOT use fields in this structure, they my change at any time.
+    Use functions defined in pa_util.h if you think you need functionality
+    which can be derived from here.
+*/
+typedef struct PaUtilPrivatePaFrontHostApiInfo {
+
+
+    unsigned long baseDeviceIndex;
+}PaUtilPrivatePaFrontHostApiInfo;
+
+
+/** The common header for all data structures whose pointers are passed through
+ the hostApiSpecificStreamInfo field of the PaStreamParameters structure.
+ Note that in order to keep the public PortAudio interface clean, this structure
+ is not used explicitly when declaring hostApiSpecificStreamInfo data structures.
+ However, some code in pa_front depends on the first 3 members being equivalent
+ with this structure.
+ @see PaStreamParameters
+*/
+typedef struct PaUtilHostApiSpecificStreamInfoHeader
+{
+    unsigned long size;             /**< size of whole structure including this header */
+    PaHostApiTypeId hostApiType;    /**< host API for which this data is intended */
+    unsigned long version;          /**< structure version */
+} PaUtilHostApiSpecificStreamInfoHeader;
+
+
+
+/** A structure representing the interface to a host API. Contains both
+ concrete data and pointers to functions which implement the interface.
+*/
+typedef struct PaUtilHostApiRepresentation {
+    PaUtilPrivatePaFrontHostApiInfo privatePaFrontInfo;
+
+    /** The host api implementation should populate the info field. In the
+        case of info.defaultInputDevice and info.defaultOutputDevice the
+        values stored should be 0 based indices within the host api's own
+        device index range (0 to deviceCount). These values will be converted
+        to global device indices by pa_front after PaUtilHostApiInitializer()
+        returns.
+    */
+    PaHostApiInfo info;
+
+    PaDeviceInfo** deviceInfos;
+
+    /**
+        (*Terminate)() is guaranteed to be called with a valid <hostApi>
+        parameter, which was previously returned from the same implementation's
+        initializer.
+    */
+    void (*Terminate)( struct PaUtilHostApiRepresentation *hostApi );
+
+    /**
+        The inputParameters and outputParameters pointers should not be saved
+        as they will not remain valid after OpenStream is called.
+
+        
+        The following guarantees are made about parameters to (*OpenStream)():
+
+            [NOTE: the following list up to *END PA FRONT VALIDATIONS* should be
+                kept in sync with the one for ValidateOpenStreamParameters and
+                Pa_OpenStream in pa_front.c]
+                
+            PaHostApiRepresentation *hostApi
+                - is valid for this implementation
+
+            PaStream** stream
+                - is non-null
+
+            - at least one of inputParameters & outputParmeters is valid (not NULL)
+
+            - if inputParameters & outputParmeters are both valid, that
+                inputParameters->device & outputParmeters->device  both use the same host api
+            PaDeviceIndex inputParameters->device
+                - is within range (0 to Pa_CountDevices-1) Or:
+                - is paUseHostApiSpecificDeviceSpecification and
+                    inputParameters->hostApiSpecificStreamInfo is non-NULL and refers
+                    to a valid host api
+
+            int inputParameters->numChannels
+                - if inputParameters->device is not paUseHostApiSpecificDeviceSpecification, numInputChannels is > 0
+                - upper bound is NOT validated against device capabilities
+            PaSampleFormat inputParameters->sampleFormat
+                - is one of the sample formats defined in portaudio.h
+
+            void *inputParameters->hostApiSpecificStreamInfo
+                - if supplied its hostApi field matches the input device's host Api
+            PaDeviceIndex outputParmeters->device
+                - is within range (0 to Pa_CountDevices-1)
+            int outputParmeters->numChannels
+                - if inputDevice is valid, numInputChannels is > 0
+                - upper bound is NOT validated against device capabilities
+            PaSampleFormat outputParmeters->sampleFormat
+                - is one of the sample formats defined in portaudio.h
+        
+            void *outputParmeters->hostApiSpecificStreamInfo
+                - if supplied its hostApi field matches the output device's host Api
+            double sampleRate
+                - is not an 'absurd' rate (less than 1000. or greater than 200000.)
+                - sampleRate is NOT validated against device capabilities
+            PaStreamFlags streamFlags
+                - unused platform neutral flags are zero
+                - paNeverDropInput is only used for full-duplex callback streams
+                    with variable buffer size (paFramesPerBufferUnspecified)
+
+            [*END PA FRONT VALIDATIONS*]
+
+
+        The following validations MUST be performed by (*OpenStream)():
+
+            - check that input device can support numInputChannels
+            
+            - check that input device can support inputSampleFormat, or that
+                we have the capability to convert from outputSampleFormat to
+                a native format
+
+            - if inputStreamInfo is supplied, validate its contents,
+                or return an error if no inputStreamInfo is expected
+
+            - check that output device can support numOutputChannels
+            
+            - check that output device can support outputSampleFormat, or that
+                we have the capability to convert from outputSampleFormat to
+                a native format
+
+            - if outputStreamInfo is supplied, validate its contents,
+                or return an error if no outputStreamInfo is expected
+
+            - if a full duplex stream is requested, check that the combination
+                of input and output parameters is supported
+
+            - check that the device supports sampleRate
+
+            - alter sampleRate to a close allowable rate if necessary
+
+            - validate inputLatency and outputLatency
+
+            - validate any platform specific flags, if flags are supplied they
+                must be valid.
+    */
+    PaError (*OpenStream)( struct PaUtilHostApiRepresentation *hostApi,
+                           PaStream** stream,
+                           const PaStreamParameters *inputParameters,
+                           const PaStreamParameters *outputParameters,
+                           double sampleRate,
+                           unsigned long framesPerCallback,
+                           PaStreamFlags streamFlags,
+                           PaStreamCallback *streamCallback,
+                           void *userData );
+
+
+    PaError (*IsFormatSupported)( struct PaUtilHostApiRepresentation *hostApi,
+                                  const PaStreamParameters *inputParameters,
+                                  const PaStreamParameters *outputParameters,
+                                  double sampleRate );
+} PaUtilHostApiRepresentation;
+
+
+/** Prototype for the initialization function which must be implemented by every
+ host API.
+ @see paHostApiInitializers
+*/
+typedef PaError PaUtilHostApiInitializer( PaUtilHostApiRepresentation**, PaHostApiIndex );
+
+
+/** paHostApiInitializers is a NULL-terminated array of host API initialization
+ functions. These functions are called by pa_front to initialize the host APIs
+ when the client calls Pa_Initialize().
+
+ There is a platform specific file which defines paHostApiInitializers for that
+ platform, pa_win/pa_win_hostapis.c contains the Win32 definitions for example.
+*/
+extern PaUtilHostApiInitializer *paHostApiInitializers[];
+
+
+/** The index of the default host API in the paHostApiInitializers array.
+ There is a platform specific file which defines paDefaultHostApiIndex for that
+ platform, see pa_win/pa_win_hostapis.c for example.
+*/
+extern int paDefaultHostApiIndex;
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* PA_HOSTAPI_H */
diff --git a/utils/iaxclient/lib/portaudio/src/common/pa_process.c b/utils/iaxclient/lib/portaudio/src/common/pa_process.c
new file mode 100644 (file)
index 0000000..257900b
--- /dev/null
@@ -0,0 +1,1763 @@
+/*
+ * $Id: pa_process.c,v 1.1 2006/06/10 21:30:55 dmazzoni Exp $
+ * Portable Audio I/O Library
+ * streamCallback <-> host buffer processing adapter
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2002 Ross Bencina, Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file
+ @brief Buffer Processor implementation.
+    
+ The code in this file is not optimised yet - although it's not clear that
+ it needs to be. there may appear to be redundancies
+ that could be factored into common functions, but the redundanceis are left
+ intentionally as each appearance may have different optimisation possibilities.
+
+ The optimisations which are planned involve only converting data in-place
+ where possible, rather than copying to the temp buffer(s).
+
+ Note that in the extreme case of being able to convert in-place, and there
+ being no conversion necessary there should be some code which short-circuits
+ the operation.
+
+    @todo Consider cache tilings for intereave<->deinterleave.
+
+    @todo implement timeInfo->currentTime int PaUtil_BeginBufferProcessing()
+
+    @todo specify and implement some kind of logical policy for handling the
+        underflow and overflow stream flags when the underflow/overflow overlaps
+        multiple user buffers/callbacks.
+
+       @todo provide support for priming the buffers with data from the callback.
+        The client interface is now implemented through PaUtil_SetNoInput()
+        which sets bp->hostInputChannels[0][0].data to zero. However this is
+        currently only implemented in NonAdaptingProcess(). It shouldn't be
+        needed for AdaptingInputOnlyProcess() (no priming should ever be
+        requested for AdaptingInputOnlyProcess()).
+        Not sure if additional work should be required to make it work with
+        AdaptingOutputOnlyProcess, but it definitely is required for
+        AdaptingProcess.
+
+    @todo implement PaUtil_SetNoOutput for AdaptingProcess
+
+    @todo don't allocate temp buffers for blocking streams unless they are
+        needed. At the moment they are needed, but perhaps for host APIs
+        where the implementation passes a buffer to the host they could be
+        used.
+*/
+
+
+#include <assert.h>
+#include <string.h> /* memset() */
+
+#include "pa_process.h"
+#include "pa_util.h"
+
+
+#define PA_FRAMES_PER_TEMP_BUFFER_WHEN_HOST_BUFFER_SIZE_IS_UNKNOWN_    1024
+
+#define PA_MIN_( a, b ) ( ((a)<(b)) ? (a) : (b) )
+
+
+/* greatest common divisor - PGCD in French */
+static unsigned long GCD( unsigned long a, unsigned long b )
+{
+    return (b==0) ? a : GCD( b, a%b);
+}
+
+/* least common multiple - PPCM in French */
+static unsigned long LCM( unsigned long a, unsigned long b )
+{
+    return (a*b) / GCD(a,b);
+}
+
+#define PA_MAX_( a, b ) (((a) > (b)) ? (a) : (b))
+
+static unsigned long CalculateFrameShift( unsigned long M, unsigned long N )
+{
+    unsigned long result = 0;
+    unsigned long i;
+    unsigned long lcm;
+
+    assert( M > 0 );
+    assert( N > 0 );
+
+    lcm = LCM( M, N );
+    for( i = M; i < lcm; i += M )
+        result = PA_MAX_( result, i % N );
+
+    return result;
+}
+
+
+PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bp,
+        int inputChannelCount, PaSampleFormat userInputSampleFormat,
+        PaSampleFormat hostInputSampleFormat,
+        int outputChannelCount, PaSampleFormat userOutputSampleFormat,
+        PaSampleFormat hostOutputSampleFormat,
+        double sampleRate,
+        PaStreamFlags streamFlags,
+        unsigned long framesPerUserBuffer,
+        unsigned long framesPerHostBuffer,
+        PaUtilHostBufferSizeMode hostBufferSizeMode,
+        PaStreamCallback *streamCallback, void *userData )
+{
+    PaError result = paNoError;
+    PaError bytesPerSample;
+    unsigned long tempInputBufferSize, tempOutputBufferSize;
+
+    if( streamFlags & paNeverDropInput )
+    {
+        /* paNeverDropInput is only valid for full-duplex callback streams, with an unspecified number of frames per buffer. */
+        if( !streamCallback || !(inputChannelCount > 0 && outputChannelCount > 0) ||
+                framesPerUserBuffer != paFramesPerBufferUnspecified )
+            return paInvalidFlag;
+    }
+
+    /* initialize buffer ptrs to zero so they can be freed if necessary in error */
+    bp->tempInputBuffer = 0;
+    bp->tempInputBufferPtrs = 0;
+    bp->tempOutputBuffer = 0;
+    bp->tempOutputBufferPtrs = 0;
+
+    bp->framesPerUserBuffer = framesPerUserBuffer;
+    bp->framesPerHostBuffer = framesPerHostBuffer;
+
+    bp->inputChannelCount = inputChannelCount;
+    bp->outputChannelCount = outputChannelCount;
+
+    bp->hostBufferSizeMode = hostBufferSizeMode;
+
+    bp->hostInputChannels[0] = bp->hostInputChannels[1] = 0;
+    bp->hostOutputChannels[0] = bp->hostOutputChannels[1] = 0;
+
+    if( framesPerUserBuffer == 0 ) /* streamCallback will accept any buffer size */
+    {
+        bp->useNonAdaptingProcess = 1;
+        bp->initialFramesInTempInputBuffer = 0;
+        bp->initialFramesInTempOutputBuffer = 0;
+
+        if( hostBufferSizeMode == paUtilFixedHostBufferSize
+                || hostBufferSizeMode == paUtilBoundedHostBufferSize )
+        {
+            bp->framesPerTempBuffer = framesPerHostBuffer;
+        }
+        else /* unknown host buffer size */
+        {
+             bp->framesPerTempBuffer = PA_FRAMES_PER_TEMP_BUFFER_WHEN_HOST_BUFFER_SIZE_IS_UNKNOWN_;
+        }
+    }
+    else
+    {
+        bp->framesPerTempBuffer = framesPerUserBuffer;
+
+        if( hostBufferSizeMode == paUtilFixedHostBufferSize
+                && framesPerHostBuffer % framesPerUserBuffer == 0 )
+        {
+            bp->useNonAdaptingProcess = 1;
+            bp->initialFramesInTempInputBuffer = 0;
+            bp->initialFramesInTempOutputBuffer = 0;
+        }
+        else
+        {
+            bp->useNonAdaptingProcess = 0;
+
+            if( inputChannelCount > 0 && outputChannelCount > 0 )
+            {
+                /* full duplex */
+                if( hostBufferSizeMode == paUtilFixedHostBufferSize )
+                {
+                    unsigned long frameShift =
+                        CalculateFrameShift( framesPerHostBuffer, framesPerUserBuffer );
+
+                    if( framesPerUserBuffer > framesPerHostBuffer )
+                    {
+                        bp->initialFramesInTempInputBuffer = frameShift;
+                        bp->initialFramesInTempOutputBuffer = 0;
+                    }
+                    else
+                    {
+                        bp->initialFramesInTempInputBuffer = 0;
+                        bp->initialFramesInTempOutputBuffer = frameShift;
+                    }
+                }
+                else /* variable host buffer size, add framesPerUserBuffer latency */
+                {
+                    bp->initialFramesInTempInputBuffer = 0;
+                    bp->initialFramesInTempOutputBuffer = framesPerUserBuffer;
+                }
+            }
+            else
+            {
+                /* half duplex */
+                bp->initialFramesInTempInputBuffer = 0;
+                bp->initialFramesInTempOutputBuffer = 0;
+            }
+        }
+    }
+
+
+    bp->framesInTempInputBuffer = bp->initialFramesInTempInputBuffer;
+    bp->framesInTempOutputBuffer = bp->initialFramesInTempOutputBuffer;
+
+    
+    if( inputChannelCount > 0 )
+    {
+        bytesPerSample = Pa_GetSampleSize( hostInputSampleFormat );
+        if( bytesPerSample > 0 )
+        {
+            bp->bytesPerHostInputSample = bytesPerSample;
+        }
+        else
+        {
+            result = bytesPerSample;
+            goto error;
+        }
+
+        bytesPerSample = Pa_GetSampleSize( userInputSampleFormat );
+        if( bytesPerSample > 0 )
+        {
+            bp->bytesPerUserInputSample = bytesPerSample;
+        }
+        else
+        {
+            result = bytesPerSample;
+            goto error;
+        }
+
+        bp->inputConverter =
+            PaUtil_SelectConverter( hostInputSampleFormat, userInputSampleFormat, streamFlags );
+
+        bp->inputZeroer = PaUtil_SelectZeroer( hostInputSampleFormat );
+            
+        bp->userInputIsInterleaved = (userInputSampleFormat & paNonInterleaved)?0:1;
+
+
+        tempInputBufferSize =
+            bp->framesPerTempBuffer * bp->bytesPerUserInputSample * inputChannelCount;
+         
+        bp->tempInputBuffer = PaUtil_AllocateMemory( tempInputBufferSize );
+        if( bp->tempInputBuffer == 0 )
+        {
+            result = paInsufficientMemory;
+            goto error;
+        }
+        
+        if( bp->framesInTempInputBuffer > 0 )
+            memset( bp->tempInputBuffer, 0, tempInputBufferSize );
+
+        if( userInputSampleFormat & paNonInterleaved )
+        {
+            bp->tempInputBufferPtrs =
+                (void **)PaUtil_AllocateMemory( sizeof(void*)*inputChannelCount );
+            if( bp->tempInputBufferPtrs == 0 )
+            {
+                result = paInsufficientMemory;
+                goto error;
+            }
+        }
+
+        bp->hostInputChannels[0] = (PaUtilChannelDescriptor*)
+                PaUtil_AllocateMemory( sizeof(PaUtilChannelDescriptor) * inputChannelCount * 2);
+        if( bp->hostInputChannels[0] == 0 )
+        {
+            result = paInsufficientMemory;
+            goto error;
+        }
+
+        bp->hostInputChannels[1] = &bp->hostInputChannels[0][inputChannelCount];
+    }
+
+    if( outputChannelCount > 0 )
+    {
+        bytesPerSample = Pa_GetSampleSize( hostOutputSampleFormat );
+        if( bytesPerSample > 0 )
+        {
+            bp->bytesPerHostOutputSample = bytesPerSample;
+        }
+        else
+        {
+            result = bytesPerSample;
+            goto error;
+        }
+
+        bytesPerSample = Pa_GetSampleSize( userOutputSampleFormat );
+        if( bytesPerSample > 0 )
+        {
+            bp->bytesPerUserOutputSample = bytesPerSample;
+        }
+        else
+        {
+            result = bytesPerSample;
+            goto error;
+        }
+
+        bp->outputConverter =
+            PaUtil_SelectConverter( userOutputSampleFormat, hostOutputSampleFormat, streamFlags );
+
+        bp->outputZeroer = PaUtil_SelectZeroer( hostOutputSampleFormat );
+
+        bp->userOutputIsInterleaved = (userOutputSampleFormat & paNonInterleaved)?0:1;
+
+        tempOutputBufferSize =
+                bp->framesPerTempBuffer * bp->bytesPerUserOutputSample * outputChannelCount;
+
+        bp->tempOutputBuffer = PaUtil_AllocateMemory( tempOutputBufferSize );
+        if( bp->tempOutputBuffer == 0 )
+        {
+            result = paInsufficientMemory;
+            goto error;
+        }
+
+        if( bp->framesInTempOutputBuffer > 0 )
+            memset( bp->tempOutputBuffer, 0, tempOutputBufferSize );
+        
+        if( userOutputSampleFormat & paNonInterleaved )
+        {
+            bp->tempOutputBufferPtrs =
+                (void **)PaUtil_AllocateMemory( sizeof(void*)*outputChannelCount );
+            if( bp->tempOutputBufferPtrs == 0 )
+            {
+                result = paInsufficientMemory;
+                goto error;
+            }
+        }
+
+        bp->hostOutputChannels[0] = (PaUtilChannelDescriptor*)
+                PaUtil_AllocateMemory( sizeof(PaUtilChannelDescriptor)*outputChannelCount * 2 );
+        if( bp->hostOutputChannels[0] == 0 )
+        {                                                                     
+            result = paInsufficientMemory;
+            goto error;
+        }
+
+        bp->hostOutputChannels[1] = &bp->hostOutputChannels[0][outputChannelCount];
+    }
+
+    PaUtil_InitializeTriangularDitherState( &bp->ditherGenerator );
+
+    bp->samplePeriod = 1. / sampleRate;
+
+    bp->streamCallback = streamCallback;
+    bp->userData = userData;
+
+    return result;
+
+error:
+    if( bp->tempInputBuffer )
+        PaUtil_FreeMemory( bp->tempInputBuffer );
+
+    if( bp->tempInputBufferPtrs )
+        PaUtil_FreeMemory( bp->tempInputBufferPtrs );
+
+    if( bp->hostInputChannels[0] )
+        PaUtil_FreeMemory( bp->hostInputChannels[0] );
+
+    if( bp->tempOutputBuffer )
+        PaUtil_FreeMemory( bp->tempOutputBuffer );
+
+    if( bp->tempOutputBufferPtrs )
+        PaUtil_FreeMemory( bp->tempOutputBufferPtrs );
+
+    if( bp->hostOutputChannels[0] )
+        PaUtil_FreeMemory( bp->hostOutputChannels[0] );
+
+    return result;
+}
+
+
+void PaUtil_TerminateBufferProcessor( PaUtilBufferProcessor* bp )
+{
+    if( bp->tempInputBuffer )
+        PaUtil_FreeMemory( bp->tempInputBuffer );
+
+    if( bp->tempInputBufferPtrs )
+        PaUtil_FreeMemory( bp->tempInputBufferPtrs );
+
+    if( bp->hostInputChannels[0] )
+        PaUtil_FreeMemory( bp->hostInputChannels[0] );
+        
+    if( bp->tempOutputBuffer )
+        PaUtil_FreeMemory( bp->tempOutputBuffer );
+
+    if( bp->tempOutputBufferPtrs )
+        PaUtil_FreeMemory( bp->tempOutputBufferPtrs );
+
+    if( bp->hostOutputChannels[0] )
+        PaUtil_FreeMemory( bp->hostOutputChannels[0] );
+}
+
+
+void PaUtil_ResetBufferProcessor( PaUtilBufferProcessor* bp )
+{
+    unsigned long tempInputBufferSize, tempOutputBufferSize;
+
+    bp->framesInTempInputBuffer = bp->initialFramesInTempInputBuffer;
+    bp->framesInTempOutputBuffer = bp->initialFramesInTempOutputBuffer;
+
+    if( bp->framesInTempInputBuffer > 0 )
+    {
+        tempInputBufferSize =
+            bp->framesPerTempBuffer * bp->bytesPerUserInputSample * bp->inputChannelCount;
+        memset( bp->tempInputBuffer, 0, tempInputBufferSize );
+    }
+
+    if( bp->framesInTempOutputBuffer > 0 )
+    {      
+        tempOutputBufferSize =
+            bp->framesPerTempBuffer * bp->bytesPerUserOutputSample * bp->outputChannelCount;
+        memset( bp->tempOutputBuffer, 0, tempOutputBufferSize );
+    }
+}
+
+
+unsigned long PaUtil_GetBufferProcessorInputLatency( PaUtilBufferProcessor* bp )
+{
+    return bp->initialFramesInTempInputBuffer;
+}
+
+
+unsigned long PaUtil_GetBufferProcessorOutputLatency( PaUtilBufferProcessor* bp )
+{
+    return bp->initialFramesInTempOutputBuffer;
+}
+
+
+void PaUtil_SetInputFrameCount( PaUtilBufferProcessor* bp,
+        unsigned long frameCount )
+{
+    if( frameCount == 0 )
+        bp->hostInputFrameCount[0] = bp->framesPerHostBuffer;
+    else
+        bp->hostInputFrameCount[0] = frameCount;
+}
+        
+
+void PaUtil_SetNoInput( PaUtilBufferProcessor* bp )
+{
+    assert( bp->inputChannelCount > 0 );
+
+    bp->hostInputChannels[0][0].data = 0;
+}
+
+
+void PaUtil_SetInputChannel( PaUtilBufferProcessor* bp,
+        unsigned int channel, void *data, unsigned int stride )
+{
+    assert( channel < bp->inputChannelCount );
+    
+    bp->hostInputChannels[0][channel].data = data;
+    bp->hostInputChannels[0][channel].stride = stride;
+}
+
+
+void PaUtil_SetInterleavedInputChannels( PaUtilBufferProcessor* bp,
+        unsigned int firstChannel, void *data, unsigned int channelCount )
+{
+    unsigned int i;
+    unsigned int channel = firstChannel;
+    unsigned char *p = (unsigned char*)data;
+
+    if( channelCount == 0 )
+        channelCount = bp->inputChannelCount;
+
+    assert( firstChannel < bp->inputChannelCount );
+    assert( firstChannel + channelCount <= bp->inputChannelCount );
+
+    for( i=0; i< channelCount; ++i )
+    {
+        bp->hostInputChannels[0][channel+i].data = p;
+        p += bp->bytesPerHostInputSample;
+        bp->hostInputChannels[0][channel+i].stride = channelCount;
+    }
+}
+
+
+void PaUtil_SetNonInterleavedInputChannel( PaUtilBufferProcessor* bp,
+        unsigned int channel, void *data )
+{
+    assert( channel < bp->inputChannelCount );
+    
+    bp->hostInputChannels[0][channel].data = data;
+    bp->hostInputChannels[0][channel].stride = 1;
+}
+
+
+void PaUtil_Set2ndInputFrameCount( PaUtilBufferProcessor* bp,
+        unsigned long frameCount )
+{
+    bp->hostInputFrameCount[1] = frameCount;
+}
+
+
+void PaUtil_Set2ndInputChannel( PaUtilBufferProcessor* bp,
+        unsigned int channel, void *data, unsigned int stride )
+{
+    assert( channel < bp->inputChannelCount );
+
+    bp->hostInputChannels[1][channel].data = data;
+    bp->hostInputChannels[1][channel].stride = stride;
+}
+
+
+void PaUtil_Set2ndInterleavedInputChannels( PaUtilBufferProcessor* bp,
+        unsigned int firstChannel, void *data, unsigned int channelCount )
+{
+    unsigned int i;
+    unsigned int channel = firstChannel;
+    unsigned char *p = (unsigned char*)data;
+
+    if( channelCount == 0 )
+        channelCount = bp->inputChannelCount;
+
+    assert( firstChannel < bp->inputChannelCount );
+    assert( firstChannel + channelCount <= bp->inputChannelCount );
+    
+    for( i=0; i< channelCount; ++i )
+    {
+        bp->hostInputChannels[1][channel+i].data = p;
+        p += bp->bytesPerHostInputSample;
+        bp->hostInputChannels[1][channel+i].stride = channelCount;
+    }
+}
+
+        
+void PaUtil_Set2ndNonInterleavedInputChannel( PaUtilBufferProcessor* bp,
+        unsigned int channel, void *data )
+{
+    assert( channel < bp->inputChannelCount );
+    
+    bp->hostInputChannels[1][channel].data = data;
+    bp->hostInputChannels[1][channel].stride = 1;
+}
+
+
+void PaUtil_SetOutputFrameCount( PaUtilBufferProcessor* bp,
+        unsigned long frameCount )
+{
+    if( frameCount == 0 )
+        bp->hostOutputFrameCount[0] = bp->framesPerHostBuffer;
+    else
+        bp->hostOutputFrameCount[0] = frameCount;
+}
+
+
+void PaUtil_SetNoOutput( PaUtilBufferProcessor* bp )
+{
+    assert( bp->outputChannelCount > 0 );
+
+    bp->hostOutputChannels[0][0].data = 0;
+}
+
+
+void PaUtil_SetOutputChannel( PaUtilBufferProcessor* bp,
+        unsigned int channel, void *data, unsigned int stride )
+{
+    assert( channel < bp->outputChannelCount );
+    assert( data != NULL );
+
+    bp->hostOutputChannels[0][channel].data = data;
+    bp->hostOutputChannels[0][channel].stride = stride;
+}
+
+
+void PaUtil_SetInterleavedOutputChannels( PaUtilBufferProcessor* bp,
+        unsigned int firstChannel, void *data, unsigned int channelCount )
+{
+    unsigned int i;
+    unsigned int channel = firstChannel;
+    unsigned char *p = (unsigned char*)data;
+
+    if( channelCount == 0 )
+        channelCount = bp->outputChannelCount;
+
+    assert( firstChannel < bp->outputChannelCount );
+    assert( firstChannel + channelCount <= bp->outputChannelCount );
+    
+    for( i=0; i< channelCount; ++i )
+    {
+        PaUtil_SetOutputChannel( bp, channel + i, p, channelCount );
+        p += bp->bytesPerHostOutputSample;
+    }
+}
+
+
+void PaUtil_SetNonInterleavedOutputChannel( PaUtilBufferProcessor* bp,
+        unsigned int channel, void *data )
+{
+    assert( channel < bp->outputChannelCount );
+
+    PaUtil_SetOutputChannel( bp, channel, data, 1 );
+}
+
+
+void PaUtil_Set2ndOutputFrameCount( PaUtilBufferProcessor* bp,
+        unsigned long frameCount )
+{
+    bp->hostOutputFrameCount[1] = frameCount;
+}
+
+
+void PaUtil_Set2ndOutputChannel( PaUtilBufferProcessor* bp,
+        unsigned int channel, void *data, unsigned int stride )
+{
+    assert( channel < bp->outputChannelCount );
+    assert( data != NULL );
+
+    bp->hostOutputChannels[1][channel].data = data;
+    bp->hostOutputChannels[1][channel].stride = stride;
+}
+
+
+void PaUtil_Set2ndInterleavedOutputChannels( PaUtilBufferProcessor* bp,
+        unsigned int firstChannel, void *data, unsigned int channelCount )
+{
+    unsigned int i;
+    unsigned int channel = firstChannel;
+    unsigned char *p = (unsigned char*)data;
+
+    if( channelCount == 0 )
+        channelCount = bp->outputChannelCount;
+
+    assert( firstChannel < bp->outputChannelCount );
+    assert( firstChannel + channelCount <= bp->outputChannelCount );
+    
+    for( i=0; i< channelCount; ++i )
+    {
+        PaUtil_Set2ndOutputChannel( bp, channel + i, p, channelCount );
+        p += bp->bytesPerHostOutputSample;
+    }
+}
+
+        
+void PaUtil_Set2ndNonInterleavedOutputChannel( PaUtilBufferProcessor* bp,
+        unsigned int channel, void *data )
+{
+    assert( channel < bp->outputChannelCount );
+    
+    PaUtil_Set2ndOutputChannel( bp, channel, data, 1 );
+}
+
+
+void PaUtil_BeginBufferProcessing( PaUtilBufferProcessor* bp,
+        PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags callbackStatusFlags )
+{
+    bp->timeInfo = timeInfo;
+
+    /* the first streamCallback will be called to process samples which are
+        currently in the input buffer before the ones starting at the timeInfo time */
+        
+    bp->timeInfo->inputBufferAdcTime -= bp->framesInTempInputBuffer * bp->samplePeriod;
+    
+    bp->timeInfo->currentTime = 0; /** FIXME: @todo time info currentTime not implemented */
+
+    /* the first streamCallback will be called to generate samples which will be
+        outputted after the frames currently in the output buffer have been
+        outputted. */
+    bp->timeInfo->outputBufferDacTime += bp->framesInTempOutputBuffer * bp->samplePeriod;
+
+    bp->callbackStatusFlags = callbackStatusFlags;
+
+    bp->hostInputFrameCount[1] = 0;
+    bp->hostOutputFrameCount[1] = 0;
+}
+
+
+/*
+    NonAdaptingProcess() is a simple buffer copying adaptor that can handle
+    both full and half duplex copies. It processes framesToProcess frames,
+    broken into blocks bp->framesPerTempBuffer long.
+    This routine can be used when the streamCallback doesn't care what length
+    the buffers are, or when framesToProcess is an integer multiple of
+    bp->framesPerTempBuffer, in which case streamCallback will always be called
+    with bp->framesPerTempBuffer samples.
+*/
+static unsigned long NonAdaptingProcess( PaUtilBufferProcessor *bp,
+        int *streamCallbackResult,
+        PaUtilChannelDescriptor *hostInputChannels,
+        PaUtilChannelDescriptor *hostOutputChannels,
+        unsigned long framesToProcess )
+{
+    void *userInput, *userOutput;
+    unsigned char *srcBytePtr, *destBytePtr;
+    unsigned int srcSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */
+    unsigned int srcChannelStrideBytes; /* stride from one channel to the next, in bytes */
+    unsigned int destSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */
+    unsigned int destChannelStrideBytes; /* stride from one channel to the next, in bytes */
+    unsigned int i;
+    unsigned long frameCount;
+    unsigned long framesToGo = framesToProcess;
+    unsigned long framesProcessed = 0;
+
+
+    if( *streamCallbackResult == paContinue )
+    {
+        do
+        {
+            frameCount = PA_MIN_( bp->framesPerTempBuffer, framesToGo );
+
+            /* configure user input buffer and convert input data (host -> user) */
+            if( bp->inputChannelCount == 0 )
+            {
+                /* no input */
+                userInput = 0;
+            }
+            else /* there are input channels */
+            {
+                /*
+                    could use more elaborate logic here and sometimes process
+                    buffers in-place.
+                */
+            
+                destBytePtr = (unsigned char *)bp->tempInputBuffer;
+
+                if( bp->userInputIsInterleaved )
+                {
+                    destSampleStrideSamples = bp->inputChannelCount;
+                    destChannelStrideBytes = bp->bytesPerUserInputSample;
+                    userInput = bp->tempInputBuffer;
+                }
+                else /* user input is not interleaved */
+                {
+                    destSampleStrideSamples = 1;
+                    destChannelStrideBytes = frameCount * bp->bytesPerUserInputSample;
+
+                    /* setup non-interleaved ptrs */
+                    for( i=0; i<bp->inputChannelCount; ++i )
+                    {
+                        bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) +
+                            i * bp->bytesPerUserInputSample * frameCount;
+                    }
+                
+                    userInput = bp->tempInputBufferPtrs;
+                }
+
+                if( !bp->hostInputChannels[0][0].data )
+                {
+                    /* no input was supplied (see PaUtil_SetNoInput), so
+                        zero the input buffer */
+
+                    for( i=0; i<bp->inputChannelCount; ++i )
+                    {
+                        bp->inputZeroer( destBytePtr, destSampleStrideSamples, frameCount );
+                        destBytePtr += destChannelStrideBytes;  /* skip to next destination channel */
+                    }
+                }
+                else
+                {
+                    for( i=0; i<bp->inputChannelCount; ++i )
+                    {
+                        bp->inputConverter( destBytePtr, destSampleStrideSamples,
+                                                hostInputChannels[i].data,
+                                                hostInputChannels[i].stride,
+                                                frameCount, &bp->ditherGenerator );
+
+                        destBytePtr += destChannelStrideBytes;  /* skip to next destination channel */
+
+                        /* advance src ptr for next iteration */
+                        hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
+                                frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
+                    }
+                }
+            }
+
+            /* configure user output buffer */
+            if( bp->outputChannelCount == 0 )
+            {
+                /* no output */
+                userOutput = 0;
+            }
+            else /* there are output channels */
+            {
+                if( bp->userOutputIsInterleaved )
+                {
+                    userOutput = bp->tempOutputBuffer;
+                }
+                else /* user output is not interleaved */
+                {
+                    for( i = 0; i < bp->outputChannelCount; ++i )
+                    {
+                        bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) +
+                            i * bp->bytesPerUserOutputSample * frameCount;
+                    }
+
+                    userOutput = bp->tempOutputBufferPtrs;
+                }
+            }
+        
+            *streamCallbackResult = bp->streamCallback( userInput, userOutput,
+                    frameCount, bp->timeInfo, bp->callbackStatusFlags, bp->userData );
+
+            if( *streamCallbackResult == paAbort )
+            {
+                /* callback returned paAbort, don't advance framesProcessed
+                        and framesToGo, they will be handled below */
+            }
+            else
+            {
+                bp->timeInfo->inputBufferAdcTime += frameCount * bp->samplePeriod;
+                bp->timeInfo->outputBufferDacTime += frameCount * bp->samplePeriod;
+
+                /* convert output data (user -> host) */
+                
+                if( bp->outputChannelCount != 0 && bp->hostOutputChannels[0][0].data )
+                {
+                    /*
+                        could use more elaborate logic here and sometimes process
+                        buffers in-place.
+                    */
+            
+                    srcBytePtr = (unsigned char *)bp->tempOutputBuffer;
+
+                    if( bp->userOutputIsInterleaved )
+                    {
+                        srcSampleStrideSamples = bp->outputChannelCount;
+                        srcChannelStrideBytes = bp->bytesPerUserOutputSample;
+                    }
+                    else /* user output is not interleaved */
+                    {
+                        srcSampleStrideSamples = 1;
+                        srcChannelStrideBytes = frameCount * bp->bytesPerUserOutputSample;
+                    }
+
+                    for( i=0; i<bp->outputChannelCount; ++i )
+                    {
+                        bp->outputConverter(    hostOutputChannels[i].data,
+                                                hostOutputChannels[i].stride,
+                                                srcBytePtr, srcSampleStrideSamples,
+                                                frameCount, &bp->ditherGenerator );
+
+                        srcBytePtr += srcChannelStrideBytes;  /* skip to next source channel */
+
+                        /* advance dest ptr for next iteration */
+                        hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
+                                frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
+                    }
+                }
+             
+                framesProcessed += frameCount;
+
+                framesToGo -= frameCount;
+            }
+        }
+        while( framesToGo > 0  && *streamCallbackResult == paContinue );
+    }
+
+    if( framesToGo > 0 )
+    {
+        /* zero any remaining frames output. There will only be remaining frames
+            if the callback has returned paComplete or paAbort */
+
+        frameCount = framesToGo;
+
+        if( bp->outputChannelCount != 0 && bp->hostOutputChannels[0][0].data )
+        {
+            for( i=0; i<bp->outputChannelCount; ++i )
+            {
+                bp->outputZeroer(   hostOutputChannels[i].data,
+                                    hostOutputChannels[i].stride,
+                                    frameCount );
+
+                /* advance dest ptr for next iteration */
+                hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
+                        frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
+            }
+        }
+
+        framesProcessed += frameCount;
+    }
+
+    return framesProcessed;
+}
+
+
+/*
+    AdaptingInputOnlyProcess() is a half duplex input buffer processor. It
+    converts data from the input buffers into the temporary input buffer,
+    when the temporary input buffer is full, it calls the streamCallback.
+*/
+static unsigned long AdaptingInputOnlyProcess( PaUtilBufferProcessor *bp,
+        int *streamCallbackResult,
+        PaUtilChannelDescriptor *hostInputChannels,
+        unsigned long framesToProcess )
+{
+    void *userInput, *userOutput;
+    unsigned char *destBytePtr;
+    unsigned int destSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */
+    unsigned int destChannelStrideBytes; /* stride from one channel to the next, in bytes */
+    unsigned int i;
+    unsigned long frameCount;
+    unsigned long framesToGo = framesToProcess;
+    unsigned long framesProcessed = 0;
+    
+    userOutput = 0;
+
+    do
+    {
+        frameCount = ( bp->framesInTempInputBuffer + framesToGo > bp->framesPerUserBuffer )
+                ? ( bp->framesPerUserBuffer - bp->framesInTempInputBuffer )
+                : framesToGo;
+
+        /* convert frameCount samples into temp buffer */
+
+        if( bp->userInputIsInterleaved )
+        {
+            destBytePtr = ((unsigned char*)bp->tempInputBuffer) +
+                    bp->bytesPerUserInputSample * bp->inputChannelCount *
+                    bp->framesInTempInputBuffer;
+                      
+            destSampleStrideSamples = bp->inputChannelCount;
+            destChannelStrideBytes = bp->bytesPerUserInputSample;
+
+            userInput = bp->tempInputBuffer;
+        }
+        else /* user input is not interleaved */
+        {
+            destBytePtr = ((unsigned char*)bp->tempInputBuffer) +
+                    bp->bytesPerUserInputSample * bp->framesInTempInputBuffer;
+
+            destSampleStrideSamples = 1;
+            destChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserInputSample;
+
+            /* setup non-interleaved ptrs */
+            for( i=0; i<bp->inputChannelCount; ++i )
+            {
+                bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) +
+                    i * bp->bytesPerUserInputSample * bp->framesPerUserBuffer;
+            }
+                    
+            userInput = bp->tempInputBufferPtrs;
+        }
+
+        for( i=0; i<bp->inputChannelCount; ++i )
+        {
+            bp->inputConverter( destBytePtr, destSampleStrideSamples,
+                                    hostInputChannels[i].data,
+                                    hostInputChannels[i].stride,
+                                    frameCount, &bp->ditherGenerator );
+
+            destBytePtr += destChannelStrideBytes;  /* skip to next destination channel */
+
+            /* advance src ptr for next iteration */
+            hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
+                    frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
+        }
+
+        bp->framesInTempInputBuffer += frameCount;
+
+        if( bp->framesInTempInputBuffer == bp->framesPerUserBuffer )
+        {
+            /**
+            @todo (non-critical optimisation)
+            The conditional below implements the continue/complete/abort mechanism
+            simply by continuing on iterating through the input buffer, but not
+            passing the data to the callback. With care, the outer loop could be
+            terminated earlier, thus some unneeded conversion cycles would be
+            saved.
+            */
+            if( *streamCallbackResult == paContinue )
+            {
+                bp->timeInfo->outputBufferDacTime = 0;
+
+                *streamCallbackResult = bp->streamCallback( userInput, userOutput,
+                        bp->framesPerUserBuffer, bp->timeInfo,
+                        bp->callbackStatusFlags, bp->userData );
+
+                bp->timeInfo->inputBufferAdcTime += frameCount * bp->samplePeriod;
+            }
+            
+            bp->framesInTempInputBuffer = 0;
+        }
+
+        framesProcessed += frameCount;
+
+        framesToGo -= frameCount;
+    }while( framesToGo > 0 );
+
+    return framesProcessed;
+}
+
+
+/*
+    AdaptingOutputOnlyProcess() is a half duplex output buffer processor.
+    It converts data from the temporary output buffer, to the output buffers,
+    when the temporary output buffer is empty, it calls the streamCallback.
+*/
+static unsigned long AdaptingOutputOnlyProcess( PaUtilBufferProcessor *bp,
+        int *streamCallbackResult,
+        PaUtilChannelDescriptor *hostOutputChannels,
+        unsigned long framesToProcess )
+{
+    void *userInput, *userOutput;
+    unsigned char *srcBytePtr;
+    unsigned int srcSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */
+    unsigned int srcChannelStrideBytes;  /* stride from one channel to the next, in bytes */
+    unsigned int i;
+    unsigned long frameCount;
+    unsigned long framesToGo = framesToProcess;
+    unsigned long framesProcessed = 0;
+
+    do
+    {
+        if( bp->framesInTempOutputBuffer == 0 && *streamCallbackResult == paContinue )
+        {
+            userInput = 0;
+
+            /* setup userOutput */
+            if( bp->userOutputIsInterleaved )
+            {
+                userOutput = bp->tempOutputBuffer;
+            }
+            else /* user output is not interleaved */
+            {
+                for( i = 0; i < bp->outputChannelCount; ++i )
+                {
+                    bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) +
+                            i * bp->framesPerUserBuffer * bp->bytesPerUserOutputSample;
+                }
+
+                userOutput = bp->tempOutputBufferPtrs;
+            }
+
+            bp->timeInfo->inputBufferAdcTime = 0;
+            
+            *streamCallbackResult = bp->streamCallback( userInput, userOutput,
+                    bp->framesPerUserBuffer, bp->timeInfo,
+                    bp->callbackStatusFlags, bp->userData );
+
+            if( *streamCallbackResult == paAbort )
+            {
+                /* if the callback returned paAbort, we disregard its output */
+            }
+            else
+            {
+                bp->timeInfo->outputBufferDacTime += bp->framesPerUserBuffer * bp->samplePeriod;
+
+                bp->framesInTempOutputBuffer = bp->framesPerUserBuffer;
+            }
+        }
+
+        if( bp->framesInTempOutputBuffer > 0 )
+        {
+            /* convert frameCount frames from user buffer to host buffer */
+
+            frameCount = PA_MIN_( bp->framesInTempOutputBuffer, framesToGo );
+
+            if( bp->userOutputIsInterleaved )
+            {
+                srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) +
+                        bp->bytesPerUserOutputSample * bp->outputChannelCount *
+                        (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer);
+
+                srcSampleStrideSamples = bp->outputChannelCount;
+                srcChannelStrideBytes = bp->bytesPerUserOutputSample;
+            }
+            else /* user output is not interleaved */
+            {
+                srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) +
+                        bp->bytesPerUserOutputSample *
+                        (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer);
+                            
+                srcSampleStrideSamples = 1;
+                srcChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserOutputSample;
+            }
+
+            for( i=0; i<bp->outputChannelCount; ++i )
+            {
+                bp->outputConverter(    hostOutputChannels[i].data,
+                                        hostOutputChannels[i].stride,
+                                        srcBytePtr, srcSampleStrideSamples,
+                                        frameCount, &bp->ditherGenerator );
+
+                srcBytePtr += srcChannelStrideBytes;  /* skip to next source channel */
+
+                /* advance dest ptr for next iteration */
+                hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
+                        frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
+            }
+
+            bp->framesInTempOutputBuffer -= frameCount;
+        }
+        else
+        {
+            /* no more user data is available because the callback has returned
+                paComplete or paAbort. Fill the remainder of the host buffer
+                with zeros.
+            */
+
+            frameCount = framesToGo;
+
+            for( i=0; i<bp->outputChannelCount; ++i )
+            {
+                bp->outputZeroer(   hostOutputChannels[i].data,
+                                    hostOutputChannels[i].stride,
+                                    frameCount );
+
+                /* advance dest ptr for next iteration */
+                hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
+                        frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
+            }
+        }
+        
+        framesProcessed += frameCount;
+        
+        framesToGo -= frameCount;
+
+    }while( framesToGo > 0 );
+
+    return framesProcessed;
+}
+
+/* CopyTempOutputBuffersToHostOutputBuffers is called from AdaptingProcess to copy frames from
+       tempOutputBuffer to hostOutputChannels. This includes data conversion
+       and interleaving. 
+*/
+static void CopyTempOutputBuffersToHostOutputBuffers( PaUtilBufferProcessor *bp)
+{
+    unsigned long maxFramesToCopy;
+    PaUtilChannelDescriptor *hostOutputChannels;
+    unsigned int frameCount;
+    unsigned char *srcBytePtr;
+    unsigned int srcSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */
+    unsigned int srcChannelStrideBytes; /* stride from one channel to the next, in bytes */
+    unsigned int i;
+
+     /* copy frames from user to host output buffers */
+     while( bp->framesInTempOutputBuffer > 0 &&
+             ((bp->hostOutputFrameCount[0] + bp->hostOutputFrameCount[1]) > 0) )
+     {
+         maxFramesToCopy = bp->framesInTempOutputBuffer;
+
+         /* select the output buffer set (1st or 2nd) */
+         if( bp->hostOutputFrameCount[0] > 0 )
+         {
+             hostOutputChannels = bp->hostOutputChannels[0];
+             frameCount = PA_MIN_( bp->hostOutputFrameCount[0], maxFramesToCopy );
+         }
+         else
+         {
+             hostOutputChannels = bp->hostOutputChannels[1];
+             frameCount = PA_MIN_( bp->hostOutputFrameCount[1], maxFramesToCopy );
+         }
+
+         if( bp->userOutputIsInterleaved )
+         {
+             srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) +
+                     bp->bytesPerUserOutputSample * bp->outputChannelCount *
+                     (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer);
+                         
+             srcSampleStrideSamples = bp->outputChannelCount;
+             srcChannelStrideBytes = bp->bytesPerUserOutputSample;
+         }
+         else /* user output is not interleaved */
+         {
+             srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) +
+                     bp->bytesPerUserOutputSample *
+                     (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer);
+
+             srcSampleStrideSamples = 1;
+             srcChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserOutputSample;
+         }
+
+         for( i=0; i<bp->outputChannelCount; ++i )
+         {
+             assert( hostOutputChannels[i].data != NULL );
+             bp->outputConverter(    hostOutputChannels[i].data,
+                                     hostOutputChannels[i].stride,
+                                     srcBytePtr, srcSampleStrideSamples,
+                                     frameCount, &bp->ditherGenerator );
+
+             srcBytePtr += srcChannelStrideBytes;  /* skip to next source channel */
+
+             /* advance dest ptr for next iteration */
+             hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
+                     frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
+         }
+
+         if( bp->hostOutputFrameCount[0] > 0 )
+             bp->hostOutputFrameCount[0] -= frameCount;
+         else
+             bp->hostOutputFrameCount[1] -= frameCount;
+
+         bp->framesInTempOutputBuffer -= frameCount;
+     }
+}
+
+/*
+    AdaptingProcess is a full duplex adapting buffer processor. It converts
+    data from the temporary output buffer into the host output buffers, then
+    from the host input buffers into the temporary input buffers. Calling the
+    streamCallback when necessary.
+    When processPartialUserBuffers is 0, all available input data will be
+    consumed and all available output space will be filled. When
+    processPartialUserBuffers is non-zero, as many full user buffers
+    as possible will be processed, but partial buffers will not be consumed.
+*/
+static unsigned long AdaptingProcess( PaUtilBufferProcessor *bp,
+        int *streamCallbackResult, int processPartialUserBuffers )
+{
+    void *userInput, *userOutput;
+    unsigned long framesProcessed = 0;
+    unsigned long framesAvailable;
+    unsigned long endProcessingMinFrameCount;
+    unsigned long maxFramesToCopy;
+    PaUtilChannelDescriptor *hostInputChannels, *hostOutputChannels;
+    unsigned int frameCount;
+    unsigned char *destBytePtr;
+    unsigned int destSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */
+    unsigned int destChannelStrideBytes; /* stride from one channel to the next, in bytes */
+    unsigned int i, j;
+
+    framesAvailable = bp->hostInputFrameCount[0] + bp->hostInputFrameCount[1];/* this is assumed to be the same as the output buffer's frame count */
+
+    if( processPartialUserBuffers )
+        endProcessingMinFrameCount = 0;
+    else
+        endProcessingMinFrameCount = (bp->framesPerUserBuffer - 1);
+
+    /* Fill host output with remaining frames in user output (tempOutputBuffer) */
+    CopyTempOutputBuffersToHostOutputBuffers( bp );                    
+
+    while( framesAvailable > endProcessingMinFrameCount ) 
+    {
+
+        if( bp->framesInTempOutputBuffer == 0 && *streamCallbackResult != paContinue )
+        {
+            /* the callback will not be called any more, so zero what remains
+                of the host output buffers */
+
+            for( i=0; i<2; ++i )
+            {
+                frameCount = bp->hostOutputFrameCount[i];
+                if( frameCount > 0 )
+                {
+                    hostOutputChannels = bp->hostOutputChannels[i];
+                    
+                    for( j=0; j<bp->outputChannelCount; ++j )
+                    {
+                        bp->outputZeroer(   hostOutputChannels[j].data,
+                                            hostOutputChannels[j].stride,
+                                            frameCount );
+
+                        /* advance dest ptr for next iteration  */
+                        hostOutputChannels[j].data = ((unsigned char*)hostOutputChannels[j].data) +
+                                frameCount * hostOutputChannels[j].stride * bp->bytesPerHostOutputSample;
+                    }
+                    bp->hostOutputFrameCount[i] = 0;
+                }
+            }
+        }          
+
+
+        /* copy frames from host to user input buffers */
+        while( bp->framesInTempInputBuffer < bp->framesPerUserBuffer &&
+                ((bp->hostInputFrameCount[0] + bp->hostInputFrameCount[1]) > 0) )
+        {
+            maxFramesToCopy = bp->framesPerUserBuffer - bp->framesInTempInputBuffer;
+
+            /* select the input buffer set (1st or 2nd) */
+            if( bp->hostInputFrameCount[0] > 0 )
+            {
+                hostInputChannels = bp->hostInputChannels[0];
+                frameCount = PA_MIN_( bp->hostInputFrameCount[0], maxFramesToCopy );
+            }
+            else
+            {
+                hostInputChannels = bp->hostInputChannels[1];
+                frameCount = PA_MIN_( bp->hostInputFrameCount[1], maxFramesToCopy );
+            }
+
+            /* configure conversion destination pointers */
+            if( bp->userInputIsInterleaved )
+            {
+                destBytePtr = ((unsigned char*)bp->tempInputBuffer) +
+                        bp->bytesPerUserInputSample * bp->inputChannelCount *
+                        bp->framesInTempInputBuffer;
+
+                destSampleStrideSamples = bp->inputChannelCount;
+                destChannelStrideBytes = bp->bytesPerUserInputSample;
+            }
+            else /* user input is not interleaved */
+            {
+                destBytePtr = ((unsigned char*)bp->tempInputBuffer) +
+                        bp->bytesPerUserInputSample * bp->framesInTempInputBuffer;
+
+                destSampleStrideSamples = 1;
+                destChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserInputSample;
+            }
+
+            for( i=0; i<bp->inputChannelCount; ++i )
+            {
+                bp->inputConverter( destBytePtr, destSampleStrideSamples,
+                                        hostInputChannels[i].data,
+                                        hostInputChannels[i].stride,
+                                        frameCount, &bp->ditherGenerator );
+
+                destBytePtr += destChannelStrideBytes;  /* skip to next destination channel */
+
+                /* advance src ptr for next iteration */
+                hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
+                        frameCount * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
+            }
+
+            if( bp->hostInputFrameCount[0] > 0 )
+                bp->hostInputFrameCount[0] -= frameCount;
+            else
+                bp->hostInputFrameCount[1] -= frameCount;
+                
+            bp->framesInTempInputBuffer += frameCount;
+
+            /* update framesAvailable and framesProcessed based on input consumed
+                unless something is very wrong this will also correspond to the
+                amount of output generated */
+            framesAvailable -= frameCount;
+            framesProcessed += frameCount;
+        }
+
+        /* call streamCallback */
+        if( bp->framesInTempInputBuffer == bp->framesPerUserBuffer &&
+            bp->framesInTempOutputBuffer == 0 )
+        {
+            if( *streamCallbackResult == paContinue )
+            {
+                /* setup userInput */
+                if( bp->userInputIsInterleaved )
+                {
+                    userInput = bp->tempInputBuffer;
+                }
+                else /* user input is not interleaved */
+                {
+                    for( i = 0; i < bp->inputChannelCount; ++i )
+                    {
+                        bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) +
+                                i * bp->framesPerUserBuffer * bp->bytesPerUserInputSample;
+                    }
+
+                    userInput = bp->tempInputBufferPtrs;
+                }
+
+                /* setup userOutput */
+                if( bp->userOutputIsInterleaved )
+                {
+                    userOutput = bp->tempOutputBuffer;
+                }
+                else /* user output is not interleaved */
+                {
+                    for( i = 0; i < bp->outputChannelCount; ++i )
+                    {
+                        bp->tempOutputBufferPtrs[i] = ((unsigned char*)bp->tempOutputBuffer) +
+                                i * bp->framesPerUserBuffer * bp->bytesPerUserOutputSample;
+                    }
+
+                    userOutput = bp->tempOutputBufferPtrs;
+                }
+
+                /* call streamCallback */
+
+                *streamCallbackResult = bp->streamCallback( userInput, userOutput,
+                        bp->framesPerUserBuffer, bp->timeInfo,
+                        bp->callbackStatusFlags, bp->userData );
+
+                bp->timeInfo->inputBufferAdcTime += bp->framesPerUserBuffer * bp->samplePeriod;
+                bp->timeInfo->outputBufferDacTime += bp->framesPerUserBuffer * bp->samplePeriod;
+
+                bp->framesInTempInputBuffer = 0;
+
+                if( *streamCallbackResult == paAbort )
+                    bp->framesInTempOutputBuffer = 0;
+                else
+                    bp->framesInTempOutputBuffer = bp->framesPerUserBuffer;
+            }
+            else
+            {
+                /* paComplete or paAbort has already been called. */
+
+                bp->framesInTempInputBuffer = 0;
+            }
+        }
+
+        /* copy frames from user (tempOutputBuffer) to host output buffers (hostOutputChannels) 
+           Means to process the user output provided by the callback. Has to be called after
+            each callback. */
+        CopyTempOutputBuffersToHostOutputBuffers( bp );                        
+
+    }
+    
+    return framesProcessed;
+}
+
+
+unsigned long PaUtil_EndBufferProcessing( PaUtilBufferProcessor* bp, int *streamCallbackResult )
+{
+    unsigned long framesToProcess, framesToGo;
+    unsigned long framesProcessed = 0;
+    
+    if( bp->inputChannelCount != 0 && bp->outputChannelCount != 0
+            && bp->hostInputChannels[0][0].data /* input was supplied (see PaUtil_SetNoInput) */
+            && bp->hostOutputChannels[0][0].data /* output was supplied (see PaUtil_SetNoOutput) */ )
+    {
+        assert( (bp->hostInputFrameCount[0] + bp->hostInputFrameCount[1]) ==
+                (bp->hostOutputFrameCount[0] + bp->hostOutputFrameCount[1]) );
+    }
+
+    assert( *streamCallbackResult == paContinue
+            || *streamCallbackResult == paComplete
+            || *streamCallbackResult == paAbort ); /* don't forget to pass in a valid callback result value */
+
+    if( bp->useNonAdaptingProcess )
+    {
+        if( bp->inputChannelCount != 0 && bp->outputChannelCount != 0 )
+        {
+            /* full duplex non-adapting process, splice buffers if they are
+                different lengths */
+
+            framesToGo = bp->hostOutputFrameCount[0] + bp->hostOutputFrameCount[1]; /* relies on assert above for input/output equivalence */
+
+            do{
+                unsigned long noInputInputFrameCount;
+                unsigned long *hostInputFrameCount;
+                PaUtilChannelDescriptor *hostInputChannels;
+                unsigned long noOutputOutputFrameCount;
+                unsigned long *hostOutputFrameCount;
+                PaUtilChannelDescriptor *hostOutputChannels;
+                unsigned long framesProcessedThisIteration;
+
+                if( !bp->hostInputChannels[0][0].data )
+                {
+                    /* no input was supplied (see PaUtil_SetNoInput)
+                        NonAdaptingProcess knows how to deal with this
+                    */
+                    noInputInputFrameCount = framesToGo;
+                    hostInputFrameCount = &noInputInputFrameCount;
+                    hostInputChannels = 0;
+                }
+                else if( bp->hostInputFrameCount[0] != 0 )
+                {
+                    hostInputFrameCount = &bp->hostInputFrameCount[0];
+                    hostInputChannels = bp->hostInputChannels[0];
+                }
+                else
+                {
+                    hostInputFrameCount = &bp->hostInputFrameCount[1];
+                    hostInputChannels = bp->hostInputChannels[1];
+                }
+
+                if( !bp->hostOutputChannels[0][0].data )
+                {
+                    /* no output was supplied (see PaUtil_SetNoOutput)
+                        NonAdaptingProcess knows how to deal with this
+                    */
+                    noOutputOutputFrameCount = framesToGo;
+                    hostOutputFrameCount = &noOutputOutputFrameCount;
+                    hostOutputChannels = 0;
+                }
+                if( bp->hostOutputFrameCount[0] != 0 )
+                {
+                    hostOutputFrameCount = &bp->hostOutputFrameCount[0];
+                    hostOutputChannels = bp->hostOutputChannels[0];
+                }
+                else
+                {
+                    hostOutputFrameCount = &bp->hostOutputFrameCount[1];
+                    hostOutputChannels = bp->hostOutputChannels[1];
+                }
+
+                framesToProcess = PA_MIN_( *hostInputFrameCount,
+                                       *hostOutputFrameCount );
+
+                assert( framesToProcess != 0 );
+                
+                framesProcessedThisIteration = NonAdaptingProcess( bp, streamCallbackResult,
+                        hostInputChannels, hostOutputChannels,
+                        framesToProcess );                                       
+
+                *hostInputFrameCount -= framesProcessedThisIteration;
+                *hostOutputFrameCount -= framesProcessedThisIteration;
+
+                framesProcessed += framesProcessedThisIteration;
+                framesToGo -= framesProcessedThisIteration;
+                
+            }while( framesToGo > 0 );
+        }
+        else
+        {
+            /* half duplex non-adapting process, just process 1st and 2nd buffer */
+            /* process first buffer */
+
+            framesToProcess = (bp->inputChannelCount != 0)
+                            ? bp->hostInputFrameCount[0]
+                            : bp->hostOutputFrameCount[0];
+
+            framesProcessed = NonAdaptingProcess( bp, streamCallbackResult,
+                        bp->hostInputChannels[0], bp->hostOutputChannels[0],
+                        framesToProcess );
+
+            /* process second buffer if provided */
+    
+            framesToProcess = (bp->inputChannelCount != 0)
+                            ? bp->hostInputFrameCount[1]
+                            : bp->hostOutputFrameCount[1];
+            if( framesToProcess > 0 )
+            {
+                framesProcessed += NonAdaptingProcess( bp, streamCallbackResult,
+                    bp->hostInputChannels[1], bp->hostOutputChannels[1],
+                    framesToProcess );
+            }
+        }
+    }
+    else /* block adaption necessary*/
+    {
+
+        if( bp->inputChannelCount != 0 && bp->outputChannelCount != 0 )
+        {
+            /* full duplex */
+            
+            if( bp->hostBufferSizeMode == paUtilVariableHostBufferSizePartialUsageAllowed  )
+            {
+                framesProcessed = AdaptingProcess( bp, streamCallbackResult,
+                        0 /* dont process partial user buffers */ );
+            }
+            else
+            {
+                framesProcessed = AdaptingProcess( bp, streamCallbackResult,
+                        1 /* process partial user buffers */ );
+            }
+        }
+        else if( bp->inputChannelCount != 0 )
+        {
+            /* input only */
+            framesToProcess = bp->hostInputFrameCount[0];
+
+            framesProcessed = AdaptingInputOnlyProcess( bp, streamCallbackResult,
+                        bp->hostInputChannels[0], framesToProcess );
+
+            framesToProcess = bp->hostInputFrameCount[1];
+            if( framesToProcess > 0 )
+            {
+                framesProcessed += AdaptingInputOnlyProcess( bp, streamCallbackResult,
+                        bp->hostInputChannels[1], framesToProcess );
+            }
+        }
+        else
+        {
+            /* output only */
+            framesToProcess = bp->hostOutputFrameCount[0];
+
+            framesProcessed = AdaptingOutputOnlyProcess( bp, streamCallbackResult,
+                        bp->hostOutputChannels[0], framesToProcess );
+
+            framesToProcess = bp->hostOutputFrameCount[1];
+            if( framesToProcess > 0 )
+            {
+                framesProcessed += AdaptingOutputOnlyProcess( bp, streamCallbackResult,
+                        bp->hostOutputChannels[1], framesToProcess );
+            }
+        }
+    }
+
+    return framesProcessed;
+}
+
+
+int PaUtil_IsBufferProcessorOutputEmpty( PaUtilBufferProcessor* bp )
+{
+    return (bp->framesInTempOutputBuffer) ? 0 : 1;
+} 
+
+
+unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bp,
+        void **buffer, unsigned long frameCount )
+{
+    PaUtilChannelDescriptor *hostInputChannels;
+    unsigned int framesToCopy;
+    unsigned char *destBytePtr;
+    void **nonInterleavedDestPtrs;
+    unsigned int destSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */
+    unsigned int destChannelStrideBytes; /* stride from one channel to the next, in bytes */
+    unsigned int i;
+
+    hostInputChannels = bp->hostInputChannels[0];
+    framesToCopy = PA_MIN_( bp->hostInputFrameCount[0], frameCount );
+
+    if( bp->userInputIsInterleaved )
+    {
+        destBytePtr = (unsigned char*)*buffer;
+        
+        destSampleStrideSamples = bp->inputChannelCount;
+        destChannelStrideBytes = bp->bytesPerUserInputSample;
+
+        for( i=0; i<bp->inputChannelCount; ++i )
+        {
+            bp->inputConverter( destBytePtr, destSampleStrideSamples,
+                                hostInputChannels[i].data,
+                                hostInputChannels[i].stride,
+                                framesToCopy, &bp->ditherGenerator );
+
+            destBytePtr += destChannelStrideBytes;  /* skip to next source channel */
+
+            /* advance dest ptr for next iteration */
+            hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
+                    framesToCopy * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
+        }
+
+        /* advance callers dest pointer (buffer) */
+        *buffer = ((unsigned char *)*buffer) +
+                framesToCopy * bp->inputChannelCount * bp->bytesPerUserInputSample;
+    }
+    else
+    {
+        /* user input is not interleaved */
+        
+        nonInterleavedDestPtrs = (void**)*buffer;
+
+        destSampleStrideSamples = 1;
+        
+        for( i=0; i<bp->inputChannelCount; ++i )
+        {
+            destBytePtr = (unsigned char*)nonInterleavedDestPtrs[i];
+
+            bp->inputConverter( destBytePtr, destSampleStrideSamples,
+                                hostInputChannels[i].data,
+                                hostInputChannels[i].stride,
+                                framesToCopy, &bp->ditherGenerator );
+
+            /* advance callers dest pointer (nonInterleavedDestPtrs[i]) */
+            destBytePtr += bp->bytesPerUserInputSample * framesToCopy;
+            nonInterleavedDestPtrs[i] = destBytePtr;
+            
+            /* advance dest ptr for next iteration */
+            hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
+                    framesToCopy * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
+        }
+    }
+
+    bp->hostInputFrameCount[0] -= framesToCopy;
+    
+    return framesToCopy;
+}
+
+unsigned long PaUtil_CopyOutput( PaUtilBufferProcessor* bp,
+        const void ** buffer, unsigned long frameCount )
+{
+    PaUtilChannelDescriptor *hostOutputChannels;
+    unsigned int framesToCopy;
+    unsigned char *srcBytePtr;
+    void **nonInterleavedSrcPtrs;
+    unsigned int srcSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */
+    unsigned int srcChannelStrideBytes; /* stride from one channel to the next, in bytes */
+    unsigned int i;
+
+    hostOutputChannels = bp->hostOutputChannels[0];
+    framesToCopy = PA_MIN_( bp->hostOutputFrameCount[0], frameCount );
+
+    if( bp->userOutputIsInterleaved )
+    {
+        srcBytePtr = (unsigned char*)*buffer;
+        
+        srcSampleStrideSamples = bp->outputChannelCount;
+        srcChannelStrideBytes = bp->bytesPerUserOutputSample;
+
+        for( i=0; i<bp->outputChannelCount; ++i )
+        {
+            bp->outputConverter(    hostOutputChannels[i].data,
+                                    hostOutputChannels[i].stride,
+                                    srcBytePtr, srcSampleStrideSamples,
+                                    framesToCopy, &bp->ditherGenerator );
+
+            srcBytePtr += srcChannelStrideBytes;  /* skip to next source channel */
+
+            /* advance dest ptr for next iteration */
+            hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
+                    framesToCopy * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
+        }
+
+        /* advance callers source pointer (buffer) */
+        *buffer = ((unsigned char *)*buffer) +
+                framesToCopy * bp->outputChannelCount * bp->bytesPerUserOutputSample;
+
+    }
+    else
+    {
+        /* user output is not interleaved */
+        
+        nonInterleavedSrcPtrs = (void**)*buffer;
+
+        srcSampleStrideSamples = 1;
+        
+        for( i=0; i<bp->outputChannelCount; ++i )
+        {
+            srcBytePtr = (unsigned char*)nonInterleavedSrcPtrs[i];
+            
+            bp->outputConverter(    hostOutputChannels[i].data,
+                                    hostOutputChannels[i].stride,
+                                    srcBytePtr, srcSampleStrideSamples,
+                                    framesToCopy, &bp->ditherGenerator );
+
+
+            /* advance callers source pointer (nonInterleavedSrcPtrs[i]) */
+            srcBytePtr += bp->bytesPerUserOutputSample * framesToCopy;
+            nonInterleavedSrcPtrs[i] = srcBytePtr;
+            
+            /* advance dest ptr for next iteration */
+            hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
+                    framesToCopy * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
+        }
+    }
+
+    bp->hostOutputFrameCount[0] += framesToCopy;
+    
+    return framesToCopy;
+}
+
+
+unsigned long PaUtil_ZeroOutput( PaUtilBufferProcessor* bp, unsigned long frameCount )
+{
+    PaUtilChannelDescriptor *hostOutputChannels;
+    unsigned int framesToZero;
+    unsigned int i;
+
+    hostOutputChannels = bp->hostOutputChannels[0];
+    framesToZero = PA_MIN_( bp->hostOutputFrameCount[0], frameCount );
+
+    for( i=0; i<bp->outputChannelCount; ++i )
+    {
+        bp->outputZeroer(   hostOutputChannels[i].data,
+                            hostOutputChannels[i].stride,
+                            framesToZero );
+
+
+        /* advance dest ptr for next iteration */
+        hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
+                framesToZero * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
+    }
+
+    bp->hostOutputFrameCount[0] += framesToZero;
+    
+    return framesToZero;
+}
diff --git a/utils/iaxclient/lib/portaudio/src/common/pa_process.h b/utils/iaxclient/lib/portaudio/src/common/pa_process.h
new file mode 100644 (file)
index 0000000..c7f9567
--- /dev/null
@@ -0,0 +1,741 @@
+#ifndef PA_PROCESS_H
+#define PA_PROCESS_H
+/*
+ * $Id: pa_process.h,v 1.1 2006/06/10 21:30:55 dmazzoni Exp $
+ * Portable Audio I/O Library callback buffer processing adapters
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2002 Phil Burk, Ross Bencina
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/** @file
+ @brief Buffer Processor prototypes. A Buffer Processor performs buffer length
+ adaption, coordinates sample format conversion, and interleaves/deinterleaves
+ channels.
+
+ <h3>Overview</h3>
+
+ The "Buffer Processor" (PaUtilBufferProcessor) manages conversion of audio
+ data from host buffers to user buffers and back again. Where required, the
+ buffer processor takes care of converting between host and user sample formats,
+ interleaving and deinterleaving multichannel buffers, and adapting between host
+ and user buffers with different lengths. The buffer processor may be used with
+ full and half duplex streams, for both callback streams and blocking read/write
+ streams.
+
+ One of the important capabilities provided by the buffer processor is
+ the ability to adapt between user and host buffer sizes of different lengths
+ with minimum latency. Although this task is relatively easy to perform when
+ the host buffer size is an integer multiple of the user buffer size, the
+ problem is more complicated when this is not the case - especially for
+ full-duplex callback streams. Where necessary the adaption is implemented by
+ internally buffering some input and/or output data. The buffer adation
+ algorithm used by the buffer processor was originally implemented by
+ Stephan Letz for the ASIO version of PortAudio, and is described in his
+ Callback_adaption_.pdf which is included in the distribution.
+
+ The buffer processor performs sample conversion using the functions provided
+ by pa_converters.c.
+
+ The following sections provide an overview of how to use the buffer processor.
+ Interested readers are advised to consult the host API implementations for
+ examples of buffer processor usage.
+
+ <h4>Initialization, resetting and termination</h4>
+
+ When a stream is opened, the buffer processor should be initialized using
+ PaUtil_InitializeBufferProcessor. This function initializes internal state
+ and allocates temporary buffers as neccesary according to the supplied
+ configuration parameters. Some of the parameters correspond to those requested
+ by the user in their call to Pa_OpenStream(), others reflect the requirements
+ of the host API implementation - they indicate host buffer sizes, formats,
+ and the type of buffering which the Host API uses. The buffer processor should
+ be initialized for callback streams and blocking read/write streams.
+
+ Call PaUtil_ResetBufferProcessor to clear any sample data which is present
+ in the buffer processor before starting to use it (for example when
+ Pa_StartStream is called).
+
+ When the buffer processor is no longer used call
+ PaUtil_TerminateBufferProcessor.
+
+ <h4>Using the buffer processor for a callback stream</h4>
+
+ The buffer processor's role in a callback stream is to take host input buffers
+ process them with the stream callback, and fill host output buffers. For a
+ full duplex stream, the buffer processor handles input and output simultaneously
+ due to the requirements of the minimum-latency buffer adation algorithm.
+
+ When a host buffer becomes available, the implementation should call
+ the buffer processor to process the buffer. The buffer processor calls the
+ stream callback to consume and/or produce audio data as necessary. The buffer
+ processor will convert sample formats, interleave/deinterleave channels,
+ and slice or chunk the data to the appropriate buffer lengths according to
+ the requirements of the stream callback and the host API.
+
+ To process a host buffer (or a pair of host buffers for a full-duplex stream)
+ use the following calling sequence:
+
+ -# Call PaUtil_BeginBufferProcessing
+ -# For a stream which takes input:
+    - Call PaUtil_SetInputFrameCount with the number of frames in the host input
+        buffer.
+    - Call one of the following functions one or more times to tell the
+        buffer processor about the host input buffer(s): PaUtil_SetInputChannel,
+        PaUtil_SetInterleavedInputChannels, PaUtil_SetNonInterleavedInputChannel.
+        Which function you call will depend on whether the host buffer(s) are
+        interleaved or not.
+    - If the available host data is split accross two buffers (for example a
+        data range at the end of a circular buffer and another range at the
+        beginning of the circular buffer), also call
+        PaUtil_Set2ndInputFrameCount, PaUtil_Set2ndInputChannel,
+        PaUtil_Set2ndInterleavedInputChannels,
+        PaUtil_Set2ndNonInterleavedInputChannel as necessary to tell the buffer
+        processor about the second buffer.
+ -# For a stream which generates output:
+    - Call PaUtil_SetOutputFrameCount with the number of frames in the host
+        output buffer.
+    - Call one of the following functions one or more times to tell the
+        buffer processor about the host output buffer(s): PaUtil_SetOutputChannel,
+        PaUtil_SetInterleavedOutputChannels, PaUtil_SetNonInterleavedOutputChannel.
+        Which function you call will depend on whether the host buffer(s) are
+        interleaved or not.
+    - If the available host output buffer space is split accross two buffers
+        (for example a data range at the end of a circular buffer and another
+        range at the beginning of the circular buffer), call
+        PaUtil_Set2ndOutputFrameCount, PaUtil_Set2ndOutputChannel,
+        PaUtil_Set2ndInterleavedOutputChannels,
+        PaUtil_Set2ndNonInterleavedOutputChannel as necessary to tell the buffer
+        processor about the second buffer.
+ -# Call PaUtil_EndBufferProcessing, this function performs the actual data
+    conversion and processing.
+
+
+ <h4>Using the buffer processor for a blocking read/write stream</h4>
+
+ Blocking read/write streams use the buffer processor to convert and copy user
+ output data to a host buffer, and to convert and copy host input data to
+ the user's buffer. The buffer processor does not perform any buffer adaption.
+ When using the buffer processor in a blocking read/write stream the input and
+ output conversion are performed separately by the PaUtil_CopyInput and
+ PaUtil_CopyOutput functions.
+
+ To copy data from a host input buffer to the buffer(s) which the user supplies
+ to Pa_ReadStream, use the following calling sequence.
+
+ - Repeat the following three steps until the user buffer(s) have been filled
+    with samples from the host input buffers:
+     -# Call PaUtil_SetInputFrameCount with the number of frames in the host
+        input buffer.
+     -# Call one of the following functions one or more times to tell the
+        buffer processor about the host input buffer(s): PaUtil_SetInputChannel,
+        PaUtil_SetInterleavedInputChannels, PaUtil_SetNonInterleavedInputChannel.
+        Which function you call will depend on whether the host buffer(s) are
+        interleaved or not.
+     -# Call PaUtil_CopyInput with the user buffer pointer (or a copy of the
+        array of buffer pointers for a non-interleaved stream) passed to
+        Pa_ReadStream, along with the number of frames in the user buffer(s).
+        Be careful to pass a <i>copy</i> of the user buffer pointers to
+        PaUtil_CopyInput because PaUtil_CopyInput advances the pointers to
+        the start of the next region to copy.
+ - PaUtil_CopyInput will not copy more data than is available in the
+    host buffer(s), so the above steps need to be repeated until the user
+    buffer(s) are full.
+
+ To copy data to the host output buffer from the user buffers(s) supplied
+ to Pa_WriteStream use the following calling sequence.
+
+ - Repeat the following three steps until all frames from the user buffer(s)
+    have been copied to the host API:
+     -# Call PaUtil_SetOutputFrameCount with the number of frames in the host
+        output buffer.
+     -# Call one of the following functions one or more times to tell the
+        buffer processor about the host output buffer(s): PaUtil_SetOutputChannel,
+        PaUtil_SetInterleavedOutputChannels, PaUtil_SetNonInterleavedOutputChannel.
+        Which function you call will depend on whether the host buffer(s) are
+        interleaved or not.
+     -# Call PaUtil_CopyOutput with the user buffer pointer (or a copy of the
+        array of buffer pointers for a non-interleaved stream) passed to
+        Pa_WriteStream, along with the number of frames in the user buffer(s).
+        Be careful to pass a <i>copy</i> of the user buffer pointers to 
+        PaUtil_CopyOutput because PaUtil_CopyOutput advances the pointers to
+        the start of the next region to copy.
+ - PaUtil_CopyOutput will not copy more data than fits in the host buffer(s),
+    so the above steps need to be repeated until all user data is copied.
+*/
+
+
+#include "portaudio.h"
+#include "pa_converters.h"
+#include "pa_dither.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+
+/** @brief Mode flag passed to PaUtil_InitializeBufferProcessor indicating the type
+ of buffering that the host API uses.
+
+ The mode used depends on whether the host API or the implementation manages
+ the buffers, and how these buffers are used (scatter gather, circular buffer).
+*/
+typedef enum {
+/** The host buffer size is a fixed known size. */
+    paUtilFixedHostBufferSize,
+
+/** The host buffer size may vary, but has a known maximum size. */
+    paUtilBoundedHostBufferSize,
+
+/** Nothing is known about the host buffer size. */
+    paUtilUnknownHostBufferSize,
+
+/** The host buffer size varies, and the client does not require the buffer
+ processor to consume all of the input and fill all of the output buffer. This
+ is useful when the implementation has access to the host API's circular buffer
+ and only needs to consume/fill some of it, not necessarily all of it, with each
+ call to the buffer processor. This is the only mode where
+ PaUtil_EndBufferProcessing() may not consume the whole buffer.
+*/
+    paUtilVariableHostBufferSizePartialUsageAllowed
+}PaUtilHostBufferSizeMode;
+
+
+/** @brief An auxilliary data structure used internally by the buffer processor
+ to represent host input and output buffers. */
+typedef struct PaUtilChannelDescriptor{
+    void *data;
+    unsigned int stride;  /**< stride in samples, not bytes */
+}PaUtilChannelDescriptor;
+
+
+/** @brief The main buffer processor data structure.
+
+ Allocate one of these, initialize it with PaUtil_InitializeBufferProcessor
+ and terminate it with PaUtil_TerminateBufferProcessor.
+*/
+typedef struct {
+    unsigned long framesPerUserBuffer;
+    unsigned long framesPerHostBuffer;
+
+    PaUtilHostBufferSizeMode hostBufferSizeMode;
+    int useNonAdaptingProcess;
+    unsigned long framesPerTempBuffer;
+
+    unsigned int inputChannelCount;
+    unsigned int bytesPerHostInputSample;
+    unsigned int bytesPerUserInputSample;
+    int userInputIsInterleaved;
+    PaUtilConverter *inputConverter;
+    PaUtilZeroer *inputZeroer;
+    
+    unsigned int outputChannelCount;
+    unsigned int bytesPerHostOutputSample;
+    unsigned int bytesPerUserOutputSample;
+    int userOutputIsInterleaved;
+    PaUtilConverter *outputConverter;
+    PaUtilZeroer *outputZeroer;
+
+    unsigned long initialFramesInTempInputBuffer;
+    unsigned long initialFramesInTempOutputBuffer;
+
+    void *tempInputBuffer;          /**< used for slips, block adaption, and conversion. */
+    void **tempInputBufferPtrs;     /**< storage for non-interleaved buffer pointers, NULL for interleaved user input */
+    unsigned long framesInTempInputBuffer; /**< frames remaining in input buffer from previous adaption iteration */
+
+    void *tempOutputBuffer;         /**< used for slips, block adaption, and conversion. */
+    void **tempOutputBufferPtrs;    /**< storage for non-interleaved buffer pointers, NULL for interleaved user output */
+    unsigned long framesInTempOutputBuffer; /**< frames remaining in input buffer from previous adaption iteration */
+
+    PaStreamCallbackTimeInfo *timeInfo;
+
+    PaStreamCallbackFlags callbackStatusFlags;
+
+    unsigned long hostInputFrameCount[2];
+    PaUtilChannelDescriptor *hostInputChannels[2]; /**< pointers to arrays of channel descriptors.
+                                                        pointers are NULL for half-duplex output processing.
+                                                        hostInputChannels[i].data is NULL when the caller
+                                                        calls PaUtil_SetNoInput()
+                                                        */
+    unsigned long hostOutputFrameCount[2];
+    PaUtilChannelDescriptor *hostOutputChannels[2]; /**< pointers to arrays of channel descriptors.
+                                                         pointers are NULL for half-duplex input processing.
+                                                         hostOutputChannels[i].data is NULL when the caller
+                                                         calls PaUtil_SetNoOutput()
+                                                         */
+
+    PaUtilTriangularDitherGenerator ditherGenerator;
+
+    double samplePeriod;
+
+    PaStreamCallback *streamCallback;
+    void *userData;
+} PaUtilBufferProcessor;
+
+
+/** @name Initialization, termination, resetting and info */
+/*@{*/
+
+/** Initialize a buffer processor's representation stored in a
+ PaUtilBufferProcessor structure. Be sure to call
+ PaUtil_TerminateBufferProcessor after finishing with a buffer processor.
+
+ @param bufferProcessor The buffer processor structure to initialize.
+
+ @param inputChannelCount The number of input channels as passed to
+ Pa_OpenStream or 0 for an output-only stream.
+
+ @param userInputSampleFormat Format of user input samples, as passed to
+ Pa_OpenStream. This parameter is ignored for ouput-only streams.
+ @param hostInputSampleFormat Format of host input samples. This parameter is
+ ignored for output-only streams. See note about host buffer interleave below.
+
+ @param outputChannelCount The number of output channels as passed to
+ Pa_OpenStream or 0 for an input-only stream.
+
+ @param userOutputSampleFormat Format of user output samples, as passed to
+ Pa_OpenStream. This parameter is ignored for input-only streams.
+ @param hostOutputSampleFormat Format of host output samples. This parameter is
+ ignored for input-only streams. See note about host buffer interleave below.
+
+ @param sampleRate Sample rate of the stream. The more accurate this is the
+ better - it is used for updating time stamps when adapting buffers.
+ @param streamFlags Stream flags as passed to Pa_OpenStream, this parameter is
+ used for selecting special sample conversion options such as clipping and
+ dithering.
+ @param framesPerUserBuffer Number of frames per user buffer, as requested
+ by the framesPerBuffer parameter to Pa_OpenStream. This parameter may be
+ zero to indicate that the user will accept any (and varying) buffer sizes.
+
+ @param framesPerHostBuffer Specifies the number of frames per host buffer
+ for the fixed buffer size mode, and the maximum number of frames
+ per host buffer for the bounded host buffer size mode. It is ignored for
+ the other modes.
+
+ @param hostBufferSizeMode A mode flag indicating the size variability of
+ host buffers that will be passed to the buffer processor. See
+ PaUtilHostBufferSizeMode for further details.
+ @param streamCallback The user stream callback passed to Pa_OpenStream.
+
+ @param userData The user data field passed to Pa_OpenStream.
+    
+ @note The interleave flag is ignored for host buffer formats. Host
+ interleave is determined by the use of different SetInput and SetOutput
+ functions.
+
+ @return An error code indicating whether the initialization was successful.
+ If the error code is not PaNoError, the buffer processor was not initialized
+ and should not be used.
+ @see Pa_OpenStream, PaUtilHostBufferSizeMode, PaUtil_TerminateBufferProcessor
+*/
+PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bufferProcessor,
+            int inputChannelCount, PaSampleFormat userInputSampleFormat,
+            PaSampleFormat hostInputSampleFormat,
+            int outputChannelCount, PaSampleFormat userOutputSampleFormat,
+            PaSampleFormat hostOutputSampleFormat,
+            double sampleRate,
+            PaStreamFlags streamFlags,
+            unsigned long framesPerUserBuffer, /* 0 indicates don't care */
+            unsigned long framesPerHostBuffer,
+            PaUtilHostBufferSizeMode hostBufferSizeMode,
+            PaStreamCallback *streamCallback, void *userData );
+
+
+/** Terminate a buffer processor's representation. Deallocates any temporary
+ buffers allocated by PaUtil_InitializeBufferProcessor.
+ @param bufferProcessor The buffer processor structure to terminate.
+
+ @see PaUtil_InitializeBufferProcessor.
+*/
+void PaUtil_TerminateBufferProcessor( PaUtilBufferProcessor* bufferProcessor );
+
+
+/** Clear any internally buffered data. If you call
+ PaUtil_InitializeBufferProcessor in your OpenStream routine, make sure you
+ call PaUtil_ResetBufferProcessor in your StartStream call.
+
+ @param bufferProcessor The buffer processor to reset.
+*/
+void PaUtil_ResetBufferProcessor( PaUtilBufferProcessor* bufferProcessor );
+
+
+/** Retrieve the input latency of a buffer processor.
+
+ @param bufferProcessor The buffer processor examine.
+
+ @return The input latency introduced by the buffer processor, in frames.
+
+ @see PaUtil_GetBufferProcessorOutputLatency
+*/
+unsigned long PaUtil_GetBufferProcessorInputLatency( PaUtilBufferProcessor* bufferProcessor );
+
+/** Retrieve the output latency of a buffer processor.
+
+ @param bufferProcessor The buffer processor examine.
+
+ @return The output latency introduced by the buffer processor, in frames.
+
+ @see PaUtil_GetBufferProcessorInputLatency
+*/
+unsigned long PaUtil_GetBufferProcessorOutputLatency( PaUtilBufferProcessor* bufferProcessor );
+
+/*@}*/
+
+
+/** @name Host buffer pointer configuration
+
+ Functions to set host input and output buffers, used by both callback streams
+ and blocking read/write streams.
+*/
+/*@{*/ 
+
+
+/** Set the number of frames in the input host buffer(s) specified by the
+ PaUtil_Set*InputChannel functions.
+
+ @param bufferProcessor The buffer processor.
+
+ @param frameCount The number of host input frames. A 0 frameCount indicates to
+ use the framesPerHostBuffer value passed to PaUtil_InitializeBufferProcessor.
+
+ @see PaUtil_SetNoInput, PaUtil_SetInputChannel,
+ PaUtil_SetInterleavedInputChannels, PaUtil_SetNonInterleavedInputChannel
+*/
+void PaUtil_SetInputFrameCount( PaUtilBufferProcessor* bufferProcessor,
+        unsigned long frameCount );
+
+        
+/** Indicate that no input is avalable. This function should be used when
+ priming the output of a full-duplex stream opened with the
+ paPrimeOutputBuffersUsingStreamCallback flag. Note that it is not necessary
+ to call this or any othe PaUtil_Set*Input* functions for ouput-only streams.
+
+ @param bufferProcessor The buffer processor.
+*/
+void PaUtil_SetNoInput( PaUtilBufferProcessor* bufferProcessor );
+
+
+/** Provide the buffer processor with a pointer to a host input channel.
+
+ @param bufferProcessor The buffer processor.
+ @param channel The channel number.
+ @param data The buffer.
+ @param stride The stride from one sample to the next, in samples. For
+ interleaved host buffers, the stride will usually be the same as the number of
+ channels in the buffer.
+*/
+void PaUtil_SetInputChannel( PaUtilBufferProcessor* bufferProcessor,
+        unsigned int channel, void *data, unsigned int stride );
+
+
+/** Provide the buffer processor with a pointer to an number of interleaved
+ host input channels.
+
+ @param bufferProcessor The buffer processor.
+ @param firstChannel The first channel number.
+ @param data The buffer.
+ @param channelCount The number of interleaved channels in the buffer. If
+ channelCount is zero, the number of channels specified to
+ PaUtil_InitializeBufferProcessor will be used.
+*/
+void PaUtil_SetInterleavedInputChannels( PaUtilBufferProcessor* bufferProcessor,
+        unsigned int firstChannel, void *data, unsigned int channelCount );
+
+
+/** Provide the buffer processor with a pointer to one non-interleaved host
+ output channel.
+
+ @param bufferProcessor The buffer processor.
+ @param channel The channel number.
+ @param data The buffer.
+*/
+void PaUtil_SetNonInterleavedInputChannel( PaUtilBufferProcessor* bufferProcessor,
+        unsigned int channel, void *data );
+
+
+/** Use for the second buffer half when the input buffer is split in two halves.
+ @see PaUtil_SetInputFrameCount
+*/
+void PaUtil_Set2ndInputFrameCount( PaUtilBufferProcessor* bufferProcessor,
+        unsigned long frameCount );
+
+/** Use for the second buffer half when the input buffer is split in two halves.
+ @see PaUtil_SetInputChannel
+*/
+void PaUtil_Set2ndInputChannel( PaUtilBufferProcessor* bufferProcessor,
+        unsigned int channel, void *data, unsigned int stride );
+
+/** Use for the second buffer half when the input buffer is split in two halves.
+ @see PaUtil_SetInterleavedInputChannels
+*/
+void PaUtil_Set2ndInterleavedInputChannels( PaUtilBufferProcessor* bufferProcessor,
+        unsigned int firstChannel, void *data, unsigned int channelCount );
+
+/** Use for the second buffer half when the input buffer is split in two halves.
+ @see PaUtil_SetNonInterleavedInputChannel
+*/
+void PaUtil_Set2ndNonInterleavedInputChannel( PaUtilBufferProcessor* bufferProcessor,
+        unsigned int channel, void *data );
+
+        
+/** Set the number of frames in the output host buffer(s) specified by the
+ PaUtil_Set*OutputChannel functions.
+
+ @param bufferProcessor The buffer processor.
+
+ @param frameCount The number of host output frames. A 0 frameCount indicates to
+ use the framesPerHostBuffer value passed to PaUtil_InitializeBufferProcessor.
+
+ @see PaUtil_SetOutputChannel, PaUtil_SetInterleavedOutputChannels,
+ PaUtil_SetNonInterleavedOutputChannel
+*/
+void PaUtil_SetOutputFrameCount( PaUtilBufferProcessor* bufferProcessor,
+        unsigned long frameCount );
+
+
+/** Indicate that the output will be discarded. This function should be used
+ when implementing the paNeverDropInput mode for full duplex streams.
+
+ @param bufferProcessor The buffer processor.
+*/
+void PaUtil_SetNoOutput( PaUtilBufferProcessor* bufferProcessor );
+
+
+/** Provide the buffer processor with a pointer to a host output channel.
+
+ @param bufferProcessor The buffer processor.
+ @param channel The channel number.
+ @param data The buffer.
+ @param stride The stride from one sample to the next, in samples. For
+ interleaved host buffers, the stride will usually be the same as the number of
+ channels in the buffer.
+*/
+void PaUtil_SetOutputChannel( PaUtilBufferProcessor* bufferProcessor,
+        unsigned int channel, void *data, unsigned int stride );
+
+
+/** Provide the buffer processor with a pointer to a number of interleaved
+ host output channels.
+
+ @param bufferProcessor The buffer processor.
+ @param firstChannel The first channel number.
+ @param data The buffer.
+ @param channelCount The number of interleaved channels in the buffer. If
+ channelCount is zero, the number of channels specified to
+ PaUtil_InitializeBufferProcessor will be used.
+*/
+void PaUtil_SetInterleavedOutputChannels( PaUtilBufferProcessor* bufferProcessor,
+        unsigned int firstChannel, void *data, unsigned int channelCount );
+
+        
+/** Provide the buffer processor with a pointer to one non-interleaved host
+ output channel.
+
+ @param bufferProcessor The buffer processor.
+ @param channel The channel number.
+ @param data The buffer.
+*/
+void PaUtil_SetNonInterleavedOutputChannel( PaUtilBufferProcessor* bufferProcessor,
+        unsigned int channel, void *data );
+
+
+/** Use for the second buffer half when the output buffer is split in two halves.
+ @see PaUtil_SetOutputFrameCount
+*/
+void PaUtil_Set2ndOutputFrameCount( PaUtilBufferProcessor* bufferProcessor,
+        unsigned long frameCount );
+
+/** Use for the second buffer half when the output buffer is split in two halves.
+ @see PaUtil_SetOutputChannel
+*/
+void PaUtil_Set2ndOutputChannel( PaUtilBufferProcessor* bufferProcessor,
+        unsigned int channel, void *data, unsigned int stride );
+
+/** Use for the second buffer half when the output buffer is split in two halves.
+ @see PaUtil_SetInterleavedOutputChannels
+*/
+void PaUtil_Set2ndInterleavedOutputChannels( PaUtilBufferProcessor* bufferProcessor,
+        unsigned int firstChannel, void *data, unsigned int channelCount );
+
+/** Use for the second buffer half when the output buffer is split in two halves.
+ @see PaUtil_SetNonInterleavedOutputChannel
+*/
+void PaUtil_Set2ndNonInterleavedOutputChannel( PaUtilBufferProcessor* bufferProcessor,
+        unsigned int channel, void *data );
+
+/*@}*/
+
+
+/** @name Buffer processing functions for callback streams
+*/
+/*@{*/
+
+/** Commence processing a host buffer (or a pair of host buffers in the
+ full-duplex case) for a callback stream.
+
+ @param bufferProcessor The buffer processor.
+
+ @param timeInfo Timing information for the first sample of the host
+ buffer(s). This information may be adjusted when buffer adaption is being
+ performed.
+
+ @param callbackStatusFlags Flags indicating whether underruns and overruns
+ have occurred since the last time the buffer processor was called.
+*/
+void PaUtil_BeginBufferProcessing( PaUtilBufferProcessor* bufferProcessor,
+        PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags callbackStatusFlags );
+
+        
+/** Finish processing a host buffer (or a pair of host buffers in the
+ full-duplex case) for a callback stream.
+
+ @param bufferProcessor The buffer processor.
+ @param callbackResult On input, indicates a previous callback result, and on
+ exit, the result of the user stream callback, if it is called.
+ On entry callbackResult should contain one of { paContinue, paComplete, or
+ paAbort}. If paComplete is passed, the stream callback will not be called
+ but any audio that was generated by previous stream callbacks will be copied
+ to the output buffer(s). You can check whether the buffer processor's internal
+ buffer is empty by calling PaUtil_IsBufferProcessorOutputEmpty.
+
+ If the stream callback is called its result is stored in *callbackResult. If
+ the stream callback returns paComplete or paAbort, all output buffers will be
+ full of valid data - some of which may be zeros to acount for data that
+ wasn't generated by the terminating callback.
+
+ @return The number of frames processed. This usually corresponds to the
+ number of frames specified by the PaUtil_Set*FrameCount functions, exept in
+ the paUtilVariableHostBufferSizePartialUsageAllowed buffer size mode when a
+ smaller value may be returned.
+*/
+unsigned long PaUtil_EndBufferProcessing( PaUtilBufferProcessor* bufferProcessor,
+        int *callbackResult );
+
+
+/** Determine whether any callback generated output remains in the bufffer
+ processor's internal buffers. This method may be used to determine when to
+ continue calling PaUtil_EndBufferProcessing() after the callback has returned
+ a callbackResult of paComplete.
+
+ @param bufferProcessor The buffer processor.
+ @return Returns non-zero when callback generated output remains in the internal
+ buffer and zero (0) when there internal buffer contains no callback generated
+ data.
+*/
+int PaUtil_IsBufferProcessorOutputEmpty( PaUtilBufferProcessor* bufferProcessor );
+
+/*@}*/
+
+
+/** @name Buffer processing functions for blocking read/write streams
+*/
+/*@{*/
+
+/** Copy samples from host input channels set up by the PaUtil_Set*InputChannels
+ functions to a user supplied buffer. This function is intended for use with
+ blocking read/write streams. Copies the minimum of the number of
+ user frames (specified by the frameCount parameter) and the number of available
+ host frames (specified in a previous call to SetInputFrameCount()).
+
+ @param bufferProcessor The buffer processor.
+
+ @param buffer A pointer to the user buffer pointer, or a pointer to a pointer
+ to an array of user buffer pointers for a non-interleaved stream. It is
+ important that this parameter points to a copy of the user buffer pointers,
+ not to the actual user buffer pointers, because this function updates the
+ pointers before returning.
+
+ @param frameCount The number of frames of data in the buffer(s) pointed to by
+ the buffer parameter.
+
+ @return The number of frames copied. The buffer pointer(s) pointed to by the
+ buffer parameter are advanced to point to the frame(s) following the last one
+ filled.
+*/
+unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bufferProcessor,
+        void **buffer, unsigned long frameCount );
+
+
+/* Copy samples from a user supplied buffer to host output channels set up by
+ the PaUtil_Set*OutputChannels functions. This function is intended for use with
+ blocking read/write streams. Copies the minimum of the number of
+ user frames (specified by the frameCount parameter) and the number of
+ host frames (specified in a previous call to SetOutputFrameCount()).
+
+ @param bufferProcessor The buffer processor.
+
+ @param buffer A pointer to the user buffer pointer, or a pointer to a pointer
+ to an array of user buffer pointers for a non-interleaved stream. It is
+ important that this parameter points to a copy of the user buffer pointers,
+ not to the actual user buffer pointers, because this function updates the
+ pointers before returning.
+
+ @param frameCount The number of frames of data in the buffer(s) pointed to by
+ the buffer parameter.
+
+ @return The number of frames copied. The buffer pointer(s) pointed to by the
+ buffer parameter are advanced to point to the frame(s) following the last one
+ copied.
+*/
+unsigned long PaUtil_CopyOutput( PaUtilBufferProcessor* bufferProcessor,
+        const void ** buffer, unsigned long frameCount );
+
+
+/* Zero samples in host output channels set up by the PaUtil_Set*OutputChannels
+ functions. This function is useful for flushing streams.
+ Zeros the minimum of frameCount and the number of host frames specified in a
+ previous call to SetOutputFrameCount().
+
+ @param bufferProcessor The buffer processor.
+
+ @param frameCount The maximum number of frames to zero.
+ @return The number of frames zeroed.
+*/
+unsigned long PaUtil_ZeroOutput( PaUtilBufferProcessor* bufferProcessor,
+        unsigned long frameCount );
+
+
+/*@}*/
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* PA_PROCESS_H */
diff --git a/utils/iaxclient/lib/portaudio/src/common/pa_skeleton.c b/utils/iaxclient/lib/portaudio/src/common/pa_skeleton.c
new file mode 100644 (file)
index 0000000..0c79b8f
--- /dev/null
@@ -0,0 +1,807 @@
+/*
+ * $Id: pa_skeleton.c,v 1.1 2006/06/10 21:30:55 dmazzoni Exp $
+ * Portable Audio I/O Library skeleton implementation
+ * demonstrates how to use the common functions to implement support
+ * for a host API
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2002 Ross Bencina, Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file
+ @brief Skeleton implementation of support for a host API.
+
+ @note This file is provided as a starting point for implementing support for
+ a new host API. IMPLEMENT ME comments are used to indicate functionality
+ which much be customised for each implementation.
+*/
+
+
+#include <string.h> /* strlen() */
+
+#include "pa_util.h"
+#include "pa_allocation.h"
+#include "pa_hostapi.h"
+#include "pa_stream.h"
+#include "pa_cpuload.h"
+#include "pa_process.h"
+
+
+/* prototypes for functions declared in this file */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+static void Terminate( struct PaUtilHostApiRepresentation *hostApi );
+static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
+                                  const PaStreamParameters *inputParameters,
+                                  const PaStreamParameters *outputParameters,
+                                  double sampleRate );
+static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
+                           PaStream** s,
+                           const PaStreamParameters *inputParameters,
+                           const PaStreamParameters *outputParameters,
+                           double sampleRate,
+                           unsigned long framesPerBuffer,
+                           PaStreamFlags streamFlags,
+                           PaStreamCallback *streamCallback,
+                           void *userData );
+static PaError CloseStream( PaStream* stream );
+static PaError StartStream( PaStream *stream );
+static PaError StopStream( PaStream *stream );
+static PaError AbortStream( PaStream *stream );
+static PaError IsStreamStopped( PaStream *s );
+static PaError IsStreamActive( PaStream *stream );
+static PaTime GetStreamTime( PaStream *stream );
+static double GetStreamCpuLoad( PaStream* stream );
+static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames );
+static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames );
+static signed long GetStreamReadAvailable( PaStream* stream );
+static signed long GetStreamWriteAvailable( PaStream* stream );
+
+
+/* IMPLEMENT ME: a macro like the following one should be used for reporting
+ host errors */
+#define PA_SKELETON_SET_LAST_HOST_ERROR( errorCode, errorText ) \
+    PaUtil_SetLastHostErrorInfo( paInDevelopment, errorCode, errorText )
+
+/* PaSkeletonHostApiRepresentation - host api datastructure specific to this implementation */
+
+typedef struct
+{
+    PaUtilHostApiRepresentation inheritedHostApiRep;
+    PaUtilStreamInterface callbackStreamInterface;
+    PaUtilStreamInterface blockingStreamInterface;
+
+    PaUtilAllocationGroup *allocations;
+
+    /* implementation specific data goes here */
+}
+PaSkeletonHostApiRepresentation;  /* IMPLEMENT ME: rename this */
+
+
+PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
+{
+    PaError result = paNoError;
+    int i, deviceCount;
+    PaSkeletonHostApiRepresentation *skeletonHostApi;
+    PaDeviceInfo *deviceInfoArray;
+
+    skeletonHostApi = (PaSkeletonHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaSkeletonHostApiRepresentation) );
+    if( !skeletonHostApi )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+
+    skeletonHostApi->allocations = PaUtil_CreateAllocationGroup();
+    if( !skeletonHostApi->allocations )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+
+    *hostApi = &skeletonHostApi->inheritedHostApiRep;
+    (*hostApi)->info.structVersion = 1;
+    (*hostApi)->info.type = paInDevelopment;            /* IMPLEMENT ME: change to correct type id */
+    (*hostApi)->info.name = "skeleton implementation";  /* IMPLEMENT ME: change to correct name */
+
+    (*hostApi)->info.defaultInputDevice = paNoDevice;  /* IMPLEMENT ME */
+    (*hostApi)->info.defaultOutputDevice = paNoDevice; /* IMPLEMENT ME */
+
+    (*hostApi)->info.deviceCount = 0;  
+
+    deviceCount = 0; /* IMPLEMENT ME */
+    
+    if( deviceCount > 0 )
+    {
+        (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
+                skeletonHostApi->allocations, sizeof(PaDeviceInfo*) * deviceCount );
+        if( !(*hostApi)->deviceInfos )
+        {
+            result = paInsufficientMemory;
+            goto error;
+        }
+
+        /* allocate all device info structs in a contiguous block */
+        deviceInfoArray = (PaDeviceInfo*)PaUtil_GroupAllocateMemory(
+                skeletonHostApi->allocations, sizeof(PaDeviceInfo) * deviceCount );
+        if( !deviceInfoArray )
+        {
+            result = paInsufficientMemory;
+            goto error;
+        }
+
+        for( i=0; i < deviceCount; ++i )
+        {
+            PaDeviceInfo *deviceInfo = &deviceInfoArray[i];
+            deviceInfo->structVersion = 2;
+            deviceInfo->hostApi = hostApiIndex;
+            deviceInfo->name = 0; /* IMPLEMENT ME: allocate block and copy name eg:
+                deviceName = (char*)PaUtil_GroupAllocateMemory( skeletonHostApi->allocations, strlen(srcName) + 1 );
+                if( !deviceName )
+                {
+                    result = paInsufficientMemory;
+                    goto error;
+                }
+                strcpy( deviceName, srcName );
+                deviceInfo->name = deviceName;
+            */
+
+            deviceInfo->maxInputChannels = 0;  /* IMPLEMENT ME */
+            deviceInfo->maxOutputChannels = 0;  /* IMPLEMENT ME */
+            
+            deviceInfo->defaultLowInputLatency = 0.;  /* IMPLEMENT ME */
+            deviceInfo->defaultLowOutputLatency = 0.;  /* IMPLEMENT ME */
+            deviceInfo->defaultHighInputLatency = 0.;  /* IMPLEMENT ME */
+            deviceInfo->defaultHighOutputLatency = 0.;  /* IMPLEMENT ME */  
+
+            deviceInfo->defaultSampleRate = 0.; /* IMPLEMENT ME */
+            
+            (*hostApi)->deviceInfos[i] = deviceInfo;
+            ++(*hostApi)->info.deviceCount;
+        }
+    }
+
+    (*hostApi)->Terminate = Terminate;
+    (*hostApi)->OpenStream = OpenStream;
+    (*hostApi)->IsFormatSupported = IsFormatSupported;
+
+    PaUtil_InitializeStreamInterface( &skeletonHostApi->callbackStreamInterface, CloseStream, StartStream,
+                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
+                                      GetStreamTime, GetStreamCpuLoad,
+                                      PaUtil_DummyRead, PaUtil_DummyWrite,
+                                      PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable );
+
+    PaUtil_InitializeStreamInterface( &skeletonHostApi->blockingStreamInterface, CloseStream, StartStream,
+                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
+                                      GetStreamTime, PaUtil_DummyGetCpuLoad,
+                                      ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );
+
+    return result;
+
+error:
+    if( skeletonHostApi )
+    {
+        if( skeletonHostApi->allocations )
+        {
+            PaUtil_FreeAllAllocations( skeletonHostApi->allocations );
+            PaUtil_DestroyAllocationGroup( skeletonHostApi->allocations );
+        }
+                
+        PaUtil_FreeMemory( skeletonHostApi );
+    }
+    return result;
+}
+
+
+static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
+{
+    PaSkeletonHostApiRepresentation *skeletonHostApi = (PaSkeletonHostApiRepresentation*)hostApi;
+
+    /*
+        IMPLEMENT ME:
+            - clean up any resources not handled by the allocation group
+    */
+
+    if( skeletonHostApi->allocations )
+    {
+        PaUtil_FreeAllAllocations( skeletonHostApi->allocations );
+        PaUtil_DestroyAllocationGroup( skeletonHostApi->allocations );
+    }
+
+    PaUtil_FreeMemory( skeletonHostApi );
+}
+
+
+static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
+                                  const PaStreamParameters *inputParameters,
+                                  const PaStreamParameters *outputParameters,
+                                  double sampleRate )
+{
+    int inputChannelCount, outputChannelCount;
+    PaSampleFormat inputSampleFormat, outputSampleFormat;
+    
+    if( inputParameters )
+    {
+        inputChannelCount = inputParameters->channelCount;
+        inputSampleFormat = inputParameters->sampleFormat;
+
+        /* all standard sample formats are supported by the buffer adapter,
+            this implementation doesn't support any custom sample formats */
+        if( inputSampleFormat & paCustomFormat )
+            return paSampleFormatNotSupported;
+            
+        /* unless alternate device specification is supported, reject the use of
+            paUseHostApiSpecificDeviceSpecification */
+
+        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
+            return paInvalidDevice;
+
+        /* check that input device can support inputChannelCount */
+        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )
+            return paInvalidChannelCount;
+
+        /* validate inputStreamInfo */
+        if( inputParameters->hostApiSpecificStreamInfo )
+            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
+    }
+    else
+    {
+        inputChannelCount = 0;
+    }
+
+    if( outputParameters )
+    {
+        outputChannelCount = outputParameters->channelCount;
+        outputSampleFormat = outputParameters->sampleFormat;
+
+        /* all standard sample formats are supported by the buffer adapter,
+            this implementation doesn't support any custom sample formats */
+        if( outputSampleFormat & paCustomFormat )
+            return paSampleFormatNotSupported;
+            
+        /* unless alternate device specification is supported, reject the use of
+            paUseHostApiSpecificDeviceSpecification */
+
+        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
+            return paInvalidDevice;
+
+        /* check that output device can support outputChannelCount */
+        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )
+            return paInvalidChannelCount;
+
+        /* validate outputStreamInfo */
+        if( outputParameters->hostApiSpecificStreamInfo )
+            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
+    }
+    else
+    {
+        outputChannelCount = 0;
+    }
+    
+    /*
+        IMPLEMENT ME:
+
+            - if a full duplex stream is requested, check that the combination
+                of input and output parameters is supported if necessary
+
+            - check that the device supports sampleRate
+
+        Because the buffer adapter handles conversion between all standard
+        sample formats, the following checks are only required if paCustomFormat
+        is implemented, or under some other unusual conditions.
+
+            - check that input device can support inputSampleFormat, or that
+                we have the capability to convert from inputSampleFormat to
+                a native format
+
+            - check that output device can support outputSampleFormat, or that
+                we have the capability to convert from outputSampleFormat to
+                a native format
+    */
+
+
+    /* suppress unused variable warnings */
+    (void) sampleRate;
+
+    return paFormatIsSupported;
+}
+
+/* PaSkeletonStream - a stream data structure specifically for this implementation */
+
+typedef struct PaSkeletonStream
+{ /* IMPLEMENT ME: rename this */
+    PaUtilStreamRepresentation streamRepresentation;
+    PaUtilCpuLoadMeasurer cpuLoadMeasurer;
+    PaUtilBufferProcessor bufferProcessor;
+
+    /* IMPLEMENT ME:
+            - implementation specific data goes here
+    */
+    unsigned long framesPerHostCallback; /* just an example */
+}
+PaSkeletonStream;
+
+/* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */
+
+static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
+                           PaStream** s,
+                           const PaStreamParameters *inputParameters,
+                           const PaStreamParameters *outputParameters,
+                           double sampleRate,
+                           unsigned long framesPerBuffer,
+                           PaStreamFlags streamFlags,
+                           PaStreamCallback *streamCallback,
+                           void *userData )
+{
+    PaError result = paNoError;
+    PaSkeletonHostApiRepresentation *skeletonHostApi = (PaSkeletonHostApiRepresentation*)hostApi;
+    PaSkeletonStream *stream = 0;
+    unsigned long framesPerHostBuffer = framesPerBuffer; /* these may not be equivalent for all implementations */
+    int inputChannelCount, outputChannelCount;
+    PaSampleFormat inputSampleFormat, outputSampleFormat;
+    PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat;
+
+
+    if( inputParameters )
+    {
+        inputChannelCount = inputParameters->channelCount;
+        inputSampleFormat = inputParameters->sampleFormat;
+
+        /* unless alternate device specification is supported, reject the use of
+            paUseHostApiSpecificDeviceSpecification */
+
+        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
+            return paInvalidDevice;
+
+        /* check that input device can support inputChannelCount */
+        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )
+            return paInvalidChannelCount;
+
+        /* validate inputStreamInfo */
+        if( inputParameters->hostApiSpecificStreamInfo )
+            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
+
+        /* IMPLEMENT ME - establish which  host formats are available */
+        hostInputSampleFormat =
+            PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, inputSampleFormat );
+    }
+    else
+    {
+        inputChannelCount = 0;
+        inputSampleFormat = hostInputSampleFormat = paInt16; /* Surpress 'uninitialised var' warnings. */
+    }
+
+    if( outputParameters )
+    {
+        outputChannelCount = outputParameters->channelCount;
+        outputSampleFormat = outputParameters->sampleFormat;
+        
+        /* unless alternate device specification is supported, reject the use of
+            paUseHostApiSpecificDeviceSpecification */
+
+        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
+            return paInvalidDevice;
+
+        /* check that output device can support inputChannelCount */
+        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )
+            return paInvalidChannelCount;
+
+        /* validate outputStreamInfo */
+        if( outputParameters->hostApiSpecificStreamInfo )
+            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
+
+        /* IMPLEMENT ME - establish which  host formats are available */
+        hostOutputSampleFormat =
+            PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, outputSampleFormat );
+    }
+    else
+    {
+        outputChannelCount = 0;
+        outputSampleFormat = hostOutputSampleFormat = paInt16; /* Surpress 'uninitialized var' warnings. */
+    }
+
+    /*
+        IMPLEMENT ME:
+
+        ( the following two checks are taken care of by PaUtil_InitializeBufferProcessor() FIXME - checks needed? )
+
+            - check that input device can support inputSampleFormat, or that
+                we have the capability to convert from outputSampleFormat to
+                a native format
+
+            - check that output device can support outputSampleFormat, or that
+                we have the capability to convert from outputSampleFormat to
+                a native format
+
+            - if a full duplex stream is requested, check that the combination
+                of input and output parameters is supported
+
+            - check that the device supports sampleRate
+
+            - alter sampleRate to a close allowable rate if possible / necessary
+
+            - validate suggestedInputLatency and suggestedOutputLatency parameters,
+                use default values where necessary
+    */
+
+
+
+
+    /* validate platform specific flags */
+    if( (streamFlags & paPlatformSpecificFlags) != 0 )
+        return paInvalidFlag; /* unexpected platform specific flag */
+
+
+    stream = (PaSkeletonStream*)PaUtil_AllocateMemory( sizeof(PaSkeletonStream) );
+    if( !stream )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+
+    if( streamCallback )
+    {
+        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
+                                               &skeletonHostApi->callbackStreamInterface, streamCallback, userData );
+    }
+    else
+    {
+        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
+                                               &skeletonHostApi->blockingStreamInterface, streamCallback, userData );
+    }
+
+    PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );
+
+
+    /* we assume a fixed host buffer size in this example, but the buffer processor
+        can also support bounded and unknown host buffer sizes by passing 
+        paUtilBoundedHostBufferSize or paUtilUnknownHostBufferSize instead of
+        paUtilFixedHostBufferSize below. */
+        
+    result =  PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
+              inputChannelCount, inputSampleFormat, hostInputSampleFormat,
+              outputChannelCount, outputSampleFormat, hostOutputSampleFormat,
+              sampleRate, streamFlags, framesPerBuffer,
+              framesPerHostBuffer, paUtilFixedHostBufferSize,
+              streamCallback, userData );
+    if( result != paNoError )
+        goto error;
+
+
+    /*
+        IMPLEMENT ME: initialise the following fields with estimated or actual
+        values.
+    */
+    stream->streamRepresentation.streamInfo.inputLatency =
+            PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor);
+    stream->streamRepresentation.streamInfo.outputLatency =
+            PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor);
+    stream->streamRepresentation.streamInfo.sampleRate = sampleRate;
+
+    
+    /*
+        IMPLEMENT ME:
+            - additional stream setup + opening
+    */
+
+    stream->framesPerHostCallback = framesPerHostBuffer;
+
+    *s = (PaStream*)stream;
+
+    return result;
+
+error:
+    if( stream )
+        PaUtil_FreeMemory( stream );
+
+    return result;
+}
+
+/*
+    ExampleHostProcessingLoop() illustrates the kind of processing which may
+    occur in a host implementation.
+*/
+static void ExampleHostProcessingLoop( void *inputBuffer, void *outputBuffer, void *userData )
+{
+    PaSkeletonStream *stream = (PaSkeletonStream*)userData;
+    PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /* IMPLEMENT ME */
+    int callbackResult;
+    unsigned long framesProcessed;
+    
+    PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
+    
+    /*
+        IMPLEMENT ME:
+            - generate timing information
+            - handle buffer slips
+    */
+
+    /*
+        If you need to byte swap or shift inputBuffer to convert it into a
+        portaudio format, do it here.
+    */
+
+
+
+    PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, 0 /* IMPLEMENT ME: pass underflow/overflow flags when necessary */ );
+
+    /*
+        depending on whether the host buffers are interleaved, non-interleaved
+        or a mixture, you will want to call PaUtil_SetInterleaved*Channels(),
+        PaUtil_SetNonInterleaved*Channel() or PaUtil_Set*Channel() here.
+    */
+    
+    PaUtil_SetInputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ );
+    PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor,
+            0, /* first channel of inputBuffer is channel 0 */
+            inputBuffer,
+            0 ); /* 0 - use inputChannelCount passed to init buffer processor */
+
+    PaUtil_SetOutputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ );
+    PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor,
+            0, /* first channel of outputBuffer is channel 0 */
+            outputBuffer,
+            0 ); /* 0 - use outputChannelCount passed to init buffer processor */
+
+    /* you must pass a valid value of callback result to PaUtil_EndBufferProcessing()
+        in general you would pass paContinue for normal operation, and
+        paComplete to drain the buffer processor's internal output buffer.
+        You can check whether the buffer processor's output buffer is empty
+        using PaUtil_IsBufferProcessorOuputEmpty( bufferProcessor )
+    */
+    callbackResult = paContinue;
+    framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult );
+
+    
+    /*
+        If you need to byte swap or shift outputBuffer to convert it to
+        host format, do it here.
+    */
+
+    PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed );
+
+
+    if( callbackResult == paContinue )
+    {
+        /* nothing special to do */
+    }
+    else if( callbackResult == paAbort )
+    {
+        /* IMPLEMENT ME - finish playback immediately  */
+
+        /* once finished, call the finished callback */
+        if( stream->streamRepresentation.streamFinishedCallback != 0 )
+            stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
+    }
+    else
+    {
+        /* User callback has asked us to stop with paComplete or other non-zero value */
+
+        /* IMPLEMENT ME - finish playback once currently queued audio has completed  */
+
+        /* once finished, call the finished callback */
+        if( stream->streamRepresentation.streamFinishedCallback != 0 )
+            stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
+    }
+}
+
+
+/*
+    When CloseStream() is called, the multi-api layer ensures that
+    the stream has already been stopped or aborted.
+*/
+static PaError CloseStream( PaStream* s )
+{
+    PaError result = paNoError;
+    PaSkeletonStream *stream = (PaSkeletonStream*)s;
+
+    /*
+        IMPLEMENT ME:
+            - additional stream closing + cleanup
+    */
+
+    PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
+    PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
+    PaUtil_FreeMemory( stream );
+
+    return result;
+}
+
+
+static PaError StartStream( PaStream *s )
+{
+    PaError result = paNoError;
+    PaSkeletonStream *stream = (PaSkeletonStream*)s;
+
+    PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
+
+    /* IMPLEMENT ME, see portaudio.h for required behavior */
+
+    /* suppress unused function warning. the code in ExampleHostProcessingLoop or
+       something similar should be implemented to feed samples to and from the
+       host after StartStream() is called.
+    */
+    (void) ExampleHostProcessingLoop;
+
+    return result;
+}
+
+
+static PaError StopStream( PaStream *s )
+{
+    PaError result = paNoError;
+    PaSkeletonStream *stream = (PaSkeletonStream*)s;
+
+    /* suppress unused variable warnings */
+    (void) stream;
+
+    /* IMPLEMENT ME, see portaudio.h for required behavior */
+
+    return result;
+}
+
+
+static PaError AbortStream( PaStream *s )
+{
+    PaError result = paNoError;
+    PaSkeletonStream *stream = (PaSkeletonStream*)s;
+
+    /* suppress unused variable warnings */
+    (void) stream;
+    
+    /* IMPLEMENT ME, see portaudio.h for required behavior */
+
+    return result;
+}
+
+
+static PaError IsStreamStopped( PaStream *s )
+{
+    PaSkeletonStream *stream = (PaSkeletonStream*)s;
+
+    /* suppress unused variable warnings */
+    (void) stream;
+    
+    /* IMPLEMENT ME, see portaudio.h for required behavior */
+
+    return 0;
+}
+
+
+static PaError IsStreamActive( PaStream *s )
+{
+    PaSkeletonStream *stream = (PaSkeletonStream*)s;
+
+    /* suppress unused variable warnings */
+    (void) stream;
+    
+    /* IMPLEMENT ME, see portaudio.h for required behavior */
+
+    return 0;
+}
+
+
+static PaTime GetStreamTime( PaStream *s )
+{
+    PaSkeletonStream *stream = (PaSkeletonStream*)s;
+
+    /* suppress unused variable warnings */
+    (void) stream;
+    
+    /* IMPLEMENT ME, see portaudio.h for required behavior*/
+
+    return 0;
+}
+
+
+static double GetStreamCpuLoad( PaStream* s )
+{
+    PaSkeletonStream *stream = (PaSkeletonStream*)s;
+
+    return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
+}
+
+
+/*
+    As separate stream interfaces are used for blocking and callback
+    streams, the following functions can be guaranteed to only be called
+    for blocking streams.
+*/
+
+static PaError ReadStream( PaStream* s,
+                           void *buffer,
+                           unsigned long frames )
+{
+    PaSkeletonStream *stream = (PaSkeletonStream*)s;
+
+    /* suppress unused variable warnings */
+    (void) buffer;
+    (void) frames;
+    (void) stream;
+    
+    /* IMPLEMENT ME, see portaudio.h for required behavior*/
+
+    return paNoError;
+}
+
+
+static PaError WriteStream( PaStream* s,
+                            const void *buffer,
+                            unsigned long frames )
+{
+    PaSkeletonStream *stream = (PaSkeletonStream*)s;
+
+    /* suppress unused variable warnings */
+    (void) buffer;
+    (void) frames;
+    (void) stream;
+    
+    /* IMPLEMENT ME, see portaudio.h for required behavior*/
+
+    return paNoError;
+}
+
+
+static signed long GetStreamReadAvailable( PaStream* s )
+{
+    PaSkeletonStream *stream = (PaSkeletonStream*)s;
+
+    /* suppress unused variable warnings */
+    (void) stream;
+    
+    /* IMPLEMENT ME, see portaudio.h for required behavior*/
+
+    return 0;
+}
+
+
+static signed long GetStreamWriteAvailable( PaStream* s )
+{
+    PaSkeletonStream *stream = (PaSkeletonStream*)s;
+
+    /* suppress unused variable warnings */
+    (void) stream;
+    
+    /* IMPLEMENT ME, see portaudio.h for required behavior*/
+
+    return 0;
+}
+
+
+
+
diff --git a/utils/iaxclient/lib/portaudio/src/common/pa_stream.c b/utils/iaxclient/lib/portaudio/src/common/pa_stream.c
new file mode 100644 (file)
index 0000000..12a8d6b
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * $Id: pa_stream.c,v 1.1 2006/06/10 21:30:55 dmazzoni Exp $
+ * Portable Audio I/O Library
+ * 
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 2002 Ross Bencina
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file
+ @brief Interface used by pa_front to virtualize functions which operate on
+ streams.
+*/
+
+
+#include "pa_stream.h"
+
+
+void PaUtil_InitializeStreamInterface( PaUtilStreamInterface *streamInterface,
+                                       PaError (*Close)( PaStream* ),
+                                       PaError (*Start)( PaStream* ),
+                                       PaError (*Stop)( PaStream* ),
+                                       PaError (*Abort)( PaStream* ),
+                                       PaError (*IsStopped)( PaStream* ),
+                                       PaError (*IsActive)( PaStream* ),
+                                       PaTime (*GetTime)( PaStream* ),
+                                       double (*GetCpuLoad)( PaStream* ),
+                                       PaError (*Read)( PaStream*, void *, unsigned long ),
+                                       PaError (*Write)( PaStream*, const void *, unsigned long ),
+                                       signed long (*GetReadAvailable)( PaStream* ),
+                                       signed long (*GetWriteAvailable)( PaStream* )  )
+{
+    streamInterface->Close = Close;
+    streamInterface->Start = Start;
+    streamInterface->Stop = Stop;
+    streamInterface->Abort = Abort;
+    streamInterface->IsStopped = IsStopped;
+    streamInterface->IsActive = IsActive;
+    streamInterface->GetTime = GetTime;
+    streamInterface->GetCpuLoad = GetCpuLoad;
+    streamInterface->Read = Read;
+    streamInterface->Write = Write;
+    streamInterface->GetReadAvailable = GetReadAvailable;
+    streamInterface->GetWriteAvailable = GetWriteAvailable;
+}
+
+
+void PaUtil_InitializeStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation,
+        PaUtilStreamInterface *streamInterface,
+        PaStreamCallback *streamCallback,
+        void *userData )
+{
+    streamRepresentation->magic = PA_STREAM_MAGIC;
+    streamRepresentation->nextOpenStream = 0;
+    streamRepresentation->streamInterface = streamInterface;
+    streamRepresentation->streamCallback = streamCallback;
+    streamRepresentation->streamFinishedCallback = 0;
+
+    streamRepresentation->userData = userData;
+
+    streamRepresentation->streamInfo.inputLatency = 0.;
+    streamRepresentation->streamInfo.outputLatency = 0.;
+    streamRepresentation->streamInfo.sampleRate = 0.;
+}
+
+
+void PaUtil_TerminateStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation )
+{
+    streamRepresentation->magic = 0;
+}
+
+
+PaError PaUtil_DummyRead( PaStream* stream,
+                               void *buffer,
+                               unsigned long frames )
+{
+    (void)stream; /* unused parameter */
+    (void)buffer; /* unused parameter */
+    (void)frames; /* unused parameter */
+
+    return paCanNotReadFromACallbackStream;
+}
+
+
+PaError PaUtil_DummyWrite( PaStream* stream,
+                               const void *buffer,
+                               unsigned long frames )
+{
+    (void)stream; /* unused parameter */
+    (void)buffer; /* unused parameter */
+    (void)frames; /* unused parameter */
+
+    return paCanNotWriteToACallbackStream;
+}
+
+
+signed long PaUtil_DummyGetReadAvailable( PaStream* stream )
+{
+    (void)stream; /* unused parameter */
+
+    return paCanNotReadFromACallbackStream;
+}
+
+
+signed long PaUtil_DummyGetWriteAvailable( PaStream* stream )
+{
+    (void)stream; /* unused parameter */
+
+    return paCanNotWriteToACallbackStream;
+}
+
+
+double PaUtil_DummyGetCpuLoad( PaStream* stream )
+{
+    (void)stream; /* unused parameter */
+
+    return 0.0;
+}
diff --git a/utils/iaxclient/lib/portaudio/src/common/pa_stream.h b/utils/iaxclient/lib/portaudio/src/common/pa_stream.h
new file mode 100644 (file)
index 0000000..a660aa9
--- /dev/null
@@ -0,0 +1,196 @@
+#ifndef PA_STREAM_H
+#define PA_STREAM_H
+/*
+ * $Id: pa_stream.h,v 1.1 2006/06/10 21:30:55 dmazzoni Exp $
+ * Portable Audio I/O Library
+ * stream interface
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2002 Ross Bencina, Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file
+ @brief Interface used by pa_front to virtualize functions which operate on
+ streams.
+*/
+
+
+#include "portaudio.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+
+#define PA_STREAM_MAGIC (0x18273645)
+
+
+/** A structure representing an (abstract) interface to a host API. Contains
+ pointers to functions which implement the interface.
+
+ All PaStreamInterface functions are guaranteed to be called with a non-null,
+ valid stream parameter.
+*/
+typedef struct {
+    PaError (*Close)( PaStream* stream );
+    PaError (*Start)( PaStream *stream );
+    PaError (*Stop)( PaStream *stream );
+    PaError (*Abort)( PaStream *stream );
+    PaError (*IsStopped)( PaStream *stream );
+    PaError (*IsActive)( PaStream *stream );
+    PaTime (*GetTime)( PaStream *stream );
+    double (*GetCpuLoad)( PaStream* stream );
+    PaError (*Read)( PaStream* stream, void *buffer, unsigned long frames );
+    PaError (*Write)( PaStream* stream, const void *buffer, unsigned long frames );
+    signed long (*GetReadAvailable)( PaStream* stream );
+    signed long (*GetWriteAvailable)( PaStream* stream );
+} PaUtilStreamInterface;
+
+
+/** Initialize the fields of a PaUtilStreamInterface structure.
+*/
+void PaUtil_InitializeStreamInterface( PaUtilStreamInterface *streamInterface,
+    PaError (*Close)( PaStream* ),
+    PaError (*Start)( PaStream* ),
+    PaError (*Stop)( PaStream* ),
+    PaError (*Abort)( PaStream* ),
+    PaError (*IsStopped)( PaStream* ),
+    PaError (*IsActive)( PaStream* ),
+    PaTime (*GetTime)( PaStream* ),
+    double (*GetCpuLoad)( PaStream* ),
+    PaError (*Read)( PaStream* stream, void *buffer, unsigned long frames ),
+    PaError (*Write)( PaStream* stream, const void *buffer, unsigned long frames ),
+    signed long (*GetReadAvailable)( PaStream* stream ),
+    signed long (*GetWriteAvailable)( PaStream* stream ) );
+
+
+/** Dummy Read function for use in interfaces to a callback based streams.
+ Pass to the Read parameter of PaUtil_InitializeStreamInterface.
+ @return An error code indicating that the function has no effect
+ because the stream is a callback stream.
+*/
+PaError PaUtil_DummyRead( PaStream* stream,
+                       void *buffer,
+                       unsigned long frames );
+
+
+/** Dummy Write function for use in an interfaces to callback based streams.
+ Pass to the Write parameter of PaUtil_InitializeStreamInterface.
+ @return An error code indicating that the function has no effect
+ because the stream is a callback stream.
+*/
+PaError PaUtil_DummyWrite( PaStream* stream,
+                       const void *buffer,
+                       unsigned long frames );
+
+
+/** Dummy GetReadAvailable function for use in interfaces to callback based
+ streams. Pass to the GetReadAvailable parameter of PaUtil_InitializeStreamInterface.
+ @return An error code indicating that the function has no effect
+ because the stream is a callback stream.
+*/
+signed long PaUtil_DummyGetReadAvailable( PaStream* stream );
+
+
+/** Dummy GetWriteAvailable function for use in interfaces to callback based
+ streams. Pass to the GetWriteAvailable parameter of PaUtil_InitializeStreamInterface.
+ @return An error code indicating that the function has no effect
+ because the stream is a callback stream.
+*/
+signed long PaUtil_DummyGetWriteAvailable( PaStream* stream );
+
+
+
+/** Dummy GetCpuLoad function for use in an interface to a read/write stream.
+ Pass to the GetCpuLoad parameter of PaUtil_InitializeStreamInterface.
+ @return Returns 0.
+*/
+double PaUtil_DummyGetCpuLoad( PaStream* stream );
+
+
+/** Non host specific data for a stream. This data is used by pa_front to
+ forward to the appropriate functions in the streamInterface structure.
+*/
+typedef struct PaUtilStreamRepresentation {
+    unsigned long magic;    /**< set to PA_STREAM_MAGIC */
+    struct PaUtilStreamRepresentation *nextOpenStream; /**< field used by multi-api code */
+    PaUtilStreamInterface *streamInterface;
+    PaStreamCallback *streamCallback;
+    PaStreamFinishedCallback *streamFinishedCallback;
+    void *userData;
+    PaStreamInfo streamInfo;
+} PaUtilStreamRepresentation;
+
+
+/** Initialize a PaUtilStreamRepresentation structure.
+
+ @see PaUtil_InitializeStreamRepresentation
+*/
+void PaUtil_InitializeStreamRepresentation(
+        PaUtilStreamRepresentation *streamRepresentation,
+        PaUtilStreamInterface *streamInterface,
+        PaStreamCallback *streamCallback,
+        void *userData );
+        
+
+/** Clean up a PaUtilStreamRepresentation structure previously initialized
+ by a call to PaUtil_InitializeStreamRepresentation.
+
+ @see PaUtil_InitializeStreamRepresentation
+*/
+void PaUtil_TerminateStreamRepresentation( PaUtilStreamRepresentation *streamRepresentation );
+
+
+/** Check that the stream pointer is valid.
+
+ @return Returns paNoError if the stream pointer appears to be OK, otherwise
+ returns an error indicating the cause of failure.
+*/
+PaError PaUtil_ValidateStreamPointer( PaStream *stream );
+
+
+/** Cast an opaque stream pointer into a pointer to a PaUtilStreamRepresentation.
+
+ @see PaUtilStreamRepresentation
+*/
+#define PA_STREAM_REP( stream )\
+    ((PaUtilStreamRepresentation*) (stream) )
+
+
+/** Cast an opaque stream pointer into a pointer to a PaUtilStreamInterface.
+
+ @see PaUtilStreamRepresentation, PaUtilStreamInterface
+*/
+#define PA_STREAM_INTERFACE( stream )\
+    PA_STREAM_REP( (stream) )->streamInterface
+
+
+    
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* PA_STREAM_H */
diff --git a/utils/iaxclient/lib/portaudio/src/common/pa_trace.c b/utils/iaxclient/lib/portaudio/src/common/pa_trace.c
new file mode 100644 (file)
index 0000000..b4f6191
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * $Id: pa_trace.c,v 1.1 2006/06/10 21:30:55 dmazzoni Exp $
+ * Portable Audio I/O Library Trace Facility
+ * Store trace information in real-time for later printing.
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2000 Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file
+ @brief Event trace mechanism for debugging.
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "pa_trace.h"
+
+#if PA_TRACE_REALTIME_EVENTS
+
+static char *traceTextArray[PA_MAX_TRACE_RECORDS];
+static int traceIntArray[PA_MAX_TRACE_RECORDS];
+static int traceIndex = 0;
+static int traceBlock = 0;
+
+/*********************************************************************/
+void PaUtil_ResetTraceMessages()
+{
+    traceIndex = 0;
+}
+
+/*********************************************************************/
+void PaUtil_DumpTraceMessages()
+{
+    int i;
+    int messageCount = (traceIndex < PA_MAX_TRACE_RECORDS) ? traceIndex : PA_MAX_TRACE_RECORDS;
+
+    printf("DumpTraceMessages: traceIndex = %d\n", traceIndex );
+    for( i=0; i<messageCount; i++ )
+    {
+        printf("%3d: %s = 0x%08X\n",
+               i, traceTextArray[i], traceIntArray[i] );
+    }
+    PaUtil_ResetTraceMessages();
+    fflush(stdout);
+}
+
+/*********************************************************************/
+void PaUtil_AddTraceMessage( const char *msg, int data )
+{
+    if( (traceIndex == PA_MAX_TRACE_RECORDS) && (traceBlock == 0) )
+    {
+        traceBlock = 1;
+        /*  PaUtil_DumpTraceMessages(); */
+    }
+    else if( traceIndex < PA_MAX_TRACE_RECORDS )
+    {
+        traceTextArray[traceIndex] = msg;
+        traceIntArray[traceIndex] = data;
+        traceIndex++;
+    }
+}
+
+#endif /* TRACE_REALTIME_EVENTS */
diff --git a/utils/iaxclient/lib/portaudio/src/common/pa_trace.h b/utils/iaxclient/lib/portaudio/src/common/pa_trace.h
new file mode 100644 (file)
index 0000000..ec41428
--- /dev/null
@@ -0,0 +1,70 @@
+#ifndef PA_TRACE_H
+#define PA_TRACE_H
+/*
+ * $Id: pa_trace.h,v 1.1 2006/06/10 21:30:55 dmazzoni Exp $
+ * Portable Audio I/O Library Trace Facility
+ * Store trace information in real-time for later printing.
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2000 Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file
+ @brief Event trace mechanism for debugging.
+
+ Allows data to be written to the buffer at interrupt time and dumped later.
+*/
+
+
+#define PA_TRACE_REALTIME_EVENTS     (0)   /* Keep log of various real-time events. */
+#define PA_MAX_TRACE_RECORDS      (2048)
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+
+#if PA_TRACE_REALTIME_EVENTS
+
+void PaUtil_ResetTraceMessages();
+void PaUtil_AddTraceMessage( const char *msg, int data );
+void PaUtil_DumpTraceMessages();
+    
+#else
+
+#define PaUtil_ResetTraceMessages() /* noop */
+#define PaUtil_AddTraceMessage(msg,data) /* noop */
+#define PaUtil_DumpTraceMessages() /* noop */
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* PA_TRACE_H */
diff --git a/utils/iaxclient/lib/portaudio/src/common/pa_types.h b/utils/iaxclient/lib/portaudio/src/common/pa_types.h
new file mode 100644 (file)
index 0000000..343dc8c
--- /dev/null
@@ -0,0 +1,65 @@
+#ifndef PA_TYPES_H
+#define PA_TYPES_H
+
+/*
+    SIZEOF_SHORT, SIZEOF_INT and SIZEOF_LONG are set by the configure script
+    when it is used. Otherwise we default to the common 32 bit values, if your
+    platform doesn't use configure, and doesn't use the default values below
+    you will need to explicitly define these symbols in your make file.
+
+    A PA_VALIDATE_SIZES macro is provided to assert that the values set in this
+    file are correct.
+*/
+
+#ifndef SIZEOF_SHORT
+#define SIZEOF_SHORT 2
+#endif
+
+#ifndef SIZEOF_INT
+#define SIZEOF_INT 4
+#endif
+
+#ifndef SIZEOF_LONG
+#define SIZEOF_LONG 4
+#endif
+
+
+#if SIZEOF_SHORT == 2
+typedef signed short PaInt16;
+typedef unsigned short PaUint16;
+#elif SIZEOF_INT == 2
+typedef signed int PaInt16;
+typedef unsigned int PaUint16;
+#else
+#error pa_types.h was unable to determine which type to use for 16bit integers on the target platform
+#endif
+
+#if SIZEOF_SHORT == 4
+typedef signed short PaInt32;
+typedef unsigned short PaUint32;
+#elif SIZEOF_INT == 4
+typedef signed int PaInt32;
+typedef unsigned int PaUint32;
+#elif SIZEOF_LONG == 4
+typedef signed long PaInt32;
+typedef unsigned long PaUint32;
+#else
+#error pa_types.h was unable to determine which type to use for 32bit integers on the target platform
+#endif
+
+
+/* PA_VALIDATE_TYPE_SIZES compares the size of the integer types at runtime to
+ ensure that PortAudio was configured correctly, and raises an assertion if
+ they don't match the expected values. <assert.h> must be included in the
+ context in which this macro is used.
+*/
+#define PA_VALIDATE_TYPE_SIZES \
+    { \
+        assert( "PortAudio: type sizes are not correct in pa_types.h" && sizeof( PaUint16 ) == 2 ); \
+        assert( "PortAudio: type sizes are not correct in pa_types.h" && sizeof( PaInt16 ) == 2 ); \
+        assert( "PortAudio: type sizes are not correct in pa_types.h" && sizeof( PaUint32 ) == 4 ); \
+        assert( "PortAudio: type sizes are not correct in pa_types.h" && sizeof( PaInt32 ) == 4 ); \
+    }
+
+
+#endif /* PA_TYPES_H */
diff --git a/utils/iaxclient/lib/portaudio/src/common/pa_util.h b/utils/iaxclient/lib/portaudio/src/common/pa_util.h
new file mode 100644 (file)
index 0000000..f617615
--- /dev/null
@@ -0,0 +1,167 @@
+#ifndef PA_UTIL_H
+#define PA_UTIL_H
+/*
+ * $Id: pa_util.h,v 1.1 2006/06/10 21:30:55 dmazzoni Exp $
+ * Portable Audio I/O Library implementation utilities header
+ * common implementation utilities and interfaces
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2002 Ross Bencina, Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file
+    @brief Prototypes for utility functions used by PortAudio implementations.
+
+    @todo Document and adhere to the alignment guarantees provided by
+    PaUtil_AllocateMemory().
+*/
+
+
+#include "portaudio.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+
+struct PaUtilHostApiRepresentation;
+
+
+/** Retrieve a specific host API representation. This function can be used
+ by implementations to retrieve a pointer to their representation in
+ host api specific extension functions which aren't passed a rep pointer
+ by pa_front.c.
+
+ @param hostApi A pointer to a host API represenation pointer. Apon success
+ this will receive the requested representation pointer.
+
+ @param type A valid host API type identifier.
+
+ @returns An error code. If the result is PaNoError then a pointer to the
+ requested host API representation will be stored in *hostApi. If the host API
+ specified by type is not found, this function returns paHostApiNotFound.
+*/
+PaError PaUtil_GetHostApiRepresentation( struct PaUtilHostApiRepresentation **hostApi,
+        PaHostApiTypeId type );
+
+
+/** Convert a PortAudio device index into a host API specific device index.
+ @param hostApiDevice Pointer to a device index, on success this will recieve the
+ converted device index value.
+ @param device The PortAudio device index to convert.
+ @param hostApi The host api which the index should be converted for.
+
+ @returns On success returns PaNoError and places the converted index in the
+ hostApiDevice parameter.
+*/
+PaError PaUtil_DeviceIndexToHostApiDeviceIndex(
+        PaDeviceIndex *hostApiDevice, PaDeviceIndex device,
+        struct PaUtilHostApiRepresentation *hostApi );
+
+
+/** Set the host error information returned by Pa_GetLastHostErrorInfo. This
+ function and the paUnanticipatedHostError error code should be used as a
+ last resort.  Implementors should use existing PA error codes where possible,
+ or nominate new ones. Note that at it is always better to use
+ PaUtil_SetLastHostErrorInfo() and paUnanticipatedHostError than to return an
+ ambiguous or inaccurate PaError code.
+
+ @param hostApiType  The host API which encountered the error (ie of the caller)
+
+ @param errorCode The error code returned by the native API function.
+
+ @param errorText A string describing the error. PaUtil_SetLastHostErrorInfo
+ makes a copy of the string, so it is not necessary for the pointer to remain
+ valid after the call to PaUtil_SetLastHostErrorInfo() returns.
+
+*/
+void PaUtil_SetLastHostErrorInfo( PaHostApiTypeId hostApiType, long errorCode,
+        const char *errorText );
+
+
+        
+/** PA_DEBUG() provides a simple debug message printing facility. The macro
+ passes it's argument to a printf-like function called PaUtil_DebugPrint()
+ which prints to stderr and always flushes the stream after printing.
+ Because preprocessor macros cannot directly accept variable length argument
+ lists, calls to the macro must include an additional set of parenthesis, eg:
+ PA_DEBUG(("errorno: %d", 1001 ));
+*/
+
+void PaUtil_DebugPrint( const char *format, ... );
+
+#ifdef PA_ENABLE_DEBUG_OUTPUT
+#define PA_DEBUG(x) PaUtil_DebugPrint x ;
+#else
+#define PA_DEBUG(x)
+#endif
+
+
+/* the following functions are implemented in a platform platform specific
+ .c file
+*/
+
+/** Allocate size bytes, guaranteed to be aligned to a FIXME byte boundary */
+void *PaUtil_AllocateMemory( long size );
+
+
+/** Realease block if non-NULL. block may be NULL */
+void PaUtil_FreeMemory( void *block );
+
+
+/** Return the number of currently allocated blocks. This function can be
+ used for detecting memory leaks.
+
+ @note Allocations will only be tracked if PA_TRACK_MEMORY is #defined. If
+ it isn't, this function will always return 0.
+*/
+int PaUtil_CountCurrentlyAllocatedBlocks( void );
+
+
+/** Initialize the clock used by PaUtil_GetTime(). Call this before calling
+ PaUtil_GetTime.
+
+ @see PaUtil_GetTime
+*/
+void PaUtil_InitializeClock( void );
+
+
+/** Return the system time in seconds. Used to implement CPU load functions
+
+ @see PaUtil_InitializeClock
+*/
+double PaUtil_GetTime( void );
+
+
+/* void Pa_Sleep( long msec );  must also be implemented in per-platform .c file */
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* PA_UTIL_H */
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/alsa/pa_linux_alsa.c b/utils/iaxclient/lib/portaudio/src/hostapi/alsa/pa_linux_alsa.c
new file mode 100644 (file)
index 0000000..9923d5a
--- /dev/null
@@ -0,0 +1,3309 @@
+/*
+ * $Id: pa_linux_alsa.c,v 1.1 2006/06/10 21:30:55 dmazzoni Exp $
+ * PortAudio Portable Real-Time Audio Library
+ * Latest Version at: http://www.portaudio.com
+ * ALSA implementation by Joshua Haberman and Arve Knudsen
+ *
+ * Copyright (c) 2002 Joshua Haberman <joshua@haberman.com>
+ * Copyright (c) 2005-2006 Arve Knudsen <aknuds-1@broadpark.no>
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2002 Ross Bencina, Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#define ALSA_PCM_NEW_HW_PARAMS_API
+#define ALSA_PCM_NEW_SW_PARAMS_API
+#include <alsa/asoundlib.h>
+#undef ALSA_PCM_NEW_HW_PARAMS_API
+#undef ALSA_PCM_NEW_SW_PARAMS_API
+
+#include <sys/poll.h>
+#include <string.h> /* strlen() */
+#include <limits.h>
+#include <math.h>
+#include <pthread.h>
+#include <signal.h>
+#include <time.h>
+#include <sys/mman.h>
+#include <signal.h> /* For sig_atomic_t */
+
+#include "portaudio.h"
+#include "pa_util.h"
+#include "pa_unix_util.h"
+#include "pa_allocation.h"
+#include "pa_hostapi.h"
+#include "pa_stream.h"
+#include "pa_cpuload.h"
+#include "pa_process.h"
+
+#include "pa_linux_alsa.h"
+
+/* Check return value of ALSA function, and map it to PaError */
+#define ENSURE_(expr, code) \
+    do { \
+        if( UNLIKELY( (aErr_ = (expr)) < 0 ) ) \
+        { \
+            /* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \
+            if( (code) == paUnanticipatedHostError && pthread_equal( pthread_self(), paUnixMainThread) ) \
+            { \
+                PaUtil_SetLastHostErrorInfo( paALSA, aErr_, snd_strerror( aErr_ ) ); \
+            } \
+            PaUtil_DebugPrint( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" ); \
+            if( (code) == paUnanticipatedHostError ) \
+                PA_DEBUG(( "Host error description: %s\n", snd_strerror( aErr_ ) )); \
+            result = (code); \
+            goto error; \
+        } \
+    } while( 0 );
+
+#define ASSERT_CALL_(expr, success) \
+    aErr_ = (expr); \
+    assert( success == aErr_ );
+
+static int aErr_;               /* Used with ENSURE_ */
+
+typedef enum
+{
+    StreamDirection_In,
+    StreamDirection_Out
+} StreamDirection;
+
+typedef struct
+{
+    PaSampleFormat hostSampleFormat;
+    unsigned long framesPerBuffer;
+    int numUserChannels, numHostChannels;
+    int userInterleaved, hostInterleaved;
+
+    snd_pcm_t *pcm;
+    snd_pcm_uframes_t bufferSize;
+    snd_pcm_format_t nativeFormat;
+    unsigned int nfds;
+    int ready;  /* Marked ready from poll */
+    void **userBuffers;
+    snd_pcm_uframes_t offset;
+    StreamDirection streamDir;
+
+    snd_pcm_channel_area_t *channelAreas;  /* Needed for channel adaption */
+} PaAlsaStreamComponent;
+
+/* Implementation specific stream structure */
+typedef struct PaAlsaStream
+{
+    PaUtilStreamRepresentation streamRepresentation;
+    PaUtilCpuLoadMeasurer cpuLoadMeasurer;
+    PaUtilBufferProcessor bufferProcessor;
+    PaUnixThread thread;
+
+    unsigned long framesPerUserBuffer, maxFramesPerHostBuffer;
+
+    int primeBuffers;
+    int callbackMode;              /* bool: are we running in callback mode? */
+    int pcmsSynced;                /* Have we successfully synced pcms */
+
+    /* the callback thread uses these to poll the sound device(s), waiting
+     * for data to be ready/available */
+    struct pollfd* pfds;
+    int pollTimeout;
+
+    /* Used in communication between threads */
+    volatile sig_atomic_t callback_finished; /* bool: are we in the "callback finished" state? */
+    volatile sig_atomic_t callbackAbort;    /* Drop frames? */
+    volatile sig_atomic_t isActive;         /* Is stream in active state? (Between StartStream and StopStream || !paContinue) */
+    PaUnixMutex stateMtx;                   /* Used to synchronize access to stream state */
+
+    int neverDropInput;
+
+    PaTime underrun;
+    PaTime overrun;
+
+    PaAlsaStreamComponent capture, playback;
+}
+PaAlsaStream;
+
+/* PaAlsaHostApiRepresentation - host api datastructure specific to this implementation */
+
+typedef struct PaAlsaHostApiRepresentation
+{
+    PaUtilHostApiRepresentation baseHostApiRep;
+    PaUtilStreamInterface callbackStreamInterface;
+    PaUtilStreamInterface blockingStreamInterface;
+
+    PaUtilAllocationGroup *allocations;
+
+    PaHostApiIndex hostApiIndex;
+}
+PaAlsaHostApiRepresentation;
+
+typedef struct PaAlsaDeviceInfo
+{
+    PaDeviceInfo baseDeviceInfo;
+    char *alsaName;
+    int isPlug;
+    int minInputChannels;
+    int minOutputChannels;
+}
+PaAlsaDeviceInfo;
+
+/* prototypes for functions declared in this file */
+
+static void Terminate( struct PaUtilHostApiRepresentation *hostApi );
+static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
+                                  const PaStreamParameters *inputParameters,
+                                  const PaStreamParameters *outputParameters,
+                                  double sampleRate );
+static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
+                           PaStream** s,
+                           const PaStreamParameters *inputParameters,
+                           const PaStreamParameters *outputParameters,
+                           double sampleRate,
+                           unsigned long framesPerBuffer,
+                           PaStreamFlags streamFlags,
+                           PaStreamCallback *callback,
+                           void *userData );
+static PaError CloseStream( PaStream* stream );
+static PaError StartStream( PaStream *stream );
+static PaError StopStream( PaStream *stream );
+static PaError AbortStream( PaStream *stream );
+static PaError IsStreamStopped( PaStream *s );
+static PaError IsStreamActive( PaStream *stream );
+static PaTime GetStreamTime( PaStream *stream );
+static double GetStreamCpuLoad( PaStream* stream );
+static PaError BuildDeviceList( PaAlsaHostApiRepresentation *hostApi );
+static int SetApproximateSampleRate( snd_pcm_t *pcm, snd_pcm_hw_params_t *hwParams, double sampleRate );
+static int GetExactSampleRate( snd_pcm_hw_params_t *hwParams, double *sampleRate );
+
+/* Callback prototypes */
+static void *CallbackThreadFunc( void *userData );
+
+/* Blocking prototypes */
+static signed long GetStreamReadAvailable( PaStream* s );
+static signed long GetStreamWriteAvailable( PaStream* s );
+static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames );
+static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames );
+
+
+static const PaAlsaDeviceInfo *GetDeviceInfo( const PaUtilHostApiRepresentation *hostApi, int device )
+{
+    return (const PaAlsaDeviceInfo *)hostApi->deviceInfos[device];
+}
+
+static void AlsaErrorHandler(const char *file, int line, const char *function, int err, const char *fmt, ...)
+{
+}
+
+PaError PaAlsa_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
+{
+    PaError result = paNoError;
+    PaAlsaHostApiRepresentation *alsaHostApi = NULL;
+
+    PA_UNLESS( alsaHostApi = (PaAlsaHostApiRepresentation*) PaUtil_AllocateMemory(
+                sizeof(PaAlsaHostApiRepresentation) ), paInsufficientMemory );
+    PA_UNLESS( alsaHostApi->allocations = PaUtil_CreateAllocationGroup(), paInsufficientMemory );
+    alsaHostApi->hostApiIndex = hostApiIndex;
+
+    *hostApi = (PaUtilHostApiRepresentation*)alsaHostApi;
+    (*hostApi)->info.structVersion = 1;
+    (*hostApi)->info.type = paALSA;
+    (*hostApi)->info.name = "ALSA";
+
+    (*hostApi)->Terminate = Terminate;
+    (*hostApi)->OpenStream = OpenStream;
+    (*hostApi)->IsFormatSupported = IsFormatSupported;
+
+    ENSURE_( snd_lib_error_set_handler(AlsaErrorHandler), paUnanticipatedHostError );
+
+    PA_ENSURE( BuildDeviceList( alsaHostApi ) );
+
+    PaUtil_InitializeStreamInterface( &alsaHostApi->callbackStreamInterface,
+                                      CloseStream, StartStream,
+                                      StopStream, AbortStream,
+                                      IsStreamStopped, IsStreamActive,
+                                      GetStreamTime, GetStreamCpuLoad,
+                                      PaUtil_DummyRead, PaUtil_DummyWrite,
+                                      PaUtil_DummyGetReadAvailable,
+                                      PaUtil_DummyGetWriteAvailable );
+
+    PaUtil_InitializeStreamInterface( &alsaHostApi->blockingStreamInterface,
+                                      CloseStream, StartStream,
+                                      StopStream, AbortStream,
+                                      IsStreamStopped, IsStreamActive,
+                                      GetStreamTime, PaUtil_DummyGetCpuLoad,
+                                      ReadStream, WriteStream,
+                                      GetStreamReadAvailable,
+                                      GetStreamWriteAvailable );
+
+    PA_ENSURE( PaUnixThreading_Initialize() );
+
+    return result;
+
+error:
+    if( alsaHostApi )
+    {
+        if( alsaHostApi->allocations )
+        {
+            PaUtil_FreeAllAllocations( alsaHostApi->allocations );
+            PaUtil_DestroyAllocationGroup( alsaHostApi->allocations );
+        }
+
+        PaUtil_FreeMemory( alsaHostApi );
+    }
+
+    return result;
+}
+
+static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
+{
+    PaAlsaHostApiRepresentation *alsaHostApi = (PaAlsaHostApiRepresentation*)hostApi;
+
+    assert( hostApi );
+
+    if( alsaHostApi->allocations )
+    {
+        PaUtil_FreeAllAllocations( alsaHostApi->allocations );
+        PaUtil_DestroyAllocationGroup( alsaHostApi->allocations );
+    }
+
+    PaUtil_FreeMemory( alsaHostApi );
+    snd_config_update_free_global();
+}
+
+/** Determine max channels and default latencies.
+ *
+ * This function provides functionality to grope an opened (might be opened for capture or playback) pcm device for 
+ * traits like max channels, suitable default latencies and default sample rate. Upon error, max channels is set to zero,
+ * and a suitable result returned. The device is closed before returning.
+ */
+static PaError GropeDevice( snd_pcm_t* pcm, int isPlug, StreamDirection mode, int openBlocking,
+        PaAlsaDeviceInfo* devInfo, int* canMmap )
+{
+    PaError result = paNoError;
+    snd_pcm_hw_params_t *hwParams;
+    snd_pcm_uframes_t lowLatency = 512, highLatency = 2048;
+    unsigned int minChans, maxChans;
+    int* minChannels, * maxChannels;
+    double * defaultLowLatency, * defaultHighLatency, * defaultSampleRate =
+        &devInfo->baseDeviceInfo.defaultSampleRate;
+    double defaultSr = *defaultSampleRate;
+
+    assert( pcm );
+
+    if( StreamDirection_In == mode )
+    {
+        minChannels = &devInfo->minInputChannels;
+        maxChannels = &devInfo->baseDeviceInfo.maxInputChannels;
+        defaultLowLatency = &devInfo->baseDeviceInfo.defaultLowInputLatency;
+        defaultHighLatency = &devInfo->baseDeviceInfo.defaultHighInputLatency;
+    }
+    else
+    {
+        minChannels = &devInfo->minOutputChannels;
+        maxChannels = &devInfo->baseDeviceInfo.maxOutputChannels;
+        defaultLowLatency = &devInfo->baseDeviceInfo.defaultLowOutputLatency;
+        defaultHighLatency = &devInfo->baseDeviceInfo.defaultHighOutputLatency;
+    }
+
+    ENSURE_( snd_pcm_nonblock( pcm, 0 ), paUnanticipatedHostError );
+
+    snd_pcm_hw_params_alloca( &hwParams );
+    snd_pcm_hw_params_any( pcm, hwParams );
+
+    *canMmap = snd_pcm_hw_params_test_access( pcm, hwParams, SND_PCM_ACCESS_MMAP_INTERLEAVED ) >= 0 ||
+            snd_pcm_hw_params_test_access( pcm, hwParams, SND_PCM_ACCESS_MMAP_NONINTERLEAVED ) >= 0;
+
+    if( defaultSr >= 0 )
+    {
+        /* Could be that the device opened in one mode supports samplerates that the other mode wont have,
+         * so try again .. */
+        if( SetApproximateSampleRate( pcm, hwParams, defaultSr ) < 0 )
+        {
+            defaultSr = -1.;
+            PA_DEBUG(( "%s: Original default samplerate failed, trying again ..\n", __FUNCTION__ ));
+        }
+    }
+
+    if( defaultSr < 0. )           /* Default sample rate not set */
+    {
+        unsigned int sampleRate = 44100;        /* Will contain approximate rate returned by alsa-lib */
+        if( snd_pcm_hw_params_set_rate_near( pcm, hwParams, &sampleRate, NULL ) < 0)
+        {
+            result = paUnanticipatedHostError;
+            goto error;
+        }
+        ENSURE_( GetExactSampleRate( hwParams, &defaultSr ), paUnanticipatedHostError );
+    }
+    
+    ENSURE_( snd_pcm_hw_params_get_channels_min( hwParams, &minChans ), paUnanticipatedHostError );
+    ENSURE_( snd_pcm_hw_params_get_channels_max( hwParams, &maxChans ), paUnanticipatedHostError );
+    assert( maxChans <= INT_MAX );
+    assert( maxChans > 0 );    /* Weird linking issue could cause wrong version of ALSA symbols to be called,
+                                   resulting in zeroed values */
+
+    /* XXX: Limit to sensible number (ALSA plugins accept a crazy amount of channels)? */
+    if( isPlug && maxChans > 128 )
+    {
+        maxChans = 128;
+        PA_DEBUG(( "%s: Limiting number of plugin channels to %u\n", __FUNCTION__, maxChans ));
+    }
+
+    /* TWEAKME:
+     *
+     * Giving values for default min and max latency is not
+     * straightforward.  Here are our objectives:
+     *
+     *         * for low latency, we want to give the lowest value
+     *         that will work reliably.  This varies based on the
+     *         sound card, kernel, CPU, etc.  I think it is better
+     *         to give sub-optimal latency than to give a number
+     *         too low and cause dropouts.  My conservative
+     *         estimate at this point is to base it on 4096-sample
+     *         latency at 44.1 kHz, which gives a latency of 23ms.
+     *         * for high latency we want to give a large enough
+     *         value that dropouts are basically impossible.  This
+     *         doesn't really require as much tweaking, since
+     *         providing too large a number will just cause us to
+     *         select the nearest setting that will work at stream
+     *         config time.
+     */
+    ENSURE_( snd_pcm_hw_params_set_buffer_size_near( pcm, hwParams, &lowLatency ), paUnanticipatedHostError );
+
+    /* Have to reset hwParams, to set new buffer size */
+    ENSURE_( snd_pcm_hw_params_any( pcm, hwParams ), paUnanticipatedHostError ); 
+    ENSURE_( snd_pcm_hw_params_set_buffer_size_near( pcm, hwParams, &highLatency ), paUnanticipatedHostError );
+
+    *minChannels = (int)minChans;
+    *maxChannels = (int)maxChans;
+    *defaultSampleRate = defaultSr;
+    *defaultLowLatency = (double) lowLatency / *defaultSampleRate;
+    *defaultHighLatency = (double) highLatency / *defaultSampleRate;
+
+end:
+    snd_pcm_close( pcm );
+    return result;
+
+error:
+    goto end;
+}
+
+/* Initialize device info with invalid values (maxInputChannels and maxOutputChannels are set to zero since these indicate
+ * wether input/output is available) */
+static void InitializeDeviceInfo( PaDeviceInfo *deviceInfo )
+{
+    deviceInfo->structVersion = -1;
+    deviceInfo->name = NULL;
+    deviceInfo->hostApi = -1;
+    deviceInfo->maxInputChannels = 0;
+    deviceInfo->maxOutputChannels = 0;
+    deviceInfo->defaultLowInputLatency = -1.;
+    deviceInfo->defaultLowOutputLatency = -1.;
+    deviceInfo->defaultHighInputLatency = -1.;
+    deviceInfo->defaultHighOutputLatency = -1.;
+    deviceInfo->defaultSampleRate = -1.;
+}
+
+/* Helper struct */
+typedef struct
+{
+    char *alsaName;
+    char *name;
+    int isPlug;
+    int hasPlayback;
+    int hasCapture;
+} DeviceNames;
+
+static PaError PaAlsa_StrDup( PaAlsaHostApiRepresentation *alsaApi,
+        char **dst,
+        const char *src)
+{
+    PaError result = paNoError;
+    int len = strlen( src ) + 1;
+
+    /* PA_DEBUG(("PaStrDup %s %d\n", src, len)); */
+
+    PA_UNLESS( *dst = (char *)PaUtil_GroupAllocateMemory( alsaApi->allocations, len ),
+            paInsufficientMemory );
+    strncpy( *dst, src, len );
+
+error:
+    return result;
+}
+
+/* Disregard some standard plugins
+ */
+static int IgnorePlugin( const char *pluginId )
+{
+    /* XXX: dmix and default ignored because after opening and closing, they seem to keep hogging resources.
+     */
+    static const char *ignoredPlugins[] = {"hw", "plughw", "plug", "dsnoop", "tee",
+        "file", "null", "shm", "cards", "dmix", "default", NULL};
+    int i = 0;
+    while( ignoredPlugins[i] )
+    {
+        if( !strcmp( pluginId, ignoredPlugins[i] ) )
+        {
+            return 1;
+        }
+        ++i;
+    }
+
+    return 0;
+}
+
+/* Build PaDeviceInfo list, ignore devices for which we cannot determine capabilities (possibly busy, sigh) */
+static PaError BuildDeviceList( PaAlsaHostApiRepresentation *alsaApi )
+{
+    PaUtilHostApiRepresentation *baseApi = &alsaApi->baseHostApiRep;
+    PaAlsaDeviceInfo *deviceInfoArray;
+    int cardIdx = -1, devIdx = 0;
+    snd_ctl_card_info_t *cardInfo;
+    PaError result = paNoError;
+    size_t numDeviceNames = 0, maxDeviceNames = 1, i;
+    DeviceNames *deviceNames = NULL;
+    snd_config_t *topNode = NULL;
+    snd_pcm_info_t *pcmInfo;
+    int res;
+    int blocking = SND_PCM_NONBLOCK;
+    char alsaCardName[50];
+    if( getenv( "PA_ALSA_INITIALIZE_BLOCK" ) && atoi( getenv( "PA_ALSA_INITIALIZE_BLOCK" ) ) )
+        blocking = 0;
+
+    /* These two will be set to the first working input and output device, respectively */
+    baseApi->info.defaultInputDevice = paNoDevice;
+    baseApi->info.defaultOutputDevice = paNoDevice;
+
+    /* count the devices by enumerating all the card numbers */
+
+    /* snd_card_next() modifies the integer passed to it to be:
+     *      the index of the first card if the parameter is -1
+     *      the index of the next card if the parameter is the index of a card
+     *      -1 if there are no more cards
+     *
+     * The function itself returns 0 if it succeeded. */
+    cardIdx = -1;
+    snd_ctl_card_info_alloca( &cardInfo );
+    snd_pcm_info_alloca( &pcmInfo );
+    while( snd_card_next( &cardIdx ) == 0 && cardIdx >= 0 )
+    {
+        char *cardName;
+        int devIdx = -1;
+        snd_ctl_t *ctl;
+        char buf[50];
+
+        snprintf( alsaCardName, sizeof (alsaCardName), "hw:%d", cardIdx );
+
+        /* Acquire name of card */
+        if( snd_ctl_open( &ctl, alsaCardName, 0 ) < 0 )
+        {
+            /* Unable to open card :( */
+            continue;
+        }
+        snd_ctl_card_info( ctl, cardInfo );
+
+        PA_ENSURE( PaAlsa_StrDup( alsaApi, &cardName, snd_ctl_card_info_get_name( cardInfo )) );
+
+        while( snd_ctl_pcm_next_device( ctl, &devIdx ) == 0 && devIdx >= 0 )
+        {
+            char *alsaDeviceName, *deviceName;
+            size_t len;
+            int hasPlayback = 0, hasCapture = 0;
+            snprintf( buf, sizeof (buf), "%s:%d,%d", "hw", cardIdx, devIdx );
+
+            /* Obtain info about this particular device */
+            snd_pcm_info_set_device( pcmInfo, devIdx );
+            snd_pcm_info_set_subdevice( pcmInfo, 0 );
+            snd_pcm_info_set_stream( pcmInfo, SND_PCM_STREAM_CAPTURE );
+            if( snd_ctl_pcm_info( ctl, pcmInfo ) >= 0 )
+            {
+                hasCapture = 1;
+            }
+            
+            snd_pcm_info_set_stream( pcmInfo, SND_PCM_STREAM_PLAYBACK );
+            if( snd_ctl_pcm_info( ctl, pcmInfo ) >= 0 )
+            {
+                hasPlayback = 1;
+            }
+
+            if( !hasPlayback && !hasCapture )
+            {
+                continue;   /* Error */
+            }
+
+            /* The length of the string written by snprintf plus terminating 0 */
+            len = snprintf( NULL, 0, "%s: %s (%s)", cardName, snd_pcm_info_get_name( pcmInfo ), buf ) + 1;
+            PA_UNLESS( deviceName = (char *)PaUtil_GroupAllocateMemory( alsaApi->allocations, len ),
+                    paInsufficientMemory );
+            snprintf( deviceName, len, "%s: %s (%s)", cardName,
+                    snd_pcm_info_get_name( pcmInfo ), buf );
+
+            ++numDeviceNames;
+            if( !deviceNames || numDeviceNames > maxDeviceNames )
+            {
+                maxDeviceNames *= 2;
+                PA_UNLESS( deviceNames = (DeviceNames *) realloc( deviceNames, maxDeviceNames * sizeof (DeviceNames) ),
+                        paInsufficientMemory );
+            }
+
+            PA_ENSURE( PaAlsa_StrDup( alsaApi, &alsaDeviceName, buf ) );
+
+            deviceNames[ numDeviceNames - 1 ].alsaName = alsaDeviceName;
+            deviceNames[ numDeviceNames - 1 ].name = deviceName;
+            deviceNames[ numDeviceNames - 1 ].isPlug = 0;
+            deviceNames[ numDeviceNames - 1 ].hasPlayback = hasPlayback;
+            deviceNames[ numDeviceNames - 1 ].hasCapture = hasCapture;
+        }
+        snd_ctl_close( ctl );
+    }
+
+    /* Iterate over plugin devices */
+    if( NULL == snd_config )
+    {
+        /* snd_config_update is called implicitly by some functions, if this hasn't happened snd_config will be NULL (bleh) */
+        ENSURE_( snd_config_update(), paUnanticipatedHostError );
+        PA_DEBUG(( "Updating snd_config\n" ));
+    }
+    assert( snd_config );
+    if( (res = snd_config_search( snd_config, "pcm", &topNode )) >= 0 )
+    {
+        snd_config_iterator_t i, next;
+
+        snd_config_for_each( i, next, topNode )
+        {
+            const char *tpStr = "unknown", *idStr = NULL;
+            int err = 0;
+
+            char *alsaDeviceName, *deviceName;
+            snd_config_t *n = snd_config_iterator_entry( i ), * tp = NULL;;
+
+            if( (err = snd_config_search( n, "type", &tp )) < 0 )
+            {
+                if( -ENOENT != err )
+                {
+                    ENSURE_(err, paUnanticipatedHostError);
+                }
+            }
+            else 
+            {
+                ENSURE_( snd_config_get_string( tp, &tpStr ), paUnanticipatedHostError );
+            }
+            ENSURE_( snd_config_get_id( n, &idStr ), paUnanticipatedHostError );
+            if( IgnorePlugin( idStr ) )
+            {
+                PA_DEBUG(( "%s: Ignoring ALSA plugin device %s of type %s\n", __FUNCTION__, idStr, tpStr ));
+                continue;
+            }
+            PA_DEBUG(( "%s: Found plugin %s of type %s\n", __FUNCTION__, idStr, tpStr ));
+
+            PA_UNLESS( alsaDeviceName = (char*)PaUtil_GroupAllocateMemory( alsaApi->allocations,
+                                                            strlen(idStr) + 6 ), paInsufficientMemory );
+            strcpy( alsaDeviceName, idStr );
+            PA_UNLESS( deviceName = (char*)PaUtil_GroupAllocateMemory( alsaApi->allocations,
+                                                            strlen(idStr) + 1 ), paInsufficientMemory );
+            strcpy( deviceName, idStr );
+
+            ++numDeviceNames;
+            if( !deviceNames || numDeviceNames > maxDeviceNames )
+            {
+                maxDeviceNames *= 2;
+                PA_UNLESS( deviceNames = (DeviceNames *) realloc( deviceNames, maxDeviceNames * sizeof (DeviceNames) ),
+                        paInsufficientMemory );
+            }
+
+            deviceNames[numDeviceNames - 1].alsaName = alsaDeviceName;
+            deviceNames[numDeviceNames - 1].name = deviceName;
+            deviceNames[numDeviceNames - 1].isPlug = 1;
+            deviceNames[numDeviceNames - 1].hasPlayback = 1;
+            deviceNames[numDeviceNames - 1].hasCapture = 1;
+        }
+    }
+    else
+        PA_DEBUG(( "%s: Iterating over ALSA plugins failed: %s\n", __FUNCTION__, snd_strerror( res ) ));
+
+    /* allocate deviceInfo memory based on the number of devices */
+    PA_UNLESS( baseApi->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
+            alsaApi->allocations, sizeof(PaDeviceInfo*) * (numDeviceNames) ), paInsufficientMemory );
+
+    /* allocate all device info structs in a contiguous block */
+    PA_UNLESS( deviceInfoArray = (PaAlsaDeviceInfo*)PaUtil_GroupAllocateMemory(
+            alsaApi->allocations, sizeof(PaAlsaDeviceInfo) * numDeviceNames ), paInsufficientMemory );
+
+    /* Loop over list of cards, filling in info, if a device is deemed unavailable (can't get name),
+     * it's ignored.
+     */
+    /* while( snd_card_next( &cardIdx ) == 0 && cardIdx >= 0 ) */
+    for( i = 0, devIdx = 0; i < numDeviceNames; ++i )
+    {
+        snd_pcm_t *pcm;
+        PaAlsaDeviceInfo *deviceInfo = &deviceInfoArray[devIdx];
+        PaDeviceInfo *baseDeviceInfo = &deviceInfo->baseDeviceInfo;
+        int canMmap = -1;
+
+        /* Zero fields */
+        InitializeDeviceInfo( baseDeviceInfo );
+
+        /* to determine device capabilities, we must open the device and query the
+         * hardware parameter configuration space */
+
+        /* Query capture */
+        if( deviceNames[i].hasCapture &&
+                snd_pcm_open( &pcm, deviceNames[i].alsaName, SND_PCM_STREAM_CAPTURE, blocking ) >= 0 )
+        {
+            if( GropeDevice( pcm, deviceNames[i].isPlug, StreamDirection_In, blocking, deviceInfo,
+                        &canMmap ) != paNoError )
+            {
+                /* Error */
+                PA_DEBUG(("%s: Failed groping %s for capture\n", __FUNCTION__, deviceNames[i].alsaName));
+                continue;
+            }
+        }
+
+        /* Query playback */
+        if( deviceNames[i].hasPlayback &&
+                snd_pcm_open( &pcm, deviceNames[i].alsaName, SND_PCM_STREAM_PLAYBACK, blocking ) >= 0 )
+        {
+            if( GropeDevice( pcm, deviceNames[i].isPlug, StreamDirection_Out, blocking, deviceInfo,
+                        &canMmap ) != paNoError )
+            {
+                /* Error */
+                PA_DEBUG(("%s: Failed groping %s for playback\n", __FUNCTION__, deviceNames[i].alsaName));
+                continue;
+            }
+        }
+
+        if( 0 == canMmap )
+        {
+            PA_DEBUG(("%s: Device %s doesn't support mmap\n", __FUNCTION__, deviceNames[i].alsaName));
+            continue;
+        }
+
+        baseDeviceInfo->structVersion = 2;
+        baseDeviceInfo->hostApi = alsaApi->hostApiIndex;
+        baseDeviceInfo->name = deviceNames[i].name;
+        deviceInfo->alsaName = deviceNames[i].alsaName;
+        deviceInfo->isPlug = deviceNames[i].isPlug;
+
+        /* A: Storing pointer to PaAlsaDeviceInfo object as pointer to PaDeviceInfo object.
+         * Should now be safe to add device info, unless the device supports neither capture nor playback
+         */
+        if( baseDeviceInfo->maxInputChannels > 0 || baseDeviceInfo->maxOutputChannels > 0 )
+        {
+            if( baseApi->info.defaultInputDevice == paNoDevice && baseDeviceInfo->maxInputChannels > 0 )
+                baseApi->info.defaultInputDevice = devIdx;
+            if(  baseApi->info.defaultOutputDevice == paNoDevice && baseDeviceInfo->maxOutputChannels > 0 )
+                baseApi->info.defaultOutputDevice = devIdx;
+            PA_DEBUG(("%s: Adding device %s\n", __FUNCTION__, deviceNames[i].name));
+            baseApi->deviceInfos[devIdx++] = (PaDeviceInfo *) deviceInfo;
+        }
+    }
+    free( deviceNames );
+
+    baseApi->info.deviceCount = devIdx;   /* Number of successfully queried devices */
+
+end:
+    return result;
+
+error:
+    /* No particular action */
+    goto end;
+}
+
+/* Check against known device capabilities */
+static PaError ValidateParameters( const PaStreamParameters *parameters, PaUtilHostApiRepresentation *hostApi, StreamDirection mode )
+{
+    PaError result = paNoError;
+    int maxChans;
+    const PaAlsaDeviceInfo *deviceInfo = NULL;
+    assert( parameters );
+
+    if( parameters->device != paUseHostApiSpecificDeviceSpecification )
+    {
+        assert( parameters->device < hostApi->info.deviceCount );
+        PA_UNLESS( parameters->hostApiSpecificStreamInfo == NULL, paBadIODeviceCombination );
+        deviceInfo = GetDeviceInfo( hostApi, parameters->device );
+    }
+    else
+    {
+        const PaAlsaStreamInfo *streamInfo = parameters->hostApiSpecificStreamInfo;
+
+        PA_UNLESS( parameters->device == paUseHostApiSpecificDeviceSpecification, paInvalidDevice );
+        PA_UNLESS( streamInfo->size == sizeof (PaAlsaStreamInfo) && streamInfo->version == 1,
+                paIncompatibleHostApiSpecificStreamInfo );
+        PA_UNLESS( streamInfo->deviceString != NULL, paInvalidDevice );
+
+        /* Skip further checking */
+        return paNoError;
+    }
+
+    assert( deviceInfo );
+    assert( parameters->hostApiSpecificStreamInfo == NULL );
+    maxChans = (StreamDirection_In == mode ? deviceInfo->baseDeviceInfo.maxInputChannels :
+        deviceInfo->baseDeviceInfo.maxOutputChannels);
+    PA_UNLESS( parameters->channelCount <= maxChans, paInvalidChannelCount );
+
+error:
+    return result;
+}
+
+/* Given an open stream, what sample formats are available? */
+static PaSampleFormat GetAvailableFormats( snd_pcm_t *pcm )
+{
+    PaSampleFormat available = 0;
+    snd_pcm_hw_params_t *hwParams;
+    snd_pcm_hw_params_alloca( &hwParams );
+
+    snd_pcm_hw_params_any( pcm, hwParams );
+
+    if( snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_FLOAT ) >= 0)
+        available |= paFloat32;
+
+    if( snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S32 ) >= 0)
+        available |= paInt32;
+
+    if( snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S24 ) >= 0)
+        available |= paInt24;
+
+    if( snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S16 ) >= 0)
+        available |= paInt16;
+
+    if( snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_U8 ) >= 0)
+        available |= paUInt8;
+
+    if( snd_pcm_hw_params_test_format( pcm, hwParams, SND_PCM_FORMAT_S8 ) >= 0)
+        available |= paInt8;
+
+    return available;
+}
+
+static snd_pcm_format_t Pa2AlsaFormat( PaSampleFormat paFormat )
+{
+    switch( paFormat )
+    {
+        case paFloat32:
+            return SND_PCM_FORMAT_FLOAT;
+
+        case paInt16:
+            return SND_PCM_FORMAT_S16;
+
+        case paInt24:
+            return SND_PCM_FORMAT_S24;
+
+        case paInt32:
+            return SND_PCM_FORMAT_S32;
+
+        case paInt8:
+            return SND_PCM_FORMAT_S8;
+
+        case paUInt8:
+            return SND_PCM_FORMAT_U8;
+
+        default:
+            return SND_PCM_FORMAT_UNKNOWN;
+    }
+}
+
+/** Open an ALSA pcm handle.
+ * 
+ * The device to be open can be specified in a custom PaAlsaStreamInfo struct, or it will be a device number. In case of a
+ * device number, it maybe specified through an env variable (PA_ALSA_PLUGHW) that we should open the corresponding plugin
+ * device.
+ */
+static PaError AlsaOpen( const PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *params, StreamDirection
+        streamDir, snd_pcm_t **pcm )
+{
+    PaError result = paNoError;
+    int ret;
+    const char *deviceName = alloca( 50 );
+    const PaAlsaDeviceInfo *deviceInfo = NULL;
+    PaAlsaStreamInfo *streamInfo = (PaAlsaStreamInfo *)params->hostApiSpecificStreamInfo;
+
+    if( !streamInfo )
+    {
+        int usePlug = 0;
+        deviceInfo = GetDeviceInfo( hostApi, params->device );
+        
+        /* If device name starts with hw: and PA_ALSA_PLUGHW is 1, we open the plughw device instead */
+        if( !strncmp( "hw:", deviceInfo->alsaName, 3 ) && getenv( "PA_ALSA_PLUGHW" ) )
+            usePlug = atoi( getenv( "PA_ALSA_PLUGHW" ) );
+        if( usePlug )
+            snprintf( (char *) deviceName, 50, "plug%s", deviceInfo->alsaName );
+        else
+            deviceName = deviceInfo->alsaName;
+    }
+    else
+        deviceName = streamInfo->deviceString;
+
+    PA_DEBUG(( "%s: Opening device %s\n", __FUNCTION__, deviceName ));
+    if( (ret = snd_pcm_open( pcm, deviceName, streamDir == StreamDirection_In ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,
+                    SND_PCM_NONBLOCK )) < 0 )
+    {
+        /* Not to be closed */
+        *pcm = NULL;
+        ENSURE_( ret, ret == -EBUSY ? paDeviceUnavailable : paBadIODeviceCombination );
+    }
+    ENSURE_( snd_pcm_nonblock( *pcm, 0 ), paUnanticipatedHostError );
+
+end:
+    return result;
+
+error:
+    goto end;
+}
+
+static PaError TestParameters( const PaUtilHostApiRepresentation *hostApi, const PaStreamParameters *parameters,
+        double sampleRate, StreamDirection streamDir )
+{
+    PaError result = paNoError;
+    snd_pcm_t *pcm = NULL;
+    PaSampleFormat availableFormats;
+    /* We are able to adapt to a number of channels less than what the device supports */
+    unsigned int numHostChannels;
+    PaSampleFormat hostFormat;
+    snd_pcm_hw_params_t *hwParams;
+    snd_pcm_hw_params_alloca( &hwParams );
+    
+    if( !parameters->hostApiSpecificStreamInfo )
+    {
+        const PaAlsaDeviceInfo *devInfo = GetDeviceInfo( hostApi, parameters->device );
+        numHostChannels = PA_MAX( parameters->channelCount, StreamDirection_In == streamDir ?
+                devInfo->minInputChannels : devInfo->minOutputChannels );
+    }
+    else
+        numHostChannels = parameters->channelCount;
+
+    PA_ENSURE( AlsaOpen( hostApi, parameters, streamDir, &pcm ) );
+
+    snd_pcm_hw_params_any( pcm, hwParams );
+
+    if( SetApproximateSampleRate( pcm, hwParams, sampleRate ) < 0 )
+    {
+        result = paInvalidSampleRate;
+        goto error;
+    }
+
+    if( snd_pcm_hw_params_set_channels( pcm, hwParams, numHostChannels ) < 0 )
+    {
+        result = paInvalidChannelCount;
+        goto error;
+    }
+
+    /* See if we can find a best possible match */
+    availableFormats = GetAvailableFormats( pcm );
+    PA_ENSURE( hostFormat = PaUtil_SelectClosestAvailableFormat( availableFormats, parameters->sampleFormat ) );
+    ENSURE_( snd_pcm_hw_params_set_format( pcm, hwParams, Pa2AlsaFormat( hostFormat ) ), paUnanticipatedHostError );
+
+    {
+        /* It happens that this call fails because the device is busy */
+        int ret = 0;
+        if( (ret = snd_pcm_hw_params( pcm, hwParams )) < 0)
+        {
+            ENSURE_( ret, ret == -EBUSY ? paDeviceUnavailable : paUnanticipatedHostError );
+        }
+    }
+
+end:
+    if( pcm )
+    {
+        snd_pcm_close( pcm );
+    }
+    return result;
+
+error:
+    goto end;
+}
+
+static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
+                                  const PaStreamParameters *inputParameters,
+                                  const PaStreamParameters *outputParameters,
+                                  double sampleRate )
+{
+    int inputChannelCount = 0, outputChannelCount = 0;
+    PaSampleFormat inputSampleFormat, outputSampleFormat;
+    PaError result = paFormatIsSupported;
+
+    if( inputParameters )
+    {
+        PA_ENSURE( ValidateParameters( inputParameters, hostApi, StreamDirection_In ) );
+
+        inputChannelCount = inputParameters->channelCount;
+        inputSampleFormat = inputParameters->sampleFormat;
+    }
+
+    if( outputParameters )
+    {
+        PA_ENSURE( ValidateParameters( outputParameters, hostApi, StreamDirection_Out ) );
+
+        outputChannelCount = outputParameters->channelCount;
+        outputSampleFormat = outputParameters->sampleFormat;
+    }
+
+    if( inputChannelCount )
+    {
+        if( (result = TestParameters( hostApi, inputParameters, sampleRate, StreamDirection_In ))
+                != paNoError )
+            goto error;
+    }
+    if ( outputChannelCount )
+    {
+        if( (result = TestParameters( hostApi, outputParameters, sampleRate, StreamDirection_Out ))
+                != paNoError )
+            goto error;
+    }
+
+    return paFormatIsSupported;
+
+error:
+    return result;
+}
+
+static PaError PaAlsaStreamComponent_Initialize( PaAlsaStreamComponent *self, PaAlsaHostApiRepresentation *alsaApi,
+        const PaStreamParameters *params, StreamDirection streamDir, int callbackMode )
+{
+    PaError result = paNoError;
+    PaSampleFormat userSampleFormat = params->sampleFormat, hostSampleFormat;
+    assert( params->channelCount > 0 );
+
+    /* Make sure things have an initial value */
+    memset( self, 0, sizeof (PaAlsaStreamComponent) );
+
+    if( NULL == params->hostApiSpecificStreamInfo )
+    {
+        const PaAlsaDeviceInfo *devInfo = GetDeviceInfo( &alsaApi->baseHostApiRep, params->device );
+        self->numHostChannels = PA_MAX( params->channelCount, StreamDirection_In == streamDir ? devInfo->minInputChannels
+                : devInfo->minOutputChannels );
+    }
+    else
+    {
+        /* We're blissfully unaware of the minimum channelCount */
+        self->numHostChannels = params->channelCount;
+    }
+
+    PA_ENSURE( AlsaOpen( &alsaApi->baseHostApiRep, params, streamDir, &self->pcm ) );
+    self->nfds = snd_pcm_poll_descriptors_count( self->pcm );
+    hostSampleFormat = PaUtil_SelectClosestAvailableFormat( GetAvailableFormats( self->pcm ), userSampleFormat );
+
+    self->hostSampleFormat = hostSampleFormat;
+    self->nativeFormat = Pa2AlsaFormat( hostSampleFormat );
+    self->hostInterleaved = self->userInterleaved = !(userSampleFormat & paNonInterleaved);
+    self->numUserChannels = params->channelCount;
+    self->streamDir = streamDir;
+
+    if( !callbackMode && !self->userInterleaved )
+    {
+        /* Pre-allocate non-interleaved user provided buffers */
+        PA_UNLESS( self->userBuffers = PaUtil_AllocateMemory( sizeof (void *) * self->numUserChannels ),
+                paInsufficientMemory );
+    }
+
+error:
+    return result;
+}
+
+static void PaAlsaStreamComponent_Terminate( PaAlsaStreamComponent *self )
+{
+    snd_pcm_close( self->pcm );
+    if( self->userBuffers )
+        PaUtil_FreeMemory( self->userBuffers );
+}
+
+int nearbyint_(float value) {
+    if(  value - (int)value > .5 )
+        return (int)ceil( value );
+    return (int)floor( value );
+}
+
+/** Initiate configuration, preparing for determining a period size suitable for both capture and playback components.
+ *
+ */
+static PaError PaAlsaStreamComponent_InitialConfigure( PaAlsaStreamComponent *self, const PaStreamParameters *params,
+        int primeBuffers, snd_pcm_hw_params_t *hwParams, double *sampleRate )
+{
+    /* Configuration consists of setting all of ALSA's parameters.
+     * These parameters come in two flavors: hardware parameters
+     * and software paramters.  Hardware parameters will affect
+     * the way the device is initialized, software parameters
+     * affect the way ALSA interacts with me, the user-level client.
+     */
+
+    PaError result = paNoError;
+    snd_pcm_access_t accessMode, alternateAccessMode;
+    int dir = 0;
+    snd_pcm_t *pcm = self->pcm;
+    double sr = *sampleRate;
+    unsigned int minPeriods = 2;
+
+    /* self->framesPerBuffer = framesPerHostBuffer; */
+
+    /* ... fill up the configuration space with all possibile
+     * combinations of parameters this device will accept */
+    ENSURE_( snd_pcm_hw_params_any( pcm, hwParams ), paUnanticipatedHostError );
+
+    ENSURE_( snd_pcm_hw_params_set_periods_integer( pcm, hwParams ), paUnanticipatedHostError );
+    /* I think there should be at least 2 periods (even though ALSA doesn't appear to enforce this) */
+    dir = 0;
+    ENSURE_( snd_pcm_hw_params_set_periods_min( pcm, hwParams, &minPeriods, &dir ), paUnanticipatedHostError );
+
+    if( self->userInterleaved )
+    {
+        accessMode = SND_PCM_ACCESS_MMAP_INTERLEAVED;
+        alternateAccessMode = SND_PCM_ACCESS_MMAP_NONINTERLEAVED;
+    }
+    else
+    {
+        accessMode = SND_PCM_ACCESS_MMAP_NONINTERLEAVED;
+        alternateAccessMode = SND_PCM_ACCESS_MMAP_INTERLEAVED;
+    }
+    /* If requested access mode fails, try alternate mode */
+    if( snd_pcm_hw_params_set_access( pcm, hwParams, accessMode ) < 0 )
+    {
+        int err = 0;
+        if( (err = snd_pcm_hw_params_set_access( pcm, hwParams, alternateAccessMode )) < 0)
+        {
+            result = paUnanticipatedHostError;
+            if( -EINVAL == err )
+            {
+                PaUtil_SetLastHostErrorInfo( paALSA, err, "PA ALSA requires that a device supports mmap access" );
+            }
+            else
+            {
+                PaUtil_SetLastHostErrorInfo( paALSA, err, snd_strerror( err ) );
+            }
+            goto error;
+        }
+        /* Flip mode */
+        self->hostInterleaved = !self->userInterleaved;
+    }
+
+    ENSURE_( snd_pcm_hw_params_set_format( pcm, hwParams, self->nativeFormat ), paUnanticipatedHostError );
+
+    ENSURE_( SetApproximateSampleRate( pcm, hwParams, sr ), paInvalidSampleRate );
+    ENSURE_( GetExactSampleRate( hwParams, &sr ), paUnanticipatedHostError );
+    /* reject if there's no sample rate within 1% of the one requested */
+    if( (fabs( *sampleRate - sr ) / *sampleRate) > 0.01 )
+    {
+        PA_DEBUG(("%s: Wanted %f, closest sample rate was %d\n", __FUNCTION__, sampleRate, sr ));                 
+        PA_ENSURE( paInvalidSampleRate );
+    }
+
+    ENSURE_( snd_pcm_hw_params_set_channels( pcm, hwParams, self->numHostChannels ), paInvalidChannelCount );
+
+    *sampleRate = sr;
+
+end:
+    return result;
+
+error:
+    /* No particular action */
+    goto end;
+}
+
+/** Finish the configuration of the component's ALSA device.
+ *
+ * As part of this method, the component's bufferSize attribute will be set.
+ * @param latency: The latency for this component.
+ */
+static PaError PaAlsaStreamComponent_FinishConfigure( PaAlsaStreamComponent *self, snd_pcm_hw_params_t* hwParams,
+        const PaStreamParameters *params, int primeBuffers, double sampleRate, PaTime* latency )
+{
+    PaError result = paNoError;
+    snd_pcm_sw_params_t* swParams;
+    snd_pcm_uframes_t bufSz = 0;
+    *latency = -1.;
+
+    snd_pcm_sw_params_alloca( &swParams );
+
+    bufSz = (params->suggestedLatency * sampleRate) + self->framesPerBuffer;    /* One period does not count as latency */
+    ENSURE_( snd_pcm_hw_params_set_buffer_size_near( self->pcm, hwParams, &bufSz ), paUnanticipatedHostError );
+
+    /* Set the parameters! */
+    ENSURE_( snd_pcm_hw_params( self->pcm, hwParams ), paUnanticipatedHostError );
+    ENSURE_( snd_pcm_hw_params_get_buffer_size( hwParams, &self->bufferSize ), paUnanticipatedHostError );
+    /* Latency in seconds, one period is not counted as latency */
+    *latency = (self->bufferSize - self->framesPerBuffer) / sampleRate;
+
+    /* Now software parameters... */
+    ENSURE_( snd_pcm_sw_params_current( self->pcm, swParams ), paUnanticipatedHostError );
+
+    ENSURE_( snd_pcm_sw_params_set_start_threshold( self->pcm, swParams, self->framesPerBuffer ), paUnanticipatedHostError );
+    ENSURE_( snd_pcm_sw_params_set_stop_threshold( self->pcm, swParams, self->bufferSize ), paUnanticipatedHostError );
+
+    /* Silence buffer in the case of underrun */
+    if( !primeBuffers ) /* XXX: Make sense? */
+    {
+        snd_pcm_uframes_t boundary;
+        ENSURE_( snd_pcm_sw_params_get_boundary( swParams, &boundary ), paUnanticipatedHostError );
+        ENSURE_( snd_pcm_sw_params_set_silence_threshold( self->pcm, swParams, 0 ), paUnanticipatedHostError );
+        ENSURE_( snd_pcm_sw_params_set_silence_size( self->pcm, swParams, boundary ), paUnanticipatedHostError );
+    }
+        
+    ENSURE_( snd_pcm_sw_params_set_avail_min( self->pcm, swParams, self->framesPerBuffer ), paUnanticipatedHostError );
+    ENSURE_( snd_pcm_sw_params_set_xfer_align( self->pcm, swParams, 1 ), paUnanticipatedHostError );
+    ENSURE_( snd_pcm_sw_params_set_tstamp_mode( self->pcm, swParams, SND_PCM_TSTAMP_MMAP ), paUnanticipatedHostError );
+
+    /* Set the parameters! */
+    ENSURE_( snd_pcm_sw_params( self->pcm, swParams ), paUnanticipatedHostError );
+
+error:
+    return result;
+}
+
+static PaError PaAlsaStream_Initialize( PaAlsaStream *self, PaAlsaHostApiRepresentation *alsaApi, const PaStreamParameters *inParams,
+        const PaStreamParameters *outParams, double sampleRate, unsigned long framesPerUserBuffer, PaStreamCallback callback,
+        PaStreamFlags streamFlags, void *userData )
+{
+    PaError result = paNoError;
+    assert( self );
+
+    memset( self, 0, sizeof (PaAlsaStream) );
+
+    if( NULL != callback )
+    {
+        PaUtil_InitializeStreamRepresentation( &self->streamRepresentation,
+                                               &alsaApi->callbackStreamInterface,
+                                               callback, userData );
+        self->callbackMode = 1;
+    }
+    else
+    {
+        PaUtil_InitializeStreamRepresentation( &self->streamRepresentation,
+                                               &alsaApi->blockingStreamInterface,
+                                               NULL, userData );
+    }
+
+    self->framesPerUserBuffer = framesPerUserBuffer;
+    self->neverDropInput = streamFlags & paNeverDropInput;
+    /* XXX: Ignore paPrimeOutputBuffersUsingStreamCallback untill buffer priming is fully supported in pa_process.c */
+    /*
+    if( outParams & streamFlags & paPrimeOutputBuffersUsingStreamCallback )
+        self->primeBuffers = 1;
+        */
+    memset( &self->capture, 0, sizeof (PaAlsaStreamComponent) );
+    memset( &self->playback, 0, sizeof (PaAlsaStreamComponent) );
+    if( inParams )
+    {
+        PA_ENSURE( PaAlsaStreamComponent_Initialize( &self->capture, alsaApi, inParams, StreamDirection_In, NULL != callback ) );
+    }
+    if( outParams )
+    {
+        PA_ENSURE( PaAlsaStreamComponent_Initialize( &self->playback, alsaApi, outParams, StreamDirection_Out, NULL != callback ) );
+    }
+
+    assert( self->capture.nfds || self->playback.nfds );
+
+    PA_UNLESS( self->pfds = (struct pollfd*)PaUtil_AllocateMemory( (self->capture.nfds +
+                    self->playback.nfds) * sizeof (struct pollfd) ), paInsufficientMemory );
+
+    PaUtil_InitializeCpuLoadMeasurer( &self->cpuLoadMeasurer, sampleRate );
+    ASSERT_CALL_( PaUnixMutex_Initialize( &self->stateMtx ), paNoError );
+
+error:
+    return result;
+}
+
+/** Free resources associated with stream, and eventually stream itself.
+ *
+ * Frees allocated memory, and terminates individual StreamComponents.
+ */
+static void PaAlsaStream_Terminate( PaAlsaStream *self )
+{
+    assert( self );
+
+    if( self->capture.pcm )
+    {
+        PaAlsaStreamComponent_Terminate( &self->capture );
+    }
+    if( self->playback.pcm )
+    {
+        PaAlsaStreamComponent_Terminate( &self->playback );
+    }
+
+    PaUtil_FreeMemory( self->pfds );
+    ASSERT_CALL_( PaUnixMutex_Terminate( &self->stateMtx ), paNoError );
+
+    PaUtil_FreeMemory( self );
+}
+
+/** Calculate polling timeout
+ *
+ * @param frames Time to wait
+ * @return Polling timeout in milliseconds
+ */
+static int CalculatePollTimeout( const PaAlsaStream *stream, unsigned long frames )
+{
+    assert( stream->streamRepresentation.streamInfo.sampleRate > 0.0 );
+    /* Period in msecs, rounded up */
+    return (int)ceil( 1000 * frames / stream->streamRepresentation.streamInfo.sampleRate );
+}
+
+/** Determine size per host buffer.
+ *
+ * During this method call, the component's framesPerBuffer attribute gets computed, and the corresponding period size
+ * gets configured for the device.
+ * @param accurate: If the configured period size is non-integer, this will be set to 0.
+ */
+static PaError PaAlsaStreamComponent_DetermineFramesPerBuffer( PaAlsaStreamComponent* self, const PaStreamParameters* params,
+        unsigned long framesPerUserBuffer, double sampleRate, snd_pcm_hw_params_t* hwParams, int* accurate )
+{
+    PaError result = paNoError;
+    unsigned long bufferSize = params->suggestedLatency * sampleRate, framesPerHostBuffer;
+    int dir = 0;
+    
+    {
+        snd_pcm_uframes_t tmp;
+        snd_pcm_hw_params_get_buffer_size_min( hwParams, &tmp );
+        bufferSize = PA_MAX( bufferSize, tmp );
+        snd_pcm_hw_params_get_buffer_size_max( hwParams, &tmp );
+        bufferSize = PA_MIN( bufferSize, tmp );
+    }
+
+    assert( bufferSize > 0 );
+
+    if( framesPerUserBuffer != paFramesPerBufferUnspecified )
+    {
+        /* Preferably the host buffer size should be a multiple of the user buffer size */
+
+        if( bufferSize > framesPerUserBuffer )
+        {
+            snd_pcm_uframes_t remainder = bufferSize % framesPerUserBuffer;
+            if( remainder > framesPerUserBuffer / 2. )
+                bufferSize += framesPerUserBuffer - remainder;
+            else
+                bufferSize -= remainder;
+
+            assert( bufferSize % framesPerUserBuffer == 0 );
+        }
+        else if( framesPerUserBuffer % bufferSize != 0 )
+        {
+            /*  Find a good compromise between user specified latency and buffer size */
+            if( bufferSize > framesPerUserBuffer * .75 )
+            {
+                bufferSize = framesPerUserBuffer;
+            }
+            else
+            {
+                snd_pcm_uframes_t newSz = framesPerUserBuffer;
+                while( newSz / 2 >= bufferSize )
+                {
+                    if( framesPerUserBuffer % (newSz / 2) != 0 )
+                    {
+                        /* No use dividing any further */
+                        break;
+                    }
+                    newSz /= 2;
+                }
+                bufferSize = newSz;
+            }
+
+            assert( framesPerUserBuffer % bufferSize == 0 );
+        }
+    }
+
+    /* Using 5 as a base number of periods, we try to approximate the suggested latency (+1 period),
+       finding a combination of period/buffer size which best fits these constraints */
+    {
+        unsigned numPeriods = 4, maxPeriods = 0;
+        /* It may be that the device only supports 2 periods for instance */
+        dir = 0;
+        ENSURE_( snd_pcm_hw_params_get_periods_max( hwParams, &maxPeriods, &dir ), paUnanticipatedHostError );
+        assert( maxPeriods > 1 );
+        /* One period is not counted as latency */
+        maxPeriods -= 1;
+        numPeriods = PA_MIN( maxPeriods, numPeriods );
+
+        if( framesPerUserBuffer != paFramesPerBufferUnspecified )
+        {
+            framesPerHostBuffer = framesPerUserBuffer;
+            if( framesPerHostBuffer < bufferSize )
+            {
+                while( bufferSize / framesPerHostBuffer > numPeriods )
+                {
+                    framesPerHostBuffer *= 2;
+                }
+            }
+            else
+            {
+                while( bufferSize / framesPerHostBuffer < numPeriods )
+                {
+                    if( framesPerUserBuffer % (framesPerHostBuffer / 2) != 0 )
+                    {
+                        /* Can't be divided any further */
+                        break;
+                    }
+                    framesPerHostBuffer /= 2;
+                }
+            }
+
+            if( framesPerHostBuffer < framesPerUserBuffer )
+            {
+                assert( framesPerUserBuffer % framesPerHostBuffer == 0 );
+                if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer, 0 ) < 0 )
+                {
+                    if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer * 2, 0 ) == 0 )
+                        framesPerHostBuffer *= 2;
+                    else if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer / 2, 0 ) == 0 )
+                        framesPerHostBuffer /= 2;
+                }
+            }
+            else
+            {
+                assert( framesPerHostBuffer % framesPerUserBuffer == 0 );
+                if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer, 0 ) < 0 )
+                {
+                    if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer + framesPerUserBuffer, 0 ) == 0 )
+                        framesPerHostBuffer += framesPerUserBuffer;
+                    else if( snd_pcm_hw_params_test_period_size( self->pcm, hwParams, framesPerHostBuffer - framesPerUserBuffer, 0 ) == 0 )
+                        framesPerHostBuffer -= framesPerUserBuffer;
+                }
+            }
+        }
+        else
+        {
+            framesPerHostBuffer = bufferSize / numPeriods;
+        }
+    }
+
+    assert( framesPerHostBuffer > 0 );
+    {
+        snd_pcm_uframes_t min = 0, max = 0;
+        ENSURE_( snd_pcm_hw_params_get_period_size_min( hwParams, &min, NULL ), paUnanticipatedHostError );
+        ENSURE_( snd_pcm_hw_params_get_period_size_max( hwParams, &max, NULL ), paUnanticipatedHostError );
+
+        if( framesPerHostBuffer < min )
+        {
+            framesPerHostBuffer = min;
+            PA_DEBUG(( "%s: The determined period size (%lu) is less than minimum (%lu)\n", __FUNCTION__,
+                        framesPerHostBuffer, min ));
+        }
+        else if( framesPerHostBuffer > max )
+        {
+            framesPerHostBuffer = max;
+            PA_DEBUG(( "%s: The determined period size (%lu) is greater than maximum (%lu)\n", __FUNCTION__,
+                        framesPerHostBuffer, max ));
+        }
+
+        assert( framesPerHostBuffer >= min && framesPerHostBuffer <= max );
+        dir = 0;
+        ENSURE_( snd_pcm_hw_params_set_period_size_near( self->pcm, hwParams, &framesPerHostBuffer, &dir ),
+                paUnanticipatedHostError );
+        if( dir != 0 )
+        {
+            PA_DEBUG(( "%s: The configured period size is non-integer.\n", __FUNCTION__, dir ));
+            *accurate = 0;
+        }
+    }
+    self->framesPerBuffer = framesPerHostBuffer;
+
+error:
+    return result;
+}
+
+/* We need to determine how many frames per host buffer (period) to use.  Our
+ * goals are to provide the best possible performance, but also to
+ * honor the requested latency settings as closely as we can. Therefore this
+ * decision is based on:
+ *
+ *   - the period sizes that playback and/or capture support.  The
+ *     host buffer size has to be one of these.
+ *   - the number of periods that playback and/or capture support.
+ *
+ * We want to make period_size*(num_periods-1) to be as close as possible
+ * to latency*rate for both playback and capture.
+ *
+ * This method will determine suitable period sizes for capture and playback handles, and report the maximum number of
+ * frames per host buffer. The latter is relevant, in case we should be so unfortunate that the period size differs
+ * between capture and playback. If this should happen, the stream's hostBufferSizeMode attribute will be set to
+ * paUtilBoundedHostBufferSize, because the best we can do is limit the size of individual host buffers to the upper
+ * bound. The size of host buffers scheduled for processing should only matter if the user has specified a buffer size,
+ * but when he/she does we must strive for an optimal configuration. By default we'll opt for a fixed host buffer size,
+ * which should be fine if the period size is the same for capture and playback. In general, if there is a specified user
+ * buffer size, this method tries it best to determine a period size which is a multiple of the user buffer size.
+ *
+ * The framesPerBuffer attributes of the individual capture and playback components of the stream are set to corresponding
+ * values determined here. Since these should be reported as 
+ *
+ * This is one of those blocks of code that will just take a lot of
+ * refinement to be any good.
+ *
+ * In the full-duplex case it is possible that the routine was unable
+ * to find a number of frames per buffer acceptable to both devices
+ * TODO: Implement an algorithm to find the value closest to acceptance
+ * by both devices, to minimize difference between period sizes?
+ *
+ * @param determinedFramesPerHostBuffer: The determined host buffer size.
+ */
+static PaError PaAlsaStream_DetermineFramesPerBuffer( PaAlsaStream* self, double sampleRate, const PaStreamParameters* inputParameters,
+        const PaStreamParameters* outputParameters, unsigned long framesPerUserBuffer, snd_pcm_hw_params_t* hwParamsCapture,
+        snd_pcm_hw_params_t* hwParamsPlayback, PaUtilHostBufferSizeMode* hostBufferSizeMode )
+{
+    PaError result = paNoError;
+    unsigned long framesPerHostBuffer = 0;
+    int dir = 0;
+    int accurate = 1;
+
+    if( self->capture.pcm && self->playback.pcm )
+    {
+        if( framesPerUserBuffer == paFramesPerBufferUnspecified )
+        {
+            snd_pcm_uframes_t desiredLatency, e, minPeriodSize, maxPeriodSize, optimalPeriodSize, periodSize,
+                              minCapture, minPlayback, maxCapture, maxPlayback;
+
+            /* Come up with a common desired latency */
+
+            dir = 0;
+            ENSURE_( snd_pcm_hw_params_get_period_size_min( hwParamsCapture, &minCapture, &dir ), paUnanticipatedHostError );
+            dir = 0;
+            ENSURE_( snd_pcm_hw_params_get_period_size_min( hwParamsPlayback, &minPlayback, &dir ), paUnanticipatedHostError );
+            dir = 0;
+            ENSURE_( snd_pcm_hw_params_get_period_size_max( hwParamsCapture, &maxCapture, &dir ), paUnanticipatedHostError );
+            dir = 0;
+            ENSURE_( snd_pcm_hw_params_get_period_size_max( hwParamsPlayback, &maxPlayback, &dir ), paUnanticipatedHostError );
+            minPeriodSize = PA_MAX( minPlayback, minCapture );
+            maxPeriodSize = PA_MIN( maxPlayback, maxCapture );
+            PA_UNLESS( minPeriodSize <= maxPeriodSize, paBadIODeviceCombination );
+
+            desiredLatency = (snd_pcm_uframes_t)(PA_MIN( outputParameters->suggestedLatency, inputParameters->suggestedLatency )
+                    * sampleRate);
+            /* Clamp desiredLatency */
+            {
+                snd_pcm_uframes_t maxBufferSize;
+                snd_pcm_uframes_t maxBufferSizeCapture, maxBufferSizePlayback;
+                ENSURE_( snd_pcm_hw_params_get_buffer_size_max( hwParamsCapture, &maxBufferSizeCapture ), paUnanticipatedHostError );
+                ENSURE_( snd_pcm_hw_params_get_buffer_size_max( hwParamsPlayback, &maxBufferSizePlayback ), paUnanticipatedHostError );
+                maxBufferSize = PA_MIN( maxBufferSizeCapture, maxBufferSizePlayback );
+
+                desiredLatency = PA_MIN( desiredLatency, maxBufferSize );
+            }
+
+            /* Find the closest power of 2 */
+            e = ilogb( minPeriodSize );
+            if( minPeriodSize & (minPeriodSize - 1) )
+                e += 1;
+            periodSize = (snd_pcm_uframes_t)pow( 2, e );
+
+            while( periodSize <= maxPeriodSize )
+            {
+                if( snd_pcm_hw_params_test_period_size( self->playback.pcm, hwParamsPlayback, periodSize, 0 ) >= 0 &&
+                        snd_pcm_hw_params_test_period_size( self->capture.pcm, hwParamsCapture, periodSize, 0 ) >= 0 )
+                    break;  /* Ok! */
+
+                periodSize *= 2;
+            }
+
+            /* 4 periods considered optimal */
+            optimalPeriodSize = PA_MAX( desiredLatency / 4, minPeriodSize );
+            optimalPeriodSize = PA_MIN( optimalPeriodSize, maxPeriodSize );
+
+            /* Find the closest power of 2 */
+            e = ilogb( optimalPeriodSize );
+            if( optimalPeriodSize & (optimalPeriodSize - 1) )
+                e += 1;
+            optimalPeriodSize = (snd_pcm_uframes_t)pow( 2, e );
+
+            while( optimalPeriodSize >= periodSize )
+            {
+                if( snd_pcm_hw_params_test_period_size( self->capture.pcm, hwParamsCapture, optimalPeriodSize, 0 ) < 0 )
+                    continue;
+                if( snd_pcm_hw_params_test_period_size( self->playback.pcm, hwParamsPlayback, optimalPeriodSize, 0 ) >= 0 )
+                    break;
+                optimalPeriodSize /= 2;
+            }
+            if( optimalPeriodSize > periodSize )
+                periodSize = optimalPeriodSize;
+
+            if( periodSize <= maxPeriodSize )
+            {
+                /* Looks good, the periodSize _should_ be acceptable by both devices */
+                ENSURE_( snd_pcm_hw_params_set_period_size( self->capture.pcm, hwParamsCapture, periodSize, 0 ),
+                        paUnanticipatedHostError );
+                ENSURE_( snd_pcm_hw_params_set_period_size( self->playback.pcm, hwParamsPlayback, periodSize, 0 ),
+                        paUnanticipatedHostError );
+                self->capture.framesPerBuffer = self->playback.framesPerBuffer = periodSize;
+                framesPerHostBuffer = periodSize;
+            }
+            else
+            {
+                /* Unable to find a common period size, oh well */
+                optimalPeriodSize = PA_MAX( desiredLatency / 4, minPeriodSize );
+                optimalPeriodSize = PA_MIN( optimalPeriodSize, maxPeriodSize );
+
+                self->capture.framesPerBuffer = optimalPeriodSize;
+                dir = 0;
+                ENSURE_( snd_pcm_hw_params_set_period_size_near( self->capture.pcm, hwParamsCapture, &self->capture.framesPerBuffer, &dir ),
+                        paUnanticipatedHostError );
+                self->playback.framesPerBuffer = optimalPeriodSize;
+                dir = 0;
+                ENSURE_( snd_pcm_hw_params_set_period_size_near( self->playback.pcm, hwParamsPlayback, &self->playback.framesPerBuffer, &dir ),
+                        paUnanticipatedHostError );
+                framesPerHostBuffer = PA_MAX( self->capture.framesPerBuffer, self->playback.framesPerBuffer );
+                *hostBufferSizeMode = paUtilBoundedHostBufferSize;
+            }
+        }
+        else
+        {
+            /* We choose the simple route and determine a suitable number of frames per buffer for one component of
+             * the stream, then we hope that this will work for the other component too (it should!).
+             */
+
+            unsigned maxPeriods = 0;
+            PaAlsaStreamComponent* first = &self->capture, * second = &self->playback;
+            const PaStreamParameters* firstStreamParams = inputParameters;
+            snd_pcm_hw_params_t* firstHwParams = hwParamsCapture, * secondHwParams = hwParamsPlayback;
+
+            dir = 0;
+            ENSURE_( snd_pcm_hw_params_get_periods_max( hwParamsPlayback, &maxPeriods, &dir ), paUnanticipatedHostError );
+            if( maxPeriods < 4 )
+            {
+                /* The playback component is trickier to get right, try that first */
+                first = &self->playback;
+                second = &self->capture;
+                firstStreamParams = outputParameters;
+                firstHwParams = hwParamsPlayback;
+                secondHwParams = hwParamsCapture;
+            }
+
+            PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( first, firstStreamParams, framesPerUserBuffer,
+                        sampleRate, firstHwParams, &accurate ) );
+
+            second->framesPerBuffer = first->framesPerBuffer;
+            dir = 0;
+            ENSURE_( snd_pcm_hw_params_set_period_size_near( second->pcm, secondHwParams, &second->framesPerBuffer, &dir ),
+                    paUnanticipatedHostError );
+            if( self->capture.framesPerBuffer == self->playback.framesPerBuffer )
+            {
+                framesPerHostBuffer = self->capture.framesPerBuffer;
+            }
+            else
+            {
+                framesPerHostBuffer = PA_MAX( self->capture.framesPerBuffer, self->playback.framesPerBuffer );
+                *hostBufferSizeMode = paUtilBoundedHostBufferSize;
+            }
+        }
+    }
+    else    /* half-duplex is a slightly simpler case */
+    {
+        if( self->capture.pcm )
+        {
+            PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( &self->capture, inputParameters, framesPerUserBuffer,
+                        sampleRate, hwParamsCapture, &accurate) );
+            framesPerHostBuffer = self->capture.framesPerBuffer;
+        }
+        else
+        {
+            assert( self->playback.pcm );
+            PA_ENSURE( PaAlsaStreamComponent_DetermineFramesPerBuffer( &self->playback, outputParameters, framesPerUserBuffer,
+                        sampleRate, hwParamsPlayback, &accurate ) );
+            framesPerHostBuffer = self->playback.framesPerBuffer;
+        }
+    }
+
+    PA_UNLESS( framesPerHostBuffer != 0, paInternalError );
+    self->maxFramesPerHostBuffer = framesPerHostBuffer;
+
+    if( !accurate )
+    {
+        /* Don't know the exact size per host buffer */
+        *hostBufferSizeMode = paUtilBoundedHostBufferSize;
+        /* Raise upper bound */
+        ++self->maxFramesPerHostBuffer;
+    }
+
+error:
+    return result;
+}
+
+/** Set up ALSA stream parameters.
+ *
+ */
+static PaError PaAlsaStream_Configure( PaAlsaStream *self, const PaStreamParameters *inParams, const PaStreamParameters*
+        outParams, double sampleRate, unsigned long framesPerUserBuffer, double* inputLatency, double* outputLatency,
+        PaUtilHostBufferSizeMode* hostBufferSizeMode )
+{
+    PaError result = paNoError;
+    double realSr = sampleRate;
+    snd_pcm_hw_params_t* hwParamsCapture, * hwParamsPlayback;
+
+    snd_pcm_hw_params_alloca( &hwParamsCapture );
+    snd_pcm_hw_params_alloca( &hwParamsPlayback );
+
+    if( self->capture.pcm )
+        PA_ENSURE( PaAlsaStreamComponent_InitialConfigure( &self->capture, inParams, self->primeBuffers, hwParamsCapture,
+                    &realSr ) );
+    if( self->playback.pcm )
+        PA_ENSURE( PaAlsaStreamComponent_InitialConfigure( &self->playback, outParams, self->primeBuffers, hwParamsPlayback,
+                    &realSr ) );
+
+    PA_ENSURE( PaAlsaStream_DetermineFramesPerBuffer( self, realSr, inParams, outParams, framesPerUserBuffer,
+                hwParamsCapture, hwParamsPlayback, hostBufferSizeMode ) );
+
+    if( self->capture.pcm )
+    {
+        assert( self->capture.framesPerBuffer != 0 );
+        PA_ENSURE( PaAlsaStreamComponent_FinishConfigure( &self->capture, hwParamsCapture, inParams, self->primeBuffers, realSr,
+                    inputLatency ) );
+        PA_DEBUG(( "%s: Capture period size: %lu, latency: %f\n", __FUNCTION__, self->capture.framesPerBuffer, *inputLatency ));
+    }
+    if( self->playback.pcm )
+    {
+        assert( self->playback.framesPerBuffer != 0 );
+        PA_ENSURE( PaAlsaStreamComponent_FinishConfigure( &self->playback, hwParamsPlayback, outParams, self->primeBuffers, realSr,
+                    outputLatency ) );
+        PA_DEBUG(( "%s: Playback period size: %lu, latency: %f\n", __FUNCTION__, self->playback.framesPerBuffer, *outputLatency ));
+    }
+
+    /* Should be exact now */
+    self->streamRepresentation.streamInfo.sampleRate = realSr;
+
+    /* this will cause the two streams to automatically start/stop/prepare in sync.
+     * We only need to execute these operations on one of the pair.
+     * A: We don't want to do this on a blocking stream.
+     */
+    if( self->callbackMode && self->capture.pcm && self->playback.pcm )
+    {
+        int err = snd_pcm_link( self->capture.pcm, self->playback.pcm );
+        if( err == 0 )
+            self->pcmsSynced = 1;
+        else
+            PA_DEBUG(( "%s: Unable to sync pcms: %s\n", __FUNCTION__, snd_strerror( err ) ));
+    }
+
+    {
+        unsigned long minFramesPerHostBuffer = PA_MIN( self->capture.pcm ? self->capture.framesPerBuffer : ULONG_MAX,
+            self->playback.pcm ? self->playback.framesPerBuffer : ULONG_MAX );
+        self->pollTimeout = CalculatePollTimeout( self, minFramesPerHostBuffer );    /* Period in msecs, rounded up */
+
+        /* Time before watchdog unthrottles realtime thread == 1/4 of period time in msecs */
+        /* self->threading.throttledSleepTime = (unsigned long) (minFramesPerHostBuffer / sampleRate / 4 * 1000); */
+    }
+
+    if( self->callbackMode )
+    {
+        /* If the user expects a certain number of frames per callback we will either have to rely on block adaption
+         * (framesPerHostBuffer is not an integer multiple of framesPerBuffer) or we can simply align the number
+         * of host buffer frames with what the user specified */
+        if( self->framesPerUserBuffer != paFramesPerBufferUnspecified )
+        {
+            /* self->alignFrames = 1; */
+
+            /* Unless the ratio between number of host and user buffer frames is an integer we will have to rely
+             * on block adaption */
+        /*
+            if( framesPerHostBuffer % framesPerBuffer != 0 || (self->capture.pcm && self->playback.pcm &&
+                        self->capture.framesPerBuffer != self->playback.framesPerBuffer) )
+                self->useBlockAdaption = 1;
+            else
+                self->alignFrames = 1;
+        */
+        }
+    }
+
+error:
+    return result;
+}
+
+static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
+                           PaStream** s,
+                           const PaStreamParameters *inputParameters,
+                           const PaStreamParameters *outputParameters,
+                           double sampleRate,
+                           unsigned long framesPerBuffer,
+                           PaStreamFlags streamFlags,
+                           PaStreamCallback* callback,
+                           void *userData )
+{
+    PaError result = paNoError;
+    PaAlsaHostApiRepresentation *alsaHostApi = (PaAlsaHostApiRepresentation*)hostApi;
+    PaAlsaStream *stream = NULL;
+    PaSampleFormat hostInputSampleFormat = 0, hostOutputSampleFormat = 0;
+    PaSampleFormat inputSampleFormat = 0, outputSampleFormat = 0;
+    int numInputChannels = 0, numOutputChannels = 0;
+    PaTime inputLatency, outputLatency;
+    /* Operate with fixed host buffer size by default, since other modes will invariably lead to block adaption */
+    /* XXX: Use Bounded by default? Output tends to get stuttery with Fixed ... */
+    PaUtilHostBufferSizeMode hostBufferSizeMode = paUtilFixedHostBufferSize;
+
+    if( (streamFlags & paPlatformSpecificFlags) != 0 )
+        return paInvalidFlag;
+
+    if( inputParameters )
+    {
+        PA_ENSURE( ValidateParameters( inputParameters, hostApi, StreamDirection_In ) );
+
+        numInputChannels = inputParameters->channelCount;
+        inputSampleFormat = inputParameters->sampleFormat;
+    }
+    if( outputParameters )
+    {
+        PA_ENSURE( ValidateParameters( outputParameters, hostApi, StreamDirection_Out ) );
+
+        numOutputChannels = outputParameters->channelCount;
+        outputSampleFormat = outputParameters->sampleFormat;
+    }
+
+    /* XXX: Why do we support this anyway? */
+    if( framesPerBuffer == paFramesPerBufferUnspecified && getenv( "PA_ALSA_PERIODSIZE" ) != NULL )
+    {
+        PA_DEBUG(( "%s: Getting framesPerBuffer from environment\n", __FUNCTION__ ));
+        framesPerBuffer = atoi( getenv("PA_ALSA_PERIODSIZE") );
+    }
+
+    PA_UNLESS( stream = (PaAlsaStream*)PaUtil_AllocateMemory( sizeof(PaAlsaStream) ), paInsufficientMemory );
+    PA_ENSURE( PaAlsaStream_Initialize( stream, alsaHostApi, inputParameters, outputParameters, sampleRate,
+                framesPerBuffer, callback, streamFlags, userData ) );
+
+    PA_ENSURE( PaAlsaStream_Configure( stream, inputParameters, outputParameters, sampleRate, framesPerBuffer,
+                &inputLatency, &outputLatency, &hostBufferSizeMode ) );
+    hostInputSampleFormat = stream->capture.hostSampleFormat;
+    hostOutputSampleFormat = stream->playback.hostSampleFormat;
+
+    PA_ENSURE( PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
+                    numInputChannels, inputSampleFormat, hostInputSampleFormat,
+                    numOutputChannels, outputSampleFormat, hostOutputSampleFormat,
+                    sampleRate, streamFlags, framesPerBuffer, stream->maxFramesPerHostBuffer,
+                    hostBufferSizeMode, callback, userData ) );
+
+    /* Ok, buffer processor is initialized, now we can deduce it's latency */
+    if( numInputChannels > 0 )
+        stream->streamRepresentation.streamInfo.inputLatency = inputLatency + PaUtil_GetBufferProcessorInputLatency(
+                &stream->bufferProcessor );
+    if( numOutputChannels > 0 )
+        stream->streamRepresentation.streamInfo.outputLatency = outputLatency + PaUtil_GetBufferProcessorOutputLatency(
+                &stream->bufferProcessor );
+
+    *s = (PaStream*)stream;
+
+    return result;
+
+error:
+    if( stream )
+    {
+        PA_DEBUG(( "%s: Stream in error, terminating\n", __FUNCTION__ ));
+        PaAlsaStream_Terminate( stream );
+    }
+
+    return result;
+}
+
+static PaError CloseStream( PaStream* s )
+{
+    PaError result = paNoError;
+    PaAlsaStream *stream = (PaAlsaStream*)s;
+
+    PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
+    PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
+
+    PaAlsaStream_Terminate( stream );
+
+    return result;
+}
+
+static void SilenceBuffer( PaAlsaStream *stream )
+{
+    const snd_pcm_channel_area_t *areas;
+    snd_pcm_uframes_t frames = (snd_pcm_uframes_t)snd_pcm_avail_update( stream->playback.pcm ), offset;
+
+    snd_pcm_mmap_begin( stream->playback.pcm, &areas, &offset, &frames );
+    snd_pcm_areas_silence( areas, offset, stream->playback.numHostChannels, frames, stream->playback.nativeFormat );
+    snd_pcm_mmap_commit( stream->playback.pcm, offset, frames );
+}
+
+/** Start/prepare pcm(s) for streaming.
+ *
+ * Depending on wether the stream is in callback or blocking mode, we will respectively start or simply
+ * prepare the playback pcm. If the buffer has _not_ been primed, we will in callback mode prepare and
+ * silence the buffer before starting playback. In blocking mode we simply prepare, as the playback will
+ * be started automatically as the user writes to output. 
+ *
+ * The capture pcm, however, will simply be prepared and started.
+ */
+static PaError AlsaStart( PaAlsaStream *stream, int priming )
+{
+    PaError result = paNoError;
+
+    if( stream->playback.pcm )
+    {
+        if( stream->callbackMode )
+        {
+            if( !priming )
+            {
+                /* Buffer isn't primed, so prepare and silence */
+                ENSURE_( snd_pcm_prepare( stream->playback.pcm ), paUnanticipatedHostError );
+                SilenceBuffer( stream );
+            }
+            ENSURE_( snd_pcm_start( stream->playback.pcm ), paUnanticipatedHostError );
+        }
+        else
+            ENSURE_( snd_pcm_prepare( stream->playback.pcm ), paUnanticipatedHostError );
+    }
+    if( stream->capture.pcm && !stream->pcmsSynced )
+    {
+        ENSURE_( snd_pcm_prepare( stream->capture.pcm ), paUnanticipatedHostError );
+        /* For a blocking stream we want to start capture as well, since nothing will happen otherwise */
+        ENSURE_( snd_pcm_start( stream->capture.pcm ), paUnanticipatedHostError );
+    }
+
+end:
+    return result;
+error:
+    goto end;
+}
+
+/** Utility function for determining if pcms are in running state.
+ *
+ */
+#if 0
+static int IsRunning( PaAlsaStream *stream )
+{
+    int result = 0;
+
+    PA_ENSURE( PaUnixMutex_Lock( &stream->stateMtx ) );
+    if( stream->capture.pcm )
+    {
+        snd_pcm_state_t capture_state = snd_pcm_state( stream->capture.pcm );
+
+        if( capture_state == SND_PCM_STATE_RUNNING || capture_state == SND_PCM_STATE_XRUN
+                || capture_state == SND_PCM_STATE_DRAINING )
+        {
+            result = 1;
+            goto end;
+        }
+    }
+
+    if( stream->playback.pcm )
+    {
+        snd_pcm_state_t playback_state = snd_pcm_state( stream->playback.pcm );
+
+        if( playback_state == SND_PCM_STATE_RUNNING || playback_state == SND_PCM_STATE_XRUN
+                || playback_state == SND_PCM_STATE_DRAINING )
+        {
+            result = 1;
+            goto end;
+        }
+    }
+
+end:
+    ASSERT_CALL_( PaUnixMutex_Unlock( &stream->stateMtx ), paNoError );
+    return result;
+error:
+    goto error;
+}
+#endif
+
+static PaError StartStream( PaStream *s )
+{
+    PaError result = paNoError;
+    PaAlsaStream* stream = (PaAlsaStream*)s;
+    int streamStarted = 0;  /* So we can know wether we need to take the stream down */
+
+    /* Ready the processor */
+    PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
+
+    /* Set now, so we can test for activity further down */
+    stream->isActive = 1;
+
+    if( stream->callbackMode )
+    {
+        PA_ENSURE( PaUnixThread_New( &stream->thread, &CallbackThreadFunc, stream, 1. ) );
+    }
+    else
+    {
+        PA_ENSURE( AlsaStart( stream, 0 ) );
+        streamStarted = 1;
+    }
+
+end:
+    return result;
+error:
+    if( streamStarted )
+    {
+        AbortStream( stream );
+    }
+    stream->isActive = 0;
+    
+    goto end;
+}
+
+/** Stop PCM handle, either softly or abruptly.
+ */
+static PaError AlsaStop( PaAlsaStream *stream, int abort )
+{
+    PaError result = paNoError;
+
+    if( abort )
+    {
+        if( stream->playback.pcm )
+        {
+            ENSURE_( snd_pcm_drop( stream->playback.pcm ), paUnanticipatedHostError );
+        }
+        if( stream->capture.pcm && !stream->pcmsSynced )
+        {
+            ENSURE_( snd_pcm_drop( stream->capture.pcm ), paUnanticipatedHostError );
+        }
+
+        PA_DEBUG(( "%s: Dropped frames\n", __FUNCTION__ ));
+    }
+    else
+    {
+        if( stream->playback.pcm )
+        {
+            ENSURE_( snd_pcm_nonblock( stream->playback.pcm, 0 ), paUnanticipatedHostError );
+            if( snd_pcm_drain( stream->playback.pcm ) < 0 )
+            {
+                PA_DEBUG(( "%s: Draining playback handle failed!\n", __FUNCTION__ ));
+            }
+        }
+        if( stream->capture.pcm && !stream->pcmsSynced )
+        {
+            /* We don't need to retrieve any remaining frames */
+            if( snd_pcm_drop( stream->capture.pcm ) < 0 )
+            {
+                PA_DEBUG(( "%s: Draining capture handle failed!\n", __FUNCTION__ ));
+            }
+        }
+    }
+
+end:
+    return result;
+error:
+    goto end;
+}
+
+/** Stop or abort stream.
+ *
+ * If a stream is in callback mode we will have to inspect wether the background thread has
+ * finished, or we will have to take it out. In either case we join the thread before
+ * returning. In blocking mode, we simply tell ALSA to stop abruptly (abort) or finish
+ * buffers (drain)
+ *
+ * Stream will be considered inactive (!PaAlsaStream::isActive) after a call to this function
+ */
+static PaError RealStop( PaAlsaStream *stream, int abort )
+{
+    PaError result = paNoError;
+
+    /* First deal with the callback thread, cancelling and/or joining
+     * it if necessary
+     */
+    if( stream->callbackMode )
+    {
+        PaError threadRes;
+        stream->callbackAbort = abort;
+
+        if( !abort )
+        {
+            PA_DEBUG(( "Stopping callback\n" ));
+        }
+        PA_ENSURE( PaUnixThread_Terminate( &stream->thread, !abort, &threadRes ) );
+        if( threadRes != paNoError )
+        {
+            PA_DEBUG(( "Callback thread returned: %d\n", threadRes ));
+        }
+#if 0
+        if( watchdogRes != paNoError )
+            PA_DEBUG(( "Watchdog thread returned: %d\n", watchdogRes ));
+#endif
+
+        stream->callback_finished = 0;
+    }
+    else
+    {
+        PA_ENSURE( AlsaStop( stream, abort ) );
+    }
+
+    stream->isActive = 0;
+
+end:
+    return result;
+
+error:
+    goto end;
+}
+
+static PaError StopStream( PaStream *s )
+{
+    return RealStop( (PaAlsaStream *) s, 0 );
+}
+
+static PaError AbortStream( PaStream *s )
+{
+    return RealStop( (PaAlsaStream * ) s, 1 );
+}
+
+/** The stream is considered stopped before StartStream, or AFTER a call to Abort/StopStream (callback
+ * returning !paContinue is not considered)
+ *
+ */
+static PaError IsStreamStopped( PaStream *s )
+{
+    PaAlsaStream *stream = (PaAlsaStream *)s;
+
+    /* callback_finished indicates we need to join callback thread (ie. in Abort/StopStream) */
+    return !IsStreamActive( s ) && !stream->callback_finished;
+}
+
+static PaError IsStreamActive( PaStream *s )
+{
+    PaAlsaStream *stream = (PaAlsaStream*)s;
+    return stream->isActive;
+}
+
+static PaTime GetStreamTime( PaStream *s )
+{
+    PaAlsaStream *stream = (PaAlsaStream*)s;
+
+    snd_timestamp_t timestamp;
+    snd_pcm_status_t* status;
+    snd_pcm_status_alloca( &status );
+
+    /* TODO: what if we have both?  does it really matter? */
+
+    /* TODO: if running in callback mode, this will mean
+     * libasound routines are being called from multiple threads.
+     * need to verify that libasound is thread-safe. */
+
+    if( stream->capture.pcm )
+    {
+        snd_pcm_status( stream->capture.pcm, status );
+    }
+    else if( stream->playback.pcm )
+    {
+        snd_pcm_status( stream->playback.pcm, status );
+    }
+
+    snd_pcm_status_get_tstamp( status, &timestamp );
+    return timestamp.tv_sec + (PaTime)timestamp.tv_usec / 1e6;
+}
+
+static double GetStreamCpuLoad( PaStream* s )
+{
+    PaAlsaStream *stream = (PaAlsaStream*)s;
+
+    return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
+}
+
+static int SetApproximateSampleRate( snd_pcm_t *pcm, snd_pcm_hw_params_t *hwParams, double sampleRate )
+{
+    unsigned long approx = (unsigned long) sampleRate;
+    int dir = 0;
+    double fraction = sampleRate - approx;
+
+    assert( pcm && hwParams );
+
+    if( fraction > 0.0 )
+    {
+        if( fraction > 0.5 )
+        {
+            ++approx;
+            dir = -1;
+        }
+        else
+            dir = 1;
+    }
+
+    return snd_pcm_hw_params_set_rate( pcm, hwParams, approx, dir );
+}
+
+/* Return exact sample rate in param sampleRate */
+static int GetExactSampleRate( snd_pcm_hw_params_t *hwParams, double *sampleRate )
+{
+    unsigned int num, den;
+    int err; 
+
+    assert( hwParams );
+
+    err = snd_pcm_hw_params_get_rate_numden( hwParams, &num, &den );
+    *sampleRate = (double) num / den;
+
+    return err;
+}
+
+/* Utility functions for blocking/callback interfaces */
+
+/* Atomic restart of stream (we don't want the intermediate state visible) */
+static PaError AlsaRestart( PaAlsaStream *stream )
+{
+    PaError result = paNoError;
+
+    PA_ENSURE( PaUnixMutex_Lock( &stream->stateMtx ) );
+    PA_ENSURE( AlsaStop( stream, 0 ) );
+    PA_ENSURE( AlsaStart( stream, 0 ) );
+
+    PA_DEBUG(( "%s: Restarted audio\n", __FUNCTION__ ));
+
+error:
+    PA_ENSURE( PaUnixMutex_Unlock( &stream->stateMtx ) );
+
+    return result;
+}
+
+/** Recover from xrun state.
+ *
+ */
+static PaError PaAlsaStream_HandleXrun( PaAlsaStream *self )
+{
+    PaError result = paNoError;
+    snd_pcm_status_t *st;
+    PaTime now = PaUtil_GetTime();
+    snd_timestamp_t t;
+
+    snd_pcm_status_alloca( &st );
+
+    if( self->playback.pcm )
+    {
+        snd_pcm_status( self->playback.pcm, st );
+        if( snd_pcm_status_get_state( st ) == SND_PCM_STATE_XRUN )
+        {
+            snd_pcm_status_get_trigger_tstamp( st, &t );
+            self->underrun = now * 1000 - ((PaTime) t.tv_sec * 1000 + (PaTime) t.tv_usec / 1000);
+        }
+    }
+    if( self->capture.pcm )
+    {
+        snd_pcm_status( self->capture.pcm, st );
+        if( snd_pcm_status_get_state( st ) == SND_PCM_STATE_XRUN )
+        {
+            snd_pcm_status_get_trigger_tstamp( st, &t );
+            self->overrun = now * 1000 - ((PaTime) t.tv_sec * 1000 + (PaTime) t.tv_usec / 1000);
+        }
+    }
+
+    PA_ENSURE( AlsaRestart( self ) );
+
+end:
+    return result;
+error:
+    goto end;
+}
+
+/** Decide if we should continue polling for specified direction, eventually adjust the poll timeout.
+ * 
+ */
+static PaError ContinuePoll( const PaAlsaStream *stream, StreamDirection streamDir, int *pollTimeout, int *continuePoll )
+{
+    PaError result = paNoError;
+    snd_pcm_sframes_t delay, margin;
+    int err;
+    const PaAlsaStreamComponent *component = NULL, *otherComponent = NULL;
+
+    *continuePoll = 1;
+
+    if( StreamDirection_In == streamDir )
+    {
+        component = &stream->capture;
+        otherComponent = &stream->playback;
+    }
+    else
+    {
+        component = &stream->playback;
+        otherComponent = &stream->capture;
+    }
+
+    /* ALSA docs say that negative delay should indicate xrun, but in my experience snd_pcm_delay returns -EPIPE */
+    if( (err = snd_pcm_delay( otherComponent->pcm, &delay )) < 0 )
+    {
+        if( err == -EPIPE )
+        {
+            /* Xrun */
+            *continuePoll = 0;
+            goto error;
+        }
+
+        ENSURE_( err, paUnanticipatedHostError );
+    }
+
+    if( StreamDirection_Out == streamDir )
+    {
+        /* Number of eligible frames before capture overrun */
+        delay = otherComponent->bufferSize - delay;
+    }
+    margin = delay - otherComponent->framesPerBuffer / 2;
+
+    if( margin < 0 )
+    {
+        PA_DEBUG(( "%s: Stopping poll for %s\n", __FUNCTION__, StreamDirection_In == streamDir ? "capture" : "playback" ));
+        *continuePoll = 0;
+    }
+    else if( margin < otherComponent->framesPerBuffer )
+    {
+        *pollTimeout = CalculatePollTimeout( stream, margin );
+        PA_DEBUG(( "%s: Trying to poll again for %s frames, pollTimeout: %d\n",
+                    __FUNCTION__, StreamDirection_In == streamDir ? "capture" : "playback", *pollTimeout ));
+    }
+
+error:
+    return result;
+}
+
+/* Callback interface */
+
+static void OnExit( void *data )
+{
+    PaAlsaStream *stream = (PaAlsaStream *) data;
+
+    assert( data );
+
+    PaUtil_ResetCpuLoadMeasurer( &stream->cpuLoadMeasurer );
+
+    stream->callback_finished = 1;  /* Let the outside world know stream was stopped in callback */
+    PA_DEBUG(( "%s: Stopping ALSA handles\n", __FUNCTION__ ));
+    AlsaStop( stream, stream->callbackAbort );
+    
+    PA_DEBUG(( "%s: Stoppage\n", __FUNCTION__ ));
+
+    /* Eventually notify user all buffers have played */
+    if( stream->streamRepresentation.streamFinishedCallback )
+    {
+        stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
+    }
+    stream->isActive = 0;
+}
+
+static void CalculateTimeInfo( PaAlsaStream *stream, PaStreamCallbackTimeInfo *timeInfo )
+{
+    snd_pcm_status_t *capture_status, *playback_status;
+    snd_timestamp_t capture_timestamp, playback_timestamp;
+    PaTime capture_time = 0., playback_time = 0.;
+
+    snd_pcm_status_alloca( &capture_status );
+    snd_pcm_status_alloca( &playback_status );
+
+    if( stream->capture.pcm )
+    {
+        snd_pcm_sframes_t capture_delay;
+
+        snd_pcm_status( stream->capture.pcm, capture_status );
+        snd_pcm_status_get_tstamp( capture_status, &capture_timestamp );
+
+        capture_time = capture_timestamp.tv_sec +
+            ((PaTime)capture_timestamp.tv_usec / 1000000.0);
+        timeInfo->currentTime = capture_time;
+
+        capture_delay = snd_pcm_status_get_delay( capture_status );
+        timeInfo->inputBufferAdcTime = timeInfo->currentTime -
+            (PaTime)capture_delay / stream->streamRepresentation.streamInfo.sampleRate;
+    }
+    if( stream->playback.pcm )
+    {
+        snd_pcm_sframes_t playback_delay;
+
+        snd_pcm_status( stream->playback.pcm, playback_status );
+        snd_pcm_status_get_tstamp( playback_status, &playback_timestamp );
+
+        playback_time = playback_timestamp.tv_sec +
+            ((PaTime)playback_timestamp.tv_usec / 1000000.0);
+
+        if( stream->capture.pcm ) /* Full duplex */
+        {
+            /* Hmm, we have both a playback and a capture timestamp.
+             * Hopefully they are the same... */
+            if( fabs( capture_time - playback_time ) > 0.01 )
+                PA_DEBUG(("Capture time and playback time differ by %f\n", fabs(capture_time-playback_time)));
+        }
+        else
+            timeInfo->currentTime = playback_time;
+
+        playback_delay = snd_pcm_status_get_delay( playback_status );
+        timeInfo->outputBufferDacTime = timeInfo->currentTime +
+            (PaTime)playback_delay / stream->streamRepresentation.streamInfo.sampleRate;
+    }
+}
+
+/** Called after buffer processing is finished.
+ *
+ * A number of mmapped frames is committed, it is possible that an xrun has occurred in the meantime.
+ *
+ * @param numFrames The number of frames that has been processed
+ * @param xrun Return whether an xrun has occurred
+ */
+static PaError PaAlsaStreamComponent_EndProcessing( PaAlsaStreamComponent *self, unsigned long numFrames, int *xrun )
+{
+    PaError result = paNoError;
+    int res;
+
+    /* @concern FullDuplex It is possible that only one direction is marked ready after polling, and processed
+     * afterwards
+     */
+    if( !self->ready )
+        goto end;
+
+    res = snd_pcm_mmap_commit( self->pcm, self->offset, numFrames );
+    if( res == -EPIPE || res == -ESTRPIPE )
+    {
+        *xrun = 1;
+    }
+    else
+    {
+        ENSURE_( res, paUnanticipatedHostError );
+    }
+
+end:
+error:
+    return result;
+}
+
+/* Extract buffer from channel area */
+static unsigned char *ExtractAddress( const snd_pcm_channel_area_t *area, snd_pcm_uframes_t offset )
+{
+    return (unsigned char *) area->addr + (area->first + offset * area->step) / 8;
+}
+
+/** Do necessary adaption between user and host channels.
+ *
+    @concern ChannelAdaption Adapting between user and host channels can involve silencing unused channels and
+    duplicating mono information if host outputs come in pairs.
+ */
+static PaError PaAlsaStreamComponent_DoChannelAdaption( PaAlsaStreamComponent *self, PaUtilBufferProcessor *bp, int numFrames )
+{
+    PaError result = paNoError;
+    unsigned char *p;
+    int i;
+    int unusedChans = self->numHostChannels - self->numUserChannels;
+    unsigned char *src, *dst;
+    int convertMono = (self->numHostChannels % 2) == 0 && (self->numUserChannels % 2) != 0;
+
+    assert( StreamDirection_Out == self->streamDir );
+
+    if( self->hostInterleaved )
+    {
+        int swidth = snd_pcm_format_size( self->nativeFormat, 1 );
+        unsigned char *buffer = ExtractAddress( self->channelAreas, self->offset );
+
+        /* Start after the last user channel */
+        p = buffer + self->numUserChannels * swidth;
+
+        if( convertMono )
+        {
+            /* Convert the last user channel into stereo pair */
+            src = buffer + (self->numUserChannels - 1) * swidth;
+            for( i = 0; i < numFrames; ++i )
+            {
+                dst = src + swidth;
+                memcpy( dst, src, swidth );
+                src += self->numHostChannels * swidth;
+            }
+
+            /* Don't touch the channel we just wrote to */
+            p += swidth;
+            --unusedChans;
+        }
+
+        if( unusedChans > 0 )
+        {
+            /* Silence unused output channels */
+            for( i = 0; i < numFrames; ++i )
+            {
+                memset( p, 0, swidth * unusedChans );
+                p += self->numHostChannels * swidth;
+            }
+        }
+    }
+    else
+    {
+        /* We extract the last user channel */
+        if( convertMono )
+        {
+            ENSURE_( snd_pcm_area_copy( self->channelAreas + self->numUserChannels, self->offset, self->channelAreas +
+                    (self->numUserChannels - 1), self->offset, numFrames, self->nativeFormat ), paUnanticipatedHostError );
+            --unusedChans;
+        }
+        if( unusedChans > 0 )
+        {
+            snd_pcm_areas_silence( self->channelAreas + (self->numHostChannels - unusedChans), self->offset, unusedChans, numFrames,
+                    self->nativeFormat );
+        }
+    }
+
+error:
+    return result;
+}
+
+static PaError PaAlsaStream_EndProcessing( PaAlsaStream *self, unsigned long numFrames, int *xrunOccurred )
+{
+    PaError result = paNoError;
+    int xrun = 0;
+
+    if( self->capture.pcm )
+    {
+        PA_ENSURE( PaAlsaStreamComponent_EndProcessing( &self->capture, numFrames, &xrun ) );
+    }
+    if( self->playback.pcm )
+    {
+        if( self->playback.numHostChannels > self->playback.numUserChannels )
+        {
+            PA_ENSURE( PaAlsaStreamComponent_DoChannelAdaption( &self->playback, &self->bufferProcessor, numFrames ) );
+        }
+        PA_ENSURE( PaAlsaStreamComponent_EndProcessing( &self->playback, numFrames, &xrun ) );
+    }
+
+error:
+    *xrunOccurred = xrun;
+    return result;
+}
+
+/** Update the number of available frames.
+ *
+ */
+static PaError PaAlsaStreamComponent_GetAvailableFrames( PaAlsaStreamComponent *self, unsigned long *numFrames, int *xrunOccurred )
+{
+    PaError result = paNoError;
+    snd_pcm_sframes_t framesAvail = snd_pcm_avail_update( self->pcm );
+    *xrunOccurred = 0;
+
+    if( -EPIPE == framesAvail )
+    {
+        *xrunOccurred = 1;
+        framesAvail = 0;
+    }
+    else
+    {
+        ENSURE_( framesAvail, paUnanticipatedHostError );
+    }
+
+    *numFrames = framesAvail;
+
+error:
+    return result;
+}
+
+/** Fill in pollfd objects.
+ */
+static PaError PaAlsaStreamComponent_BeginPolling( PaAlsaStreamComponent* self, struct pollfd* pfds )
+{
+    PaError result = paNoError;
+    int ret = snd_pcm_poll_descriptors( self->pcm, pfds, self->nfds );
+    (void)ret;  /* Prevent unused variable warning if asserts are turned off */
+    assert( ret == self->nfds );
+
+    self->ready = 0;
+
+    return result;
+}
+
+/** Examine results from poll().
+ *
+ * @param pfds pollfds to inspect
+ * @param shouldPoll Should we continue to poll
+ * @param xrun Has an xrun occurred
+ */
+static PaError PaAlsaStreamComponent_EndPolling( PaAlsaStreamComponent* self, struct pollfd* pfds, int* shouldPoll, int* xrun )
+{
+    PaError result = paNoError;
+    unsigned short revents;
+
+    ENSURE_( snd_pcm_poll_descriptors_revents( self->pcm, pfds, self->nfds, &revents ), paUnanticipatedHostError );
+    if( revents != 0 )
+    {
+        if( revents & POLLERR )
+        {
+            *xrun = 1;
+        }
+        else
+            self->ready = 1;
+
+        *shouldPoll = 0;
+    }
+
+error:
+    return result;
+}
+
+/** Return the number of available frames for this stream.
+ *
+ * @concern FullDuplex The minimum available for the two directions is calculated, it might be desirable to ignore
+ * one direction however (not marked ready from poll), so this is controlled by queryCapture and queryPlayback.
+ *
+ * @param queryCapture Check available for capture
+ * @param queryPlayback Check available for playback
+ * @param available The returned number of frames
+ * @param xrunOccurred Return whether an xrun has occurred
+ */
+static PaError PaAlsaStream_GetAvailableFrames( PaAlsaStream *self, int queryCapture, int queryPlayback, unsigned long
+        *available, int *xrunOccurred )
+{
+    PaError result = paNoError;
+    unsigned long captureFrames, playbackFrames;
+    *xrunOccurred = 0;
+
+    assert( queryCapture || queryPlayback );
+
+    if( queryCapture )
+    {
+        assert( self->capture.pcm );
+        PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &self->capture, &captureFrames, xrunOccurred ) );
+        if( *xrunOccurred )
+        {
+            goto end;
+        }
+    }
+    if( queryPlayback )
+    {
+        assert( self->playback.pcm );
+        PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &self->playback, &playbackFrames, xrunOccurred ) );
+        if( *xrunOccurred )
+        {
+            goto end;
+        }
+    }
+
+    if( queryCapture && queryPlayback )
+    {
+        *available = PA_MIN( captureFrames, playbackFrames );
+        /*PA_DEBUG(("capture: %lu, playback: %lu, combined: %lu\n", captureFrames, playbackFrames, *available));*/
+    }
+    else if( queryCapture )
+    {
+        *available = captureFrames;
+    }
+    else
+    {
+        *available = playbackFrames;
+    }
+
+end:
+error:
+    return result;
+}
+
+/** Wait for and report available buffer space from ALSA.
+ *
+ * Unless ALSA reports a minimum of frames available for I/O, we poll the ALSA filedescriptors for more.
+ * Both of these operations can uncover xrun conditions.
+ *
+ * @concern Xruns Both polling and querying available frames can report an xrun condition.
+ *
+ * @param framesAvail Return the number of available frames
+ * @param xrunOccurred Return whether an xrun has occurred
+ */ 
+static PaError PaAlsaStream_WaitForFrames( PaAlsaStream *self, unsigned long *framesAvail, int *xrunOccurred )
+{
+    PaError result = paNoError;
+    int pollPlayback = self->playback.pcm != NULL, pollCapture = self->capture.pcm != NULL;
+    int pollTimeout = self->pollTimeout;
+    int xrun = 0;
+
+    assert( self );
+    assert( framesAvail );
+
+    if( !self->callbackMode )
+    {
+        /* In blocking mode we will only wait if necessary */
+        PA_ENSURE( PaAlsaStream_GetAvailableFrames( self, self->capture.pcm != NULL, self->playback.pcm != NULL,
+                    framesAvail, &xrun ) );
+        if( xrun )
+        {
+            goto end;
+        }
+
+        if( *framesAvail > 0 )
+        {
+            /* Mark pcms ready from poll */
+            if( self->capture.pcm )
+                self->capture.ready = 1;
+            if( self->playback.pcm )
+                self->playback.ready = 1;
+
+            goto end;
+        }
+    }
+
+    while( pollPlayback || pollCapture )
+    {
+        int totalFds = 0;
+        struct pollfd *capturePfds = NULL, *playbackPfds = NULL;
+
+        pthread_testcancel();
+
+        if( pollCapture )
+        {
+            capturePfds = self->pfds;
+            PA_ENSURE( PaAlsaStreamComponent_BeginPolling( &self->capture, capturePfds ) );
+            totalFds += self->capture.nfds;
+        }
+        if( pollPlayback )
+        {
+            playbackPfds = self->pfds + (self->capture.pcm ? self->capture.nfds : 0);
+            PA_ENSURE( PaAlsaStreamComponent_BeginPolling( &self->playback, playbackPfds ) );
+            totalFds += self->playback.nfds;
+        }
+        
+        if( poll( self->pfds, totalFds, pollTimeout ) < 0 )
+        {
+            /*  XXX: Depend on preprocessor condition? */
+            if( errno == EINTR )
+            {
+                /* gdb */
+                continue;
+            }
+
+            /* TODO: Add macro for checking system calls */
+            PA_ENSURE( paInternalError );
+        }
+
+        /* check the return status of our pfds */
+        if( pollCapture )
+        {
+            PA_ENSURE( PaAlsaStreamComponent_EndPolling( &self->capture, capturePfds, &pollCapture, &xrun ) );
+        }
+        if( pollPlayback )
+        {
+            PA_ENSURE( PaAlsaStreamComponent_EndPolling( &self->playback, playbackPfds, &pollPlayback, &xrun ) );
+        }
+        if( xrun )
+        {
+            break;
+        }
+
+        /* @concern FullDuplex If only one of two pcms is ready we may want to compromise between the two.
+         * If there is less than half a period's worth of samples left of frames in the other pcm's buffer we will
+         * stop polling.
+         */
+        if( self->capture.pcm && self->playback.pcm )
+        {
+            if( pollCapture && !pollPlayback )
+            {
+                PA_ENSURE( ContinuePoll( self, StreamDirection_In, &pollTimeout, &pollCapture ) );
+            }
+            else if( pollPlayback && !pollCapture )
+            {
+                PA_ENSURE( ContinuePoll( self, StreamDirection_Out, &pollTimeout, &pollPlayback ) );
+            }
+        }
+    }
+
+    if( !xrun )
+    {
+        /* Get the number of available frames for the pcms that are marked ready.
+         * @concern FullDuplex If only one direction is marked ready (from poll), the number of frames available for
+         * the other direction is returned. Output is normally preferred over capture however, so capture frames may be
+         * discarded to avoid overrun unless paNeverDropInput is specified.
+         */
+        int captureReady = self->capture.pcm ? self->capture.ready : 0,
+            playbackReady = self->playback.pcm ? self->playback.ready : 0;
+        PA_ENSURE( PaAlsaStream_GetAvailableFrames( self, captureReady, playbackReady, framesAvail, &xrun ) );
+
+        if( self->capture.pcm && self->playback.pcm )
+        {
+            if( !self->playback.ready && !self->neverDropInput )
+            {
+                /* Drop input, a period's worth */
+                assert( self->capture.ready );
+                PaAlsaStreamComponent_EndProcessing( &self->capture, PA_MIN( self->capture.framesPerBuffer,
+                            *framesAvail ), &xrun );
+                *framesAvail = 0;
+                self->capture.ready = 0;
+            }
+        }
+        else if( self->capture.pcm )
+            assert( self->capture.ready );
+        else
+            assert( self->playback.ready );
+    }
+
+end:
+error:
+    if( xrun )
+    {
+        /* Recover from the xrun state */
+        PA_ENSURE( PaAlsaStream_HandleXrun( self ) );
+        *framesAvail = 0;
+    }
+    else
+    {
+        if( 0 != *framesAvail )
+        {
+            /* If we're reporting frames eligible for processing, one of the handles better be ready */
+            PA_UNLESS( self->capture.ready || self->playback.ready, paInternalError );
+        }
+    }
+    *xrunOccurred = xrun;
+
+    return result;
+}
+
+/** Register per-channel ALSA buffer information with buffer processor.
+ *
+ * Mmapped buffer space is acquired from ALSA, and registered with the buffer processor. Differences between the
+ * number of host and user channels is taken into account.
+ * 
+ * @param numFrames On entrance the number of requested frames, on exit the number of contiguously accessible frames.
+ */
+static PaError PaAlsaStreamComponent_RegisterChannels( PaAlsaStreamComponent* self, PaUtilBufferProcessor* bp,
+        unsigned long* numFrames, int* xrun )
+{
+    PaError result = paNoError;
+    const snd_pcm_channel_area_t *areas, *area;
+    void (*setChannel)(PaUtilBufferProcessor *, unsigned int, void *, unsigned int) =
+        StreamDirection_In == self->streamDir ? PaUtil_SetInputChannel : PaUtil_SetOutputChannel;
+    unsigned char *buffer, *p;
+    int i;
+    unsigned long framesAvail;
+
+    /* This _must_ be called before mmap_begin */
+    PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( self, &framesAvail, xrun ) );
+    if( *xrun )
+    {
+        *numFrames = 0;
+        goto end;
+    }
+
+    ENSURE_( snd_pcm_mmap_begin( self->pcm, &areas, &self->offset, numFrames ), paUnanticipatedHostError );
+
+    if( self->hostInterleaved )
+    {
+        int swidth = snd_pcm_format_size( self->nativeFormat, 1 );
+
+        p = buffer = ExtractAddress( areas, self->offset );
+        for( i = 0; i < self->numUserChannels; ++i )
+        {
+            /* We're setting the channels up to userChannels, but the stride will be hostChannels samples */
+            setChannel( bp, i, p, self->numHostChannels );
+            p += swidth;
+        }
+    }
+    else
+    {
+        for( i = 0; i < self->numUserChannels; ++i )
+        {
+            area = areas + i;
+            buffer = ExtractAddress( area, self->offset );
+            setChannel( bp, i, buffer, 1 );
+        }
+    }
+
+    /* @concern ChannelAdaption Buffer address is recorded so we can do some channel adaption later */
+    self->channelAreas = (snd_pcm_channel_area_t *)areas;
+
+end:
+error:
+    return result;
+}
+
+/** Initiate buffer processing.
+ *
+ * ALSA buffers are registered with the PA buffer processor and the buffer size (in frames) set.
+ *
+ * @concern FullDuplex If both directions are being processed, the minimum amount of frames for the two directions is
+ * calculated.
+ *
+ * @param numFrames On entrance the number of available frames, on exit the number of received frames
+ * @param xrunOccurred Return whether an xrun has occurred
+ */
+static PaError PaAlsaStream_SetUpBuffers( PaAlsaStream* self, unsigned long* numFrames, int* xrunOccurred )
+{
+    PaError result = paNoError;
+    unsigned long captureFrames = ULONG_MAX, playbackFrames = ULONG_MAX, commonFrames = 0;
+    int xrun = 0;
+
+    if( *xrunOccurred )
+    {
+        *numFrames = 0;
+        return result;
+    }
+    /* If we got here at least one of the pcm's should be marked ready */
+    PA_UNLESS( self->capture.ready || self->playback.ready, paInternalError );
+
+    /* Extract per-channel ALSA buffer pointers and register them with the buffer processor.
+     * It is possible that a direction is not marked ready however, because it is out of sync with the other.
+     */
+    if( self->capture.pcm && self->capture.ready )
+    {
+        captureFrames = *numFrames;
+        PA_ENSURE( PaAlsaStreamComponent_RegisterChannels( &self->capture, &self->bufferProcessor, &captureFrames, 
+                    &xrun ) );
+    }
+    if( self->playback.pcm && self->playback.ready )
+    {
+        playbackFrames = *numFrames;
+        PA_ENSURE( PaAlsaStreamComponent_RegisterChannels( &self->playback, &self->bufferProcessor, &playbackFrames, 
+                    &xrun ) );
+    }
+    if( xrun )
+    {
+        /* Nothing more to do */
+        assert( 0 == commonFrames );
+        goto end;
+    }
+
+    commonFrames = PA_MIN( captureFrames, playbackFrames );
+    /* assert( commonFrames <= *numFrames ); */
+    if( commonFrames > *numFrames )
+    {
+        /* Hmmm ... how come there are more frames available than we requested!? Blah. */
+        PA_DEBUG(( "%s: Common available frames are reported to be more than number requested: %lu, %lu, callbackMode: %d\n", __FUNCTION__,
+                    commonFrames, *numFrames, self->callbackMode ));
+        if( self->capture.pcm )
+        {
+            PA_DEBUG(( "%s: captureFrames: %lu, capture.ready: %d\n", __FUNCTION__, captureFrames, self->capture.ready ));
+        }
+        if( self->playback.pcm )
+        {
+            PA_DEBUG(( "%s: playbackFrames: %lu, playback.ready: %d\n", __FUNCTION__, playbackFrames, self->playback.ready ));
+        }
+        
+        commonFrames = 0;
+        goto end;
+    }
+
+    /* Inform PortAudio of the number of frames we got.
+     * @concern FullDuplex We might be experiencing underflow in either end; if its an input underflow, we go on
+     * with output. If its output underflow however, depending on the paNeverDropInput flag, we may want to simply
+     * discard the excess input or call the callback with paOutputOverflow flagged.
+     */
+    if( self->capture.pcm )
+    {
+        if( self->capture.ready )
+        {
+            PaUtil_SetInputFrameCount( &self->bufferProcessor, commonFrames );
+        }
+        else
+        {
+            /* We have input underflow */
+            PaUtil_SetNoInput( &self->bufferProcessor );
+        }
+    }
+    if( self->playback.pcm )
+    {
+        if( self->playback.ready )
+        {
+            PaUtil_SetOutputFrameCount( &self->bufferProcessor, commonFrames );
+        }
+        else
+        {
+            /* We have output underflow, but keeping input data (paNeverDropInput) */
+            assert( self->neverDropInput );
+            assert( self->capture.pcm != NULL );
+            PA_DEBUG(( "%s: Setting output buffers to NULL\n", __FUNCTION__ ));
+            PaUtil_SetNoOutput( &self->bufferProcessor );
+        }
+    }
+    
+end:
+    *numFrames = commonFrames;
+error:
+    if( xrun )
+    {
+        PA_ENSURE( PaAlsaStream_HandleXrun( self ) );
+        *numFrames = 0;
+    }
+    *xrunOccurred = xrun;
+
+    return result;
+}
+
+/** Callback thread's function.
+ *
+ * Roughly, the workflow can be described in the following way: The number of available frames that can be processed
+ * directly is obtained from ALSA, we then request as much directly accessible memory as possible within this amount
+ * from ALSA. The buffer memory is registered with the PA buffer processor and processing is carried out with
+ * PaUtil_EndBufferProcessing. Finally, the number of processed frames is reported to ALSA. The processing can
+ * happen in several iterations untill we have consumed the known number of available frames (or an xrun is detected).
+ */
+static void *CallbackThreadFunc( void *userData )
+{
+    PaError result = paNoError;
+    PaAlsaStream *stream = (PaAlsaStream*) userData;
+    PaStreamCallbackTimeInfo timeInfo = {0, 0, 0};
+    snd_pcm_sframes_t startThreshold = 0;
+    int callbackResult = paContinue;
+    PaStreamCallbackFlags cbFlags = 0;  /* We might want to keep state across iterations */
+    int streamStarted = 0;
+
+    assert( stream );
+
+    /* Execute OnExit when exiting */
+    pthread_cleanup_push( &OnExit, stream );
+
+    /* Not implemented */
+    assert( !stream->primeBuffers );
+
+    /* @concern StreamStart If the output is being primed the output pcm needs to be prepared, otherwise the
+     * stream is started immediately. The latter involves signaling the waiting main thread.
+     */
+    if( stream->primeBuffers )
+    {
+        snd_pcm_sframes_t avail;
+        
+        if( stream->playback.pcm )
+            ENSURE_( snd_pcm_prepare( stream->playback.pcm ), paUnanticipatedHostError );
+        if( stream->capture.pcm && !stream->pcmsSynced )
+            ENSURE_( snd_pcm_prepare( stream->capture.pcm ), paUnanticipatedHostError );
+
+        /* We can't be certain that the whole ring buffer is available for priming, but there should be
+         * at least one period */
+        avail = snd_pcm_avail_update( stream->playback.pcm );
+        startThreshold = avail - (avail % stream->playback.framesPerBuffer);
+        assert( startThreshold >= stream->playback.framesPerBuffer );
+    }
+    else
+    {
+        PA_ENSURE( PaUnixThread_PrepareNotify( &stream->thread ) );
+        /* Buffer will be zeroed */
+        PA_ENSURE( AlsaStart( stream, 0 ) );
+        PA_ENSURE( PaUnixThread_NotifyParent( &stream->thread ) );
+
+        streamStarted = 1;
+    }
+
+    while( 1 )
+    {
+        unsigned long framesAvail, framesGot;
+        int xrun = 0;
+
+        pthread_testcancel();
+
+        /* @concern StreamStop if the main thread has requested a stop and the stream has not been effectively
+         * stopped we signal this condition by modifying callbackResult (we'll want to flush buffered output).
+         */
+        if( PaUnixThread_StopRequested( &stream->thread ) && paContinue == callbackResult )
+        {
+            PA_DEBUG(( "Setting callbackResult to paComplete\n" ));
+            callbackResult = paComplete;
+        }
+
+        if( paContinue != callbackResult )
+        {
+            stream->callbackAbort = (paAbort == callbackResult);
+            if( stream->callbackAbort ||
+                    /** @concern BlockAdaption: Go on if adaption buffers are empty */
+                    PaUtil_IsBufferProcessorOutputEmpty( &stream->bufferProcessor ) ) 
+            {
+                goto end;
+            }
+
+            PA_DEBUG(( "%s: Flushing buffer processor\n", __FUNCTION__ ));
+            /* There is still buffered output that needs to be processed */
+        }
+
+        /* Wait for data to become available, this comes down to polling the ALSA file descriptors untill we have
+         * a number of available frames.
+         */
+        PA_ENSURE( PaAlsaStream_WaitForFrames( stream, &framesAvail, &xrun ) );
+        if( xrun )
+        {
+            assert( 0 == framesAvail );
+            continue;
+
+            /* XXX: Report xruns to the user? A situation is conceivable where the callback is never invoked due
+             * to constant xruns, it might be desirable to notify the user of this.
+             */
+        }
+
+        /* Consume buffer space. Once we have a number of frames available for consumption we must retrieve the
+         * mmapped buffers from ALSA, this is contiguously accessible memory however, so we may receive smaller
+         * portions at a time than is available as a whole. Therefore we should be prepared to process several
+         * chunks successively. The buffers are passed to the PA buffer processor.
+         */
+        while( framesAvail > 0 )
+        {
+            xrun = 0;
+
+            pthread_testcancel();
+
+            /** @concern Xruns Under/overflows are to be reported to the callback */
+            if( stream->underrun > 0.0 )
+            {
+                cbFlags |= paOutputUnderflow;
+                stream->underrun = 0.0;
+            }
+            if( stream->overrun > 0.0 )
+            {
+                cbFlags |= paInputOverflow;
+                stream->overrun = 0.0;
+            }
+            if( stream->capture.pcm && stream->playback.pcm )
+            {
+                /** @concern FullDuplex It's possible that only one direction is being processed to avoid an
+                 * under- or overflow, this should be reported correspondingly */
+                if( !stream->capture.ready )
+                {
+                    cbFlags |= paInputUnderflow;
+                    PA_DEBUG(( "%s: Input underflow\n", __FUNCTION__ ));
+                }
+                else if( !stream->playback.ready )
+                {
+                    cbFlags |= paOutputOverflow;
+                    PA_DEBUG(( "%s: Output overflow\n", __FUNCTION__ ));
+                }
+            }
+
+#if 0
+            CallbackUpdate( &stream->threading );
+#endif
+            CalculateTimeInfo( stream, &timeInfo );
+            PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, cbFlags );
+            cbFlags = 0;
+
+            /* CPU load measurement should include processing activivity external to the stream callback */
+            PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
+
+            framesGot = framesAvail;
+            if( paUtilFixedHostBufferSize == stream->bufferProcessor.hostBufferSizeMode )
+            {
+                /* We've committed to a fixed host buffer size, stick to that */
+                framesGot = framesGot >= stream->maxFramesPerHostBuffer ? stream->maxFramesPerHostBuffer : 0;
+            }
+            else
+            {
+                /* We've committed to an upper bound on the size of host buffers */
+                assert( paUtilBoundedHostBufferSize == stream->bufferProcessor.hostBufferSizeMode );
+                framesGot = PA_MIN( framesGot, stream->maxFramesPerHostBuffer );
+            }
+            PA_ENSURE( PaAlsaStream_SetUpBuffers( stream, &framesGot, &xrun ) );
+            /* Check the host buffer size against the buffer processor configuration */
+            framesAvail -= framesGot;
+
+            if( framesGot > 0 )
+            {
+                assert( !xrun );
+                PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult );
+                PA_ENSURE( PaAlsaStream_EndProcessing( stream, framesGot, &xrun ) );
+            }
+            PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesGot );
+
+            if( 0 == framesGot )
+            {
+                /* Go back to polling for more frames */
+                break;
+
+            }
+
+            if( paContinue != callbackResult )
+                break;
+        }
+    }
+
+    /* Match pthread_cleanup_push */
+    pthread_cleanup_pop( 1 );
+
+end:
+    PA_DEBUG(( "%s: Thread %d exiting\n ", __FUNCTION__, pthread_self() ));
+    PaUnixThreading_EXIT( result );
+error:
+    goto end;
+}
+
+/* Blocking interface */
+
+static PaError ReadStream( PaStream* s, void *buffer, unsigned long frames )
+{
+    PaError result = paNoError;
+    PaAlsaStream *stream = (PaAlsaStream*)s;
+    unsigned long framesGot, framesAvail;
+    void *userBuffer;
+    snd_pcm_t *save = stream->playback.pcm;
+
+    assert( stream );
+
+    PA_UNLESS( stream->capture.pcm, paCanNotReadFromAnOutputOnlyStream );
+
+    /* Disregard playback */
+    stream->playback.pcm = NULL;
+
+    if( stream->overrun > 0. )
+    {
+        result = paInputOverflowed;
+        stream->overrun = 0.0;
+    }
+
+    if( stream->capture.userInterleaved )
+    {
+        userBuffer = buffer;
+    }
+    else
+    {
+        /* Copy channels into local array */
+        userBuffer = stream->capture.userBuffers;
+        memcpy( userBuffer, buffer, sizeof (void *) * stream->capture.numUserChannels );
+    }
+
+    /* Start stream if in prepared state */
+    if( snd_pcm_state( stream->capture.pcm ) == SND_PCM_STATE_PREPARED )
+    {
+        ENSURE_( snd_pcm_start( stream->capture.pcm ), paUnanticipatedHostError );
+    }
+
+    while( frames > 0 )
+    {
+        int xrun = 0;
+        PA_ENSURE( PaAlsaStream_WaitForFrames( stream, &framesAvail, &xrun ) );
+        framesGot = PA_MIN( framesAvail, frames );
+
+        PA_ENSURE( PaAlsaStream_SetUpBuffers( stream, &framesGot, &xrun ) );
+        if( framesGot > 0 )
+        {
+            framesGot = PaUtil_CopyInput( &stream->bufferProcessor, &userBuffer, framesGot );
+            PA_ENSURE( PaAlsaStream_EndProcessing( stream, framesGot, &xrun ) );
+            frames -= framesGot;
+        }
+    }
+
+end:
+    stream->playback.pcm = save;
+    return result;
+error:
+    goto end;
+}
+
+static PaError WriteStream( PaStream* s, const void *buffer, unsigned long frames )
+{
+    PaError result = paNoError;
+    signed long err;
+    PaAlsaStream *stream = (PaAlsaStream*)s;
+    snd_pcm_uframes_t framesGot, framesAvail;
+    const void *userBuffer;
+    snd_pcm_t *save = stream->capture.pcm;
+    
+    assert( stream );
+
+    PA_UNLESS( stream->playback.pcm, paCanNotWriteToAnInputOnlyStream );
+
+    /* Disregard capture */
+    stream->capture.pcm = NULL;
+
+    if( stream->underrun > 0. )
+    {
+        result = paOutputUnderflowed;
+        stream->underrun = 0.0;
+    }
+
+    if( stream->playback.userInterleaved )
+        userBuffer = buffer;
+    else /* Copy channels into local array */
+    {
+        userBuffer = stream->playback.userBuffers;
+        memcpy( (void *)userBuffer, buffer, sizeof (void *) * stream->playback.numUserChannels );
+    }
+
+    while( frames > 0 )
+    {
+        int xrun = 0;
+        snd_pcm_uframes_t hwAvail;
+
+        PA_ENSURE( PaAlsaStream_WaitForFrames( stream, &framesAvail, &xrun ) );
+        framesGot = PA_MIN( framesAvail, frames );
+
+        PA_ENSURE( PaAlsaStream_SetUpBuffers( stream, &framesGot, &xrun ) );
+        if( framesGot > 0 )
+        {
+            framesGot = PaUtil_CopyOutput( &stream->bufferProcessor, &userBuffer, framesGot );
+            PA_ENSURE( PaAlsaStream_EndProcessing( stream, framesGot, &xrun ) );
+            frames -= framesGot;
+        }
+
+        /* Start stream after one period of samples worth */
+
+        /* Frames residing in buffer */
+        PA_ENSURE( err = GetStreamWriteAvailable( stream ) );
+        framesAvail = err;
+        hwAvail = stream->playback.bufferSize - framesAvail;
+
+        if( snd_pcm_state( stream->playback.pcm ) == SND_PCM_STATE_PREPARED &&
+                hwAvail >= stream->playback.framesPerBuffer )
+        {
+            ENSURE_( snd_pcm_start( stream->playback.pcm ), paUnanticipatedHostError );
+        }
+    }
+
+end:
+    stream->capture.pcm = save;
+    return result;
+error:
+    goto end;
+}
+
+/* Return frames available for reading. In the event of an overflow, the capture pcm will be restarted */
+static signed long GetStreamReadAvailable( PaStream* s )
+{
+    PaError result = paNoError;
+    PaAlsaStream *stream = (PaAlsaStream*)s;
+    unsigned long avail;
+    int xrun;
+
+    PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &stream->capture, &avail, &xrun ) );
+    if( xrun )
+    {
+        PA_ENSURE( PaAlsaStream_HandleXrun( stream ) );
+        PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &stream->capture, &avail, &xrun ) );
+        if( xrun )
+            PA_ENSURE( paInputOverflowed );
+    }
+
+    return (signed long)avail;
+
+error:
+    return result;
+}
+
+static signed long GetStreamWriteAvailable( PaStream* s )
+{
+    PaError result = paNoError;
+    PaAlsaStream *stream = (PaAlsaStream*)s;
+    unsigned long avail;
+    int xrun;
+
+    PA_ENSURE( PaAlsaStreamComponent_GetAvailableFrames( &stream->playback, &avail, &xrun ) );
+    if( xrun )
+    {
+        snd_pcm_sframes_t savail;
+
+        PA_ENSURE( PaAlsaStream_HandleXrun( stream ) );
+        savail = snd_pcm_avail_update( stream->playback.pcm );
+
+        /* savail should not contain -EPIPE now, since PaAlsaStream_HandleXrun will only prepare the pcm */
+        ENSURE_( savail, paUnanticipatedHostError );
+
+        avail = (unsigned long) savail;
+    }
+
+    return (signed long)avail;
+
+error:
+    return result;
+}
+
+/* Extensions */
+
+/* Initialize host api specific structure */
+void PaAlsa_InitializeStreamInfo( PaAlsaStreamInfo *info )
+{
+    info->size = sizeof (PaAlsaStreamInfo);
+    info->hostApiType = paALSA;
+    info->version = 1;
+    info->deviceString = NULL;
+}
+
+void PaAlsa_EnableRealtimeScheduling( PaStream *s, int enable )
+{
+#if 0
+    PaAlsaStream *stream = (PaAlsaStream *) s;
+    stream->threading.rtSched = enable;
+#endif
+}
+
+void PaAlsa_EnableWatchdog( PaStream *s, int enable )
+{
+#if 0
+    PaAlsaStream *stream = (PaAlsaStream *) s;
+    stream->threading.useWatchdog = enable;
+#endif
+}
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/asio/ASIO-README.txt b/utils/iaxclient/lib/portaudio/src/hostapi/asio/ASIO-README.txt
new file mode 100644 (file)
index 0000000..9fb74ae
--- /dev/null
@@ -0,0 +1,137 @@
+ASIO-README.txt
+
+This document contains information to help you compile PortAudio with 
+ASIO support. If you find any omissions or errors in this document 
+please notify Ross Bencina <rossb@audiomulch.com>.
+
+
+Building PortAudio with ASIO support
+------------------------------------
+
+To build PortAudio with ASIO support you need to compile and link with
+pa_asio.c, and files from the ASIO SDK (see below), along with the common 
+files from pa_common/ and platform specific files from pa_win/ (for Win32) 
+or pa_mac/ (for Macintosh).
+
+If you are compiling with a non-Microsoft compiler on windows, also 
+compile and link with iasiothiscallresolver.cpp (see below for 
+an explanation).
+
+For some platforms (MingW, possibly Mac), you may simply
+be able to type:
+
+./configure --with-host_os=mingw --with-winapi=asio [--with-asiodir=/usr/local/asiosdk2]
+make
+
+./configure --with-host_os=darwin --with-winapi=asio [--with-asiodir=/usr/local/asiosdk2]
+make
+
+and life will be good.
+
+
+Obtaining the ASIO SDK
+----------------------
+
+In order to build PortAudio with ASIO support, you need to download 
+the ASIO SDK (version 2.0) from Steinberg. Steinberg makes the ASIO 
+SDK available to anyone free of charge, however they do not permit its 
+source code to be distributed.
+
+NOTE: In some cases the ASIO SDK may require patching, see below 
+for further details.
+
+http://www.steinberg.net/en/ps/support/3rdparty/asio_sdk/
+
+If the above link is broken search Google for:
+"download steinberg ASIO SDK"
+
+
+
+Building the ASIO SDK on Macintosh
+----------------------------------
+
+To build the ASIO SDK on Macintosh you need to compile and link with the 
+following files from the ASIO SDK:
+
+host/asiodrivers.cpp 
+host/mac/asioshlib.cpp 
+host/mac/codefragements.cpp
+
+
+
+Building the ASIO SDK on Windows
+--------------------------------
+
+To build the ASIO SDK on Windows you need to compile and link with the 
+following files from the ASIO SDK:
+
+asio_sdk\common\asio.cpp
+asio_sdk\host\asiodrivers.cpp
+asio_sdk\host\pc\asiolist.cpp
+
+You may also need to adjust your include paths to support inclusion of 
+header files from the above directories.
+
+The ASIO SDK depends on the following COM API functions: 
+CoInitialize, CoUninitialize, CoCreateInstance, CLSIDFromString
+For compilation with MinGW you will need to link with -lole32, for
+Borland link with Import32.lib.
+
+
+
+Non-Microsoft (MSVC) Compilers on Windows including Borland and GCC
+-------------------------------------------------------------------
+
+Steinberg did not specify a calling convention in the IASIO interface 
+definition. This causes the Microsoft compiler to use the proprietary 
+thiscall convention which is not compatible with other compilers, such 
+as compilers from Borland (BCC and C++Builder) and GNU (gcc). 
+Steinberg's ASIO SDK will compile but crash on initialization if 
+compiled with a non-Microsoft compiler on Windows.
+
+PortAudio solves this problem using the iasiothiscallresolver library 
+which is included in the distribution. When building ASIO support for
+non-Microsoft compilers, be sure to compile and link with
+iasiothiscallresolver.cpp. Note that iasiothiscallresolver includes
+conditional directives which cause it to have no effect if it is
+compiled with a Microsoft compiler, or on the Macintosh.
+
+If you use configure and make (see above), this should be handled
+automatically for you.
+
+For further information about the IASIO thiscall problem see this page:
+http://www.audiomulch.com/~rossb/code/calliasio
+
+
+
+Macintosh ASIO SDK Bug Patch
+----------------------------
+
+There is a bug in the ASIO SDK that causes the Macintosh version to 
+often fail during initialization. Below is a patch that you can apply.
+
+In codefragments.cpp replace getFrontProcessDirectory function with 
+the following one (GetFrontProcess replaced by GetCurrentProcess).
+
+
+bool CodeFragments::getFrontProcessDirectory(void *specs)
+{
+       FSSpec *fss = (FSSpec *)specs;
+       ProcessInfoRec pif;
+       ProcessSerialNumber psn;
+
+       memset(&psn,0,(long)sizeof(ProcessSerialNumber));
+       //  if(GetFrontProcess(&psn) == noErr)  // wrong !!!
+       if(GetCurrentProcess(&psn) == noErr)  // correct !!!
+       {
+               pif.processName = 0;
+               pif.processAppSpec = fss;
+               pif.processInfoLength = sizeof(ProcessInfoRec);
+               if(GetProcessInformation(&psn, &pif) == noErr)
+                               return true;
+       }
+       return false;
+}
+
+
+---
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/asio/Callback_adaptation_.pdf b/utils/iaxclient/lib/portaudio/src/hostapi/asio/Callback_adaptation_.pdf
new file mode 100644 (file)
index 0000000..76bf678
Binary files /dev/null and b/utils/iaxclient/lib/portaudio/src/hostapi/asio/Callback_adaptation_.pdf differ
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/asio/Pa_ASIO.pdf b/utils/iaxclient/lib/portaudio/src/hostapi/asio/Pa_ASIO.pdf
new file mode 100644 (file)
index 0000000..ac5ecad
Binary files /dev/null and b/utils/iaxclient/lib/portaudio/src/hostapi/asio/Pa_ASIO.pdf differ
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/asio/iasiothiscallresolver.cpp b/utils/iaxclient/lib/portaudio/src/hostapi/asio/iasiothiscallresolver.cpp
new file mode 100644 (file)
index 0000000..8dfefbd
--- /dev/null
@@ -0,0 +1,563 @@
+/*
+       IASIOThiscallResolver.cpp see the comments in iasiothiscallresolver.h for
+    the top level description - this comment describes the technical details of
+    the implementation.
+
+    The latest version of this file is available from:
+    http://www.audiomulch.com/~rossb/code/calliasio
+
+    please email comments to Ross Bencina <rossb@audiomulch.com>
+
+    BACKGROUND
+
+    The IASIO interface declared in the Steinberg ASIO 2 SDK declares
+    functions with no explicit calling convention. This causes MSVC++ to default
+    to using the thiscall convention, which is a proprietary convention not
+    implemented by some non-microsoft compilers - notably borland BCC,
+    C++Builder, and gcc. MSVC++ is the defacto standard compiler used by
+    Steinberg. As a result of this situation, the ASIO sdk will compile with
+    any compiler, however attempting to execute the compiled code will cause a
+    crash due to different default calling conventions on non-Microsoft
+    compilers.
+
+    IASIOThiscallResolver solves the problem by providing an adapter class that
+    delegates to the IASIO interface using the correct calling convention
+    (thiscall). Due to the lack of support for thiscall in the Borland and GCC
+    compilers, the calls have been implemented in assembly language.
+
+    A number of macros are defined for thiscall function calls with different
+    numbers of parameters, with and without return values - it may be possible
+    to modify the format of these macros to make them work with other inline
+    assemblers.
+
+
+    THISCALL DEFINITION
+
+    A number of definitions of the thiscall calling convention are floating
+    around the internet. The following definition has been validated against
+    output from the MSVC++ compiler:
+
+    For non-vararg functions, thiscall works as follows: the object (this)
+    pointer is passed in ECX. All arguments are passed on the stack in
+    right to left order. The return value is placed in EAX. The callee
+    clears the passed arguments from the stack.
+
+
+    FINDING FUNCTION POINTERS FROM AN IASIO POINTER
+
+    The first field of a COM object is a pointer to its vtble. Thus a pointer
+    to an object implementing the IASIO interface also points to a pointer to
+    that object's vtbl. The vtble is a table of function pointers for all of
+    the virtual functions exposed by the implemented interfaces.
+
+    If we consider a variable declared as a pointer to IASO:
+
+    IASIO *theAsioDriver
+
+    theAsioDriver points to:
+
+    object implementing IASIO
+    {
+        IASIOvtbl *vtbl
+        other data
+    }
+
+    in other words, theAsioDriver points to a pointer to an IASIOvtbl
+
+    vtbl points to a table of function pointers:
+
+    IASIOvtbl ( interface IASIO : public IUnknown )
+    {
+    (IUnknown functions)
+    0   virtual HRESULT STDMETHODCALLTYPE (*QueryInterface)(REFIID riid, void **ppv) = 0;
+    4   virtual ULONG STDMETHODCALLTYPE (*AddRef)() = 0;
+    8   virtual ULONG STDMETHODCALLTYPE (*Release)() = 0;      
+
+    (IASIO functions)
+    12 virtual ASIOBool (*init)(void *sysHandle) = 0;
+    16 virtual void (*getDriverName)(char *name) = 0;
+    20 virtual long (*getDriverVersion)() = 0;
+    24 virtual void (*getErrorMessage)(char *string) = 0;
+    28 virtual ASIOError (*start)() = 0;
+    32 virtual ASIOError (*stop)() = 0;
+    36 virtual ASIOError (*getChannels)(long *numInputChannels, long *numOutputChannels) = 0;
+    40 virtual ASIOError (*getLatencies)(long *inputLatency, long *outputLatency) = 0;
+    44 virtual ASIOError (*getBufferSize)(long *minSize, long *maxSize,
+            long *preferredSize, long *granularity) = 0;
+    48 virtual ASIOError (*canSampleRate)(ASIOSampleRate sampleRate) = 0;
+    52 virtual ASIOError (*getSampleRate)(ASIOSampleRate *sampleRate) = 0;
+    56 virtual ASIOError (*setSampleRate)(ASIOSampleRate sampleRate) = 0;
+    60 virtual ASIOError (*getClockSources)(ASIOClockSource *clocks, long *numSources) = 0;
+    64 virtual ASIOError (*setClockSource)(long reference) = 0;
+    68 virtual ASIOError (*getSamplePosition)(ASIOSamples *sPos, ASIOTimeStamp *tStamp) = 0;
+    72 virtual ASIOError (*getChannelInfo)(ASIOChannelInfo *info) = 0;
+    76 virtual ASIOError (*createBuffers)(ASIOBufferInfo *bufferInfos, long numChannels,
+            long bufferSize, ASIOCallbacks *callbacks) = 0;
+    80 virtual ASIOError (*disposeBuffers)() = 0;
+    84 virtual ASIOError (*controlPanel)() = 0;
+    88 virtual ASIOError (*future)(long selector,void *opt) = 0;
+    92 virtual ASIOError (*outputReady)() = 0;
+    };
+
+    The numbers in the left column show the byte offset of each function ptr
+    from the beginning of the vtbl. These numbers are used in the code below
+    to select different functions.
+
+    In order to find the address of a particular function, theAsioDriver
+    must first be dereferenced to find the value of the vtbl pointer:
+
+    mov     eax, theAsioDriver
+    mov     edx, [theAsioDriver]  // edx now points to vtbl[0]
+
+    Then an offset must be added to the vtbl pointer to select a
+    particular function, for example vtbl+44 points to the slot containing
+    a pointer to the getBufferSize function.
+
+    Finally vtbl+x must be dereferenced to obtain the value of the function
+    pointer stored in that address:
+
+    call    [edx+44]    // call the function pointed to by
+                        // the value in the getBufferSize field of the vtbl
+
+
+    SEE ALSO
+
+    Martin Fay's OpenASIO DLL at http://www.martinfay.com solves the same
+    problem by providing a new COM interface which wraps IASIO with an
+    interface that uses portable calling conventions. OpenASIO must be compiled
+    with MSVC, and requires that you ship the OpenASIO DLL with your
+    application.
+
+    
+    ACKNOWLEDGEMENTS
+
+    Ross Bencina: worked out the thiscall details above, wrote the original
+    Borland asm macros, and a patch for asio.cpp (which is no longer needed).
+    Thanks to Martin Fay for introducing me to the issues discussed here,
+    and to Rene G. Ceballos for assisting with asm dumps from MSVC++.
+
+    Antti Silvast: converted the original calliasio to work with gcc and NASM
+    by implementing the asm code in a separate file.
+
+       Fraser Adams: modified the original calliasio containing the Borland inline
+    asm to add inline asm for gcc i.e. Intel syntax for Borland and AT&T syntax
+    for gcc. This seems a neater approach for gcc than to have a separate .asm
+    file and it means that we only need one version of the thiscall patch.
+
+    Fraser Adams: rewrote the original calliasio patch in the form of the
+    IASIOThiscallResolver class in order to avoid modifications to files from
+    the Steinberg SDK, which may have had potential licence issues.
+
+    Andrew Baldwin: contributed fixes for compatibility problems with more
+    recent versions of the gcc assembler.
+*/
+
+
+// We only need IASIOThiscallResolver at all if we are on Win32. For other
+// platforms we simply bypass the IASIOThiscallResolver definition to allow us
+// to be safely #include'd whatever the platform to keep client code portable
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
+
+
+// If microsoft compiler we can call IASIO directly so IASIOThiscallResolver
+// is not used.
+#if !defined(_MSC_VER)
+
+
+#include <new>
+#include <assert.h>
+
+// We have a mechanism in iasiothiscallresolver.h to ensure that asio.h is
+// #include'd before it in client code, we do NOT want to do this test here.
+#define iasiothiscallresolver_sourcefile 1
+#include "iasiothiscallresolver.h"
+#undef iasiothiscallresolver_sourcefile
+
+// iasiothiscallresolver.h redefines ASIOInit for clients, but we don't want
+// this macro defined in this translation unit.
+#undef ASIOInit
+
+
+// theAsioDriver is a global pointer to the current IASIO instance which the
+// ASIO SDK uses to perform all actions on the IASIO interface. We substitute
+// our own forwarding interface into this pointer.
+extern IASIO* theAsioDriver;
+
+
+// The following macros define the inline assembler for BORLAND first then gcc
+
+#if defined(__BCPLUSPLUS__) || defined(__BORLANDC__)          
+
+
+#define CALL_THISCALL_0( resultName, thisPtr, funcOffset )\
+    void *this_ = (thisPtr);                                                \
+    __asm {                                                                 \
+        mov     ecx, this_            ;                                     \
+        mov     eax, [ecx]            ;                                     \
+        call    [eax+funcOffset]      ;                                     \
+        mov     resultName, eax       ;                                     \
+    }
+
+
+#define CALL_VOID_THISCALL_1( thisPtr, funcOffset, param1 )\
+    void *this_ = (thisPtr);                                                \
+    __asm {                                                                 \
+        mov     eax, param1           ;                                     \
+        push    eax                   ;                                     \
+        mov     ecx, this_            ;                                     \
+        mov     eax, [ecx]            ;                                     \
+        call    [eax+funcOffset]      ;                                     \
+    }
+
+
+#define CALL_THISCALL_1( resultName, thisPtr, funcOffset, param1 )\
+    void *this_ = (thisPtr);                                                \
+    __asm {                                                                 \
+        mov     eax, param1           ;                                     \
+        push    eax                   ;                                     \
+        mov     ecx, this_            ;                                     \
+        mov     eax, [ecx]            ;                                     \
+        call    [eax+funcOffset]      ;                                     \
+        mov     resultName, eax       ;                                     \
+    }
+
+
+#define CALL_THISCALL_1_DOUBLE( resultName, thisPtr, funcOffset, param1 )\
+    void *this_ = (thisPtr);                                                \
+    void *doubleParamPtr_ (&param1);                                        \
+    __asm {                                                                 \
+        mov     eax, doubleParamPtr_  ;                                     \
+        push    [eax+4]               ;                                     \
+        push    [eax]                 ;                                     \
+        mov     ecx, this_            ;                                     \
+        mov     eax, [ecx]            ;                                     \
+        call    [eax+funcOffset]      ;                                     \
+        mov     resultName, eax       ;                                     \
+    }
+
+
+#define CALL_THISCALL_2( resultName, thisPtr, funcOffset, param1, param2 )\
+    void *this_ = (thisPtr);                                                \
+    __asm {                                                                 \
+        mov     eax, param2           ;                                     \
+        push    eax                   ;                                     \
+        mov     eax, param1           ;                                     \
+        push    eax                   ;                                     \
+        mov     ecx, this_            ;                                     \
+        mov     eax, [ecx]            ;                                     \
+        call    [eax+funcOffset]      ;                                     \
+        mov     resultName, eax       ;                                     \
+    }
+
+
+#define CALL_THISCALL_4( resultName, thisPtr, funcOffset, param1, param2, param3, param4 )\
+    void *this_ = (thisPtr);                                                \
+    __asm {                                                                 \
+        mov     eax, param4           ;                                     \
+        push    eax                   ;                                     \
+        mov     eax, param3           ;                                     \
+        push    eax                   ;                                     \
+        mov     eax, param2           ;                                     \
+        push    eax                   ;                                     \
+        mov     eax, param1           ;                                     \
+        push    eax                   ;                                     \
+        mov     ecx, this_            ;                                     \
+        mov     eax, [ecx]            ;                                     \
+        call    [eax+funcOffset]      ;                                     \
+        mov     resultName, eax       ;                                     \
+    }
+
+
+#elif defined(__GNUC__)
+
+
+#define CALL_THISCALL_0( resultName, thisPtr, funcOffset )                  \
+    __asm__ __volatile__ ("movl (%1), %%edx\n\t"                            \
+                          "call *"#funcOffset"(%%edx)\n\t"                  \
+                          :"=a"(resultName) /* Output Operands */           \
+                          :"c"(thisPtr)     /* Input Operands */            \
+                         );                                                 \
+
+
+#define CALL_VOID_THISCALL_1( thisPtr, funcOffset, param1 )                 \
+    __asm__ __volatile__ ("pushl %0\n\t"                                    \
+                          "movl (%1), %%edx\n\t"                            \
+                          "call *"#funcOffset"(%%edx)\n\t"                  \
+                          :                 /* Output Operands */           \
+                          :"r"(param1),     /* Input Operands */            \
+                           "c"(thisPtr)                                     \
+                         );                                                 \
+
+
+#define CALL_THISCALL_1( resultName, thisPtr, funcOffset, param1 )          \
+    __asm__ __volatile__ ("pushl %1\n\t"                                    \
+                          "movl (%2), %%edx\n\t"                            \
+                          "call *"#funcOffset"(%%edx)\n\t"                  \
+                          :"=a"(resultName) /* Output Operands */           \
+                          :"r"(param1),     /* Input Operands */            \
+                           "c"(thisPtr)                                     \
+                          );                                                \
+
+
+#define CALL_THISCALL_1_DOUBLE( resultName, thisPtr, funcOffset, param1 )   \
+    __asm__ __volatile__ ("pushl 4(%1)\n\t"                                 \
+                          "pushl (%1)\n\t"                                  \
+                          "movl (%2), %%edx\n\t"                            \
+                          "call *"#funcOffset"(%%edx);\n\t"                 \
+                          :"=a"(resultName) /* Output Operands */           \
+                          :"a"(&param1),    /* Input Operands */            \
+                           /* Note: Using "r" above instead of "a" fails */ \
+                           /* when using GCC 3.3.3, and maybe later versions*/\
+                           "c"(thisPtr)                                     \
+                          );                                                \
+
+
+#define CALL_THISCALL_2( resultName, thisPtr, funcOffset, param1, param2 )  \
+    __asm__ __volatile__ ("pushl %1\n\t"                                    \
+                          "pushl %2\n\t"                                    \
+                          "movl (%3), %%edx\n\t"                            \
+                          "call *"#funcOffset"(%%edx)\n\t"                  \
+                          :"=a"(resultName) /* Output Operands */           \
+                          :"r"(param2),     /* Input Operands */            \
+                           "r"(param1),                                     \
+                           "c"(thisPtr)                                     \
+                          );                                                \
+
+
+#define CALL_THISCALL_4( resultName, thisPtr, funcOffset, param1, param2, param3, param4 )\
+    __asm__ __volatile__ ("pushl %1\n\t"                                    \
+                          "pushl %2\n\t"                                    \
+                          "pushl %3\n\t"                                    \
+                          "pushl %4\n\t"                                    \
+                          "movl (%5), %%edx\n\t"                            \
+                          "call *"#funcOffset"(%%edx)\n\t"                  \
+                          :"=a"(resultName) /* Output Operands */           \
+                          :"r"(param4),     /* Input Operands  */           \
+                           "r"(param3),                                     \
+                           "r"(param2),                                     \
+                           "r"(param1),                                     \
+                           "c"(thisPtr)                                     \
+                          );                                                \
+
+#endif
+
+
+
+// Our static singleton instance.
+IASIOThiscallResolver IASIOThiscallResolver::instance;
+
+// Constructor called to initialize static Singleton instance above. Note that
+// it is important not to clear that_ incase it has already been set by the call
+// to placement new in ASIOInit().
+IASIOThiscallResolver::IASIOThiscallResolver()
+{
+}
+
+// Constructor called from ASIOInit() below
+IASIOThiscallResolver::IASIOThiscallResolver(IASIO* that)
+: that_( that )
+{
+}
+
+// Implement IUnknown methods as assert(false). IASIOThiscallResolver is not
+// really a COM object, just a wrapper which will work with the ASIO SDK.
+// If you wanted to use ASIO without the SDK you might want to implement COM
+// aggregation in these methods.
+HRESULT STDMETHODCALLTYPE IASIOThiscallResolver::QueryInterface(REFIID riid, void **ppv)
+{
+    (void)riid;     // suppress unused variable warning
+
+    assert( false ); // this function should never be called by the ASIO SDK.
+
+    *ppv = NULL;
+    return E_NOINTERFACE;
+}
+
+ULONG STDMETHODCALLTYPE IASIOThiscallResolver::AddRef()
+{
+    assert( false ); // this function should never be called by the ASIO SDK.
+
+    return 1;
+}
+
+ULONG STDMETHODCALLTYPE IASIOThiscallResolver::Release()
+{
+    assert( false ); // this function should never be called by the ASIO SDK.
+    
+    return 1;
+}
+
+
+// Implement the IASIO interface methods by performing the vptr manipulation
+// described above then delegating to the real implementation.
+ASIOBool IASIOThiscallResolver::init(void *sysHandle)
+{
+    ASIOBool result;
+    CALL_THISCALL_1( result, that_, 12, sysHandle );
+    return result;
+}
+
+void IASIOThiscallResolver::getDriverName(char *name)
+{
+    CALL_VOID_THISCALL_1( that_, 16, name );
+}
+
+long IASIOThiscallResolver::getDriverVersion()
+{
+    ASIOBool result;
+    CALL_THISCALL_0( result, that_, 20 );
+    return result;
+}
+
+void IASIOThiscallResolver::getErrorMessage(char *string)
+{
+     CALL_VOID_THISCALL_1( that_, 24, string );
+}
+
+ASIOError IASIOThiscallResolver::start()
+{
+    ASIOBool result;
+    CALL_THISCALL_0( result, that_, 28 );
+    return result;
+}
+
+ASIOError IASIOThiscallResolver::stop()
+{
+    ASIOBool result;
+    CALL_THISCALL_0( result, that_, 32 );
+    return result;
+}
+
+ASIOError IASIOThiscallResolver::getChannels(long *numInputChannels, long *numOutputChannels)
+{
+    ASIOBool result;
+    CALL_THISCALL_2( result, that_, 36, numInputChannels, numOutputChannels );
+    return result;
+}
+
+ASIOError IASIOThiscallResolver::getLatencies(long *inputLatency, long *outputLatency)
+{
+    ASIOBool result;
+    CALL_THISCALL_2( result, that_, 40, inputLatency, outputLatency );
+    return result;
+}
+
+ASIOError IASIOThiscallResolver::getBufferSize(long *minSize, long *maxSize,
+        long *preferredSize, long *granularity)
+{
+    ASIOBool result;
+    CALL_THISCALL_4( result, that_, 44, minSize, maxSize, preferredSize, granularity );
+    return result;
+}
+
+ASIOError IASIOThiscallResolver::canSampleRate(ASIOSampleRate sampleRate)
+{
+    ASIOBool result;
+    CALL_THISCALL_1_DOUBLE( result, that_, 48, sampleRate );
+    return result;
+}
+
+ASIOError IASIOThiscallResolver::getSampleRate(ASIOSampleRate *sampleRate)
+{
+    ASIOBool result;
+    CALL_THISCALL_1( result, that_, 52, sampleRate );
+    return result;
+}
+
+ASIOError IASIOThiscallResolver::setSampleRate(ASIOSampleRate sampleRate)
+{    
+    ASIOBool result;
+    CALL_THISCALL_1_DOUBLE( result, that_, 56, sampleRate );
+    return result;
+}
+
+ASIOError IASIOThiscallResolver::getClockSources(ASIOClockSource *clocks, long *numSources)
+{
+    ASIOBool result;
+    CALL_THISCALL_2( result, that_, 60, clocks, numSources );
+    return result;
+}
+
+ASIOError IASIOThiscallResolver::setClockSource(long reference)
+{
+    ASIOBool result;
+    CALL_THISCALL_1( result, that_, 64, reference );
+    return result;
+}
+
+ASIOError IASIOThiscallResolver::getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp)
+{
+    ASIOBool result;
+    CALL_THISCALL_2( result, that_, 68, sPos, tStamp );
+    return result;
+}
+
+ASIOError IASIOThiscallResolver::getChannelInfo(ASIOChannelInfo *info)
+{
+    ASIOBool result;
+    CALL_THISCALL_1( result, that_, 72, info );
+    return result;
+}
+
+ASIOError IASIOThiscallResolver::createBuffers(ASIOBufferInfo *bufferInfos,
+        long numChannels, long bufferSize, ASIOCallbacks *callbacks)
+{
+    ASIOBool result;
+    CALL_THISCALL_4( result, that_, 76, bufferInfos, numChannels, bufferSize, callbacks );
+    return result;
+}
+
+ASIOError IASIOThiscallResolver::disposeBuffers()
+{
+    ASIOBool result;
+    CALL_THISCALL_0( result, that_, 80 );
+    return result;
+}
+
+ASIOError IASIOThiscallResolver::controlPanel()
+{
+    ASIOBool result;
+    CALL_THISCALL_0( result, that_, 84 );
+    return result;
+}
+
+ASIOError IASIOThiscallResolver::future(long selector,void *opt)
+{
+    ASIOBool result;
+    CALL_THISCALL_2( result, that_, 88, selector, opt );
+    return result;
+}
+
+ASIOError IASIOThiscallResolver::outputReady()
+{
+    ASIOBool result;
+    CALL_THISCALL_0( result, that_, 92 );
+    return result;
+}
+
+
+// Implement our substitute ASIOInit() method
+ASIOError IASIOThiscallResolver::ASIOInit(ASIODriverInfo *info)
+{
+    // To ensure that our instance's vptr is correctly constructed, even if
+    // ASIOInit is called prior to main(), we explicitly call its constructor
+    // (potentially over the top of an existing instance). Note that this is
+    // pretty ugly, and is only safe because IASIOThiscallResolver has no
+    // destructor and contains no objects with destructors.
+    new((void*)&instance) IASIOThiscallResolver( theAsioDriver );
+
+    // Interpose between ASIO client code and the real driver.
+    theAsioDriver = &instance;
+
+    // Note that we never need to switch theAsioDriver back to point to the
+    // real driver because theAsioDriver is reset to zero in ASIOExit().
+
+    // Delegate to the real ASIOInit
+       return ::ASIOInit(info);
+}
+
+
+#endif /* !defined(_MSC_VER) */
+
+#endif /* Win32 */
+
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/asio/iasiothiscallresolver.h b/utils/iaxclient/lib/portaudio/src/hostapi/asio/iasiothiscallresolver.h
new file mode 100644 (file)
index 0000000..2ecfed7
--- /dev/null
@@ -0,0 +1,197 @@
+// ****************************************************************************
+// File:                       IASIOThiscallResolver.h
+// Description:     The IASIOThiscallResolver class implements the IASIO
+//                                     interface and acts as a proxy to the real IASIO interface by
+//                  calling through its vptr table using the thiscall calling
+//                  convention. To put it another way, we interpose
+//                  IASIOThiscallResolver between ASIO SDK code and the driver.
+//                  This is necessary because most non-Microsoft compilers don't
+//                  implement the thiscall calling convention used by IASIO.
+//
+//                                     iasiothiscallresolver.cpp contains the background of this
+//                                     problem plus a technical description of the vptr
+//                  manipulations.
+//
+//                                     In order to use this mechanism one simply has to add
+//                                     iasiothiscallresolver.cpp to the list of files to compile
+//                  and #include <iasiothiscallresolver.h>
+//
+//                                     Note that this #include must come after the other ASIO SDK
+//                  #includes, for example:
+//
+//                                     #include <windows.h>
+//                                     #include <asiosys.h>
+//                                     #include <asio.h>
+//                                     #include <asiodrivers.h>
+//                                     #include <iasiothiscallresolver.h>
+//
+//                                     Actually the important thing is to #include
+//                  <iasiothiscallresolver.h> after <asio.h>. We have
+//                  incorporated a test to enforce this ordering.
+//
+//                                     The code transparently takes care of the interposition by
+//                  using macro substitution to intercept calls to ASIOInit()
+//                  and ASIOExit(). We save the original ASIO global
+//                  "theAsioDriver" in our "that" variable, and then set
+//                  "theAsioDriver" to equal our IASIOThiscallResolver instance.
+//
+//                                     Whilst this method of resolving the thiscall problem requires
+//                                     the addition of #include <iasiothiscallresolver.h> to client
+//                  code it has the advantage that it does not break the terms
+//                  of the ASIO licence by publishing it. We are NOT modifying
+//                  any Steinberg code here, we are merely implementing the IASIO
+//                                     interface in the same way that we would need to do if we
+//                                     wished to provide an open source ASIO driver.
+//
+//                                     For compilation with MinGW -lole32 needs to be added to the
+//                  linker options. For BORLAND, linking with Import32.lib is
+//                  sufficient.
+//
+//                                     The dependencies are with: CoInitialize, CoUninitialize,
+//                                     CoCreateInstance, CLSIDFromString - used by asiolist.cpp
+//                                     and are required on Windows whether ThiscallResolver is used
+//                                     or not.
+//
+//                                     Searching for the above strings in the root library path
+//                                     of your compiler should enable the correct libraries to be
+//                                     identified if they aren't immediately obvious.
+//
+//                  Note that the current implementation of IASIOThiscallResolver
+//                  is not COM compliant - it does not correctly implement the
+//                  IUnknown interface. Implementing it is not necessary because
+//                  it is not called by parts of the ASIO SDK which call through
+//                  theAsioDriver ptr. The IUnknown methods are implemented as
+//                  assert(false) to ensure that the code fails if they are
+//                  ever called.
+// Restrictions:       None. Public Domain & Open Source distribute freely
+//                                     You may use IASIOThiscallResolver commercially as well as
+//                  privately.
+//                                     You the user assume the responsibility for the use of the
+//                                     files, binary or text, and there is no guarantee or warranty,
+//                                     expressed or implied, including but not limited to the
+//                                     implied warranties of merchantability and fitness for a
+//                                     particular purpose. You assume all responsibility and agree
+//                                     to hold no entity, copyright holder or distributors liable
+//                                     for any loss of data or inaccurate representations of data
+//                                     as a result of using IASIOThiscallResolver.
+// Version:         1.4 Added separate macro CALL_THISCALL_1_DOUBLE from
+//                  Andrew Baldwin, and volatile for whole gcc asm blocks,
+//                  both for compatibility with newer gcc versions. Cleaned up
+//                  Borland asm to use one less register.
+//                  1.3 Switched to including assert.h for better compatibility.
+//                  Wrapped entire .h and .cpp contents with a check for
+//                  _MSC_VER to provide better compatibility with MS compilers.
+//                  Changed Singleton implementation to use static instance
+//                  instead of freestore allocated instance. Removed ASIOExit
+//                  macro as it is no longer needed.
+//                  1.2 Removed semicolons from ASIOInit and ASIOExit macros to
+//                  allow them to be embedded in expressions (if statements).
+//                  Cleaned up some comments. Removed combase.c dependency (it
+//                  doesn't compile with BCB anyway) by stubbing IUnknown.
+//                  1.1 Incorporated comments from Ross Bencina including things
+//                                     such as changing name from ThiscallResolver to
+//                                     IASIOThiscallResolver, tidying up the constructor, fixing
+//                                     a bug in IASIOThiscallResolver::ASIOExit() and improving
+//                                     portability through the use of conditional compilation
+//                                     1.0 Initial working version.
+// Created:                    6/09/2003
+// Authors:         Fraser Adams
+//                  Ross Bencina
+//                  Rene G. Ceballos
+//                  Martin Fay
+//                  Antti Silvast
+//                  Andrew Baldwin
+//
+// ****************************************************************************
+
+
+#ifndef included_iasiothiscallresolver_h
+#define included_iasiothiscallresolver_h
+
+// We only need IASIOThiscallResolver at all if we are on Win32. For other
+// platforms we simply bypass the IASIOThiscallResolver definition to allow us
+// to be safely #include'd whatever the platform to keep client code portable
+#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
+
+
+// If microsoft compiler we can call IASIO directly so IASIOThiscallResolver
+// is not used.
+#if !defined(_MSC_VER)
+
+
+// The following is in order to ensure that this header is only included after
+// the other ASIO headers (except for the case of iasiothiscallresolver.cpp).
+// We need to do this because IASIOThiscallResolver works by eclipsing the
+// original definition of ASIOInit() with a macro (see below).
+#if !defined(iasiothiscallresolver_sourcefile)
+       #if !defined(__ASIO_H)
+       #error iasiothiscallresolver.h must be included AFTER asio.h
+       #endif
+#endif
+
+#include <windows.h>
+#include <asiodrvr.h> /* From ASIO SDK */
+
+
+class IASIOThiscallResolver : public IASIO {
+private:
+       IASIO* that_; // Points to the real IASIO
+
+       static IASIOThiscallResolver instance; // Singleton instance
+
+       // Constructors - declared private so construction is limited to
+    // our Singleton instance
+    IASIOThiscallResolver();
+       IASIOThiscallResolver(IASIO* that);
+public:
+
+    // Methods from the IUnknown interface. We don't fully implement IUnknown
+    // because the ASIO SDK never calls these methods through theAsioDriver ptr.
+    // These methods are implemented as assert(false).
+    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppv);
+    virtual ULONG STDMETHODCALLTYPE AddRef();
+    virtual ULONG STDMETHODCALLTYPE Release();
+
+    // Methods from the IASIO interface, implemented as forwarning calls to that.
+       virtual ASIOBool init(void *sysHandle);
+       virtual void getDriverName(char *name);
+       virtual long getDriverVersion();
+       virtual void getErrorMessage(char *string);
+       virtual ASIOError start();
+       virtual ASIOError stop();
+       virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels);
+       virtual ASIOError getLatencies(long *inputLatency, long *outputLatency);
+       virtual ASIOError getBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity);
+       virtual ASIOError canSampleRate(ASIOSampleRate sampleRate);
+       virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate);
+       virtual ASIOError setSampleRate(ASIOSampleRate sampleRate);
+       virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources);
+       virtual ASIOError setClockSource(long reference);
+       virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp);
+       virtual ASIOError getChannelInfo(ASIOChannelInfo *info);
+       virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, long bufferSize, ASIOCallbacks *callbacks);
+       virtual ASIOError disposeBuffers();
+       virtual ASIOError controlPanel();
+       virtual ASIOError future(long selector,void *opt);
+       virtual ASIOError outputReady();
+
+    // Class method, see ASIOInit() macro below.
+    static ASIOError ASIOInit(ASIODriverInfo *info); // Delegates to ::ASIOInit
+};
+
+
+// Replace calls to ASIOInit with our interposing version.
+// This macro enables us to perform thiscall resolution simply by #including
+// <iasiothiscallresolver.h> after the asio #includes (this file _must_ be
+// included _after_ the asio #includes)
+
+#define ASIOInit(name) IASIOThiscallResolver::ASIOInit((name))
+
+
+#endif /* !defined(_MSC_VER) */
+
+#endif /* Win32 */
+
+#endif /* included_iasiothiscallresolver_h */
+
+
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/asio/pa_asio.cpp b/utils/iaxclient/lib/portaudio/src/hostapi/asio/pa_asio.cpp
new file mode 100644 (file)
index 0000000..f7b2e08
--- /dev/null
@@ -0,0 +1,2968 @@
+/*
+ * $Id: pa_asio.cpp,v 1.1 2006/06/10 21:30:55 dmazzoni Exp $
+ * Portable Audio I/O Library for ASIO Drivers
+ *
+ * Author: Stephane Letz
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 2000-2002 Stephane Letz, Phil Burk, Ross Bencina
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* Modification History
+
+        08-03-01 First version : Stephane Letz
+        08-06-01 Tweaks for PC, use C++, buffer allocation, Float32 to Int32 conversion : Phil Burk
+        08-20-01 More conversion, PA_StreamTime, Pa_GetHostError : Stephane Letz
+        08-21-01 PaUInt8 bug correction, implementation of ASIOSTFloat32LSB and ASIOSTFloat32MSB native formats : Stephane Letz
+        08-24-01 MAX_INT32_FP hack, another Uint8 fix : Stephane and Phil
+        08-27-01 Implementation of hostBufferSize < userBufferSize case, better management of the ouput buffer when
+                 the stream is stopped : Stephane Letz
+        08-28-01 Check the stream pointer for null in bufferSwitchTimeInfo, correct bug in bufferSwitchTimeInfo when
+                 the stream is stopped : Stephane Letz
+        10-12-01 Correct the PaHost_CalcNumHostBuffers function: computes FramesPerHostBuffer to be the lowest that
+                 respect requested FramesPerUserBuffer and userBuffersPerHostBuffer : Stephane Letz
+        10-26-01 Management of hostBufferSize and userBufferSize of any size : Stephane Letz
+        10-27-01 Improve calculus of hostBufferSize to be multiple or divisor of userBufferSize if possible : Stephane and Phil
+        10-29-01 Change MAX_INT32_FP to (2147483520.0f) to prevent roundup to 0x80000000 : Phil Burk
+        10-31-01 Clear the ouput buffer and user buffers in PaHost_StartOutput, correct bug in GetFirstMultiple : Stephane Letz
+        11-06-01 Rename functions : Stephane Letz
+        11-08-01 New Pa_ASIO_Adaptor_Init function to init Callback adpatation variables, cleanup of Pa_ASIO_Callback_Input: Stephane Letz
+        11-29-01 Break apart device loading to debug random failure in Pa_ASIO_QueryDeviceInfo ; Phil Burk
+        01-03-02 Desallocate all resources in PaHost_Term for cases where Pa_CloseStream is not called properly :  Stephane Letz
+        02-01-02 Cleanup, test of multiple-stream opening : Stephane Letz
+        19-02-02 New Pa_ASIO_loadDriver that calls CoInitialize on each thread on Windows : Stephane Letz
+        09-04-02 Correct error code management in PaHost_Term, removes various compiler warning : Stephane Letz
+        12-04-02 Add Mac includes for <Devices.h> and <Timer.h> : Phil Burk
+        13-04-02 Removes another compiler warning : Stephane Letz
+        30-04-02 Pa_ASIO_QueryDeviceInfo bug correction, memory allocation checking, better error handling : D Viens, P Burk, S Letz
+        12-06-02 Rehashed into new multi-api infrastructure, added support for all ASIO sample formats : Ross Bencina
+        18-06-02 Added pa_asio.h, PaAsio_GetAvailableLatencyValues() : Ross B.
+        21-06-02 Added SelectHostBufferSize() which selects host buffer size based on user latency parameters : Ross Bencina
+        ** NOTE  maintanance history is now stored in CVS **
+*/
+
+/** @file
+
+    Note that specific support for paInputUnderflow, paOutputOverflow and
+    paNeverDropInput is not necessary or possible with this driver due to the
+    synchronous full duplex double-buffered architecture of ASIO.
+
+    @todo check that CoInitialize()/CoUninitialize() are always correctly
+        paired, even in error cases.
+
+    @todo implement host api specific extension to set i/o buffer sizes in frames
+
+    @todo implement ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable
+
+    @todo implement IsFormatSupported
+
+    @todo work out how to implement stream stoppage from callback and
+            implement IsStreamActive properly. Stream stoppage could be implemented
+            using a high-priority thread blocked on an Event which is signalled
+            by the callback. Or, we could just call ASIO stop from the callback
+            and see what happens.
+
+    @todo rigorously check asio return codes and convert to pa error codes
+
+    @todo Different channels of a multichannel stream can have different sample
+            formats, but we assume that all are the same as the first channel for now.
+            Fixing this will require the block processor to maintain per-channel
+            conversion functions - could get nasty.
+
+    @todo investigate whether the asio processNow flag needs to be honoured
+
+    @todo handle asioMessages() callbacks in a useful way, or at least document
+            what cases we don't handle.
+
+    @todo miscellaneous other FIXMEs
+
+    @todo provide an asio-specific method for setting the systems specific
+        value (aka main window handle) - check that this matches the value
+        passed to PaAsio_ShowControlPanel, or remove it entirely from
+        PaAsio_ShowControlPanel. - this would allow PaAsio_ShowControlPanel
+        to be called for the currently open stream (at present all streams
+        must be closed).
+*/
+
+
+
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+//#include <values.h>
+
+#include <windows.h>
+#include <mmsystem.h>
+
+#include "portaudio.h"
+#include "pa_asio.h"
+#include "pa_util.h"
+#include "pa_allocation.h"
+#include "pa_hostapi.h"
+#include "pa_stream.h"
+#include "pa_cpuload.h"
+#include "pa_process.h"
+
+
+/* This version of pa_asio.cpp is currently only targetted at Win32,
+   It would require a few tweaks to work with pre-OS X Macintosh.
+   To make configuration easier, we define WIN32 here to make sure
+   that the ASIO SDK knows this is Win32.
+*/
+#ifndef WIN32
+#define WIN32
+#endif
+
+#include "asiosys.h"
+#include "asio.h"
+#include "asiodrivers.h"
+#include "iasiothiscallresolver.h"
+
+/*
+#if MAC
+#include <Devices.h>
+#include <Timer.h>
+#include <Math64.h>
+#else
+*/
+/*
+#include <math.h>
+#include <windows.h>
+#include <mmsystem.h>
+*/
+/*
+#endif
+*/
+
+/* external references */
+extern AsioDrivers* asioDrivers ;
+bool loadAsioDriver(char *name);
+
+
+/* We are trying to be compatible with CARBON but this has not been thoroughly tested. */
+/* not tested at all since new code was introduced. */
+#define CARBON_COMPATIBLE  (0)
+
+
+
+
+/* prototypes for functions declared in this file */
+
+extern "C" PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex );
+static void Terminate( struct PaUtilHostApiRepresentation *hostApi );
+static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
+                           PaStream** s,
+                           const PaStreamParameters *inputParameters,
+                           const PaStreamParameters *outputParameters,
+                           double sampleRate,
+                           unsigned long framesPerBuffer,
+                           PaStreamFlags streamFlags,
+                           PaStreamCallback *streamCallback,
+                           void *userData );
+static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
+                                  const PaStreamParameters *inputParameters,
+                                  const PaStreamParameters *outputParameters,
+                                  double sampleRate );
+static PaError CloseStream( PaStream* stream );
+static PaError StartStream( PaStream *stream );
+static PaError StopStream( PaStream *stream );
+static PaError AbortStream( PaStream *stream );
+static PaError IsStreamStopped( PaStream *s );
+static PaError IsStreamActive( PaStream *stream );
+static PaTime GetStreamTime( PaStream *stream );
+static double GetStreamCpuLoad( PaStream* stream );
+static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames );
+static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames );
+static signed long GetStreamReadAvailable( PaStream* stream );
+static signed long GetStreamWriteAvailable( PaStream* stream );
+
+/* our ASIO callback functions */
+
+static void bufferSwitch(long index, ASIOBool processNow);
+static ASIOTime *bufferSwitchTimeInfo(ASIOTime *timeInfo, long index, ASIOBool processNow);
+static void sampleRateChanged(ASIOSampleRate sRate);
+static long asioMessages(long selector, long value, void* message, double* opt);
+
+static ASIOCallbacks asioCallbacks_ =
+    { bufferSwitch, sampleRateChanged, asioMessages, bufferSwitchTimeInfo };
+
+
+#define PA_ASIO_SET_LAST_HOST_ERROR( errorCode, errorText ) \
+    PaUtil_SetLastHostErrorInfo( paASIO, errorCode, errorText )
+
+
+static void PaAsio_SetLastSystemError( DWORD errorCode )
+{
+    LPVOID lpMsgBuf;
+    FormatMessage(
+        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+        NULL,
+        errorCode,
+        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+        (LPTSTR) &lpMsgBuf,
+        0,
+        NULL
+    );
+    PaUtil_SetLastHostErrorInfo( paASIO, errorCode, (const char*)lpMsgBuf );
+    LocalFree( lpMsgBuf );
+}
+
+#define PA_ASIO_SET_LAST_SYSTEM_ERROR( errorCode ) \
+    PaAsio_SetLastSystemError( errorCode )
+
+
+static const char* PaAsio_GetAsioErrorText( ASIOError asioError )
+{
+    const char *result;
+
+    switch( asioError ){
+        case ASE_OK:
+        case ASE_SUCCESS:           result = "Success"; break;
+        case ASE_NotPresent:        result = "Hardware input or output is not present or available"; break;
+        case ASE_HWMalfunction:     result = "Hardware is malfunctioning"; break;
+        case ASE_InvalidParameter:  result = "Input parameter invalid"; break;
+        case ASE_InvalidMode:       result = "Hardware is in a bad mode or used in a bad mode"; break;
+        case ASE_SPNotAdvancing:    result = "Hardware is not running when sample position is inquired"; break;
+        case ASE_NoClock:           result = "Sample clock or rate cannot be determined or is not present"; break;
+        case ASE_NoMemory:          result = "Not enough memory for completing the request"; break;
+        default:                    result = "Unknown ASIO error"; break;
+    }
+
+    return result;
+}
+
+
+#define PA_ASIO_SET_LAST_ASIO_ERROR( asioError ) \
+    PaUtil_SetLastHostErrorInfo( paASIO, asioError, PaAsio_GetAsioErrorText( asioError ) )
+
+
+
+
+// Atomic increment and decrement operations
+#if MAC
+       /* need to be implemented on Mac */
+       inline long PaAsio_AtomicIncrement(volatile long* v) {return ++(*const_cast<long*>(v));}
+       inline long PaAsio_AtomicDecrement(volatile long* v) {return --(*const_cast<long*>(v));}
+#elif WINDOWS
+       inline long PaAsio_AtomicIncrement(volatile long* v) {return InterlockedIncrement(const_cast<long*>(v));}
+       inline long PaAsio_AtomicDecrement(volatile long* v) {return InterlockedDecrement(const_cast<long*>(v));}
+#endif
+
+
+
+typedef struct PaAsioDriverInfo
+{
+    ASIODriverInfo asioDriverInfo;
+    long inputChannelCount, outputChannelCount;
+    long bufferMinSize, bufferMaxSize, bufferPreferredSize, bufferGranularity;
+    bool postOutput;
+}
+PaAsioDriverInfo;
+
+
+/* PaAsioHostApiRepresentation - host api datastructure specific to this implementation */
+
+typedef struct
+{
+    PaUtilHostApiRepresentation inheritedHostApiRep;
+    PaUtilStreamInterface callbackStreamInterface;
+    PaUtilStreamInterface blockingStreamInterface;
+
+    PaUtilAllocationGroup *allocations;
+
+    void *systemSpecific;
+    
+    /* the ASIO C API only allows one ASIO driver to be open at a time,
+        so we keep track of whether we have the driver open here, and
+        use this information to return errors from OpenStream if the
+        driver is already open.
+
+        openAsioDeviceIndex will be PaNoDevice if there is no device open
+        and a valid pa_asio (not global) device index otherwise.
+
+        openAsioDriverInfo is populated with the driver info for the
+        currently open device (if any)
+    */
+    PaDeviceIndex openAsioDeviceIndex;
+    PaAsioDriverInfo openAsioDriverInfo;
+}
+PaAsioHostApiRepresentation;
+
+
+/*
+    Retrieve <driverCount> driver names from ASIO, returned in a char**
+    allocated in <group>.
+*/
+static char **GetAsioDriverNames( PaUtilAllocationGroup *group, long driverCount )
+{
+    char **result = 0;
+    int i;
+
+    result =(char**)PaUtil_GroupAllocateMemory(
+            group, sizeof(char*) * driverCount );
+    if( !result )
+        goto error;
+
+    result[0] = (char*)PaUtil_GroupAllocateMemory(
+            group, 32 * driverCount );
+    if( !result[0] )
+        goto error;
+
+    for( i=0; i<driverCount; ++i )
+        result[i] = result[0] + (32 * i);
+
+    asioDrivers->getDriverNames( result, driverCount );
+
+error:
+    return result;
+}
+
+
+static PaSampleFormat AsioSampleTypeToPaNativeSampleFormat(ASIOSampleType type)
+{
+    switch (type) {
+        case ASIOSTInt16MSB:
+        case ASIOSTInt16LSB:
+                return paInt16;
+
+        case ASIOSTFloat32MSB:
+        case ASIOSTFloat32LSB:
+        case ASIOSTFloat64MSB:
+        case ASIOSTFloat64LSB:
+                return paFloat32;
+
+        case ASIOSTInt32MSB:
+        case ASIOSTInt32LSB:
+        case ASIOSTInt32MSB16:
+        case ASIOSTInt32LSB16:
+        case ASIOSTInt32MSB18:
+        case ASIOSTInt32MSB20:
+        case ASIOSTInt32MSB24:
+        case ASIOSTInt32LSB18:
+        case ASIOSTInt32LSB20:
+        case ASIOSTInt32LSB24:
+                return paInt32;
+
+        case ASIOSTInt24MSB:
+        case ASIOSTInt24LSB:
+                return paInt24;
+
+        default:
+                return paCustomFormat;
+    }
+}
+
+void AsioSampleTypeLOG(ASIOSampleType type)
+{
+    switch (type) {
+        case ASIOSTInt16MSB:  PA_DEBUG(("ASIOSTInt16MSB\n"));  break;
+        case ASIOSTInt16LSB:  PA_DEBUG(("ASIOSTInt16LSB\n"));  break;
+        case ASIOSTFloat32MSB:PA_DEBUG(("ASIOSTFloat32MSB\n"));break;
+        case ASIOSTFloat32LSB:PA_DEBUG(("ASIOSTFloat32LSB\n"));break;
+        case ASIOSTFloat64MSB:PA_DEBUG(("ASIOSTFloat64MSB\n"));break;
+        case ASIOSTFloat64LSB:PA_DEBUG(("ASIOSTFloat64LSB\n"));break;
+        case ASIOSTInt32MSB:  PA_DEBUG(("ASIOSTInt32MSB\n"));  break;
+        case ASIOSTInt32LSB:  PA_DEBUG(("ASIOSTInt32LSB\n"));  break;
+        case ASIOSTInt32MSB16:PA_DEBUG(("ASIOSTInt32MSB16\n"));break;
+        case ASIOSTInt32LSB16:PA_DEBUG(("ASIOSTInt32LSB16\n"));break;
+        case ASIOSTInt32MSB18:PA_DEBUG(("ASIOSTInt32MSB18\n"));break;
+        case ASIOSTInt32MSB20:PA_DEBUG(("ASIOSTInt32MSB20\n"));break;
+        case ASIOSTInt32MSB24:PA_DEBUG(("ASIOSTInt32MSB24\n"));break;
+        case ASIOSTInt32LSB18:PA_DEBUG(("ASIOSTInt32LSB18\n"));break;
+        case ASIOSTInt32LSB20:PA_DEBUG(("ASIOSTInt32LSB20\n"));break;
+        case ASIOSTInt32LSB24:PA_DEBUG(("ASIOSTInt32LSB24\n"));break;
+        case ASIOSTInt24MSB:  PA_DEBUG(("ASIOSTInt24MSB\n"));  break;
+        case ASIOSTInt24LSB:  PA_DEBUG(("ASIOSTInt24LSB\n"));  break;
+        default:              PA_DEBUG(("Custom Format%d\n",type));break;
+
+    }
+}
+
+static int BytesPerAsioSample( ASIOSampleType sampleType )
+{
+    switch (sampleType) {
+        case ASIOSTInt16MSB:
+        case ASIOSTInt16LSB:
+            return 2;
+
+        case ASIOSTFloat64MSB:
+        case ASIOSTFloat64LSB:
+            return 8;
+
+        case ASIOSTFloat32MSB:
+        case ASIOSTFloat32LSB:
+        case ASIOSTInt32MSB:
+        case ASIOSTInt32LSB:
+        case ASIOSTInt32MSB16:
+        case ASIOSTInt32LSB16:
+        case ASIOSTInt32MSB18:
+        case ASIOSTInt32MSB20:
+        case ASIOSTInt32MSB24:
+        case ASIOSTInt32LSB18:
+        case ASIOSTInt32LSB20:
+        case ASIOSTInt32LSB24:
+            return 4;
+
+        case ASIOSTInt24MSB:
+        case ASIOSTInt24LSB:
+            return 3;
+
+        default:
+            return 0;
+    }
+}
+
+
+static void Swap16( void *buffer, long shift, long count )
+{
+    unsigned short *p = (unsigned short*)buffer;
+    unsigned short temp;
+    (void) shift; /* unused parameter */
+
+    while( count-- )
+    {
+        temp = *p;
+        *p++ = (unsigned short)((temp<<8) | (temp>>8));
+    }
+}
+
+static void Swap24( void *buffer, long shift, long count )
+{
+    unsigned char *p = (unsigned char*)buffer;
+    unsigned char temp;
+    (void) shift; /* unused parameter */
+
+    while( count-- )
+    {
+        temp = *p;
+        *p = *(p+2);
+        *(p+2) = temp;
+        p += 3;
+    }
+}
+
+#define PA_SWAP32_( x ) ((x>>24) | ((x>>8)&0xFF00) | ((x<<8)&0xFF0000) | (x<<24));
+
+static void Swap32( void *buffer, long shift, long count )
+{
+    unsigned long *p = (unsigned long*)buffer;
+    unsigned long temp;
+    (void) shift; /* unused parameter */
+
+    while( count-- )
+    {
+        temp = *p;
+        *p++ = PA_SWAP32_( temp);
+    }
+}
+
+static void SwapShiftLeft32( void *buffer, long shift, long count )
+{
+    unsigned long *p = (unsigned long*)buffer;
+    unsigned long temp;
+
+    while( count-- )
+    {
+        temp = *p;
+        temp = PA_SWAP32_( temp);
+        *p++ = temp << shift;
+    }
+}
+
+static void ShiftRightSwap32( void *buffer, long shift, long count )
+{
+    unsigned long *p = (unsigned long*)buffer;
+    unsigned long temp;
+
+    while( count-- )
+    {
+        temp = *p >> shift;
+        *p++ = PA_SWAP32_( temp);
+    }
+}
+
+static void ShiftLeft32( void *buffer, long shift, long count )
+{
+    unsigned long *p = (unsigned long*)buffer;
+    unsigned long temp;
+
+    while( count-- )
+    {
+        temp = *p;
+        *p++ = temp << shift;
+    }
+}
+
+static void ShiftRight32( void *buffer, long shift, long count )
+{
+    unsigned long *p = (unsigned long*)buffer;
+    unsigned long temp;
+
+    while( count-- )
+    {
+        temp = *p;
+        *p++ = temp >> shift;
+    }
+}
+
+#define PA_SWAP_( x, y ) temp=x; x = y; y = temp;
+
+static void Swap64ConvertFloat64ToFloat32( void *buffer, long shift, long count )
+{
+    double *in = (double*)buffer;
+    float *out = (float*)buffer;
+    unsigned char *p;
+    unsigned char temp;
+    (void) shift; /* unused parameter */
+
+    while( count-- )
+    {
+        p = (unsigned char*)in;
+        PA_SWAP_( p[0], p[7] );
+        PA_SWAP_( p[1], p[6] );
+        PA_SWAP_( p[2], p[5] );
+        PA_SWAP_( p[3], p[4] );
+
+        *out++ = (float) (*in++);
+    }
+}
+
+static void ConvertFloat64ToFloat32( void *buffer, long shift, long count )
+{
+    double *in = (double*)buffer;
+    float *out = (float*)buffer;
+    (void) shift; /* unused parameter */
+
+    while( count-- )
+        *out++ = (float) (*in++);
+}
+
+static void ConvertFloat32ToFloat64Swap64( void *buffer, long shift, long count )
+{
+    float *in = ((float*)buffer) + (count-1);
+    double *out = ((double*)buffer) + (count-1);
+    unsigned char *p;
+    unsigned char temp;
+    (void) shift; /* unused parameter */
+
+    while( count-- )
+    {
+        *out = *in--;
+
+        p = (unsigned char*)out;
+        PA_SWAP_( p[0], p[7] );
+        PA_SWAP_( p[1], p[6] );
+        PA_SWAP_( p[2], p[5] );
+        PA_SWAP_( p[3], p[4] );
+
+        out--;
+    }
+}
+
+static void ConvertFloat32ToFloat64( void *buffer, long shift, long count )
+{
+    float *in = ((float*)buffer) + (count-1);
+    double *out = ((double*)buffer) + (count-1);
+    (void) shift; /* unused parameter */
+
+    while( count-- )
+        *out-- = *in--;
+}
+
+#ifdef MAC
+#define PA_MSB_IS_NATIVE_
+#undef PA_LSB_IS_NATIVE_
+#endif
+
+#ifdef WINDOWS
+#undef PA_MSB_IS_NATIVE_
+#define PA_LSB_IS_NATIVE_
+#endif
+
+typedef void PaAsioBufferConverter( void *, long, long );
+
+static void SelectAsioToPaConverter( ASIOSampleType type, PaAsioBufferConverter **converter, long *shift )
+{
+    *shift = 0;
+    *converter = 0;
+
+    switch (type) {
+        case ASIOSTInt16MSB:
+            /* dest: paInt16, no conversion necessary, possible byte swap*/
+            #ifdef PA_LSB_IS_NATIVE_
+                *converter = Swap16;
+            #endif
+            break;
+        case ASIOSTInt16LSB:
+            /* dest: paInt16, no conversion necessary, possible byte swap*/
+            #ifdef PA_MSB_IS_NATIVE_
+                *converter = Swap16;
+            #endif
+            break;
+        case ASIOSTFloat32MSB:
+            /* dest: paFloat32, no conversion necessary, possible byte swap*/
+            #ifdef PA_LSB_IS_NATIVE_
+                *converter = Swap32;
+            #endif
+            break;
+        case ASIOSTFloat32LSB:
+            /* dest: paFloat32, no conversion necessary, possible byte swap*/
+            #ifdef PA_MSB_IS_NATIVE_
+                *converter = Swap32;
+            #endif
+            break;
+        case ASIOSTFloat64MSB:
+            /* dest: paFloat32, in-place conversion to/from float32, possible byte swap*/
+            #ifdef PA_LSB_IS_NATIVE_
+                *converter = Swap64ConvertFloat64ToFloat32;
+            #else
+                *converter = ConvertFloat64ToFloat32;
+            #endif
+            break;
+        case ASIOSTFloat64LSB:
+            /* dest: paFloat32, in-place conversion to/from float32, possible byte swap*/
+            #ifdef PA_MSB_IS_NATIVE_
+                *converter = Swap64ConvertFloat64ToFloat32;
+            #else
+                *converter = ConvertFloat64ToFloat32;
+            #endif
+            break;
+        case ASIOSTInt32MSB:
+            /* dest: paInt32, no conversion necessary, possible byte swap */
+            #ifdef PA_LSB_IS_NATIVE_
+                *converter = Swap32;
+            #endif
+            break;
+        case ASIOSTInt32LSB:
+            /* dest: paInt32, no conversion necessary, possible byte swap */
+            #ifdef PA_MSB_IS_NATIVE_
+                *converter = Swap32;
+            #endif
+            break;
+        case ASIOSTInt32MSB16:
+            /* dest: paInt32, 16 bit shift, possible byte swap */
+            #ifdef PA_LSB_IS_NATIVE_
+                *converter = SwapShiftLeft32;
+            #else
+                *converter = ShiftLeft32;
+            #endif
+            *shift = 16;
+            break;
+        case ASIOSTInt32MSB18:
+            /* dest: paInt32, 14 bit shift, possible byte swap */
+            #ifdef PA_LSB_IS_NATIVE_
+                *converter = SwapShiftLeft32;
+            #else
+                *converter = ShiftLeft32;
+            #endif
+            *shift = 14;
+            break;
+        case ASIOSTInt32MSB20:
+            /* dest: paInt32, 12 bit shift, possible byte swap */
+            #ifdef PA_LSB_IS_NATIVE_
+                *converter = SwapShiftLeft32;
+            #else
+                *converter = ShiftLeft32;
+            #endif
+            *shift = 12;
+            break;
+        case ASIOSTInt32MSB24:
+            /* dest: paInt32, 8 bit shift, possible byte swap */
+            #ifdef PA_LSB_IS_NATIVE_
+                *converter = SwapShiftLeft32;
+            #else
+                *converter = ShiftLeft32;
+            #endif
+            *shift = 8;
+            break;
+        case ASIOSTInt32LSB16:
+            /* dest: paInt32, 16 bit shift, possible byte swap */
+            #ifdef PA_MSB_IS_NATIVE_
+                *converter = SwapShiftLeft32;
+            #else
+                *converter = ShiftLeft32;
+            #endif
+            *shift = 16;
+            break;
+        case ASIOSTInt32LSB18:
+            /* dest: paInt32, 14 bit shift, possible byte swap */
+            #ifdef PA_MSB_IS_NATIVE_
+                *converter = SwapShiftLeft32;
+            #else
+                *converter = ShiftLeft32;
+            #endif
+            *shift = 14;
+            break;
+        case ASIOSTInt32LSB20:
+            /* dest: paInt32, 12 bit shift, possible byte swap */
+            #ifdef PA_MSB_IS_NATIVE_
+                *converter = SwapShiftLeft32;
+            #else
+                *converter = ShiftLeft32;
+            #endif
+            *shift = 12;
+            break;
+        case ASIOSTInt32LSB24:
+            /* dest: paInt32, 8 bit shift, possible byte swap */
+            #ifdef PA_MSB_IS_NATIVE_
+                *converter = SwapShiftLeft32;
+            #else
+                *converter = ShiftLeft32;
+            #endif
+            *shift = 8;
+            break;
+        case ASIOSTInt24MSB:
+            /* dest: paInt24, no conversion necessary, possible byte swap */
+            #ifdef PA_LSB_IS_NATIVE_
+                *converter = Swap24;
+            #endif
+            break;
+        case ASIOSTInt24LSB:
+            /* dest: paInt24, no conversion necessary, possible byte swap */
+            #ifdef PA_MSB_IS_NATIVE_
+                *converter = Swap24;
+            #endif
+            break;
+    }
+}
+
+
+static void SelectPaToAsioConverter( ASIOSampleType type, PaAsioBufferConverter **converter, long *shift )
+{
+    *shift = 0;
+    *converter = 0;
+
+    switch (type) {
+        case ASIOSTInt16MSB:
+            /* src: paInt16, no conversion necessary, possible byte swap*/
+            #ifdef PA_LSB_IS_NATIVE_
+                *converter = Swap16;
+            #endif
+            break;
+        case ASIOSTInt16LSB:
+            /* src: paInt16, no conversion necessary, possible byte swap*/
+            #ifdef PA_MSB_IS_NATIVE_
+                *converter = Swap16;
+            #endif
+            break;
+        case ASIOSTFloat32MSB:
+            /* src: paFloat32, no conversion necessary, possible byte swap*/
+            #ifdef PA_LSB_IS_NATIVE_
+                *converter = Swap32;
+            #endif
+            break;
+        case ASIOSTFloat32LSB:
+            /* src: paFloat32, no conversion necessary, possible byte swap*/
+            #ifdef PA_MSB_IS_NATIVE_
+                *converter = Swap32;
+            #endif
+            break;
+        case ASIOSTFloat64MSB:
+            /* src: paFloat32, in-place conversion to/from float32, possible byte swap*/
+            #ifdef PA_LSB_IS_NATIVE_
+                *converter = ConvertFloat32ToFloat64Swap64;
+            #else
+                *converter = ConvertFloat32ToFloat64;
+            #endif
+            break;
+        case ASIOSTFloat64LSB:
+            /* src: paFloat32, in-place conversion to/from float32, possible byte swap*/
+            #ifdef PA_MSB_IS_NATIVE_
+                *converter = ConvertFloat32ToFloat64Swap64;
+            #else
+                *converter = ConvertFloat32ToFloat64;
+            #endif
+            break;
+        case ASIOSTInt32MSB:
+            /* src: paInt32, no conversion necessary, possible byte swap */
+            #ifdef PA_LSB_IS_NATIVE_
+                *converter = Swap32;
+            #endif
+            break;
+        case ASIOSTInt32LSB:
+            /* src: paInt32, no conversion necessary, possible byte swap */
+            #ifdef PA_MSB_IS_NATIVE_
+                *converter = Swap32;
+            #endif
+            break;
+        case ASIOSTInt32MSB16:
+            /* src: paInt32, 16 bit shift, possible byte swap */
+            #ifdef PA_LSB_IS_NATIVE_
+                *converter = ShiftRightSwap32;
+            #else
+                *converter = ShiftRight32;
+            #endif
+            *shift = 16;
+            break;
+        case ASIOSTInt32MSB18:
+            /* src: paInt32, 14 bit shift, possible byte swap */
+            #ifdef PA_LSB_IS_NATIVE_
+                *converter = ShiftRightSwap32;
+            #else
+                *converter = ShiftRight32;
+            #endif
+            *shift = 14;
+            break;
+        case ASIOSTInt32MSB20:
+            /* src: paInt32, 12 bit shift, possible byte swap */
+            #ifdef PA_LSB_IS_NATIVE_
+                *converter = ShiftRightSwap32;
+            #else
+                *converter = ShiftRight32;
+            #endif
+            *shift = 12;
+            break;
+        case ASIOSTInt32MSB24:
+            /* src: paInt32, 8 bit shift, possible byte swap */
+            #ifdef PA_LSB_IS_NATIVE_
+                *converter = ShiftRightSwap32;
+            #else
+                *converter = ShiftRight32;
+            #endif
+            *shift = 8;
+            break;
+        case ASIOSTInt32LSB16:
+            /* src: paInt32, 16 bit shift, possible byte swap */
+            #ifdef PA_MSB_IS_NATIVE_
+                *converter = ShiftRightSwap32;
+            #else
+                *converter = ShiftRight32;
+            #endif
+            *shift = 16;
+            break;
+        case ASIOSTInt32LSB18:
+            /* src: paInt32, 14 bit shift, possible byte swap */
+            #ifdef PA_MSB_IS_NATIVE_
+                *converter = ShiftRightSwap32;
+            #else
+                *converter = ShiftRight32;
+            #endif
+            *shift = 14;
+            break;
+        case ASIOSTInt32LSB20:
+            /* src: paInt32, 12 bit shift, possible byte swap */
+            #ifdef PA_MSB_IS_NATIVE_
+                *converter = ShiftRightSwap32;
+            #else
+                *converter = ShiftRight32;
+            #endif
+            *shift = 12;
+            break;
+        case ASIOSTInt32LSB24:
+            /* src: paInt32, 8 bit shift, possible byte swap */
+            #ifdef PA_MSB_IS_NATIVE_
+                *converter = ShiftRightSwap32;
+            #else
+                *converter = ShiftRight32;
+            #endif
+            *shift = 8;
+            break;
+        case ASIOSTInt24MSB:
+            /* src: paInt24, no conversion necessary, possible byte swap */
+            #ifdef PA_LSB_IS_NATIVE_
+                *converter = Swap24;
+            #endif
+            break;
+        case ASIOSTInt24LSB:
+            /* src: paInt24, no conversion necessary, possible byte swap */
+            #ifdef PA_MSB_IS_NATIVE_
+                *converter = Swap24;
+            #endif
+            break;
+    }
+}
+
+
+typedef struct PaAsioDeviceInfo
+{
+    PaDeviceInfo commonDeviceInfo;
+    long minBufferSize;
+    long maxBufferSize;
+    long preferredBufferSize;
+    long bufferGranularity;
+
+    ASIOChannelInfo *asioChannelInfos;
+}
+PaAsioDeviceInfo;
+
+
+PaError PaAsio_GetAvailableLatencyValues( PaDeviceIndex device,
+               long *minLatency, long *maxLatency, long *preferredLatency, long *granularity )
+{
+    PaError result;
+    PaUtilHostApiRepresentation *hostApi;
+    PaDeviceIndex hostApiDevice;
+
+    result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO );
+
+    if( result == paNoError )
+    {
+        result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, device, hostApi );
+
+        if( result == paNoError )
+        {
+            PaAsioDeviceInfo *asioDeviceInfo =
+                    (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice];
+
+            *minLatency = asioDeviceInfo->minBufferSize;
+            *maxLatency = asioDeviceInfo->maxBufferSize;
+            *preferredLatency = asioDeviceInfo->preferredBufferSize;
+            *granularity = asioDeviceInfo->bufferGranularity;
+        }
+    }
+
+    return result;
+}
+
+
+
+/*
+    load the asio driver named by <driverName> and return statistics about
+    the driver in info. If no error occurred, the driver will remain open
+    and must be closed by the called by calling ASIOExit() - if an error
+    is returned the driver will already be closed.
+*/
+static PaError LoadAsioDriver( const char *driverName,
+        PaAsioDriverInfo *driverInfo, void *systemSpecific )
+{
+    PaError result = paNoError;
+    ASIOError asioError;
+    int asioIsInitialized = 0;
+
+    if( !loadAsioDriver( const_cast<char*>(driverName) ) )
+    {
+        result = paUnanticipatedHostError;
+        PA_ASIO_SET_LAST_HOST_ERROR( 0, "Failed to load ASIO driver" );
+        goto error;
+    }
+
+    memset( &driverInfo->asioDriverInfo, 0, sizeof(ASIODriverInfo) );
+    driverInfo->asioDriverInfo.asioVersion = 2;
+    driverInfo->asioDriverInfo.sysRef = systemSpecific;
+    if( (asioError = ASIOInit( &driverInfo->asioDriverInfo )) != ASE_OK )
+    {
+        result = paUnanticipatedHostError;
+        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
+        goto error;
+    }
+    else
+    {
+        asioIsInitialized = 1;
+    }
+
+    if( (asioError = ASIOGetChannels(&driverInfo->inputChannelCount,
+            &driverInfo->outputChannelCount)) != ASE_OK )
+    {
+        result = paUnanticipatedHostError;
+        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
+        goto error;
+    }
+
+    if( (asioError = ASIOGetBufferSize(&driverInfo->bufferMinSize,
+            &driverInfo->bufferMaxSize, &driverInfo->bufferPreferredSize,
+            &driverInfo->bufferGranularity)) != ASE_OK )
+    {
+        result = paUnanticipatedHostError;
+        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
+        goto error;
+    }
+
+    if( ASIOOutputReady() == ASE_OK )
+        driverInfo->postOutput = true;
+    else
+        driverInfo->postOutput = false;
+
+    return result;
+
+error:
+    if( asioIsInitialized )
+        ASIOExit();
+
+    return result;
+}
+
+
+#define PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_     13   /* must be the same number of elements as in the array below */
+static ASIOSampleRate defaultSampleRateSearchOrder_[]
+     = {44100.0, 48000.0, 32000.0, 24000.0, 22050.0, 88200.0, 96000.0,
+        192000.0, 16000.0, 12000.0, 11025.0, 9600.0, 8000.0 };
+
+
+PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
+{
+    PaError result = paNoError;
+    int i, driverCount;
+    PaAsioHostApiRepresentation *asioHostApi;
+    PaAsioDeviceInfo *deviceInfoArray;
+    char **names;
+    PaAsioDriverInfo paAsioDriverInfo;
+
+    asioHostApi = (PaAsioHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaAsioHostApiRepresentation) );
+    if( !asioHostApi )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+
+    asioHostApi->allocations = PaUtil_CreateAllocationGroup();
+    if( !asioHostApi->allocations )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+
+    asioHostApi->systemSpecific = 0;
+    asioHostApi->openAsioDeviceIndex = paNoDevice;
+
+    *hostApi = &asioHostApi->inheritedHostApiRep;
+    (*hostApi)->info.structVersion = 1;
+
+    (*hostApi)->info.type = paASIO;
+    (*hostApi)->info.name = "ASIO";
+    (*hostApi)->info.deviceCount = 0;
+
+    #ifdef WINDOWS
+        /* use desktop window as system specific ptr */
+        asioHostApi->systemSpecific = GetDesktopWindow();
+        CoInitialize(NULL);
+    #endif
+
+    /* MUST BE CHECKED : to force fragments loading on Mac */
+    loadAsioDriver( "dummy" ); 
+
+    /* driverCount is the number of installed drivers - not necessarily
+        the number of installed physical devices. */
+    #if MAC
+        driverCount = asioDrivers->getNumFragments();
+    #elif WINDOWS
+        driverCount = asioDrivers->asioGetNumDev();
+    #endif
+
+    if( driverCount > 0 )
+    {
+        names = GetAsioDriverNames( asioHostApi->allocations, driverCount );
+        if( !names )
+        {
+            result = paInsufficientMemory;
+            goto error;
+        }
+
+
+        /* allocate enough space for all drivers, even if some aren't installed */
+
+        (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
+                asioHostApi->allocations, sizeof(PaDeviceInfo*) * driverCount );
+        if( !(*hostApi)->deviceInfos )
+        {
+            result = paInsufficientMemory;
+            goto error;
+        }
+
+        /* allocate all device info structs in a contiguous block */
+        deviceInfoArray = (PaAsioDeviceInfo*)PaUtil_GroupAllocateMemory(
+                asioHostApi->allocations, sizeof(PaAsioDeviceInfo) * driverCount );
+        if( !deviceInfoArray )
+        {
+            result = paInsufficientMemory;
+            goto error;
+        }
+
+        for( i=0; i < driverCount; ++i )
+        {
+
+            PA_DEBUG(("ASIO names[%d]:%s\n",i,names[i]));
+
+            // Since portaudio opens ALL ASIO drivers, and no one else does that,
+            // we face fact that some drivers were not meant for it, drivers which act
+            // like shells on top of REAL drivers, for instance.
+            // so we get duplicate handles, locks and other problems.
+            // so lets NOT try to load any such wrappers. 
+            // The ones i [davidv] know of so far are:
+
+            if (   strcmp (names[i],"ASIO DirectX Full Duplex Driver") == 0
+                || strcmp (names[i],"ASIO Multimedia Driver")          == 0
+                || strncmp(names[i],"Premiere",8)                      == 0   //"Premiere Elements Windows Sound 1.0"
+                || strncmp(names[i],"Adobe",5)                         == 0 ) //"Adobe Default Windows Sound 1.5"
+            {
+                PA_DEBUG(("BLACKLISTED!!!\n"));
+                continue;
+            }
+
+
+            /* Attempt to load the asio driver... */
+            if( LoadAsioDriver( names[i], &paAsioDriverInfo, asioHostApi->systemSpecific ) == paNoError )
+            {
+                PaAsioDeviceInfo *asioDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ];
+                PaDeviceInfo *deviceInfo = &asioDeviceInfo->commonDeviceInfo;
+
+                deviceInfo->structVersion = 2;
+                deviceInfo->hostApi = hostApiIndex;
+
+                deviceInfo->name = names[i];
+                PA_DEBUG(("PaAsio_Initialize: drv:%d name = %s\n",  i,deviceInfo->name));
+                PA_DEBUG(("PaAsio_Initialize: drv:%d inputChannels       = %d\n", i, paAsioDriverInfo.inputChannelCount));
+                PA_DEBUG(("PaAsio_Initialize: drv:%d outputChannels      = %d\n", i, paAsioDriverInfo.outputChannelCount));
+                PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMinSize       = %d\n", i, paAsioDriverInfo.bufferMinSize));
+                PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMaxSize       = %d\n", i, paAsioDriverInfo.bufferMaxSize));
+                PA_DEBUG(("PaAsio_Initialize: drv:%d bufferPreferredSize = %d\n", i, paAsioDriverInfo.bufferPreferredSize));
+                PA_DEBUG(("PaAsio_Initialize: drv:%d bufferGranularity   = %d\n", i, paAsioDriverInfo.bufferGranularity));
+
+                deviceInfo->maxInputChannels  = paAsioDriverInfo.inputChannelCount;
+                deviceInfo->maxOutputChannels = paAsioDriverInfo.outputChannelCount;
+
+                deviceInfo->defaultSampleRate = 0.;
+                bool foundDefaultSampleRate = false;
+                for( int j=0; j < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++j )
+                {
+                    ASIOError asioError = ASIOCanSampleRate( defaultSampleRateSearchOrder_[j] );
+                    if( asioError != ASE_NoClock && asioError != ASE_NotPresent )
+                    {
+                        deviceInfo->defaultSampleRate = defaultSampleRateSearchOrder_[j];
+                        foundDefaultSampleRate = true;
+                        break;
+                    }
+                }
+
+                PA_DEBUG(("PaAsio_Initialize: drv:%d defaultSampleRate = %f\n", i, deviceInfo->defaultSampleRate));
+
+                if( foundDefaultSampleRate ){
+
+                    /* calculate default latency values from bufferPreferredSize
+                        for default low latency, and bufferPreferredSize * 3
+                        for default high latency.
+                        use the default sample rate to convert from samples to
+                        seconds. Without knowing what sample rate the user will
+                        use this is the best we can do.
+                    */
+
+                    double defaultLowLatency =
+                            paAsioDriverInfo.bufferPreferredSize / deviceInfo->defaultSampleRate;
+
+                    deviceInfo->defaultLowInputLatency = defaultLowLatency;
+                    deviceInfo->defaultLowOutputLatency = defaultLowLatency;
+
+                    long defaultHighLatencyBufferSize =
+                            paAsioDriverInfo.bufferPreferredSize * 3;
+
+                    if( defaultHighLatencyBufferSize > paAsioDriverInfo.bufferMaxSize )
+                        defaultHighLatencyBufferSize = paAsioDriverInfo.bufferMaxSize;
+
+                    double defaultHighLatency =
+                            defaultHighLatencyBufferSize / deviceInfo->defaultSampleRate;
+
+                    if( defaultHighLatency < defaultLowLatency )
+                        defaultHighLatency = defaultLowLatency; /* just incase the driver returns something strange */ 
+                            
+                    deviceInfo->defaultHighInputLatency = defaultHighLatency;
+                    deviceInfo->defaultHighOutputLatency = defaultHighLatency;
+                    
+                }else{
+
+                    deviceInfo->defaultLowInputLatency = 0.;
+                    deviceInfo->defaultLowOutputLatency = 0.;
+                    deviceInfo->defaultHighInputLatency = 0.;
+                    deviceInfo->defaultHighOutputLatency = 0.;
+                }
+
+                PA_DEBUG(("PaAsio_Initialize: drv:%d defaultLowInputLatency = %f\n", i, deviceInfo->defaultLowInputLatency));
+                PA_DEBUG(("PaAsio_Initialize: drv:%d defaultLowOutputLatency = %f\n", i, deviceInfo->defaultLowOutputLatency));
+                PA_DEBUG(("PaAsio_Initialize: drv:%d defaultHighInputLatency = %f\n", i, deviceInfo->defaultHighInputLatency));
+                PA_DEBUG(("PaAsio_Initialize: drv:%d defaultHighOutputLatency = %f\n", i, deviceInfo->defaultHighOutputLatency));
+
+                asioDeviceInfo->minBufferSize = paAsioDriverInfo.bufferMinSize;
+                asioDeviceInfo->maxBufferSize = paAsioDriverInfo.bufferMaxSize;
+                asioDeviceInfo->preferredBufferSize = paAsioDriverInfo.bufferPreferredSize;
+                asioDeviceInfo->bufferGranularity = paAsioDriverInfo.bufferGranularity;
+
+
+                asioDeviceInfo->asioChannelInfos = (ASIOChannelInfo*)PaUtil_GroupAllocateMemory(
+                        asioHostApi->allocations,
+                        sizeof(ASIOChannelInfo) * (deviceInfo->maxInputChannels
+                                + deviceInfo->maxOutputChannels) );
+                if( !asioDeviceInfo->asioChannelInfos )
+                {
+                    result = paInsufficientMemory;
+                    goto error;
+                }
+
+                int a;
+
+                for( a=0; a < deviceInfo->maxInputChannels; ++a ){
+                    asioDeviceInfo->asioChannelInfos[a].channel = a;
+                    asioDeviceInfo->asioChannelInfos[a].isInput = ASIOTrue;
+                    ASIOError asioError = ASIOGetChannelInfo( &asioDeviceInfo->asioChannelInfos[a] );
+                    if( asioError != ASE_OK )
+                    {
+                        result = paUnanticipatedHostError;
+                        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
+                        goto error;
+                    }
+                }
+
+                for( a=0; a < deviceInfo->maxOutputChannels; ++a ){
+                    int b = deviceInfo->maxInputChannels + a;
+                    asioDeviceInfo->asioChannelInfos[b].channel = a;
+                    asioDeviceInfo->asioChannelInfos[b].isInput = ASIOFalse;
+                    ASIOError asioError = ASIOGetChannelInfo( &asioDeviceInfo->asioChannelInfos[b] );
+                    if( asioError != ASE_OK )
+                    {
+                        result = paUnanticipatedHostError;
+                        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
+                        goto error;
+                    }
+                }
+
+
+                /* unload the driver */
+                ASIOExit();
+
+                (*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo;
+                ++(*hostApi)->info.deviceCount;
+            }
+        }
+    }
+
+    if( (*hostApi)->info.deviceCount > 0 )
+    {
+        (*hostApi)->info.defaultInputDevice = 0;
+        (*hostApi)->info.defaultOutputDevice = 0;
+    }
+    else
+    {
+        (*hostApi)->info.defaultInputDevice = paNoDevice;
+        (*hostApi)->info.defaultOutputDevice = paNoDevice;
+    }
+
+
+    (*hostApi)->Terminate = Terminate;
+    (*hostApi)->OpenStream = OpenStream;
+    (*hostApi)->IsFormatSupported = IsFormatSupported;
+
+    PaUtil_InitializeStreamInterface( &asioHostApi->callbackStreamInterface, CloseStream, StartStream,
+                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
+                                      GetStreamTime, GetStreamCpuLoad,
+                                      PaUtil_DummyRead, PaUtil_DummyWrite,
+                                      PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable );
+
+    PaUtil_InitializeStreamInterface( &asioHostApi->blockingStreamInterface, CloseStream, StartStream,
+                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
+                                      GetStreamTime, PaUtil_DummyGetCpuLoad,
+                                      ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );
+
+    return result;
+
+error:
+    if( asioHostApi )
+    {
+        if( asioHostApi->allocations )
+        {
+            PaUtil_FreeAllAllocations( asioHostApi->allocations );
+            PaUtil_DestroyAllocationGroup( asioHostApi->allocations );
+        }
+
+        PaUtil_FreeMemory( asioHostApi );
+    }
+    return result;
+}
+
+
+static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
+{
+    PaAsioHostApiRepresentation *asioHostApi = (PaAsioHostApiRepresentation*)hostApi;
+
+    /*
+        IMPLEMENT ME:
+            - clean up any resources not handled by the allocation group
+    */
+
+    if( asioHostApi->allocations )
+    {
+        PaUtil_FreeAllAllocations( asioHostApi->allocations );
+        PaUtil_DestroyAllocationGroup( asioHostApi->allocations );
+    }
+
+    PaUtil_FreeMemory( asioHostApi );
+}
+
+
+static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
+                                  const PaStreamParameters *inputParameters,
+                                  const PaStreamParameters *outputParameters,
+                                  double sampleRate )
+{
+    PaError result = paNoError;
+    PaAsioHostApiRepresentation *asioHostApi = (PaAsioHostApiRepresentation*)hostApi;
+    PaAsioDriverInfo *driverInfo = &asioHostApi->openAsioDriverInfo;
+    int inputChannelCount, outputChannelCount;
+    PaSampleFormat inputSampleFormat, outputSampleFormat;
+    PaDeviceIndex asioDeviceIndex;                                  
+    ASIOError asioError;
+    
+    if( inputParameters && outputParameters )
+    {
+        /* full duplex ASIO stream must use the same device for input and output */
+
+        if( inputParameters->device != outputParameters->device )
+            return paBadIODeviceCombination;
+    }
+    
+    if( inputParameters )
+    {
+        inputChannelCount = inputParameters->channelCount;
+        inputSampleFormat = inputParameters->sampleFormat;
+
+        /* all standard sample formats are supported by the buffer adapter,
+            this implementation doesn't support any custom sample formats */
+        if( inputSampleFormat & paCustomFormat )
+            return paSampleFormatNotSupported;
+            
+        /* unless alternate device specification is supported, reject the use of
+            paUseHostApiSpecificDeviceSpecification */
+
+        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
+            return paInvalidDevice;
+
+        asioDeviceIndex = inputParameters->device;
+
+        /* validate inputStreamInfo */
+        /** @todo do more validation here */
+        // if( inputParameters->hostApiSpecificStreamInfo )
+        //    return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
+    }
+    else
+    {
+        inputChannelCount = 0;
+    }
+
+    if( outputParameters )
+    {
+        outputChannelCount = outputParameters->channelCount;
+        outputSampleFormat = outputParameters->sampleFormat;
+
+        /* all standard sample formats are supported by the buffer adapter,
+            this implementation doesn't support any custom sample formats */
+        if( outputSampleFormat & paCustomFormat )
+            return paSampleFormatNotSupported;
+            
+        /* unless alternate device specification is supported, reject the use of
+            paUseHostApiSpecificDeviceSpecification */
+
+        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
+            return paInvalidDevice;
+
+        asioDeviceIndex = outputParameters->device;
+
+        /* validate outputStreamInfo */
+        /** @todo do more validation here */
+        // if( outputParameters->hostApiSpecificStreamInfo )
+        //    return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
+    }
+    else
+    {
+        outputChannelCount = 0;
+    }
+
+
+
+    /* if an ASIO device is open we can only get format information for the currently open device */
+
+    if( asioHostApi->openAsioDeviceIndex != paNoDevice 
+                       && asioHostApi->openAsioDeviceIndex != asioDeviceIndex )
+    {
+        return paDeviceUnavailable;
+    }
+
+
+    /* NOTE: we load the driver and use its current settings
+        rather than the ones in our device info structure which may be stale */
+
+    /* open the device if it's not already open */
+    if( asioHostApi->openAsioDeviceIndex == paNoDevice )
+    {
+        result = LoadAsioDriver( asioHostApi->inheritedHostApiRep.deviceInfos[ asioDeviceIndex ]->name,
+                driverInfo, asioHostApi->systemSpecific );
+        if( result != paNoError )
+            return result;
+    }
+
+    /* check that input device can support inputChannelCount */
+    if( inputChannelCount > 0 )
+    {
+        if( inputChannelCount > driverInfo->inputChannelCount )
+        {
+            result = paInvalidChannelCount;
+            goto done;
+        }
+    }
+
+    /* check that output device can support outputChannelCount */
+    if( outputChannelCount )
+    {
+        if( outputChannelCount > driverInfo->outputChannelCount )
+        {
+            result = paInvalidChannelCount;
+            goto done;
+        }
+    }
+    
+    /* query for sample rate support */
+    asioError = ASIOCanSampleRate( sampleRate );
+    if( asioError == ASE_NoClock || asioError == ASE_NotPresent )
+    {
+        result = paInvalidSampleRate;
+        goto done;
+    }
+
+done:
+    /* close the device if it wasn't already open */
+    if( asioHostApi->openAsioDeviceIndex == paNoDevice )
+    {
+        ASIOExit(); /* not sure if we should check for errors here */
+    }
+
+    if( result == paNoError )
+        return paFormatIsSupported;
+    else
+        return result;
+}
+
+
+
+/* PaAsioStream - a stream data structure specifically for this implementation */
+
+typedef struct PaAsioStream
+{
+    PaUtilStreamRepresentation streamRepresentation;
+    PaUtilCpuLoadMeasurer cpuLoadMeasurer;
+    PaUtilBufferProcessor bufferProcessor;
+
+    PaAsioHostApiRepresentation *asioHostApi;
+    unsigned long framesPerHostCallback;
+
+    /* ASIO driver info  - these may not be needed for the life of the stream,
+        but store them here until we work out how format conversion is going
+        to work. */
+
+    ASIOBufferInfo *asioBufferInfos;
+    ASIOChannelInfo *asioChannelInfos;
+    long inputLatency, outputLatency; // actual latencies returned by asio
+
+    long inputChannelCount, outputChannelCount;
+    bool postOutput;
+
+    void **bufferPtrs; /* this is carved up for inputBufferPtrs and outputBufferPtrs */
+    void **inputBufferPtrs[2];
+    void **outputBufferPtrs[2];
+
+    PaAsioBufferConverter *inputBufferConverter;
+    long inputShift;
+    PaAsioBufferConverter *outputBufferConverter;
+    long outputShift;
+
+    volatile bool stopProcessing;
+    int stopPlayoutCount;
+    HANDLE completedBuffersPlayedEvent;
+
+    bool streamFinishedCallbackCalled;
+    volatile int isActive;
+    volatile bool zeroOutput; /* all future calls to the callback will output silence */
+
+    volatile long reenterCount;
+    volatile long reenterError;
+
+    PaStreamCallbackFlags callbackFlags;
+}
+PaAsioStream;
+
+static PaAsioStream *theAsioStream = 0; /* due to ASIO sdk limitations there can be only one stream */
+
+
+static void ZeroOutputBuffers( PaAsioStream *stream, long index )
+{
+    int i;
+
+    for( i=0; i < stream->outputChannelCount; ++i )
+    {
+        void *buffer = stream->asioBufferInfos[ i + stream->inputChannelCount ].buffers[index];
+
+        int bytesPerSample = BytesPerAsioSample( stream->asioChannelInfos[ i + stream->inputChannelCount ].type );
+
+        memset( buffer, 0, stream->framesPerHostCallback * bytesPerSample );
+    }
+}
+
+
+static unsigned long SelectHostBufferSize( unsigned long suggestedLatencyFrames,
+        PaAsioDriverInfo *driverInfo )
+{
+    unsigned long result;
+
+    if( suggestedLatencyFrames == 0 )
+    {
+        result = driverInfo->bufferPreferredSize;
+    }
+    else{
+        if( suggestedLatencyFrames <= (unsigned long)driverInfo->bufferMinSize )
+        {
+            result = driverInfo->bufferMinSize;
+        }
+        else if( suggestedLatencyFrames >= (unsigned long)driverInfo->bufferMaxSize )
+        {
+            result = driverInfo->bufferMaxSize;
+        }
+        else
+        {
+            if( driverInfo->bufferGranularity == -1 )
+            {
+                /* power-of-two */
+                result = 2;
+
+                while( result < suggestedLatencyFrames )
+                    result *= 2;
+
+                if( result < (unsigned long)driverInfo->bufferMinSize )
+                    result = driverInfo->bufferMinSize;
+
+                if( result > (unsigned long)driverInfo->bufferMaxSize )
+                    result = driverInfo->bufferMaxSize;
+            }
+            else if( driverInfo->bufferGranularity == 0 )
+            {
+                /* the documentation states that bufferGranularity should be
+                    zero when bufferMinSize, bufferMaxSize and
+                    bufferPreferredSize are the same. We assume that is the case.
+                */
+
+                result = driverInfo->bufferPreferredSize;
+            }
+            else
+            {
+                /* modulo granularity */
+
+                unsigned long remainder =
+                        suggestedLatencyFrames % driverInfo->bufferGranularity;
+
+                if( remainder == 0 )
+                {
+                    result = suggestedLatencyFrames;
+                }
+                else
+                {
+                    result = suggestedLatencyFrames
+                            + (driverInfo->bufferGranularity - remainder);
+
+                    if( result > (unsigned long)driverInfo->bufferMaxSize )
+                        result = driverInfo->bufferMaxSize;
+                }
+            }
+        }
+    }
+
+    return result;
+}
+
+
+/* returns channelSelectors if present */
+
+static PaError ValidateAsioSpecificStreamInfo(
+        const PaStreamParameters *streamParameters,
+        const PaAsioStreamInfo *streamInfo,
+        int deviceChannelCount,
+        int **channelSelectors )
+{
+       if( streamInfo )
+       {
+           if( streamInfo->size != sizeof( PaAsioStreamInfo )
+                   || streamInfo->version != 1 )
+           {
+               return paIncompatibleHostApiSpecificStreamInfo;
+           }
+
+           if( streamInfo->flags & paAsioUseChannelSelectors )
+            *channelSelectors = streamInfo->channelSelectors;
+
+        if( !(*channelSelectors) )
+            return paIncompatibleHostApiSpecificStreamInfo;
+
+        for( int i=0; i < streamParameters->channelCount; ++i ){
+             if( (*channelSelectors)[i] < 0
+                    || (*channelSelectors)[i] >= deviceChannelCount ){
+                return paInvalidChannelCount;
+             }           
+        }
+       }
+
+       return paNoError;
+}
+
+
+/* see pa_hostapi.h for a list of validity guarantees made about OpenStream  parameters */
+
+static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
+                           PaStream** s,
+                           const PaStreamParameters *inputParameters,
+                           const PaStreamParameters *outputParameters,
+                           double sampleRate,
+                           unsigned long framesPerBuffer,
+                           PaStreamFlags streamFlags,
+                           PaStreamCallback *streamCallback,
+                           void *userData )
+{
+    PaError result = paNoError;
+    PaAsioHostApiRepresentation *asioHostApi = (PaAsioHostApiRepresentation*)hostApi;
+    PaAsioStream *stream = 0;
+    PaAsioStreamInfo *inputStreamInfo, *outputStreamInfo;
+    unsigned long framesPerHostBuffer;
+    int inputChannelCount, outputChannelCount;
+    PaSampleFormat inputSampleFormat, outputSampleFormat;
+    PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat;
+    unsigned long suggestedInputLatencyFrames;
+    unsigned long suggestedOutputLatencyFrames;
+    PaDeviceIndex asioDeviceIndex;
+    ASIOError asioError;
+    int asioIsInitialized = 0;
+    int asioBuffersCreated = 0;
+    int completedBuffersPlayedEventInited = 0;
+    int i;
+    PaAsioDriverInfo *driverInfo;
+    int *inputChannelSelectors = 0;
+    int *outputChannelSelectors = 0;
+
+    /* unless we move to using lower level ASIO calls, we can only have
+        one device open at a time */
+    if( asioHostApi->openAsioDeviceIndex != paNoDevice ){
+        PA_DEBUG(("OpenStream paDeviceUnavailable\n"));
+        return paDeviceUnavailable;
+    }
+
+    if( inputParameters && outputParameters )
+    {
+        /* full duplex ASIO stream must use the same device for input and output */
+
+        if( inputParameters->device != outputParameters->device ){
+            PA_DEBUG(("OpenStream paBadIODeviceCombination\n"));
+            return paBadIODeviceCombination;
+    }
+    }
+
+    if( inputParameters )
+    {
+        inputChannelCount = inputParameters->channelCount;
+        inputSampleFormat = inputParameters->sampleFormat;
+        suggestedInputLatencyFrames = (unsigned long)((inputParameters->suggestedLatency * sampleRate)+0.5f);
+
+        /* unless alternate device specification is supported, reject the use of
+            paUseHostApiSpecificDeviceSpecification */
+        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
+            return paInvalidDevice;
+
+        asioDeviceIndex = inputParameters->device;
+
+        PaAsioDeviceInfo *asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[asioDeviceIndex];
+
+        /* validate hostApiSpecificStreamInfo */
+        inputStreamInfo = (PaAsioStreamInfo*)inputParameters->hostApiSpecificStreamInfo;
+        result = ValidateAsioSpecificStreamInfo( inputParameters, inputStreamInfo,
+            asioDeviceInfo->commonDeviceInfo.maxInputChannels,
+            &inputChannelSelectors
+        );
+        if( result != paNoError ) return result;
+    }
+    else
+    {
+        inputChannelCount = 0;
+        inputSampleFormat = 0;
+        suggestedInputLatencyFrames = 0;
+    }
+
+    if( outputParameters )
+    {
+        outputChannelCount = outputParameters->channelCount;
+        outputSampleFormat = outputParameters->sampleFormat;
+        suggestedOutputLatencyFrames = (unsigned long)((outputParameters->suggestedLatency * sampleRate)+0.5f);
+
+        /* unless alternate device specification is supported, reject the use of
+            paUseHostApiSpecificDeviceSpecification */
+        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
+            return paInvalidDevice;
+
+        asioDeviceIndex = outputParameters->device;
+
+        PaAsioDeviceInfo *asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[asioDeviceIndex];
+
+        /* validate hostApiSpecificStreamInfo */
+        outputStreamInfo = (PaAsioStreamInfo*)outputParameters->hostApiSpecificStreamInfo;
+        result = ValidateAsioSpecificStreamInfo( outputParameters, outputStreamInfo,
+            asioDeviceInfo->commonDeviceInfo.maxOutputChannels,
+            &outputChannelSelectors
+        );
+        if( result != paNoError ) return result;
+    }
+    else
+    {
+        outputChannelCount = 0;
+        outputSampleFormat = 0;
+        suggestedOutputLatencyFrames = 0;
+    }
+
+    driverInfo = &asioHostApi->openAsioDriverInfo;
+
+    /* NOTE: we load the driver and use its current settings
+        rather than the ones in our device info structure which may be stale */
+
+    result = LoadAsioDriver( asioHostApi->inheritedHostApiRep.deviceInfos[ asioDeviceIndex ]->name,
+            driverInfo, asioHostApi->systemSpecific );
+    if( result == paNoError )
+        asioIsInitialized = 1;
+    else{
+        PA_DEBUG(("OpenStream ERROR1\n"));
+        goto error;
+    }
+
+    /* check that input device can support inputChannelCount */
+    if( inputChannelCount > 0 )
+    {
+        if( inputChannelCount > driverInfo->inputChannelCount )
+        {
+            result = paInvalidChannelCount;
+            PA_DEBUG(("OpenStream ERROR2\n"));
+            goto error;
+        }
+    }
+
+    /* check that output device can support outputChannelCount */
+    if( outputChannelCount )
+    {
+        if( outputChannelCount > driverInfo->outputChannelCount )
+        {
+            result = paInvalidChannelCount;
+            PA_DEBUG(("OpenStream ERROR3\n"));
+            goto error;
+        }
+    }
+
+
+    // check that the device supports the requested sample rate 
+
+    asioError = ASIOCanSampleRate( sampleRate );
+    PA_DEBUG(("ASIOCanSampleRate(%f):%d\n",sampleRate, asioError ));
+
+    if( asioError != ASE_OK )
+    {
+        result = paInvalidSampleRate;
+        PA_DEBUG(("ERROR: ASIOCanSampleRate: %s\n", PaAsio_GetAsioErrorText(asioError) ));
+        goto error;
+    }
+
+
+    // retrieve the current sample rate, we only change to the requested
+    // sample rate if the device is not already in that rate.
+
+    ASIOSampleRate oldRate;
+    asioError = ASIOGetSampleRate(&oldRate);
+    if( asioError != ASE_OK )
+    {
+        result = paInvalidSampleRate;
+        PA_DEBUG(("ERROR: ASIOGetSampleRate: %s\n", PaAsio_GetAsioErrorText(asioError) ));
+        goto error;
+    }
+    PA_DEBUG(("ASIOGetSampleRate:%f\n",oldRate));
+
+    if (oldRate != sampleRate){
+
+        PA_DEBUG(("before ASIOSetSampleRate(%f)\n",sampleRate));
+        asioError = ASIOSetSampleRate( sampleRate );
+        /* Set sample rate */
+        if( asioError != ASE_OK )
+        {
+            result = paInvalidSampleRate;
+            PA_DEBUG(("ERROR: ASIOSetSampleRate: %s\n", PaAsio_GetAsioErrorText(asioError) ));
+            goto error;
+        }
+        PA_DEBUG(("after ASIOSetSampleRate(%f)\n",sampleRate));
+    }
+    else
+    {
+        PA_DEBUG(("No Need to change SR\n"));
+    }
+
+
+    /*
+        IMPLEMENT ME:
+            - if a full duplex stream is requested, check that the combination
+                of input and output parameters is supported
+    */
+
+    /* validate platform specific flags */
+    if( (streamFlags & paPlatformSpecificFlags) != 0 ){
+        PA_DEBUG(("OpenStream invalid flags!!\n"));
+        return paInvalidFlag; /* unexpected platform specific flag */
+    }
+
+
+    stream = (PaAsioStream*)PaUtil_AllocateMemory( sizeof(PaAsioStream) );
+    if( !stream )
+    {
+        result = paInsufficientMemory;
+        PA_DEBUG(("OpenStream ERROR5\n"));
+        goto error;
+    }
+
+    stream->completedBuffersPlayedEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
+    if( stream->completedBuffersPlayedEvent == NULL )
+    {
+        result = paUnanticipatedHostError;
+        PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() );
+        PA_DEBUG(("OpenStream ERROR6\n"));
+        goto error;
+    }
+    completedBuffersPlayedEventInited = 1;
+
+
+    stream->asioBufferInfos = 0; /* for deallocation in error */
+    stream->asioChannelInfos = 0; /* for deallocation in error */
+    stream->bufferPtrs = 0; /* for deallocation in error */
+
+    if( streamCallback )
+    {
+        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
+                                               &asioHostApi->callbackStreamInterface, streamCallback, userData );
+    }
+    else
+    {
+        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
+                                               &asioHostApi->blockingStreamInterface, streamCallback, userData );
+    }
+
+
+    PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );
+
+
+    stream->asioBufferInfos = (ASIOBufferInfo*)PaUtil_AllocateMemory(
+            sizeof(ASIOBufferInfo) * (inputChannelCount + outputChannelCount) );
+    if( !stream->asioBufferInfos )
+    {
+        result = paInsufficientMemory;
+        PA_DEBUG(("OpenStream ERROR7\n"));
+        goto error;
+    }
+
+
+    for( i=0; i < inputChannelCount; ++i )
+    {
+        ASIOBufferInfo *info = &stream->asioBufferInfos[i];
+
+        info->isInput = ASIOTrue;
+
+        if( inputChannelSelectors ){
+            // inputChannelSelectors values have already been validated in
+            // ValidateAsioSpecificStreamInfo() above
+            info->channelNum = inputChannelSelectors[i];
+        }else{
+            info->channelNum = i;
+        }
+
+        info->buffers[0] = info->buffers[1] = 0;
+    }
+
+    for( i=0; i < outputChannelCount; ++i ){
+        ASIOBufferInfo *info = &stream->asioBufferInfos[inputChannelCount+i];
+
+        info->isInput = ASIOFalse;
+
+        if( outputChannelSelectors ){
+            // outputChannelSelectors values have already been validated in
+            // ValidateAsioSpecificStreamInfo() above
+            info->channelNum = outputChannelSelectors[i];
+        }else{
+            info->channelNum = i;
+        }
+        
+        info->buffers[0] = info->buffers[1] = 0;
+    }
+
+
+    framesPerHostBuffer = SelectHostBufferSize(
+            (( suggestedInputLatencyFrames > suggestedOutputLatencyFrames )
+                    ? suggestedInputLatencyFrames : suggestedOutputLatencyFrames),
+            driverInfo );
+
+
+       PA_DEBUG(("PaAsioOpenStream: framesPerHostBuffer :%d\n",  framesPerHostBuffer));
+
+    asioError = ASIOCreateBuffers( stream->asioBufferInfos,
+            inputChannelCount+outputChannelCount,
+            framesPerHostBuffer, &asioCallbacks_ );
+
+    if( asioError != ASE_OK
+            && framesPerHostBuffer != (unsigned long)driverInfo->bufferPreferredSize )
+    {
+        PA_DEBUG(("ERROR: ASIOCreateBuffers: %s\n", PaAsio_GetAsioErrorText(asioError) ));
+        /*
+            Some buggy drivers (like the Hoontech DSP24) give incorrect
+            [min, preferred, max] values They should work with the preferred size
+            value, thus if Pa_ASIO_CreateBuffers fails with the hostBufferSize
+            computed in SelectHostBufferSize, we try again with the preferred size.
+        */
+
+        framesPerHostBuffer = driverInfo->bufferPreferredSize;
+
+        PA_DEBUG(("PaAsioOpenStream: CORRECTED framesPerHostBuffer :%d\n",  framesPerHostBuffer));
+
+        ASIOError asioError2 = ASIOCreateBuffers( stream->asioBufferInfos,
+                inputChannelCount+outputChannelCount,
+                 framesPerHostBuffer, &asioCallbacks_ );
+        if( asioError2 == ASE_OK )
+            asioError = ASE_OK;
+    }
+
+    if( asioError != ASE_OK )
+    {
+        result = paUnanticipatedHostError;
+        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
+        PA_DEBUG(("OpenStream ERROR9\n"));
+        goto error;
+    }
+
+    asioBuffersCreated = 1;
+
+    stream->asioChannelInfos = (ASIOChannelInfo*)PaUtil_AllocateMemory(
+            sizeof(ASIOChannelInfo) * (inputChannelCount + outputChannelCount) );
+    if( !stream->asioChannelInfos )
+    {
+        result = paInsufficientMemory;
+        PA_DEBUG(("OpenStream ERROR10\n"));
+        goto error;
+    }
+
+    for( i=0; i < inputChannelCount + outputChannelCount; ++i )
+    {
+        stream->asioChannelInfos[i].channel = stream->asioBufferInfos[i].channelNum;
+        stream->asioChannelInfos[i].isInput = stream->asioBufferInfos[i].isInput;
+        asioError = ASIOGetChannelInfo( &stream->asioChannelInfos[i] );
+        if( asioError != ASE_OK )
+        {
+            result = paUnanticipatedHostError;
+            PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
+            PA_DEBUG(("OpenStream ERROR11\n"));
+            goto error;
+        }
+    }
+
+    stream->bufferPtrs = (void**)PaUtil_AllocateMemory(
+            2 * sizeof(void*) * (inputChannelCount + outputChannelCount) );
+    if( !stream->bufferPtrs )
+    {
+        result = paInsufficientMemory;
+        PA_DEBUG(("OpenStream ERROR12\n"));
+        goto error;
+    }
+
+    if( inputChannelCount > 0 )
+    {
+        stream->inputBufferPtrs[0] = stream-> bufferPtrs;
+        stream->inputBufferPtrs[1] = &stream->bufferPtrs[inputChannelCount];
+
+        for( i=0; i<inputChannelCount; ++i )
+        {
+            stream->inputBufferPtrs[0][i] = stream->asioBufferInfos[i].buffers[0];
+            stream->inputBufferPtrs[1][i] = stream->asioBufferInfos[i].buffers[1];
+        }
+    }
+    else
+    {
+        stream->inputBufferPtrs[0] = 0;
+        stream->inputBufferPtrs[1] = 0;
+    }
+
+    if( outputChannelCount > 0 )
+    {
+        stream->outputBufferPtrs[0] = &stream->bufferPtrs[inputChannelCount*2];
+        stream->outputBufferPtrs[1] = &stream->bufferPtrs[inputChannelCount*2 + outputChannelCount];
+
+        for( i=0; i<outputChannelCount; ++i )
+        {
+            stream->outputBufferPtrs[0][i] = stream->asioBufferInfos[inputChannelCount+i].buffers[0];
+            stream->outputBufferPtrs[1][i] = stream->asioBufferInfos[inputChannelCount+i].buffers[1];
+        }
+    }
+    else
+    {
+        stream->outputBufferPtrs[0] = 0;
+        stream->outputBufferPtrs[1] = 0;
+    }
+
+    if( inputChannelCount > 0 )
+    {
+        /* FIXME: assume all channels use the same type for now */
+        ASIOSampleType inputType = stream->asioChannelInfos[0].type;
+
+        PA_DEBUG(("ASIO Input  type:%d",inputType));
+        AsioSampleTypeLOG(inputType);
+        hostInputSampleFormat = AsioSampleTypeToPaNativeSampleFormat( inputType );
+
+        SelectAsioToPaConverter( inputType, &stream->inputBufferConverter, &stream->inputShift );
+    }
+    else
+    {
+        hostInputSampleFormat = 0;
+        stream->inputBufferConverter = 0;
+    }
+
+    if( outputChannelCount > 0 )
+    {
+        /* FIXME: assume all channels use the same type for now */
+        ASIOSampleType outputType = stream->asioChannelInfos[inputChannelCount].type;
+
+        PA_DEBUG(("ASIO Output type:%d",outputType));
+        AsioSampleTypeLOG(outputType);
+        hostOutputSampleFormat = AsioSampleTypeToPaNativeSampleFormat( outputType );
+
+        SelectPaToAsioConverter( outputType, &stream->outputBufferConverter, &stream->outputShift );
+    }
+    else
+    {
+        hostOutputSampleFormat = 0;
+        stream->outputBufferConverter = 0;
+    }
+
+    result =  PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
+                    inputChannelCount, inputSampleFormat, hostInputSampleFormat,
+                    outputChannelCount, outputSampleFormat, hostOutputSampleFormat,
+                    sampleRate, streamFlags, framesPerBuffer,
+                    framesPerHostBuffer, paUtilFixedHostBufferSize,
+                    streamCallback, userData );
+    if( result != paNoError ){
+        PA_DEBUG(("OpenStream ERROR13\n"));
+        goto error;
+    }
+
+
+    ASIOGetLatencies( &stream->inputLatency, &stream->outputLatency );
+
+    stream->streamRepresentation.streamInfo.inputLatency =
+            (double)( PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor)
+                + stream->inputLatency) / sampleRate;   // seconds
+    stream->streamRepresentation.streamInfo.outputLatency =
+            (double)( PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor)
+                + stream->outputLatency) / sampleRate; // seconds
+    stream->streamRepresentation.streamInfo.sampleRate = sampleRate;
+
+    // the code below prints the ASIO latency which doesn't include the
+    // buffer processor latency. it reports the added latency separately
+    PA_DEBUG(("PaAsio : ASIO InputLatency = %ld (%ld ms), added buffProc:%ld (%ld ms)\n",
+            stream->inputLatency,
+            (long)((stream->inputLatency*1000)/ sampleRate),  
+            PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor),
+            (long)((PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor)*1000)/ sampleRate)
+            ));
+
+    PA_DEBUG(("PaAsio : ASIO OuputLatency = %ld (%ld ms), added buffProc:%ld (%ld ms)\n",
+            stream->outputLatency,
+            (long)((stream->outputLatency*1000)/ sampleRate), 
+            PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor),
+            (long)((PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor)*1000)/ sampleRate)
+            ));
+
+    stream->asioHostApi = asioHostApi;
+    stream->framesPerHostCallback = framesPerHostBuffer;
+
+    stream->inputChannelCount = inputChannelCount;
+    stream->outputChannelCount = outputChannelCount;
+    stream->postOutput = driverInfo->postOutput;
+    stream->isActive = 0;
+
+    asioHostApi->openAsioDeviceIndex = asioDeviceIndex;
+
+    *s = (PaStream*)stream;
+
+    return result;
+
+error:
+    PA_DEBUG(("goto errored\n"));
+    if( stream )
+    {
+        if( completedBuffersPlayedEventInited )
+            CloseHandle( stream->completedBuffersPlayedEvent );
+
+        if( stream->asioBufferInfos )
+            PaUtil_FreeMemory( stream->asioBufferInfos );
+
+        if( stream->asioChannelInfos )
+            PaUtil_FreeMemory( stream->asioChannelInfos );
+
+        if( stream->bufferPtrs )
+            PaUtil_FreeMemory( stream->bufferPtrs );
+
+        PaUtil_FreeMemory( stream );
+    }
+
+    if( asioBuffersCreated )
+        ASIODisposeBuffers();
+
+    if( asioIsInitialized )
+        ASIOExit();
+
+    return result;
+}
+
+
+/*
+    When CloseStream() is called, the multi-api layer ensures that
+    the stream has already been stopped or aborted.
+*/
+static PaError CloseStream( PaStream* s )
+{
+    PaError result = paNoError;
+    PaAsioStream *stream = (PaAsioStream*)s;
+
+    /*
+        IMPLEMENT ME:
+            - additional stream closing + cleanup
+    */
+
+    PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
+    PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
+
+    stream->asioHostApi->openAsioDeviceIndex = paNoDevice;
+
+    CloseHandle( stream->completedBuffersPlayedEvent );
+
+    PaUtil_FreeMemory( stream->asioBufferInfos );
+    PaUtil_FreeMemory( stream->asioChannelInfos );
+    PaUtil_FreeMemory( stream->bufferPtrs );
+    PaUtil_FreeMemory( stream );
+
+    ASIODisposeBuffers();
+    ASIOExit();
+
+    return result;
+}
+
+
+static void bufferSwitch(long index, ASIOBool directProcess)
+{
+//TAKEN FROM THE ASIO SDK
+
+    // the actual processing callback.
+    // Beware that this is normally in a seperate thread, hence be sure that
+    // you take care about thread synchronization. This is omitted here for
+    // simplicity.
+
+    // as this is a "back door" into the bufferSwitchTimeInfo a timeInfo needs
+    // to be created though it will only set the timeInfo.samplePosition and
+    // timeInfo.systemTime fields and the according flags
+
+    ASIOTime  timeInfo;
+    memset( &timeInfo, 0, sizeof (timeInfo) );
+
+    // get the time stamp of the buffer, not necessary if no
+    // synchronization to other media is required
+    if( ASIOGetSamplePosition(&timeInfo.timeInfo.samplePosition, &timeInfo.timeInfo.systemTime) == ASE_OK)
+            timeInfo.timeInfo.flags = kSystemTimeValid | kSamplePositionValid;
+
+    // Call the real callback
+    bufferSwitchTimeInfo( &timeInfo, index, directProcess );
+}
+
+
+// conversion from 64 bit ASIOSample/ASIOTimeStamp to double float
+#if NATIVE_INT64
+       #define ASIO64toDouble(a)  (a)
+#else
+       const double twoRaisedTo32 = 4294967296.;
+       #define ASIO64toDouble(a)  ((a).lo + (a).hi * twoRaisedTo32)
+#endif
+
+static ASIOTime *bufferSwitchTimeInfo( ASIOTime *timeInfo, long index, ASIOBool directProcess )
+{
+    // the actual processing callback.
+    // Beware that this is normally in a seperate thread, hence be sure that
+    // you take care about thread synchronization.
+
+
+    /* The SDK says the following about the directProcess flag:
+        suggests to the host whether it should immediately start processing
+        (directProcess == ASIOTrue), or whether its process should be deferred
+        because the call comes from a very low level (for instance, a high level
+        priority interrupt), and direct processing would cause timing instabilities for
+        the rest of the system. If in doubt, directProcess should be set to ASIOFalse.
+
+        We just ignore directProcess. This could cause incompatibilities with
+        drivers which really don't want the audio processing to occur in this
+        callback, but none have been identified yet.
+    */
+
+    (void) directProcess; /* suppress unused parameter warning */
+
+#if 0
+    // store the timeInfo for later use
+    asioDriverInfo.tInfo = *timeInfo;
+
+    // get the time stamp of the buffer, not necessary if no
+    // synchronization to other media is required
+
+    if (timeInfo->timeInfo.flags & kSystemTimeValid)
+            asioDriverInfo.nanoSeconds = ASIO64toDouble(timeInfo->timeInfo.systemTime);
+    else
+            asioDriverInfo.nanoSeconds = 0;
+
+    if (timeInfo->timeInfo.flags & kSamplePositionValid)
+            asioDriverInfo.samples = ASIO64toDouble(timeInfo->timeInfo.samplePosition);
+    else
+            asioDriverInfo.samples = 0;
+
+    if (timeInfo->timeCode.flags & kTcValid)
+            asioDriverInfo.tcSamples = ASIO64toDouble(timeInfo->timeCode.timeCodeSamples);
+    else
+            asioDriverInfo.tcSamples = 0;
+
+    // get the system reference time
+    asioDriverInfo.sysRefTime = get_sys_reference_time();
+#endif
+
+#if 0
+    // a few debug messages for the Windows device driver developer
+    // tells you the time when driver got its interrupt and the delay until the app receives
+    // the event notification.
+    static double last_samples = 0;
+    char tmp[128];
+    sprintf (tmp, "diff: %d / %d ms / %d ms / %d samples                 \n", asioDriverInfo.sysRefTime - (long)(asioDriverInfo.nanoSeconds / 1000000.0), asioDriverInfo.sysRefTime, (long)(asioDriverInfo.nanoSeconds / 1000000.0), (long)(asioDriverInfo.samples - last_samples));
+    OutputDebugString (tmp);
+    last_samples = asioDriverInfo.samples;
+#endif
+
+
+    if( !theAsioStream )
+        return 0L;
+
+    // Keep sample position
+    // FIXME: asioDriverInfo.pahsc_NumFramesDone = timeInfo->timeInfo.samplePosition.lo;
+
+
+    // protect against reentrancy
+    if( PaAsio_AtomicIncrement(&theAsioStream->reenterCount) )
+    {
+        theAsioStream->reenterError++;
+        //DBUG(("bufferSwitchTimeInfo : reentrancy detection = %d\n", asioDriverInfo.reenterError));
+        return 0L;
+    }
+
+    int buffersDone = 0;
+    
+    do
+    {
+        if( buffersDone > 0 )
+        {
+            // this is a reentered buffer, we missed processing it on time
+            // set the input overflow and output underflow flags as appropriate
+            
+            if( theAsioStream->inputChannelCount > 0 )
+                theAsioStream->callbackFlags |= paInputOverflow;
+                
+            if( theAsioStream->outputChannelCount > 0 )
+                theAsioStream->callbackFlags |= paOutputUnderflow;
+        }
+        else
+        {
+            if( theAsioStream->zeroOutput )
+            {
+                ZeroOutputBuffers( theAsioStream, index );
+
+                // Finally if the driver supports the ASIOOutputReady() optimization,
+                // do it here, all data are in place
+                if( theAsioStream->postOutput )
+                    ASIOOutputReady();
+
+                if( theAsioStream->stopProcessing )
+                {
+                    if( theAsioStream->stopPlayoutCount < 2 )
+                    {
+                        ++theAsioStream->stopPlayoutCount;
+                        if( theAsioStream->stopPlayoutCount == 2 )
+                        {
+                            theAsioStream->isActive = 0;
+                            if( theAsioStream->streamRepresentation.streamFinishedCallback != 0 )
+                                theAsioStream->streamRepresentation.streamFinishedCallback( theAsioStream->streamRepresentation.userData );
+                            theAsioStream->streamFinishedCallbackCalled = true;
+                            SetEvent( theAsioStream->completedBuffersPlayedEvent );
+                        }
+                    }
+                }
+            }
+            else
+            {
+
+#if 0
+// test code to try to detect slip conditions... these may work on some systems
+// but neither of them work on the RME Digi96
+
+// check that sample delta matches buffer size (otherwise we must have skipped
+// a buffer.
+static double last_samples = -512;
+double samples;
+//if( timeInfo->timeCode.flags & kTcValid )
+//    samples = ASIO64toDouble(timeInfo->timeCode.timeCodeSamples);
+//else
+    samples = ASIO64toDouble(timeInfo->timeInfo.samplePosition);
+int delta = samples - last_samples;
+//printf( "%d\n", delta);
+last_samples = samples;
+
+if( delta > theAsioStream->framesPerHostCallback )
+{
+    if( theAsioStream->inputChannelCount > 0 )
+        theAsioStream->callbackFlags |= paInputOverflow;
+
+    if( theAsioStream->outputChannelCount > 0 )
+        theAsioStream->callbackFlags |= paOutputUnderflow;
+}
+
+// check that the buffer index is not the previous index (which would indicate
+// that a buffer was skipped.
+static int previousIndex = 1;
+if( index == previousIndex )
+{
+    if( theAsioStream->inputChannelCount > 0 )
+        theAsioStream->callbackFlags |= paInputOverflow;
+
+    if( theAsioStream->outputChannelCount > 0 )
+        theAsioStream->callbackFlags |= paOutputUnderflow;
+}
+previousIndex = index;
+#endif
+
+                int i;
+
+                PaUtil_BeginCpuLoadMeasurement( &theAsioStream->cpuLoadMeasurer );
+
+                PaStreamCallbackTimeInfo paTimeInfo;
+
+                // asio systemTime is supposed to be measured according to the same
+                // clock as timeGetTime
+                paTimeInfo.currentTime = (ASIO64toDouble( timeInfo->timeInfo.systemTime ) * .000000001);
+
+                /* patch from Paul Boege */
+                paTimeInfo.inputBufferAdcTime = paTimeInfo.currentTime -
+                    ((double)theAsioStream->inputLatency/theAsioStream->streamRepresentation.streamInfo.sampleRate);
+
+                paTimeInfo.outputBufferDacTime = paTimeInfo.currentTime +
+                    ((double)theAsioStream->outputLatency/theAsioStream->streamRepresentation.streamInfo.sampleRate);
+
+                /* old version is buggy because the buffer processor also adds in its latency to the time parameters
+                paTimeInfo.inputBufferAdcTime = paTimeInfo.currentTime - theAsioStream->streamRepresentation.streamInfo.inputLatency;
+                paTimeInfo.outputBufferDacTime = paTimeInfo.currentTime + theAsioStream->streamRepresentation.streamInfo.outputLatency;
+                */
+#if 1
+// detect underflows by checking inter-callback time > 2 buffer period
+static double previousTime = -1;
+if( previousTime > 0 ){
+
+    double delta = paTimeInfo.currentTime - previousTime;
+
+    if( delta >= 2. * (theAsioStream->framesPerHostCallback / theAsioStream->streamRepresentation.streamInfo.sampleRate) ){
+        if( theAsioStream->inputChannelCount > 0 )
+            theAsioStream->callbackFlags |= paInputOverflow;
+
+        if( theAsioStream->outputChannelCount > 0 )
+            theAsioStream->callbackFlags |= paOutputUnderflow;
+    }
+}
+previousTime = paTimeInfo.currentTime;
+#endif
+
+                // note that the above input and output times do not need to be
+                // adjusted for the latency of the buffer processor -- the buffer
+                // processor handles that.
+
+                if( theAsioStream->inputBufferConverter )
+                {
+                    for( i=0; i<theAsioStream->inputChannelCount; i++ )
+                    {
+                        theAsioStream->inputBufferConverter( theAsioStream->inputBufferPtrs[index][i],
+                                theAsioStream->inputShift, theAsioStream->framesPerHostCallback );
+                    }
+                }
+
+                PaUtil_BeginBufferProcessing( &theAsioStream->bufferProcessor, &paTimeInfo, theAsioStream->callbackFlags );
+
+                /* reset status flags once they've been passed to the callback */
+                theAsioStream->callbackFlags = 0;
+
+                PaUtil_SetInputFrameCount( &theAsioStream->bufferProcessor, 0 /* default to host buffer size */ );
+                for( i=0; i<theAsioStream->inputChannelCount; ++i )
+                    PaUtil_SetNonInterleavedInputChannel( &theAsioStream->bufferProcessor, i, theAsioStream->inputBufferPtrs[index][i] );
+
+                PaUtil_SetOutputFrameCount( &theAsioStream->bufferProcessor, 0 /* default to host buffer size */ );
+                for( i=0; i<theAsioStream->outputChannelCount; ++i )
+                    PaUtil_SetNonInterleavedOutputChannel( &theAsioStream->bufferProcessor, i, theAsioStream->outputBufferPtrs[index][i] );
+
+                int callbackResult;
+                if( theAsioStream->stopProcessing )
+                    callbackResult = paComplete;
+                else
+                    callbackResult = paContinue;
+                unsigned long framesProcessed = PaUtil_EndBufferProcessing( &theAsioStream->bufferProcessor, &callbackResult );
+
+                if( theAsioStream->outputBufferConverter )
+                {
+                    for( i=0; i<theAsioStream->outputChannelCount; i++ )
+                    {
+                        theAsioStream->outputBufferConverter( theAsioStream->outputBufferPtrs[index][i],
+                                theAsioStream->outputShift, theAsioStream->framesPerHostCallback );
+                    }
+                }
+
+                PaUtil_EndCpuLoadMeasurement( &theAsioStream->cpuLoadMeasurer, framesProcessed );
+
+                // Finally if the driver supports the ASIOOutputReady() optimization,
+                // do it here, all data are in place
+                if( theAsioStream->postOutput )
+                    ASIOOutputReady();
+
+                if( callbackResult == paContinue )
+                {
+                    /* nothing special to do */
+                }
+                else if( callbackResult == paAbort )
+                {
+                    /* finish playback immediately  */
+                    theAsioStream->isActive = 0;
+                    if( theAsioStream->streamRepresentation.streamFinishedCallback != 0 )
+                        theAsioStream->streamRepresentation.streamFinishedCallback( theAsioStream->streamRepresentation.userData );
+                    theAsioStream->streamFinishedCallbackCalled = true;
+                    SetEvent( theAsioStream->completedBuffersPlayedEvent );
+                    theAsioStream->zeroOutput = true;
+                }
+                else /* paComplete or other non-zero value indicating complete */
+                {
+                    /* Finish playback once currently queued audio has completed. */
+                    theAsioStream->stopProcessing = true;
+
+                    if( PaUtil_IsBufferProcessorOutputEmpty( &theAsioStream->bufferProcessor ) )
+                    {
+                        theAsioStream->zeroOutput = true;
+                        theAsioStream->stopPlayoutCount = 0;
+                    }
+                }
+            }
+        }
+        
+        ++buffersDone;
+    }while( PaAsio_AtomicDecrement(&theAsioStream->reenterCount) >= 0 );
+
+    return 0L;
+}
+
+
+static void sampleRateChanged(ASIOSampleRate sRate)
+{
+    // TAKEN FROM THE ASIO SDK
+    // do whatever you need to do if the sample rate changed
+    // usually this only happens during external sync.
+    // Audio processing is not stopped by the driver, actual sample rate
+    // might not have even changed, maybe only the sample rate status of an
+    // AES/EBU or S/PDIF digital input at the audio device.
+    // You might have to update time/sample related conversion routines, etc.
+
+    (void) sRate; /* unused parameter */
+    PA_DEBUG( ("sampleRateChanged : %d \n", sRate));
+}
+
+static long asioMessages(long selector, long value, void* message, double* opt)
+{
+// TAKEN FROM THE ASIO SDK
+    // currently the parameters "value", "message" and "opt" are not used.
+    long ret = 0;
+
+    (void) message; /* unused parameters */
+    (void) opt;
+
+    PA_DEBUG( ("asioMessages : %d , %d \n", selector, value));
+
+    switch(selector)
+    {
+        case kAsioSelectorSupported:
+            if(value == kAsioResetRequest
+            || value == kAsioEngineVersion
+            || value == kAsioResyncRequest
+            || value == kAsioLatenciesChanged
+            // the following three were added for ASIO 2.0, you don't necessarily have to support them
+            || value == kAsioSupportsTimeInfo
+            || value == kAsioSupportsTimeCode
+            || value == kAsioSupportsInputMonitor)
+                    ret = 1L;
+            break;
+
+        case kAsioBufferSizeChange:
+            //printf("kAsioBufferSizeChange \n");
+            break;
+
+        case kAsioResetRequest:
+            // defer the task and perform the reset of the driver during the next "safe" situation
+            // You cannot reset the driver right now, as this code is called from the driver.
+            // Reset the driver is done by completely destruct is. I.e. ASIOStop(), ASIODisposeBuffers(), Destruction
+            // Afterwards you initialize the driver again.
+
+            /*FIXME: commented the next line out */
+            //asioDriverInfo.stopped;  // In this sample the processing will just stop
+            ret = 1L;
+            break;
+
+        case kAsioResyncRequest:
+            // This informs the application, that the driver encountered some non fatal data loss.
+            // It is used for synchronization purposes of different media.
+            // Added mainly to work around the Win16Mutex problems in Windows 95/98 with the
+            // Windows Multimedia system, which could loose data because the Mutex was hold too long
+            // by another thread.
+            // However a driver can issue it in other situations, too.
+            ret = 1L;
+            break;
+
+        case kAsioLatenciesChanged:
+            // This will inform the host application that the drivers were latencies changed.
+            // Beware, it this does not mean that the buffer sizes have changed!
+            // You might need to update internal delay data.
+            ret = 1L;
+            //printf("kAsioLatenciesChanged \n");
+            break;
+
+        case kAsioEngineVersion:
+            // return the supported ASIO version of the host application
+            // If a host applications does not implement this selector, ASIO 1.0 is assumed
+            // by the driver
+            ret = 2L;
+            break;
+
+        case kAsioSupportsTimeInfo:
+            // informs the driver wether the asioCallbacks.bufferSwitchTimeInfo() callback
+            // is supported.
+            // For compatibility with ASIO 1.0 drivers the host application should always support
+            // the "old" bufferSwitch method, too.
+            ret = 1;
+            break;
+
+        case kAsioSupportsTimeCode:
+            // informs the driver wether application is interested in time code info.
+            // If an application does not need to know about time code, the driver has less work
+            // to do.
+            ret = 0;
+            break;
+    }
+    return ret;
+}
+
+
+static PaError StartStream( PaStream *s )
+{
+    PaError result = paNoError;
+    PaAsioStream *stream = (PaAsioStream*)s;
+    ASIOError asioError;
+
+    if( stream->outputChannelCount > 0 )
+    {
+        ZeroOutputBuffers( stream, 0 );
+        ZeroOutputBuffers( stream, 1 );
+    }
+
+    PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
+    stream->stopProcessing = false;
+    stream->zeroOutput = false;
+
+    /* Reentrancy counter initialisation */
+    stream->reenterCount = -1;
+    stream->reenterError = 0;
+
+    stream->callbackFlags = 0;
+
+    if( ResetEvent( stream->completedBuffersPlayedEvent ) == 0 )
+    {
+        result = paUnanticipatedHostError;
+        PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() );
+    }
+
+    if( result == paNoError )
+    {
+        theAsioStream = stream;
+        asioError = ASIOStart();
+        if( asioError == ASE_OK )
+        {
+            stream->isActive = 1;
+            stream->streamFinishedCallbackCalled = false;
+        }
+        else
+        {
+            theAsioStream = 0;
+            result = paUnanticipatedHostError;
+            PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
+        }
+    }
+
+    return result;
+}
+
+
+static PaError StopStream( PaStream *s )
+{
+    PaError result = paNoError;
+    PaAsioStream *stream = (PaAsioStream*)s;
+    ASIOError asioError;
+
+    if( stream->isActive )
+    {
+        stream->stopProcessing = true;
+
+        /* wait for the stream to finish playing out enqueued buffers.
+            timeout after four times the stream latency.
+
+            @todo should use a better time out value - if the user buffer
+            length is longer than the asio buffer size then that should
+            be taken into account.
+        */
+        if( WaitForSingleObject( theAsioStream->completedBuffersPlayedEvent,
+                (DWORD)(stream->streamRepresentation.streamInfo.outputLatency * 1000. * 4.) )
+                    == WAIT_TIMEOUT     )
+        {
+            PA_DEBUG(("WaitForSingleObject() timed out in StopStream()\n" ));
+        }
+    }
+
+    asioError = ASIOStop();
+    if( asioError != ASE_OK )
+    {
+        result = paUnanticipatedHostError;
+        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
+    }
+
+    theAsioStream = 0;
+    stream->isActive = 0;
+
+    if( !stream->streamFinishedCallbackCalled )
+    {
+        if( stream->streamRepresentation.streamFinishedCallback != 0 )
+            stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
+    }
+
+    return result;
+}
+
+
+static PaError AbortStream( PaStream *s )
+{
+    PaError result = paNoError;
+    PaAsioStream *stream = (PaAsioStream*)s;
+    ASIOError asioError;
+
+    stream->zeroOutput = true;
+
+    asioError = ASIOStop();
+    if( asioError != ASE_OK )
+    {
+        result = paUnanticipatedHostError;
+        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
+    }
+    else
+    {
+        // make sure that the callback is not still in-flight when ASIOStop()
+        // returns. This has been observed to happen on the Hoontech DSP24 for
+        // example.
+        int count = 2000;  // only wait for 2 seconds, rather than hanging.
+        while( theAsioStream->reenterCount != -1 && count > 0 )
+        {
+            Sleep(1);
+            --count;
+        }
+    }
+
+    /* it is questionable whether we should zero theAsioStream if ASIOStop()
+        returns an error, because the callback could still be active. We assume
+        not - this is based on the fact that ASIOStop is unlikely to fail
+        if the callback is running - it's more likely to fail because the
+        callback is not running. */
+        
+    theAsioStream = 0;
+    stream->isActive = 0;
+
+    if( !stream->streamFinishedCallbackCalled )
+    {
+        if( stream->streamRepresentation.streamFinishedCallback != 0 )
+            stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
+    }
+
+    return result;
+}
+
+
+static PaError IsStreamStopped( PaStream *s )
+{
+    //PaAsioStream *stream = (PaAsioStream*)s;
+    (void) s; /* unused parameter */
+    return theAsioStream == 0;
+}
+
+
+static PaError IsStreamActive( PaStream *s )
+{
+    PaAsioStream *stream = (PaAsioStream*)s;
+
+    return stream->isActive;
+}
+
+
+static PaTime GetStreamTime( PaStream *s )
+{
+    (void) s; /* unused parameter */
+    return (double)timeGetTime() * .001;
+}
+
+
+static double GetStreamCpuLoad( PaStream* s )
+{
+    PaAsioStream *stream = (PaAsioStream*)s;
+
+    return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
+}
+
+
+/*
+    As separate stream interfaces are used for blocking and callback
+    streams, the following functions can be guaranteed to only be called
+    for blocking streams.
+*/
+
+static PaError ReadStream( PaStream* s,
+                           void *buffer,
+                           unsigned long frames )
+{
+    PaAsioStream *stream = (PaAsioStream*)s;
+
+    /* IMPLEMENT ME, see portaudio.h for required behavior*/
+    (void) stream; /* unused parameters */
+    (void) buffer;
+    (void) frames;
+
+    return paNoError;
+}
+
+
+static PaError WriteStream( PaStream* s,
+                            const void *buffer,
+                            unsigned long frames )
+{
+    PaAsioStream *stream = (PaAsioStream*)s;
+
+    /* IMPLEMENT ME, see portaudio.h for required behavior*/
+    (void) stream; /* unused parameters */
+    (void) buffer;
+    (void) frames;
+
+    return paNoError;
+}
+
+
+static signed long GetStreamReadAvailable( PaStream* s )
+{
+    PaAsioStream *stream = (PaAsioStream*)s;
+
+    /* IMPLEMENT ME, see portaudio.h for required behavior*/
+    (void) stream; /* unused parameter */
+
+    return 0;
+}
+
+
+static signed long GetStreamWriteAvailable( PaStream* s )
+{
+    PaAsioStream *stream = (PaAsioStream*)s;
+
+    /* IMPLEMENT ME, see portaudio.h for required behavior*/
+    (void) stream; /* unused parameter */
+
+    return 0;
+}
+
+
+PaError PaAsio_ShowControlPanel( PaDeviceIndex device, void* systemSpecific )
+{
+       PaError result = paNoError;
+    PaUtilHostApiRepresentation *hostApi;
+    PaDeviceIndex hostApiDevice;
+    ASIODriverInfo asioDriverInfo;
+       ASIOError asioError;
+    int asioIsInitialized = 0;
+    PaAsioHostApiRepresentation *asioHostApi;
+    PaAsioDeviceInfo *asioDeviceInfo;
+
+
+    result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO );
+    if( result != paNoError )
+        goto error;
+
+    result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, device, hostApi );
+    if( result != paNoError )
+        goto error;
+
+    /*
+        In theory we could proceed if the currently open device was the same
+        one for which the control panel was requested, however  because the
+        window pointer is not available until this function is called we
+        currently need to call ASIOInit() again here, which of course can't be
+        done safely while a stream is open.
+    */
+
+    asioHostApi = (PaAsioHostApiRepresentation*)hostApi;
+    if( asioHostApi->openAsioDeviceIndex != paNoDevice )
+    {
+        result = paDeviceUnavailable;
+        goto error;
+    }
+
+    asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice];
+
+    if( !loadAsioDriver( const_cast<char*>(asioDeviceInfo->commonDeviceInfo.name) ) )
+    {
+        result = paUnanticipatedHostError;
+        goto error;
+    }
+
+    /* CRUCIAL!!! */
+    memset( &asioDriverInfo, 0, sizeof(ASIODriverInfo) );
+    asioDriverInfo.asioVersion = 2;
+    asioDriverInfo.sysRef = systemSpecific;
+    asioError = ASIOInit( &asioDriverInfo );
+    if( asioError != ASE_OK )
+    {
+        result = paUnanticipatedHostError;
+        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
+        goto error;
+    }
+    else
+    {
+        asioIsInitialized = 1;
+    }
+
+PA_DEBUG(("PaAsio_ShowControlPanel: ASIOInit(): %s\n", PaAsio_GetAsioErrorText(asioError) ));
+PA_DEBUG(("asioVersion: ASIOInit(): %ld\n",   asioDriverInfo.asioVersion )); 
+PA_DEBUG(("driverVersion: ASIOInit(): %ld\n", asioDriverInfo.driverVersion )); 
+PA_DEBUG(("Name: ASIOInit(): %s\n",           asioDriverInfo.name )); 
+PA_DEBUG(("ErrorMessage: ASIOInit(): %s\n",   asioDriverInfo.errorMessage )); 
+
+    asioError = ASIOControlPanel();
+    if( asioError != ASE_OK )
+    {
+        PA_DEBUG(("PaAsio_ShowControlPanel: ASIOControlPanel(): %s\n", PaAsio_GetAsioErrorText(asioError) ));
+        result = paUnanticipatedHostError;
+        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
+        goto error;
+    }
+
+PA_DEBUG(("PaAsio_ShowControlPanel: ASIOControlPanel(): %s\n", PaAsio_GetAsioErrorText(asioError) ));
+
+    asioError = ASIOExit();
+    if( asioError != ASE_OK )
+    {
+        result = paUnanticipatedHostError;
+        PA_ASIO_SET_LAST_ASIO_ERROR( asioError );
+        asioIsInitialized = 0;
+        goto error;
+    }
+
+PA_DEBUG(("PaAsio_ShowControlPanel: ASIOExit(): %s\n", PaAsio_GetAsioErrorText(asioError) ));
+
+       return result;
+
+error:
+    if( asioIsInitialized )
+        ASIOExit();
+
+       return result;
+}
+
+
+PaError PaAsio_GetInputChannelName( PaDeviceIndex device, int channelIndex,
+        const char** channelName )
+{
+    PaError result = paNoError;
+    PaUtilHostApiRepresentation *hostApi;
+    PaDeviceIndex hostApiDevice;
+    PaAsioDeviceInfo *asioDeviceInfo;
+
+
+    result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO );
+    if( result != paNoError )
+        goto error;
+
+    result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, device, hostApi );
+    if( result != paNoError )
+        goto error;
+
+    asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice];
+
+    if( channelIndex < 0 || channelIndex >= asioDeviceInfo->commonDeviceInfo.maxInputChannels ){
+        result = paInvalidChannelCount;
+        goto error;
+    }
+
+    *channelName = asioDeviceInfo->asioChannelInfos[channelIndex].name;
+
+    return paNoError;
+    
+error:
+    return result;
+}
+
+
+PaError PaAsio_GetOutputChannelName( PaDeviceIndex device, int channelIndex,
+        const char** channelName )
+{
+    PaError result = paNoError;
+    PaUtilHostApiRepresentation *hostApi;
+    PaDeviceIndex hostApiDevice;
+    PaAsioDeviceInfo *asioDeviceInfo;
+
+
+    result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO );
+    if( result != paNoError )
+        goto error;
+
+    result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, device, hostApi );
+    if( result != paNoError )
+        goto error;
+
+    asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice];
+
+    if( channelIndex < 0 || channelIndex >= asioDeviceInfo->commonDeviceInfo.maxOutputChannels ){
+        result = paInvalidChannelCount;
+        goto error;
+    }
+
+    *channelName = asioDeviceInfo->asioChannelInfos[
+            asioDeviceInfo->commonDeviceInfo.maxInputChannels + channelIndex].name;
+
+    return paNoError;
+    
+error:
+    return result;
+}
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/notes.txt b/utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/notes.txt
new file mode 100644 (file)
index 0000000..ad66f35
--- /dev/null
@@ -0,0 +1,145 @@
+Notes on status of CoreAudio Implementation of PortAudio
+
+Document Last Updated December 9, 2005
+
+There are currently two implementations of PortAudio for Mac Core Audio.
+
+The original is in pa_mac_core_old.c, and the newer, default implementation
+is in pa_mac_core.c.
+Only pa_mac_core.c is currently developed and supported as it uses apple's
+current core audio technology. To select use the old implementation, replace
+pa_mac_core.c with pa_mac_core_old.c (eg. "cp pa_mac_core_auhal.c
+pa_mac_core.c"), then run configure and make as usual.
+
+----------------------------------------
+
+Notes on Original implementation:
+
+by Phil Burk and Darren Gibbs
+
+Last updated March 20, 2002
+
+WHAT WORKS
+
+Output with very low latency, <10 msec.
+Half duplex input or output.
+Full duplex on the same CoreAudio device.
+The paFLoat32, paInt16, paInt8, paUInt8 sample formats.
+Pa_GetCPULoad()
+Pa_StreamTime()
+
+KNOWN BUGS OR LIMITATIONS
+
+We do not yet support simultaneous input and output on different 
+devices. Note that some CoreAudio devices like the Roland UH30 look 
+like one device but are actually two different CoreAudio devices. The 
+Built-In audio is typically one CoreAudio device.
+
+Mono doesn't work.
+
+DEVICE MAPPING
+
+CoreAudio devices can support both input and output. But the sample 
+rates supported may be different. So we have map one or two PortAudio 
+device to each CoreAudio device depending on whether it supports 
+input, output or both.
+
+When we query devices, we first get a list of CoreAudio devices. Then 
+we scan the list and add a PortAudio device for each CoreAudio device 
+that supports input. Then we make a scan for output devices.
+
+-------------------------------------------
+
+Notes on Newer/Default AUHAL implementation:
+
+by Bjorn Roche
+
+Last Updated December 9, 2005
+
+Principle of Operation:
+
+This implementation uses AUHAL for audio I/O. To some extent, it also
+operates at the "HAL" Layer, though this behavior can be limited by
+platform specific flags (see pa_mac_core.h for details). The default
+settings should be reasonable: they don't change the SR of the device and
+don't cause interruptions if other devices are using the device.
+
+Major Software Elements Used: Apple's HAL AUs provide output SR
+conversion transparently, however, only on output, so this
+implementation uses AudioConverters to convert the sample rate on input.
+A PortAudio ring buffer is used to buffer input when sample rate
+conversion is required or when separate audio units are used for duplex
+IO. Finally, a PortAudio buffer processor is used to convert formats and
+provide additional buffers if needed. Internally, interleaved floating
+point data streams are used exclusively - the audio unit converts from
+the audio hardware's native format to interleaved float PCM and
+PortAudio's Buffer processor is used for conversion to user formats.
+
+Simplex Input: Simplex input uses a single callback. If sample rate
+conversion is required, a ring buffer and AudioConverter are used as
+well.
+
+Simplex output: Simplex output uses a single callback. No ring buffer or
+audio converter is used because AUHAL does its own output SR conversion.
+
+Duplex, one device (no SR conversion): When one device is used, a single
+callback is used. This achieves very low latency.
+
+Duplex, separate devices or SR conversion: When SR conversion is
+required, data must be buffered before it is converted and data is not
+always available at the same times on input and output, so SR conversion
+requires the same treatment as separate devices. The input callback
+reads data and puts it in the ring buffer. The output callback reads the
+data off the ring buffer, into an audio converter and finally to the
+buffer processor.
+
+Platform Specific Options:
+
+By using the flags in pa_mac_core.h, the user may specify several options.
+For example, the user can specify the sample-rate conversion quality, and
+the extent to which PA will attempt to "play nice" and to what extent it
+will interrupt other apps to improve performance. For example, if 44100 Hz
+sample rate is requested but the device is set at 48000 Hz, PA can either
+change the device for optimal playback ("Pro" mode), which may interrupt
+other programs playing back audio, or simple use a sample-rate coversion,
+which allows for friendlier sharing of the device ("Play Nice" mode).
+
+
+Known issues:
+
+- Latency: Latency settings are ignored in most cases. Exceptions are when
+doing I/O between different devices and as a hint for selecting a realtively
+low or relatively high latency in conjunction with
+paHostFramesPerBufferUnspecified. Latency settings are always automatically
+bound to "safe" values, however, so setting extreme values here should not be
+an issue.
+
+- Buffer Size: paHostFramesPerBufferUnspecified and specific host buffer sizes
+are supported. paHostFramesPerBufferUnspecified works best in "pro" mode,
+where the buffer size and sample rate of the audio device is most likely
+to match the expected values.
+
+- Timing info. It reports on stream time, but I'm probably doing something
+wrong since patest_sine_time often reports negative latency numbers.
+
+- xrun detection: The only xrun detection performed is when reading
+and writing the ring buffer. There is probably more that can be done.
+
+- abort/stop issues: stopping a stream is always a complete operation,
+but latency should be low enough to make the lack of a separate abort
+unnecessary. Apple clarifies its AudioOutputUnitStop() call here:
+http://lists.apple.com/archives/coreaudio-api/2005/Dec/msg00055.html
+
+- blocking interface: Not implemented.
+
+- multichannel: It has been tested successfully on multichannel hardware
+from MOTU: traveler and 896HD.
+
+- sample rate conversion quality: By default, SR conversion is the maximum
+available. This can be tweaked using flags pa_mac_core.h. Note that the AU
+render quyality property is used to set the sample rat conversion quality
+as "documented" here:
+http://lists.apple.com/archives/coreaudio-api/2004/Jan/msg00141.html
+
+- x86: I haven't tested it on an x86 Mac myself, but users have reported 
+being able to comiple and run it.
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/pa_mac_core.c b/utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/pa_mac_core.c
new file mode 100644 (file)
index 0000000..bfcb06d
--- /dev/null
@@ -0,0 +1,907 @@
+/*
+ * $Id: pa_mac_core_old.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * pa_mac_core.c
+ * Implementation of PortAudio for Mac OS X CoreAudio       
+ *                                                                                         
+ * PortAudio Portable Real-Time Audio Library
+ * Latest Version at: http://www.portaudio.com
+ *
+ * Authors: Ross Bencina and Phil Burk
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <CoreAudio/CoreAudio.h>
+#include <AudioToolbox/AudioToolbox.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <assert.h>
+
+#include "portaudio.h"
+#include "pa_trace.h"
+#include "pa_util.h"
+#include "pa_allocation.h"
+#include "pa_hostapi.h"
+#include "pa_stream.h"
+#include "pa_cpuload.h"
+#include "pa_process.h"
+
+// =====  constants  =====
+
+// =====  structs  =====
+#pragma mark structs
+
+// PaMacCoreHostApiRepresentation - host api datastructure specific to this implementation
+typedef struct PaMacCore_HAR
+{
+    PaUtilHostApiRepresentation inheritedHostApiRep;
+    PaUtilStreamInterface callbackStreamInterface;
+    PaUtilStreamInterface blockingStreamInterface;
+    
+    PaUtilAllocationGroup *allocations;
+    AudioDeviceID *macCoreDeviceIds;
+}
+PaMacCoreHostApiRepresentation;
+
+typedef struct PaMacCore_DI
+{
+    PaDeviceInfo inheritedDeviceInfo;
+}
+PaMacCoreDeviceInfo;
+
+// PaMacCoreStream - a stream data structure specifically for this implementation
+typedef struct PaMacCore_S
+{
+    PaUtilStreamRepresentation streamRepresentation;
+    PaUtilCpuLoadMeasurer cpuLoadMeasurer;
+    PaUtilBufferProcessor bufferProcessor;
+    
+    int primeStreamUsingCallback;
+    
+    AudioDeviceID inputDevice;
+    AudioDeviceID outputDevice;
+    
+    // Processing thread management --------------
+//    HANDLE abortEvent;
+//    HANDLE processingThread;
+//    DWORD processingThreadId;
+    
+    char throttleProcessingThreadOnOverload; // 0 -> don't throtte, non-0 -> throttle
+    int processingThreadPriority;
+    int highThreadPriority;
+    int throttledThreadPriority;
+    unsigned long throttledSleepMsecs;
+    
+    int isStopped;
+    volatile int isActive;
+    volatile int stopProcessing; // stop thread once existing buffers have been returned
+    volatile int abortProcessing; // stop thread immediately
+    
+//    DWORD allBuffersDurationMs; // used to calculate timeouts
+}
+PaMacCoreStream;
+
+// Data needed by the CoreAudio callback functions
+typedef struct PaMacCore_CD
+{
+    PaMacCoreStream *stream;
+    PaStreamCallback *callback;
+    void *userData;
+    PaUtilConverter *inputConverter;
+    PaUtilConverter *outputConverter;
+    void *inputBuffer;
+    void *outputBuffer;
+    int inputChannelCount;
+    int outputChannelCount;
+    PaSampleFormat inputSampleFormat;
+    PaSampleFormat outputSampleFormat;
+    PaUtilTriangularDitherGenerator *ditherGenerator;
+}
+PaMacClientData;
+
+// =====  CoreAudio-PortAudio bridge functions =====
+#pragma mark CoreAudio-PortAudio bridge functions
+
+// Maps CoreAudio OSStatus codes to PortAudio PaError codes
+static PaError conv_err(OSStatus error)
+{
+    PaError result;
+    
+    switch (error) {
+        case kAudioHardwareNoError:
+            result = paNoError; break;
+        case kAudioHardwareNotRunningError:
+            result = paInternalError; break;
+        case kAudioHardwareUnspecifiedError:
+            result = paInternalError; break;
+        case kAudioHardwareUnknownPropertyError:
+            result = paInternalError; break;
+        case kAudioHardwareBadPropertySizeError:
+            result = paInternalError; break;
+        case kAudioHardwareIllegalOperationError:
+            result = paInternalError; break;
+        case kAudioHardwareBadDeviceError:
+            result = paInvalidDevice; break;
+        case kAudioHardwareBadStreamError:
+            result = paBadStreamPtr; break;
+        case kAudioHardwareUnsupportedOperationError:
+            result = paInternalError; break;
+        case kAudioDeviceUnsupportedFormatError:
+            result = paSampleFormatNotSupported; break;
+        case kAudioDevicePermissionsError:
+            result = paDeviceUnavailable; break;
+        default:
+            result = paInternalError;
+    }
+    
+    return result;
+}
+
+/* This function is unused
+static AudioStreamBasicDescription *InitializeStreamDescription(const PaStreamParameters *parameters, double sampleRate)
+{
+    struct AudioStreamBasicDescription *streamDescription = PaUtil_AllocateMemory(sizeof(AudioStreamBasicDescription));
+    streamDescription->mSampleRate = sampleRate;
+    streamDescription->mFormatID = kAudioFormatLinearPCM;
+    streamDescription->mFormatFlags = 0;
+    streamDescription->mFramesPerPacket = 1;
+    
+    if (parameters->sampleFormat & paNonInterleaved) {
+        streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsNonInterleaved;
+        streamDescription->mChannelsPerFrame = 1;
+        streamDescription->mBytesPerFrame = Pa_GetSampleSize(parameters->sampleFormat);
+        streamDescription->mBytesPerPacket = Pa_GetSampleSize(parameters->sampleFormat);
+    }
+    else {
+        streamDescription->mChannelsPerFrame = parameters->channelCount;
+    }
+    
+    streamDescription->mBytesPerFrame = Pa_GetSampleSize(parameters->sampleFormat) * streamDescription->mChannelsPerFrame;
+    streamDescription->mBytesPerPacket = streamDescription->mBytesPerFrame * streamDescription->mFramesPerPacket;
+    
+    if (parameters->sampleFormat & paFloat32) {
+        streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsFloat;
+        streamDescription->mBitsPerChannel = 32;
+    }
+    else if (parameters->sampleFormat & paInt32) {
+        streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
+        streamDescription->mBitsPerChannel = 32;
+    }
+    else if (parameters->sampleFormat & paInt24) {
+        streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
+        streamDescription->mBitsPerChannel = 24;
+    }
+    else if (parameters->sampleFormat & paInt16) {
+        streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
+        streamDescription->mBitsPerChannel = 16;
+    }
+    else if (parameters->sampleFormat & paInt8) {
+        streamDescription->mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
+        streamDescription->mBitsPerChannel = 8;
+    }    
+    else if (parameters->sampleFormat & paInt32) {
+        streamDescription->mBitsPerChannel = 8;
+    }
+    
+    return streamDescription;
+}
+*/
+
+static PaStreamCallbackTimeInfo *InitializeTimeInfo(const AudioTimeStamp* now, const AudioTimeStamp* inputTime, const AudioTimeStamp* outputTime)
+{
+    PaStreamCallbackTimeInfo *timeInfo = PaUtil_AllocateMemory(sizeof(PaStreamCallbackTimeInfo));
+    
+    timeInfo->inputBufferAdcTime = inputTime->mSampleTime;
+    timeInfo->currentTime = now->mSampleTime;
+    timeInfo->outputBufferDacTime = outputTime->mSampleTime;
+    
+    return timeInfo;
+}
+
+// =====  support functions  =====
+#pragma mark support functions
+
+static void CleanUp(PaMacCoreHostApiRepresentation *macCoreHostApi)
+{
+    if( macCoreHostApi->allocations )
+    {
+        PaUtil_FreeAllAllocations( macCoreHostApi->allocations );
+        PaUtil_DestroyAllocationGroup( macCoreHostApi->allocations );
+    }
+    
+    PaUtil_FreeMemory( macCoreHostApi );    
+}
+
+static PaError GetChannelInfo(PaDeviceInfo *deviceInfo, AudioDeviceID macCoreDeviceId, int isInput)
+{
+    UInt32 propSize;
+    PaError err = paNoError;
+    UInt32 i;
+    int numChannels = 0;
+    AudioBufferList *buflist;
+
+    err = conv_err(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, isInput, kAudioDevicePropertyStreamConfiguration, &propSize, NULL));
+    buflist = PaUtil_AllocateMemory(propSize);
+    err = conv_err(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyStreamConfiguration, &propSize, buflist));
+    if (!err) {
+        for (i = 0; i < buflist->mNumberBuffers; ++i) {
+            numChannels += buflist->mBuffers[i].mNumberChannels;
+        }
+               
+               if (isInput)
+                       deviceInfo->maxInputChannels = numChannels;
+               else
+                       deviceInfo->maxOutputChannels = numChannels;
+               
+        int frameLatency;
+        propSize = sizeof(UInt32);
+        err = conv_err(AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyLatency, &propSize, &frameLatency));
+        if (!err) {
+            double secondLatency = frameLatency / deviceInfo->defaultSampleRate;
+            if (isInput) {
+                deviceInfo->defaultLowInputLatency = secondLatency;
+                deviceInfo->defaultHighInputLatency = secondLatency;
+            }
+            else {
+                deviceInfo->defaultLowOutputLatency = secondLatency;
+                deviceInfo->defaultHighOutputLatency = secondLatency;
+            }
+        }
+    }
+    PaUtil_FreeMemory(buflist);
+    
+    return err;
+}
+
+static PaError InitializeDeviceInfo(PaMacCoreDeviceInfo *macCoreDeviceInfo,  AudioDeviceID macCoreDeviceId, PaHostApiIndex hostApiIndex )
+{
+    PaDeviceInfo *deviceInfo = &macCoreDeviceInfo->inheritedDeviceInfo;
+    deviceInfo->structVersion = 2;
+    deviceInfo->hostApi = hostApiIndex;
+    
+    PaError err = paNoError;
+    UInt32 propSize;
+
+    err = conv_err(AudioDeviceGetPropertyInfo(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, NULL));
+    // FIXME: this allocation should be part of the allocations group
+    char *name = PaUtil_AllocateMemory(propSize);
+    err = conv_err(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyDeviceName, &propSize, name));
+    if (!err) {
+        deviceInfo->name = name;
+    }
+    
+    Float64 sampleRate;
+    propSize = sizeof(Float64);
+    err = conv_err(AudioDeviceGetProperty(macCoreDeviceId, 0, 0, kAudioDevicePropertyNominalSampleRate, &propSize, &sampleRate));
+    if (!err) {
+        deviceInfo->defaultSampleRate = sampleRate;
+    }
+
+
+    // Get channel info
+    err = GetChannelInfo(deviceInfo, macCoreDeviceId, 1);
+    err = GetChannelInfo(deviceInfo, macCoreDeviceId, 0);
+
+    return err;
+}
+
+static PaError InitializeDeviceInfos( PaMacCoreHostApiRepresentation *macCoreHostApi, PaHostApiIndex hostApiIndex )
+{
+    PaError result = paNoError;
+    PaUtilHostApiRepresentation *hostApi;
+    PaMacCoreDeviceInfo *deviceInfoArray;
+
+    // initialise device counts and default devices under the assumption that there are no devices. These values are incremented below if and when devices are successfully initialized.
+    hostApi = &macCoreHostApi->inheritedHostApiRep;
+    hostApi->info.deviceCount = 0;
+    hostApi->info.defaultInputDevice = paNoDevice;
+    hostApi->info.defaultOutputDevice = paNoDevice;
+    
+    UInt32 propsize;
+    AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices, &propsize, NULL);
+    int numDevices = propsize / sizeof(AudioDeviceID);
+    hostApi->info.deviceCount = numDevices;
+    if (numDevices > 0) {
+        hostApi->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
+                                            macCoreHostApi->allocations, sizeof(PaDeviceInfo*) * numDevices );
+        if( !hostApi->deviceInfos )
+        {
+            return paInsufficientMemory;
+        }
+
+        // allocate all device info structs in a contiguous block
+        deviceInfoArray = (PaMacCoreDeviceInfo*)PaUtil_GroupAllocateMemory(
+                                macCoreHostApi->allocations, sizeof(PaMacCoreDeviceInfo) * numDevices );
+        if( !deviceInfoArray )
+        {
+            return paInsufficientMemory;
+        }
+        
+        macCoreHostApi->macCoreDeviceIds = PaUtil_GroupAllocateMemory(macCoreHostApi->allocations, propsize);
+        AudioHardwareGetProperty(kAudioHardwarePropertyDevices, &propsize, macCoreHostApi->macCoreDeviceIds);
+
+        AudioDeviceID defaultInputDevice, defaultOutputDevice;
+        propsize = sizeof(AudioDeviceID);
+        AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice, &propsize, &defaultInputDevice);
+        AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &propsize, &defaultOutputDevice);
+        
+        UInt32 i;
+        for (i = 0; i < numDevices; ++i) {
+            if (macCoreHostApi->macCoreDeviceIds[i] == defaultInputDevice) {
+                hostApi->info.defaultInputDevice = i;
+            }
+            if (macCoreHostApi->macCoreDeviceIds[i] == defaultOutputDevice) {
+                hostApi->info.defaultOutputDevice = i;
+            }
+            InitializeDeviceInfo(&deviceInfoArray[i], macCoreHostApi->macCoreDeviceIds[i], hostApiIndex);
+            hostApi->deviceInfos[i] = &(deviceInfoArray[i].inheritedDeviceInfo);      
+        }
+    }
+
+    return result;
+}
+
+static OSStatus CheckFormat(AudioDeviceID macCoreDeviceId, const PaStreamParameters *parameters, double sampleRate, int isInput)
+{
+    UInt32 propSize = sizeof(AudioStreamBasicDescription);
+    AudioStreamBasicDescription *streamDescription = PaUtil_AllocateMemory(propSize);
+
+    streamDescription->mSampleRate = sampleRate;
+    streamDescription->mFormatID = 0;
+    streamDescription->mFormatFlags = 0;
+    streamDescription->mBytesPerPacket = 0;
+    streamDescription->mFramesPerPacket = 0;
+    streamDescription->mBytesPerFrame = 0;
+    streamDescription->mChannelsPerFrame = 0;
+    streamDescription->mBitsPerChannel = 0;
+    streamDescription->mReserved = 0;
+
+    OSStatus result = AudioDeviceGetProperty(macCoreDeviceId, 0, isInput, kAudioDevicePropertyStreamFormatSupported, &propSize, streamDescription);
+    PaUtil_FreeMemory(streamDescription);
+    return result;
+}
+
+static OSStatus CopyInputData(PaMacClientData* destination, const AudioBufferList *source, unsigned long frameCount)
+{
+    int frameSpacing, channelSpacing;
+    if (destination->inputSampleFormat & paNonInterleaved) {
+        frameSpacing = 1;
+        channelSpacing = destination->inputChannelCount;
+    }
+    else {
+        frameSpacing = destination->inputChannelCount;
+        channelSpacing = 1;
+    }
+    
+    AudioBuffer const *inputBuffer = &source->mBuffers[0];
+    void *coreAudioBuffer = inputBuffer->mData;
+    void *portAudioBuffer = destination->inputBuffer;
+    UInt32 i, streamNumber, streamChannel;
+    for (i = streamNumber = streamChannel = 0; i < destination->inputChannelCount; ++i, ++streamChannel) {
+        if (streamChannel >= inputBuffer->mNumberChannels) {
+            ++streamNumber;
+            inputBuffer = &source->mBuffers[streamNumber];
+            coreAudioBuffer = inputBuffer->mData;
+            streamChannel = 0;
+        }
+        destination->inputConverter(portAudioBuffer, frameSpacing, coreAudioBuffer, inputBuffer->mNumberChannels, frameCount, destination->ditherGenerator);
+        coreAudioBuffer += sizeof(Float32);
+        portAudioBuffer += Pa_GetSampleSize(destination->inputSampleFormat) * channelSpacing;
+    }
+    return noErr;
+}
+
+static OSStatus CopyOutputData(AudioBufferList* destination, PaMacClientData *source, unsigned long frameCount)
+{
+    int frameSpacing, channelSpacing;
+    if (source->outputSampleFormat & paNonInterleaved) {
+        frameSpacing = 1;
+        channelSpacing = source->outputChannelCount;
+    }
+    else {
+        frameSpacing = source->outputChannelCount;
+        channelSpacing = 1;
+    }
+    
+    AudioBuffer *outputBuffer = &destination->mBuffers[0];
+    void *coreAudioBuffer = outputBuffer->mData;
+    void *portAudioBuffer = source->outputBuffer;
+    UInt32 i, streamNumber, streamChannel;
+    for (i = streamNumber = streamChannel = 0; i < source->outputChannelCount; ++i, ++streamChannel) {
+        if (streamChannel >= outputBuffer->mNumberChannels) {
+            ++streamNumber;
+            outputBuffer = &destination->mBuffers[streamNumber];
+            coreAudioBuffer = outputBuffer->mData;
+            streamChannel = 0;
+        }
+        source->outputConverter(coreAudioBuffer, outputBuffer->mNumberChannels, portAudioBuffer, frameSpacing, frameCount, NULL);
+        coreAudioBuffer += sizeof(Float32);
+        portAudioBuffer += Pa_GetSampleSize(source->outputSampleFormat) * channelSpacing;
+    }
+    return noErr;
+}
+
+static OSStatus AudioIOProc( AudioDeviceID inDevice,
+                      const AudioTimeStamp* inNow,
+                      const AudioBufferList* inInputData,
+                      const AudioTimeStamp* inInputTime,
+                      AudioBufferList* outOutputData, 
+                      const AudioTimeStamp* inOutputTime,
+                      void* inClientData)
+{
+    PaMacClientData *clientData = (PaMacClientData *)inClientData;
+    PaStreamCallbackTimeInfo *timeInfo = InitializeTimeInfo(inNow, inInputTime, inOutputTime);
+    
+    PaUtil_BeginCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer );
+    
+    AudioBuffer *outputBuffer = &outOutputData->mBuffers[0];
+    unsigned long frameCount = outputBuffer->mDataByteSize / (outputBuffer->mNumberChannels * sizeof(Float32));
+
+    if (clientData->inputBuffer) {
+        CopyInputData(clientData, inInputData, frameCount);
+    }
+    PaStreamCallbackResult result = clientData->callback(clientData->inputBuffer, clientData->outputBuffer, frameCount, timeInfo, paNoFlag, clientData->userData);
+    if (clientData->outputBuffer) {
+        CopyOutputData(outOutputData, clientData, frameCount);
+    }
+
+    PaUtil_EndCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer, frameCount );
+    
+    if (result == paComplete || result == paAbort) {
+        Pa_StopStream(clientData->stream);
+    }
+
+    PaUtil_FreeMemory( timeInfo );
+    return noErr;
+}
+
+// This is not for input-only streams, this is for streams where the input device is different from the output device
+static OSStatus AudioInputProc( AudioDeviceID inDevice,
+                         const AudioTimeStamp* inNow,
+                         const AudioBufferList* inInputData,
+                         const AudioTimeStamp* inInputTime,
+                         AudioBufferList* outOutputData, 
+                         const AudioTimeStamp* inOutputTime,
+                         void* inClientData)
+{
+    PaMacClientData *clientData = (PaMacClientData *)inClientData;
+    PaStreamCallbackTimeInfo *timeInfo = InitializeTimeInfo(inNow, inInputTime, inOutputTime);
+
+    PaUtil_BeginCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer );
+
+    AudioBuffer const *inputBuffer = &inInputData->mBuffers[0];
+    unsigned long frameCount = inputBuffer->mDataByteSize / (inputBuffer->mNumberChannels * sizeof(Float32));
+
+    CopyInputData(clientData, inInputData, frameCount);
+    PaStreamCallbackResult result = clientData->callback(clientData->inputBuffer, clientData->outputBuffer, frameCount, timeInfo, paNoFlag, clientData->userData);
+    
+    PaUtil_EndCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer, frameCount );
+    if( result == paComplete || result == paAbort )
+       Pa_StopStream(clientData->stream);
+    PaUtil_FreeMemory( timeInfo );
+    return noErr;
+}
+
+// This is not for output-only streams, this is for streams where the input device is different from the output device
+static OSStatus AudioOutputProc( AudioDeviceID inDevice,
+                          const AudioTimeStamp* inNow,
+                          const AudioBufferList* inInputData,
+                          const AudioTimeStamp* inInputTime,
+                          AudioBufferList* outOutputData, 
+                          const AudioTimeStamp* inOutputTime,
+                          void* inClientData)
+{
+    PaMacClientData *clientData = (PaMacClientData *)inClientData;
+    //PaStreamCallbackTimeInfo *timeInfo = InitializeTimeInfo(inNow, inInputTime, inOutputTime);
+
+    PaUtil_BeginCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer );
+
+    AudioBuffer *outputBuffer = &outOutputData->mBuffers[0];
+    unsigned long frameCount = outputBuffer->mDataByteSize / (outputBuffer->mNumberChannels * sizeof(Float32));
+
+    //clientData->callback(NULL, clientData->outputBuffer, frameCount, timeInfo, paNoFlag, clientData->userData);
+
+    CopyOutputData(outOutputData, clientData, frameCount);
+
+    PaUtil_EndCpuLoadMeasurement( &clientData->stream->cpuLoadMeasurer, frameCount );
+    return noErr;
+}
+
+static PaError SetSampleRate(AudioDeviceID device, double sampleRate, int isInput)
+{
+    PaError result = paNoError;
+    
+    double actualSampleRate;
+    UInt32 propSize = sizeof(double);
+    result = conv_err(AudioDeviceSetProperty(device, NULL, 0, isInput, kAudioDevicePropertyNominalSampleRate, propSize, &sampleRate));
+    
+    result = conv_err(AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyNominalSampleRate, &propSize, &actualSampleRate));
+    
+    if (result == paNoError && actualSampleRate != sampleRate) {
+        result = paInvalidSampleRate;
+    }
+    
+    return result;    
+}
+
+static PaError SetFramesPerBuffer(AudioDeviceID device, unsigned long framesPerBuffer, int isInput)
+{
+    PaError result = paNoError;
+    UInt32 preferredFramesPerBuffer = framesPerBuffer;
+    //    while (preferredFramesPerBuffer > UINT32_MAX) {
+    //        preferredFramesPerBuffer /= 2;
+    //    }
+    
+    UInt32 actualFramesPerBuffer;
+    UInt32 propSize = sizeof(UInt32);
+    result = conv_err(AudioDeviceSetProperty(device, NULL, 0, isInput, kAudioDevicePropertyBufferFrameSize, propSize, &preferredFramesPerBuffer));
+    
+    result = conv_err(AudioDeviceGetProperty(device, 0, isInput, kAudioDevicePropertyBufferFrameSize, &propSize, &actualFramesPerBuffer));
+    
+    if (result != paNoError) {
+        // do nothing
+    }
+    else if (actualFramesPerBuffer > framesPerBuffer) {
+        result = paBufferTooSmall;
+    }
+    else if (actualFramesPerBuffer < framesPerBuffer) {
+        result = paBufferTooBig;
+    }
+    
+    return result;    
+}
+    
+static PaError SetUpUnidirectionalStream(AudioDeviceID device, double sampleRate, unsigned long framesPerBuffer, int isInput)
+{
+    PaError err = paNoError;
+    err = SetSampleRate(device, sampleRate, isInput);
+    if( err == paNoError )
+        err = SetFramesPerBuffer(device, framesPerBuffer, isInput);
+    return err;
+}
+
+// =====  PortAudio functions  =====
+#pragma mark PortAudio functions
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif // __cplusplus
+    
+    PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
+    
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
+static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
+{
+    PaMacCoreHostApiRepresentation *macCoreHostApi = (PaMacCoreHostApiRepresentation*)hostApi;
+    
+    CleanUp(macCoreHostApi);
+}
+
+static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
+                                  const PaStreamParameters *inputParameters,
+                                  const PaStreamParameters *outputParameters,
+                                  double sampleRate )
+{
+    PaMacCoreHostApiRepresentation *macCoreHostApi = (PaMacCoreHostApiRepresentation*)hostApi;
+    PaDeviceInfo *deviceInfo;
+    
+    PaError result = paNoError;
+    if (inputParameters) {
+        deviceInfo = macCoreHostApi->inheritedHostApiRep.deviceInfos[inputParameters->device];
+        if (inputParameters->channelCount > deviceInfo->maxInputChannels)
+            result = paInvalidChannelCount;
+        else if (CheckFormat(macCoreHostApi->macCoreDeviceIds[inputParameters->device], inputParameters, sampleRate, 1) != kAudioHardwareNoError) {
+            result = paInvalidSampleRate;
+        }
+    }
+    if (outputParameters && result == paNoError) {
+        deviceInfo = macCoreHostApi->inheritedHostApiRep.deviceInfos[outputParameters->device];
+        if (outputParameters->channelCount > deviceInfo->maxOutputChannels)
+            result = paInvalidChannelCount;
+        else if (CheckFormat(macCoreHostApi->macCoreDeviceIds[outputParameters->device], outputParameters, sampleRate, 0) != kAudioHardwareNoError) {
+            result = paInvalidSampleRate;
+        }
+    }
+
+    return result;
+}
+
+static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
+                           PaStream** s,
+                           const PaStreamParameters *inputParameters,
+                           const PaStreamParameters *outputParameters,
+                           double sampleRate,
+                           unsigned long framesPerBuffer,
+                           PaStreamFlags streamFlags,
+                           PaStreamCallback *streamCallback,
+                           void *userData )
+{
+    PaError err = paNoError;
+    PaMacCoreHostApiRepresentation *macCoreHostApi = (PaMacCoreHostApiRepresentation *)hostApi;
+    PaMacCoreStream *stream = PaUtil_AllocateMemory(sizeof(PaMacCoreStream));
+    stream->isActive = 0;
+    stream->isStopped = 1;
+    stream->inputDevice = kAudioDeviceUnknown;
+    stream->outputDevice = kAudioDeviceUnknown;
+    
+    PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
+                                           ( (streamCallback)
+                                             ? &macCoreHostApi->callbackStreamInterface
+                                             : &macCoreHostApi->blockingStreamInterface ),
+                                           streamCallback, userData );
+    PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );
+    
+    *s = (PaStream*)stream;
+    PaMacClientData *clientData = PaUtil_AllocateMemory(sizeof(PaMacClientData));
+    clientData->stream = stream;
+    clientData->callback = streamCallback;
+    clientData->userData = userData;
+    clientData->inputBuffer = 0;
+    clientData->outputBuffer = 0;
+    clientData->ditherGenerator = PaUtil_AllocateMemory(sizeof(PaUtilTriangularDitherGenerator));
+    PaUtil_InitializeTriangularDitherState(clientData->ditherGenerator);
+    
+    if (inputParameters != NULL) {
+        stream->inputDevice = macCoreHostApi->macCoreDeviceIds[inputParameters->device];
+        clientData->inputConverter = PaUtil_SelectConverter(paFloat32, inputParameters->sampleFormat, streamFlags);
+        clientData->inputBuffer = PaUtil_AllocateMemory(Pa_GetSampleSize(inputParameters->sampleFormat) * framesPerBuffer * inputParameters->channelCount);
+        clientData->inputChannelCount = inputParameters->channelCount;
+        clientData->inputSampleFormat = inputParameters->sampleFormat;
+        err = SetUpUnidirectionalStream(stream->inputDevice, sampleRate, framesPerBuffer, 1);
+    }
+    
+    if (err == paNoError && outputParameters != NULL) {
+        stream->outputDevice = macCoreHostApi->macCoreDeviceIds[outputParameters->device];
+        clientData->outputConverter = PaUtil_SelectConverter(outputParameters->sampleFormat, paFloat32, streamFlags);
+        clientData->outputBuffer = PaUtil_AllocateMemory(Pa_GetSampleSize(outputParameters->sampleFormat) * framesPerBuffer * outputParameters->channelCount);
+        clientData->outputChannelCount = outputParameters->channelCount;
+        clientData->outputSampleFormat = outputParameters->sampleFormat;
+        err = SetUpUnidirectionalStream(stream->outputDevice, sampleRate, framesPerBuffer, 0);
+    }
+
+    if (inputParameters == NULL || outputParameters == NULL || stream->inputDevice == stream->outputDevice) {
+        AudioDeviceID device = (inputParameters == NULL) ? stream->outputDevice : stream->inputDevice;
+
+        AudioDeviceAddIOProc(device, AudioIOProc, clientData);
+    }
+    else {
+        // using different devices for input and output
+        AudioDeviceAddIOProc(stream->inputDevice, AudioInputProc, clientData);
+        AudioDeviceAddIOProc(stream->outputDevice, AudioOutputProc, clientData);
+    }
+    
+    return err;
+}
+
+// Note: When CloseStream() is called, the multi-api layer ensures that the stream has already been stopped or aborted.
+static PaError CloseStream( PaStream* s )
+{
+    PaError err = paNoError;
+    PaMacCoreStream *stream = (PaMacCoreStream*)s;
+
+    PaUtil_ResetCpuLoadMeasurer( &stream->cpuLoadMeasurer );
+
+    if (stream->inputDevice != kAudioDeviceUnknown) {
+        if (stream->outputDevice == kAudioDeviceUnknown || stream->outputDevice == stream->inputDevice) {
+            err = conv_err(AudioDeviceRemoveIOProc(stream->inputDevice, AudioIOProc));
+        }
+        else {
+            err = conv_err(AudioDeviceRemoveIOProc(stream->inputDevice, AudioInputProc));
+            err = conv_err(AudioDeviceRemoveIOProc(stream->outputDevice, AudioOutputProc));
+        }
+    }
+    else {
+        err = conv_err(AudioDeviceRemoveIOProc(stream->outputDevice, AudioIOProc));
+    }
+    
+    return err;
+}
+
+
+static PaError StartStream( PaStream *s )
+{
+    PaError err = paNoError;
+    PaMacCoreStream *stream = (PaMacCoreStream*)s;
+
+    if (stream->inputDevice != kAudioDeviceUnknown) {
+        if (stream->outputDevice == kAudioDeviceUnknown || stream->outputDevice == stream->inputDevice) {
+            err = conv_err(AudioDeviceStart(stream->inputDevice, AudioIOProc));
+        }
+        else {
+            err = conv_err(AudioDeviceStart(stream->inputDevice, AudioInputProc));
+            err = conv_err(AudioDeviceStart(stream->outputDevice, AudioOutputProc));
+        }
+    }
+    else {
+        err = conv_err(AudioDeviceStart(stream->outputDevice, AudioIOProc));
+    }
+    
+    stream->isActive = 1;
+    stream->isStopped = 0;
+    return err;
+}
+
+static PaError AbortStream( PaStream *s )
+{
+    PaError err = paNoError;
+    PaMacCoreStream *stream = (PaMacCoreStream*)s;
+    
+    if (stream->inputDevice != kAudioDeviceUnknown) {
+        if (stream->outputDevice == kAudioDeviceUnknown || stream->outputDevice == stream->inputDevice) {
+            err = conv_err(AudioDeviceStop(stream->inputDevice, AudioIOProc));
+        }
+        else {
+            err = conv_err(AudioDeviceStop(stream->inputDevice, AudioInputProc));
+            err = conv_err(AudioDeviceStop(stream->outputDevice, AudioOutputProc));
+        }
+    }
+    else {
+        err = conv_err(AudioDeviceStop(stream->outputDevice, AudioIOProc));
+    }
+    
+    stream->isActive = 0;
+    stream->isStopped = 1;
+    return err;
+}    
+
+static PaError StopStream( PaStream *s )
+{
+    // TODO: this should be nicer than abort
+    return AbortStream(s);
+}
+
+static PaError IsStreamStopped( PaStream *s )
+{
+    PaMacCoreStream *stream = (PaMacCoreStream*)s;
+    
+    return stream->isStopped;
+}
+
+
+static PaError IsStreamActive( PaStream *s )
+{
+    PaMacCoreStream *stream = (PaMacCoreStream*)s;
+
+    return stream->isActive;
+}
+
+
+static PaTime GetStreamTime( PaStream *s )
+{
+    OSStatus err;
+    PaTime result;
+    PaMacCoreStream *stream = (PaMacCoreStream*)s;
+
+    AudioTimeStamp *timeStamp = PaUtil_AllocateMemory(sizeof(AudioTimeStamp));
+    if (stream->inputDevice != kAudioDeviceUnknown) {
+        err = AudioDeviceGetCurrentTime(stream->inputDevice, timeStamp);
+    }
+    else {
+        err = AudioDeviceGetCurrentTime(stream->outputDevice, timeStamp);
+    }
+    
+    result = err ? 0 : timeStamp->mSampleTime;
+    PaUtil_FreeMemory(timeStamp);
+
+    return result;
+}
+
+
+static double GetStreamCpuLoad( PaStream* s )
+{
+    PaMacCoreStream *stream = (PaMacCoreStream*)s;
+    
+    return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
+}
+
+
+// As separate stream interfaces are used for blocking and callback streams, the following functions can be guaranteed to only be called for blocking streams.
+
+static PaError ReadStream( PaStream* s,
+                           void *buffer,
+                           unsigned long frames )
+{
+    return paInternalError;
+}
+
+
+static PaError WriteStream( PaStream* s,
+                            const void *buffer,
+                            unsigned long frames )
+{
+    return paInternalError;
+}
+
+
+static signed long GetStreamReadAvailable( PaStream* s )
+{
+    return paInternalError;
+}
+
+
+static signed long GetStreamWriteAvailable( PaStream* s )
+{
+    return paInternalError;
+}
+
+// HostAPI-specific initialization function
+PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
+{
+    PaError result = paNoError;
+    PaMacCoreHostApiRepresentation *macCoreHostApi = (PaMacCoreHostApiRepresentation *)PaUtil_AllocateMemory( sizeof(PaMacCoreHostApiRepresentation) );
+    if( !macCoreHostApi )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+    
+    macCoreHostApi->allocations = PaUtil_CreateAllocationGroup();
+    if( !macCoreHostApi->allocations )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+    
+    *hostApi = &macCoreHostApi->inheritedHostApiRep;
+    (*hostApi)->info.structVersion = 1;
+    (*hostApi)->info.type = paCoreAudio;
+    (*hostApi)->info.name = "CoreAudio";
+
+    result = InitializeDeviceInfos(macCoreHostApi, hostApiIndex);
+    if (result != paNoError) {
+        goto error;
+    }
+    
+    // Set up the proper callbacks to this HostApi's functions
+    (*hostApi)->Terminate = Terminate;
+    (*hostApi)->OpenStream = OpenStream;
+    (*hostApi)->IsFormatSupported = IsFormatSupported;
+    
+    PaUtil_InitializeStreamInterface( &macCoreHostApi->callbackStreamInterface, CloseStream, StartStream,
+                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
+                                      GetStreamTime, GetStreamCpuLoad,
+                                      PaUtil_DummyRead, PaUtil_DummyWrite,
+                                      PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable );
+    
+    PaUtil_InitializeStreamInterface( &macCoreHostApi->blockingStreamInterface, CloseStream, StartStream,
+                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
+                                      GetStreamTime, PaUtil_DummyGetCpuLoad,
+                                      ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );
+    
+    return result;
+    
+error:
+        if( macCoreHostApi ) {
+            CleanUp(macCoreHostApi);
+        }
+    
+    return result;
+}
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.c b/utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.c
new file mode 100644 (file)
index 0000000..9aec2a3
--- /dev/null
@@ -0,0 +1,512 @@
+/* This file contains the implementation
+ * required for blocking I/O. It is separated from pa_mac_core.c simply to ease
+ * development. */
+
+#include "pa_mac_core_blocking.h"
+#include "pa_mac_core_internal.h"
+#include <assert.h>
+//#include <libkern/OSAtomic.h>
+#include <CoreServices/CoreServices.h>
+
+/*
+ * This fnuction determines the size of a particular sample format.
+ * if the format is not recognized, this returns zero.
+ */
+static size_t computeSampleSizeFromFormat( PaSampleFormat format )
+{
+   switch( format ) {
+   case paFloat32: return 4;
+   case paInt32: return 4;
+   case paInt24: return 3;
+   case paInt16: return 2;
+   case paInt8: case paUInt8: return 1;
+   default: return 0;
+   }
+}
+
+
+/*
+ * Functions for initializing, resetting, and destroying BLIO structures.
+ *
+ */
+
+/* This should be called with the relevant info when initializing a stream for
+   callback. */
+PaError initializeBlioRingBuffers(
+                                       PaMacBlio *blio,
+                                       PaSampleFormat inputSampleFormat,
+                                       PaSampleFormat outputSampleFormat,
+                                       size_t framesPerBuffer,
+                                       long ringBufferSize,
+                                       int inChan,
+                                       int outChan )
+{
+   void *data;
+   int result;
+
+   /* zeroify things */
+   bzero( blio, sizeof( PaMacBlio ) );
+   /* this is redundant, but the buffers are used to check
+      if the bufffers have been initialized, so we do it explicitly. */
+   blio->inputRingBuffer.buffer = NULL;
+   blio->outputRingBuffer.buffer = NULL;
+
+   /* initialize simple data */
+   blio->inputSampleFormat = inputSampleFormat;
+   blio->inputSampleSize = computeSampleSizeFromFormat(inputSampleFormat);
+   blio->outputSampleFormat = outputSampleFormat;
+   blio->outputSampleSize = computeSampleSizeFromFormat(outputSampleFormat);
+   blio->framesPerBuffer = framesPerBuffer;
+   blio->inChan = inChan;
+   blio->outChan = outChan;
+   blio->statusFlags = 0;
+   blio->errors = paNoError;
+#ifdef PA_MAC_BLIO_MUTEX
+   blio->isInputEmpty = false;
+   blio->isOutputFull = false;
+#endif
+
+   /* setup ring buffers */
+#ifdef PA_MAC_BLIO_MUTEX
+   result = PaMacCore_SetUnixError( pthread_mutex_init(&(blio->inputMutex),NULL), 0 );
+   if( result )
+      goto error;
+   result = UNIX_ERR( pthread_cond_init( &(blio->inputCond), NULL ) );
+   if( result )
+      goto error;
+   result = UNIX_ERR( pthread_mutex_init(&(blio->outputMutex),NULL) );
+   if( result )
+      goto error;
+   result = UNIX_ERR( pthread_cond_init( &(blio->outputCond), NULL ) );
+#endif
+   if( inChan ) {
+      data = calloc( ringBufferSize, blio->inputSampleSize );
+      if( !data )
+      {
+         result = paInsufficientMemory;
+         goto error;
+      }
+
+      assert( 0 == RingBuffer_Init(
+            &blio->inputRingBuffer,
+            ringBufferSize*blio->inputSampleSize,
+            data ) );
+   }
+   if( outChan ) {
+      data = calloc( ringBufferSize, blio->outputSampleSize );
+      if( !data )
+      {
+         result = paInsufficientMemory;
+         goto error;
+      }
+
+      assert( 0 == RingBuffer_Init(
+            &blio->outputRingBuffer,
+            ringBufferSize*blio->outputSampleSize,
+            data ) );
+   }
+
+   result = resetBlioRingBuffers( blio );
+   if( result )
+      goto error;
+
+   return 0;
+
+ error:
+   destroyBlioRingBuffers( blio );
+   return result;
+}
+
+#ifdef PA_MAC_BLIO_MUTEX
+PaError blioSetIsInputEmpty( PaMacBlio *blio, bool isEmpty )
+{
+   PaError result = paNoError;
+   if( isEmpty == blio->isInputEmpty )
+      goto done;
+
+   /* we need to update the value. Here's what we do:
+    * - Lock the mutex, so noone else can write.
+    * - update the value.
+    * - unlock.
+    * - broadcast to all listeners.
+    */
+   result = UNIX_ERR( pthread_mutex_lock( &blio->inputMutex ) );
+   if( result )
+      goto done;
+   blio->isInputEmpty = isEmpty;
+   result = UNIX_ERR( pthread_mutex_unlock( &blio->inputMutex ) );
+   if( result )
+      goto done;
+   result = UNIX_ERR( pthread_cond_broadcast( &blio->inputCond ) );
+   if( result )
+      goto done;
+
+ done:
+   return result;
+}
+PaError blioSetIsOutputFull( PaMacBlio *blio, bool isFull )
+{
+   PaError result = paNoError;
+   if( isFull == blio->isOutputFull )
+      goto done;
+
+   /* we need to update the value. Here's what we do:
+    * - Lock the mutex, so noone else can write.
+    * - update the value.
+    * - unlock.
+    * - broadcast to all listeners.
+    */
+   result = UNIX_ERR( pthread_mutex_lock( &blio->outputMutex ) );
+   if( result )
+      goto done;
+   blio->isOutputFull = isFull;
+   result = UNIX_ERR( pthread_mutex_unlock( &blio->outputMutex ) );
+   if( result )
+      goto done;
+   result = UNIX_ERR( pthread_cond_broadcast( &blio->outputCond ) );
+   if( result )
+      goto done;
+
+ done:
+   return result;
+}
+#endif
+
+/* This should be called after stopping or aborting the stream, so that on next
+   start, the buffers will be ready. */
+PaError resetBlioRingBuffers( PaMacBlio *blio )
+{
+#ifdef PA_MAC__BLIO_MUTEX
+   int result;
+#endif
+   blio->statusFlags = 0;
+   if( blio->outputRingBuffer.buffer ) {
+      RingBuffer_Flush( &blio->outputRingBuffer );
+      bzero( blio->outputRingBuffer.buffer,
+             blio->outputRingBuffer.bufferSize );
+      /* Advance buffer */
+      RingBuffer_AdvanceWriteIndex( &blio->outputRingBuffer, blio->outputRingBuffer.bufferSize );
+
+      /* Update isOutputFull. */
+#ifdef PA_MAC__BLIO_MUTEX
+      result = blioSetIsOutputFull( blio, toAdvance == blio->outputRingBuffer.bufferSize );
+      if( result )
+         goto error;
+#endif
+/*
+      printf( "------%d\n" ,  blio->framesPerBuffer );
+      printf( "------%d\n" ,  blio->outChan );
+      printf( "------%d\n" ,  blio->outputSampleSize );
+      printf( "------%d\n" ,  blio->framesPerBuffer*blio->outChan*blio->outputSampleSize );
+*/
+   }
+   if( blio->inputRingBuffer.buffer ) {
+      RingBuffer_Flush( &blio->inputRingBuffer );
+      bzero( blio->inputRingBuffer.buffer,
+             blio->inputRingBuffer.bufferSize );
+      /* Update isInputEmpty. */
+#ifdef PA_MAC__BLIO_MUTEX
+      result = blioSetIsInputEmpty( blio, true );
+      if( result )
+         goto error;
+#endif
+   }
+   return paNoError;
+#ifdef PA_MAC__BLIO_MUTEX
+ error:
+   return result;
+#endif
+}
+
+/*This should be called when you are done with the blio. It can safely be called
+  multiple times if there are no exceptions. */
+PaError destroyBlioRingBuffers( PaMacBlio *blio )
+{
+   PaError result = paNoError;
+   if( blio->inputRingBuffer.buffer ) {
+      free( blio->inputRingBuffer.buffer );
+#ifdef PA_MAC__BLIO_MUTEX
+      result = UNIX_ERR( pthread_mutex_destroy( & blio->inputMutex ) );
+      if( result ) return result;
+      result = UNIX_ERR( pthread_cond_destroy( & blio->inputCond ) );
+      if( result ) return result;
+#endif
+   }
+   blio->inputRingBuffer.buffer = NULL;
+   if( blio->outputRingBuffer.buffer ) {
+      free( blio->outputRingBuffer.buffer );
+#ifdef PA_MAC__BLIO_MUTEX
+      result = UNIX_ERR( pthread_mutex_destroy( & blio->outputMutex ) );
+      if( result ) return result;
+      result = UNIX_ERR( pthread_cond_destroy( & blio->outputCond ) );
+      if( result ) return result;
+#endif
+   }
+   blio->outputRingBuffer.buffer = NULL;
+
+   return result;
+}
+
+/*
+ * this is the BlioCallback function. It expects to recieve a PaMacBlio Object
+ * pointer as userData.
+ *
+ */
+int BlioCallback( const void *input, void *output, unsigned long frameCount,
+       const PaStreamCallbackTimeInfo* timeInfo,
+        PaStreamCallbackFlags statusFlags,
+        void *userData )
+{
+   PaMacBlio *blio = (PaMacBlio*)userData;
+   long avail;
+   long toRead;
+   long toWrite;
+
+   /* set flags returned by OS: */
+   // Mihai: replacing OSAtomic32 with BitOrAtomic 
+   //OSAtomicOr32( statusFlags, &blio->statusFlags ) ;
+   BitOrAtomic( statusFlags, &blio->statusFlags );
+   
+   /* --- Handle Input Buffer --- */
+   if( blio->inChan ) {
+      avail = RingBuffer_GetWriteAvailable( &blio->inputRingBuffer );
+
+      /* check for underflow */
+      if( avail < frameCount * blio->inputSampleSize * blio->inChan )
+        // Mihai: replacing OSAtomic32 with BitOrAtomic
+         //OSAtomicOr32( paInputOverflow, &blio->statusFlags );
+         BitOrAtomic( paInputOverflow, &blio->statusFlags );
+
+      toRead = MIN( avail, frameCount * blio->inputSampleSize * blio->inChan );
+
+      /* copy the data */
+      /*printf( "reading %d\n", toRead );*/
+      assert( toRead == RingBuffer_Write( &blio->inputRingBuffer, input, toRead ) );
+#ifdef PA_MAC__BLIO_MUTEX
+      /* Priority inversion. See notes below. */
+      blioSetIsInputEmpty( blio, false );
+#endif
+   }
+
+
+   /* --- Handle Output Buffer --- */
+   if( blio->outChan ) {
+      avail = RingBuffer_GetReadAvailable( &blio->outputRingBuffer );
+
+      /* check for underflow */
+      if( avail < frameCount * blio->outputSampleSize * blio->outChan )
+         //Mihai: replacing OSAtomic32 with BitOrAtomic
+         //OSAtomicOr32( paOutputUnderflow, &blio->statusFlags );
+         BitOrAtomic( paOutputUnderflow, &blio->statusFlags );
+
+      toWrite = MIN( avail, frameCount * blio->outputSampleSize * blio->outChan );
+
+      if( toWrite != frameCount * blio->outputSampleSize * blio->outChan )
+         bzero( ((char *)output)+toWrite,
+                frameCount * blio->outputSampleSize * blio->outChan - toWrite );
+      /* copy the data */
+      /*printf( "writing %d\n", toWrite );*/
+      assert( toWrite == RingBuffer_Read( &blio->outputRingBuffer, output, toWrite ) );
+#ifdef PA_MAC__BLIO_MUTEX
+      /* We have a priority inversion here. However, we will only have to
+         wait if this was true and is now false, which means we've got
+         some room in the buffer.
+         Hopefully problems will be minimized. */
+      blioSetIsOutputFull( blio, false );
+#endif
+   }
+
+   return paContinue;
+}
+
+PaError ReadStream( PaStream* stream,
+                           void *buffer,
+                           unsigned long frames )
+{
+    PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio;
+    char *cbuf = (char *) buffer;
+    PaError ret = paNoError;
+    VVDBUG(("ReadStream()\n"));
+
+    while( frames > 0 ) {
+       long avail;
+       long toRead;
+       do {
+          avail = RingBuffer_GetReadAvailable( &blio->inputRingBuffer );
+/*
+          printf( "Read Buffer is %%%g full: %ld of %ld.\n",
+                  100 * (float)avail / (float) blio->inputRingBuffer.bufferSize,
+                  avail, blio->inputRingBuffer.bufferSize );
+*/
+          if( avail == 0 ) {
+#ifdef PA_MAC_BLIO_MUTEX
+             /**block when empty*/
+             ret = UNIX_ERR( pthread_mutex_lock( &blio->inputMutex ) );
+             if( ret )
+                return ret;
+             while( blio->isInputEmpty ) {
+                ret = UNIX_ERR( pthread_cond_wait( &blio->inputCond, &blio->inputMutex ) );
+                if( ret )
+                   return ret;
+             }
+             ret = UNIX_ERR( pthread_mutex_unlock( &blio->inputMutex ) );
+             if( ret )
+                return ret;
+#else
+             Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );
+#endif
+          }
+       } while( avail == 0 );
+       toRead = MIN( avail, frames * blio->inputSampleSize * blio->inChan );
+       toRead -= toRead % blio->inputSampleSize * blio->inChan ;
+       RingBuffer_Read( &blio->inputRingBuffer, (void *)cbuf, toRead );
+       cbuf += toRead;
+       frames -= toRead / ( blio->inputSampleSize * blio->inChan );
+
+       if( toRead == avail ) {
+#ifdef PA_MAC_BLIO_MUTEX
+          /* we just emptied the buffer, so we need to mark it as empty. */
+          ret = blioSetIsInputEmpty( blio, true );
+          if( ret )
+             return ret;
+          /* of course, in the meantime, the callback may have put some sats
+             in, so
+             so check for that, too, to avoid a race condition. */
+          if( RingBuffer_GetReadAvailable( &blio->inputRingBuffer ) ) {
+             blioSetIsInputEmpty( blio, false );
+             if( ret )
+                return ret;
+          }
+#endif
+       }
+    }
+
+    /*   Report either paNoError or paInputOverflowed. */
+    /*   may also want to report other errors, but this is non-standard. */
+    ret = blio->statusFlags & paInputOverflow;
+
+    /* report underflow only once: */
+    if( ret ) {
+       //Mihai: replacing OSAtomicAnd32 with BitAndAtomic
+       //OSAtomicAnd32( ~paInputOverflow, &blio->statusFlags );
+       BitAndAtomic( ~paInputOverflow, &blio->statusFlags );
+       ret = paInputOverflowed;
+    }
+
+    return ret;
+}
+
+
+PaError WriteStream( PaStream* stream,
+                            const void *buffer,
+                            unsigned long frames )
+{
+    PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio;
+    char *cbuf = (char *) buffer;
+    PaError ret = paNoError;
+    VVDBUG(("WriteStream()\n"));
+
+    while( frames > 0 ) {
+       long avail = 0;
+       long toWrite;
+
+       do {
+          avail = RingBuffer_GetWriteAvailable( &blio->outputRingBuffer );
+/*
+          printf( "Write Buffer is %%%g full: %ld of %ld.\n",
+                  100 - 100 * (float)avail / (float) blio->outputRingBuffer.bufferSize,
+                  avail, blio->outputRingBuffer.bufferSize );
+*/
+          if( avail == 0 ) {
+#ifdef PA_MAC_BLIO_MUTEX
+             /*block while full*/
+             ret = UNIX_ERR( pthread_mutex_lock( &blio->outputMutex ) );
+             if( ret )
+                return ret;
+             while( blio->isOutputFull ) {
+                ret = UNIX_ERR( pthread_cond_wait( &blio->outputCond, &blio->outputMutex ) );
+                if( ret )
+                   return ret;
+             }
+             ret = UNIX_ERR( pthread_mutex_unlock( &blio->outputMutex ) );
+             if( ret )
+                return ret;
+#else
+             Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );
+#endif
+          }
+       } while( avail == 0 );
+
+       toWrite = MIN( avail, frames * blio->outputSampleSize * blio->outChan );
+       toWrite -= toWrite % blio->outputSampleSize * blio->outChan ;
+       RingBuffer_Write( &blio->outputRingBuffer, (void *)cbuf, toWrite );
+       cbuf += toWrite;
+       frames -= toWrite / ( blio->outputSampleSize * blio->outChan );
+
+#ifdef PA_MAC_BLIO_MUTEX
+       if( toWrite == avail ) {
+          /* we just filled up the buffer, so we need to mark it as filled. */
+          ret = blioSetIsOutputFull( blio, true );
+          if( ret )
+             return ret;
+          /* of course, in the meantime, we may have emptied the buffer, so
+             so check for that, too, to avoid a race condition. */
+          if( RingBuffer_GetWriteAvailable( &blio->outputRingBuffer ) ) {
+             blioSetIsOutputFull( blio, false );
+             if( ret )
+                return ret;
+          }
+       }
+#endif
+    }
+
+    /*   Report either paNoError or paOutputUnderflowed. */
+    /*   may also want to report other errors, but this is non-standard. */
+    ret = blio->statusFlags & paOutputUnderflow;
+
+    /* report underflow only once: */
+    if( ret ) {
+       //Mihai: replacing OSAtomicAnd32 with BitAndAtomic
+       //OSAtomicAnd32( ~paOutputUnderflow, &blio->statusFlags );
+       BitAndAtomic( ~paOutputUnderflow, &blio->statusFlags );
+       ret = paOutputUnderflowed;
+    }
+
+    return ret;
+}
+
+/*
+ *
+ */
+void waitUntilBlioWriteBufferIsFlushed( PaMacBlio *blio )
+{
+    if( blio->outputRingBuffer.buffer ) {
+       long avail = RingBuffer_GetWriteAvailable( &blio->outputRingBuffer );
+       while( avail != blio->outputRingBuffer.bufferSize ) {
+          if( avail == 0 )
+             Pa_Sleep( PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL );
+          avail = RingBuffer_GetWriteAvailable( &blio->outputRingBuffer );
+       }
+    }
+}
+
+
+signed long GetStreamReadAvailable( PaStream* stream )
+{
+    PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio;
+    VVDBUG(("GetStreamReadAvailable()\n"));
+
+    return RingBuffer_GetReadAvailable( &blio->inputRingBuffer )
+                         / ( blio->outputSampleSize * blio->outChan );
+}
+
+
+signed long GetStreamWriteAvailable( PaStream* stream )
+{
+    PaMacBlio *blio = & ((PaMacCoreStream*)stream) -> blio;
+    VVDBUG(("GetStreamWriteAvailable()\n"));
+
+    return RingBuffer_GetWriteAvailable( &blio->outputRingBuffer )
+                         / ( blio->outputSampleSize * blio->outChan );
+}
+
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.h b/utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/pa_mac_core_blocking.h
new file mode 100644 (file)
index 0000000..657689c
--- /dev/null
@@ -0,0 +1,76 @@
+
+#ifndef PA_MAC_CORE_BLOCKING_H_
+#define PA_MAC_CORE_BLOCKING_H_
+
+#include "ringbuffer.h"
+#include "portaudio.h"
+#include "pa_mac_core_utilities.h"
+
+/*
+ * Number of miliseconds to busy wait whil waiting for data in blocking calls.
+ */
+#define PA_MAC_BLIO_BUSY_WAIT_SLEEP_INTERVAL (5)
+/*
+ * Define exactly one of these blocking methods
+ * PA_MAC_BLIO_MUTEX is not actively maintained.
+ */
+#define PA_MAC_BLIO_BUSY_WAIT
+/*
+#define PA_MAC_BLIO_MUTEX
+*/
+
+typedef struct {
+    RingBuffer inputRingBuffer;
+    RingBuffer outputRingBuffer;
+    PaSampleFormat inputSampleFormat;
+    size_t inputSampleSize;
+    PaSampleFormat outputSampleFormat;
+    size_t outputSampleSize;
+
+    size_t framesPerBuffer;
+
+    int inChan;
+    int outChan;
+
+    //PaStreamCallbackFlags statusFlags;
+    uint32_t statusFlags;
+    PaError errors;
+
+    /* Here we handle blocking, using condition variables. */
+#ifdef  PA_MAC_BLIO_MUTEX
+    volatile bool isInputEmpty;
+    pthread_mutex_t inputMutex;
+    pthread_cond_t inputCond;
+
+    volatile bool isOutputFull;
+    pthread_mutex_t outputMutex;
+    pthread_cond_t outputCond;
+#endif
+}
+PaMacBlio;
+
+/*
+ * These functions operate on condition and related variables.
+ */
+
+PaError initializeBlioRingBuffers(
+                                       PaMacBlio *blio,
+                                       PaSampleFormat inputSampleFormat,
+                                       PaSampleFormat outputSampleFormat,
+                                       size_t framesPerBuffer,
+                                       long ringBufferSize,
+                                       int inChan,
+                                       int outChan );
+PaError destroyBlioRingBuffers( PaMacBlio *blio );
+PaError resetBlioRingBuffers( PaMacBlio *blio );
+
+int BlioCallback(
+        const void *input, void *output,
+        unsigned long frameCount,
+        const PaStreamCallbackTimeInfo* timeInfo,
+        PaStreamCallbackFlags statusFlags,
+        void *userData );
+
+void waitUntilBlioWriteBufferIsFlushed( PaMacBlio *blio );
+
+#endif /*PA_MAC_CORE_BLOCKING_H_*/
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/pa_mac_core_internal.h b/utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/pa_mac_core_internal.h
new file mode 100644 (file)
index 0000000..5deb8ef
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * This is the AUHAL implementation of portaudio.
+ *
+ * Written by Bjorn Roche of XO Audio LLC, from PA skeleton code.
+ * Portions copied from code by Dominic Mazzoni (who wrote a HAL implementation)
+ *
+ * Dominic's code was based on code by Phil Burk, Darren Gibbs,
+ * Gord Peters, Stephane Letz, and Greg Pfiel.
+ *
+ * Bjorn Roche and XO Audio LLC reserve no rights to this code.
+ * The maintainers of PortAudio may redistribute and modify the code and
+ * licenses as they deam appropriate.
+ *
+ * The following people also deserve acknowledgements:
+ *
+ * Olivier Tristan for feedback and testing
+ * Glenn Zelniker and Z-Systems engineering for sponsoring the Blocking I/O
+ * interface.
+ * 
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2002 Ross Bencina, Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ @file pa_mac_core
+ @author Bjorn Roche
+ @brief AUHAL implementation of PortAudio
+*/
+
+#ifndef PA_MAC_CORE_INTERNAL_H__
+#define PA_MAC_CORE_INTERNAL_H__
+
+#include <AudioUnit/AudioUnit.h>
+#include <AudioToolbox/AudioToolbox.h>
+
+
+#include "portaudio.h"
+#include "pa_util.h"
+#include "pa_hostapi.h"
+#include "pa_stream.h"
+#include "pa_allocation.h"
+#include "pa_cpuload.h"
+#include "pa_process.h"
+#include "ringbuffer.h"
+
+#include "pa_mac_core_blocking.h"
+
+/* function prototypes */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#define RING_BUFFER_ADVANCE_DENOMINATOR (4)
+
+PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames );
+PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames );
+signed long GetStreamReadAvailable( PaStream* stream );
+signed long GetStreamWriteAvailable( PaStream* stream );
+/* PaMacAUHAL - host api datastructure specific to this implementation */
+typedef struct
+{
+    PaUtilHostApiRepresentation inheritedHostApiRep;
+    PaUtilStreamInterface callbackStreamInterface;
+    PaUtilStreamInterface blockingStreamInterface;
+
+    PaUtilAllocationGroup *allocations;
+
+    /* implementation specific data goes here */
+    long devCount;
+    AudioDeviceID *devIds; /*array of all audio devices*/
+    AudioDeviceID defaultIn;
+    AudioDeviceID defaultOut;
+}
+PaMacAUHAL;
+
+
+
+/* stream data structure specifically for this implementation */
+typedef struct PaMacCoreStream
+{
+    PaUtilStreamRepresentation streamRepresentation;
+    PaUtilCpuLoadMeasurer cpuLoadMeasurer;
+    PaUtilBufferProcessor bufferProcessor;
+
+    /* implementation specific data goes here */
+    bool bufferProcessorIsInitialized;
+    AudioUnit inputUnit;
+    AudioUnit outputUnit;
+    AudioDeviceID inputDevice;
+    AudioDeviceID outputDevice;
+    size_t userInChan;
+    size_t userOutChan;
+    size_t inputFramesPerBuffer;
+    size_t outputFramesPerBuffer;
+    PaMacBlio blio;
+    /* We use this ring buffer when input and out devs are different. */
+    RingBuffer inputRingBuffer;
+    /* We may need to do SR conversion on input. */
+    AudioConverterRef inputSRConverter;
+    /* We need to preallocate an inputBuffer for reading data. */
+    AudioBufferList inputAudioBufferList;
+    AudioTimeStamp startTime;
+    volatile PaStreamCallbackFlags xrunFlags;
+    volatile enum {
+       STOPPED          = 0, /* playback is completely stopped,
+                                and the user has called StopStream(). */
+       CALLBACK_STOPPED = 1, /* callback has requested stop,
+                                but user has not yet called StopStream(). */
+       STOPPING         = 2, /* The stream is in the process of closing.
+                                This state is just used internally;
+                                externally it is indistinguishable from
+                                ACTIVE.*/
+       ACTIVE           = 3  /* The stream is active and running. */
+    } state;
+    double sampleRate;
+}
+PaMacCoreStream;
+
+#endif /* PA_MAC_CORE_INTERNAL_H__ */
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/pa_mac_core_utilities.c b/utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/pa_mac_core_utilities.c
new file mode 100644 (file)
index 0000000..29c851d
--- /dev/null
@@ -0,0 +1,565 @@
+/*
+ *
+ * pa_mac_core_utilities.c
+ *
+ * utilitiy functions for pa_mac_core.c
+ *
+ * This functions are more like helper functions than part of the core,
+ *  so I moved them to a separate file so the core code would be cleaner.
+ *
+ * by Bjorn Roche.
+ */
+
+#include "pa_mac_core_utilities.h"
+
+PaError PaMacCore_SetUnixError( int err, int line )
+{
+   PaError ret;
+   const char *errorText;
+
+   if( err == 0 )
+   {
+      return paNoError;
+   }
+
+   ret = paNoError;
+   errorText = strerror( err );
+
+   /** Map Unix error to PaError. Pretty much the only one that maps
+       is ENOMEM. */
+   if( err == ENOMEM )
+      ret = paInsufficientMemory;
+   else
+      ret = paInternalError;
+
+   DBUG(("%d on line %d: msg='%s'\n", err, line, errorText));
+   PaUtil_SetLastHostErrorInfo( paCoreAudio, err, errorText );
+
+   return ret;
+}
+
+/*
+ * Translates MacOS generated errors into PaErrors
+ */
+PaError PaMacCore_SetError(OSStatus error, int line, int isError)
+{
+    /*FIXME: still need to handle possible ComponentResult values.*/
+    /*       unfortunately, they don't seem to be documented anywhere.*/
+    PaError result;
+    const char *errorType; 
+    const char *errorText;
+    
+    switch (error) {
+    case kAudioHardwareNoError:
+        return paNoError;
+    case kAudioHardwareNotRunningError:
+        errorText = "Audio Hardware Not Running";
+        result = paInternalError; break;
+    case kAudioHardwareUnspecifiedError: 
+        errorText = "Unspecified Audio Hardware Error";
+        result = paInternalError; break;
+    case kAudioHardwareUnknownPropertyError:
+        errorText = "Audio Hardware: Unknown Property";
+        result = paInternalError; break;
+    case kAudioHardwareBadPropertySizeError:
+        errorText = "Audio Hardware: Bad Property Size";
+        result = paInternalError; break;
+    case kAudioHardwareIllegalOperationError: 
+        errorText = "Audio Hardware: Illegal Operation";
+        result = paInternalError; break;
+    case kAudioHardwareBadDeviceError:
+        errorText = "Audio Hardware: Bad Device";
+        result = paInvalidDevice; break;
+    case kAudioHardwareBadStreamError:
+        errorText = "Audio Hardware: BadStream";
+        result = paBadStreamPtr; break;
+    case kAudioHardwareUnsupportedOperationError:
+        errorText = "Audio Hardware: Unsupported Operation";
+        result = paInternalError; break;
+    case kAudioDeviceUnsupportedFormatError:
+        errorText = "Audio Device: Unsupported Format";
+        result = paSampleFormatNotSupported; break;
+    case kAudioDevicePermissionsError:
+        errorText = "Audio Device: Permissions Error";
+        result = paDeviceUnavailable; break;
+    /* Audio Unit Errors: http://developer.apple.com/documentation/MusicAudio/Reference/CoreAudio/audio_units/chapter_5_section_3.html */
+    case kAudioUnitErr_InvalidProperty:
+        errorText = "Audio Unit: Invalid Property";
+        result = paInternalError; break;
+    case kAudioUnitErr_InvalidParameter:
+        errorText = "Audio Unit: Invalid Parameter";
+        result = paInternalError; break;
+    case kAudioUnitErr_NoConnection:
+        errorText = "Audio Unit: No Connection";
+        result = paInternalError; break;
+    case kAudioUnitErr_FailedInitialization:
+        errorText = "Audio Unit: Initialization Failed";
+        result = paInternalError; break;
+    case kAudioUnitErr_TooManyFramesToProcess:
+        errorText = "Audio Unit: Too Many Frames";
+        result = paInternalError; break;
+    case kAudioUnitErr_IllegalInstrument:
+        errorText = "Audio Unit: Illegal Instrument";
+        result = paInternalError; break;
+    case kAudioUnitErr_InstrumentTypeNotFound:
+        errorText = "Audio Unit: Instrument Type Not Found";
+        result = paInternalError; break;
+    case kAudioUnitErr_InvalidFile:
+        errorText = "Audio Unit: Invalid File";
+        result = paInternalError; break;
+    case kAudioUnitErr_UnknownFileType:
+        errorText = "Audio Unit: Unknown File Type";
+        result = paInternalError; break;
+    case kAudioUnitErr_FileNotSpecified:
+        errorText = "Audio Unit: File Not Specified";
+        result = paInternalError; break;
+    case kAudioUnitErr_FormatNotSupported:
+        errorText = "Audio Unit: Format Not Supported";
+        result = paInternalError; break;
+    case kAudioUnitErr_Uninitialized:
+        errorText = "Audio Unit: Unitialized";
+        result = paInternalError; break;
+    case kAudioUnitErr_InvalidScope:
+        errorText = "Audio Unit: Invalid Scope";
+        result = paInternalError; break;
+    case kAudioUnitErr_PropertyNotWritable:
+        errorText = "Audio Unit: PropertyNotWritable";
+        result = paInternalError; break;
+    case kAudioUnitErr_InvalidPropertyValue:
+        errorText = "Audio Unit: Invalid Property Value";
+        result = paInternalError; break;
+    case kAudioUnitErr_PropertyNotInUse:
+        errorText = "Audio Unit: Property Not In Use";
+        result = paInternalError; break;
+    case kAudioUnitErr_Initialized:
+        errorText = "Audio Unit: Initialized";
+        result = paInternalError; break;
+    case kAudioUnitErr_InvalidOfflineRender:
+        errorText = "Audio Unit: Invalid Offline Render";
+        result = paInternalError; break;
+    case kAudioUnitErr_Unauthorized:
+        errorText = "Audio Unit: Unauthorized";
+        result = paInternalError; break;
+    case kAudioUnitErr_CannotDoInCurrentContext:
+        errorText = "Audio Unit: cannot do in current context";
+        result = paInternalError; break;
+    default:
+        errorText = "Unknown Error";
+        result = paInternalError;
+    }
+
+    if (isError)
+        errorType = "Error";
+    else
+        errorType = "Warning";
+
+    if ((int)error < -99999 || (int)error > 99999)
+        DBUG(("%s on line %d: err='%4s', msg='%s'\n", errorType, line, (const char *)&error, errorText));
+    else
+        DBUG(("%s on line %d: err=%d, 0x%x, msg='%s'\n", errorType, line, (int)error, (unsigned)error, errorText));
+
+    PaUtil_SetLastHostErrorInfo( paCoreAudio, error, errorText );
+
+    return result;
+}
+
+/*
+ * This function computes an appropriate ring buffer size given
+ * a requested latency (in seconds), sample rate and framesPerBuffer.
+ *
+ * The returned ringBufferSize is computed using the following
+ * constraints:
+ *   - it must be at least 4.
+ *   - it must be at least 3x framesPerBuffer.
+ *   - it must be at least 2x the suggestedLatency.
+ *   - it must be a power of 2.
+ * This function attempts to compute the minimum such size.
+ *
+ * FEEDBACK: too liberal/conservative/another way?
+ */
+long computeRingBufferSize( const PaStreamParameters *inputParameters,
+                                   const PaStreamParameters *outputParameters,
+                                   long inputFramesPerBuffer,
+                                   long outputFramesPerBuffer,
+                                   double sampleRate )
+{
+   long ringSize;
+   int index;
+   int i;
+   double latencyTimesChannelCount ;
+   long framesPerBufferTimesChannelCount ;
+
+   VVDBUG(( "computeRingBufferSize()\n" ));
+
+   assert( inputParameters || outputParameters );
+
+   if( outputParameters && inputParameters )
+   {
+      latencyTimesChannelCount = MAX(
+           inputParameters->suggestedLatency * inputParameters->channelCount,
+           outputParameters->suggestedLatency * outputParameters->channelCount );
+      framesPerBufferTimesChannelCount = MAX(
+           inputFramesPerBuffer * inputParameters->channelCount,
+           outputFramesPerBuffer * outputParameters->channelCount );
+   } 
+   else if( outputParameters )
+   {
+      latencyTimesChannelCount
+                = outputParameters->suggestedLatency * outputParameters->channelCount;
+      framesPerBufferTimesChannelCount
+                = outputFramesPerBuffer * outputParameters->channelCount;
+   }
+   else /* we have inputParameters  */
+   {
+      latencyTimesChannelCount
+                = inputParameters->suggestedLatency * inputParameters->channelCount;
+      framesPerBufferTimesChannelCount
+                = inputFramesPerBuffer * inputParameters->channelCount;
+   }
+
+   ringSize = (long) ( latencyTimesChannelCount * sampleRate * 2 + .5);
+   VDBUG( ( "suggested latency * channelCount: %d\n", (int) (latencyTimesChannelCount*sampleRate) ) );
+   if( ringSize < framesPerBufferTimesChannelCount * 3 )
+      ringSize = framesPerBufferTimesChannelCount * 3 ;
+   VDBUG(("framesPerBuffer*channelCount:%d\n",(int)framesPerBufferTimesChannelCount));
+   VDBUG(("Ringbuffer size (1): %d\n", (int)ringSize ));
+
+   /* make sure it's at least 4 */
+   ringSize = MAX( ringSize, 4 );
+
+   /* round up to the next power of 2 */
+   index = -1;
+   for( i=0; i<sizeof(long)*8; ++i )
+      if( ringSize >> i & 0x01 )
+         index = i;
+   assert( index > 0 );
+   if( ringSize <= ( 0x01 << index ) )
+      ringSize = 0x01 << index ;
+   else
+      ringSize = 0x01 << ( index + 1 );
+
+   VDBUG(( "Final Ringbuffer size (2): %d\n", (int)ringSize ));
+   return ringSize;
+}
+
+
+/*
+ * Durring testing of core audio, I found that serious crashes could occur
+ * if properties such as sample rate were changed multiple times in rapid
+ * succession. The function below has some fancy logic to make sure that changes
+ * are acknowledged before another is requested. That seems to help a lot.
+ */
+
+OSStatus propertyProc(
+    AudioDeviceID inDevice, 
+    UInt32 inChannel, 
+    Boolean isInput, 
+    AudioDevicePropertyID inPropertyID, 
+    void* inClientData )
+{
+   MutexAndBool *mab = (MutexAndBool *) inClientData;
+   mab->once = TRUE;
+   pthread_mutex_unlock( &(mab->mutex) );
+   return noErr;
+}
+
+/* sets the value of the given property and waits for the change to 
+   be acknowledged, and returns the final value, which is not guaranteed
+   by this function to be the same as the desired value. Obviously, this
+   function can only be used for data whose input and output are the
+   same size and format, and their size and format are known in advance.*/
+PaError AudioDeviceSetPropertyNowAndWaitForChange(
+    AudioDeviceID inDevice,
+    UInt32 inChannel, 
+    Boolean isInput, 
+    AudioDevicePropertyID inPropertyID,
+    UInt32 inPropertyDataSize, 
+    const void *inPropertyData,
+    void *outPropertyData )
+{
+   OSStatus macErr;
+   int unixErr;
+   MutexAndBool mab;
+   UInt32 outPropertyDataSize = inPropertyDataSize;
+
+   /* First, see if it already has that value. If so, return. */
+   macErr = AudioDeviceGetProperty( inDevice, inChannel,
+                                 isInput, inPropertyID, 
+                                 &outPropertyDataSize, outPropertyData );
+   if( macErr )
+      goto failMac2;
+   if( inPropertyDataSize!=outPropertyDataSize )
+      return paInternalError;
+   if( 0==memcmp( outPropertyData, inPropertyData, outPropertyDataSize ) )
+      return paNoError;
+
+   /* setup and lock mutex */
+   mab.once = FALSE;
+   unixErr = pthread_mutex_init( &mab.mutex, NULL );
+   if( unixErr )
+      goto failUnix2;
+   unixErr = pthread_mutex_lock( &mab.mutex );
+   if( unixErr )
+      goto failUnix;
+
+   /* add property listener */
+   macErr = AudioDeviceAddPropertyListener( inDevice, inChannel, isInput,
+                                   inPropertyID, propertyProc,
+                                   &mab ); 
+   if( macErr )
+      goto failMac;
+   /* set property */
+   macErr  = AudioDeviceSetProperty( inDevice, NULL, inChannel,
+                                 isInput, inPropertyID,
+                                 inPropertyDataSize, inPropertyData );
+   if( macErr ) {
+      /* we couldn't set the property, so we'll just unlock the mutex
+         and move on. */
+      pthread_mutex_unlock( &mab.mutex );
+   }
+
+   /* wait for property to change */                      
+   unixErr = pthread_mutex_lock( &mab.mutex );
+   if( unixErr )
+      goto failUnix;
+
+   /* now read the property back out */
+   macErr = AudioDeviceGetProperty( inDevice, inChannel,
+                                 isInput, inPropertyID, 
+                                 &outPropertyDataSize, outPropertyData );
+   if( macErr )
+      goto failMac;
+   /* cleanup */
+   AudioDeviceRemovePropertyListener( inDevice, inChannel, isInput,
+                                      inPropertyID, propertyProc );
+   unixErr = pthread_mutex_unlock( &mab.mutex );
+   if( unixErr )
+      goto failUnix2;
+   unixErr = pthread_mutex_destroy( &mab.mutex );
+   if( unixErr )
+      goto failUnix2;
+
+   return paNoError;
+
+ failUnix:
+   pthread_mutex_destroy( &mab.mutex );
+   AudioDeviceRemovePropertyListener( inDevice, inChannel, isInput,
+                                      inPropertyID, propertyProc );
+
+ failUnix2:
+   DBUG( ("Error #%d while setting a device property: %s\n", unixErr, strerror( unixErr ) ) );
+   return paUnanticipatedHostError;
+
+ failMac:
+   pthread_mutex_destroy( &mab.mutex );
+   AudioDeviceRemovePropertyListener( inDevice, inChannel, isInput,
+                                      inPropertyID, propertyProc );
+ failMac2:
+   return ERR( macErr );
+}
+
+/*
+ * Sets the sample rate the HAL device.
+ * if requireExact: set the sample rate or fail.
+ *
+ * otherwise      : set the exact sample rate.
+ *             If that fails, check for available sample rates, and choose one
+ *             higher than the requested rate. If there isn't a higher one,
+ *             just use the highest available.
+ */
+PaError setBestSampleRateForDevice( const AudioDeviceID device,
+                                    const bool isOutput,
+                                    const bool requireExact,
+                                    const Float64 desiredSrate )
+{
+   /*FIXME: changing the sample rate is disruptive to other programs using the
+            device, so it might be good to offer a custom flag to not change the
+            sample rate and just do conversion. (in my casual tests, there is
+            no disruption unless the sample rate really does need to change) */
+   const bool isInput = isOutput ? 0 : 1;
+   Float64 srate;
+   UInt32 propsize = sizeof( Float64 );
+   OSErr err;
+   AudioValueRange *ranges;
+   int i=0;
+   Float64 max  = -1; /*the maximum rate available*/
+   Float64 best = -1; /*the lowest sample rate still greater than desired rate*/
+   VDBUG(("Setting sample rate for device %ld to %g.\n",device,(float)desiredSrate));
+
+   /* -- try setting the sample rate -- */
+   err = AudioDeviceSetPropertyNowAndWaitForChange(
+                                 device, 0, isInput,
+                                 kAudioDevicePropertyNominalSampleRate,
+                                 propsize, &desiredSrate, &srate );
+   if( err )
+      return err;
+
+   /* -- if the rate agrees, and we got no errors, we are done -- */
+   if( !err && srate == desiredSrate )
+      return paNoError;
+   /* -- we've failed if the rates disagree and we are setting input -- */
+   if( requireExact )
+      return paInvalidSampleRate;
+
+   /* -- generate a list of available sample rates -- */
+   err = AudioDeviceGetPropertyInfo( device, 0, isInput,
+                                kAudioDevicePropertyAvailableNominalSampleRates,
+                                &propsize, NULL );
+   if( err )
+      return ERR( err );
+   ranges = (AudioValueRange *)calloc( 1, propsize );
+   if( !ranges )
+      return paInsufficientMemory;
+   err = AudioDeviceGetProperty( device, 0, isInput,
+                                kAudioDevicePropertyAvailableNominalSampleRates,
+                                &propsize, ranges );
+   if( err )
+   {
+      free( ranges );
+      return ERR( err );
+   }
+   VDBUG(("Requested sample rate of %g was not available.\n", (float)desiredSrate));
+   VDBUG(("%lu Available Sample Rates are:\n",propsize/sizeof(AudioValueRange)));
+#ifdef MAC_CORE_VERBOSE_DEBUG
+   for( i=0; i<propsize/sizeof(AudioValueRange); ++i )
+      VDBUG( ("\t%g-%g\n",
+              (float) ranges[i].mMinimum,
+              (float) ranges[i].mMaximum ) );
+#endif
+   VDBUG(("-----\n"));
+   
+   /* -- now pick the best available sample rate -- */
+   for( i=0; i<propsize/sizeof(AudioValueRange); ++i )
+   {
+      if( ranges[i].mMaximum > max ) max = ranges[i].mMaximum;
+      if( ranges[i].mMinimum > desiredSrate ) {
+         if( best < 0 )
+            best = ranges[i].mMinimum;
+         else if( ranges[i].mMinimum < best )
+            best = ranges[i].mMinimum;
+      }
+   }
+   if( best < 0 )
+      best = max;
+   VDBUG( ("Maximum Rate %g. best is %g.\n", max, best ) );
+   free( ranges );
+
+   /* -- set the sample rate -- */
+   propsize = sizeof( best );
+   err = AudioDeviceSetPropertyNowAndWaitForChange(
+                                 device, 0, isInput,
+                                 kAudioDevicePropertyNominalSampleRate,
+                                 propsize, &best, &srate );
+   if( err )
+      return err;
+
+   if( err )
+      return ERR( err );
+   /* -- if the set rate matches, we are done -- */
+   if( srate == best )
+      return paNoError;
+
+   /* -- otherwise, something wierd happened: we didn't set the rate, and we got no errors. Just bail. */
+   return paInternalError;
+}
+
+
+/*
+   Attempts to set the requestedFramesPerBuffer. If it can't set the exact
+   value, it settles for something smaller if available. If nothing smaller
+   is available, it uses the smallest available size.
+   actualFramesPerBuffer will be set to the actual value on successful return.
+   OK to pass NULL to actualFramesPerBuffer.
+   The logic is very simmilar too setBestSampleRate only failure here is
+   not usually catastrophic.
+*/
+PaError setBestFramesPerBuffer( const AudioDeviceID device,
+                                       const bool isOutput,
+                                       unsigned long requestedFramesPerBuffer, 
+                                       unsigned long *actualFramesPerBuffer )
+{
+   UInt32 afpb;
+   const bool isInput = !isOutput;
+   UInt32 propsize = sizeof(UInt32);
+   OSErr err;
+   Float64 min  = -1; /*the min blocksize*/
+   Float64 best = -1; /*the best blocksize*/
+   int i=0;
+   AudioValueRange *ranges;
+
+   if( actualFramesPerBuffer == NULL )
+      actualFramesPerBuffer = &afpb;
+
+
+   /* -- try and set exact FPB -- */
+   err = AudioDeviceSetProperty( device, NULL, 0, isInput,
+                                 kAudioDevicePropertyBufferFrameSize,
+                                 propsize, &requestedFramesPerBuffer);
+   err = AudioDeviceGetProperty( device, 0, isInput,
+                           kAudioDevicePropertyBufferFrameSize,
+                           &propsize, actualFramesPerBuffer);
+   if( err )
+      return ERR( err );
+   if( *actualFramesPerBuffer == requestedFramesPerBuffer )
+      return paNoError; /* we are done */
+
+   /* -- fetch available block sizes -- */
+   err = AudioDeviceGetPropertyInfo( device, 0, isInput,
+                           kAudioDevicePropertyBufferSizeRange,
+                           &propsize, NULL );
+   if( err )
+      return ERR( err );
+   ranges = (AudioValueRange *)calloc( 1, propsize );
+   if( !ranges )
+      return paInsufficientMemory;
+   err = AudioDeviceGetProperty( device, 0, isInput,
+                                kAudioDevicePropertyBufferSizeRange,
+                                &propsize, ranges );
+   if( err )
+   {
+      free( ranges );
+      return ERR( err );
+   }
+   VDBUG(("Requested block size of %lu was not available.\n",
+          requestedFramesPerBuffer ));
+   VDBUG(("%lu Available block sizes are:\n",propsize/sizeof(AudioValueRange)));
+#ifdef MAC_CORE_VERBOSE_DEBUG
+   for( i=0; i<propsize/sizeof(AudioValueRange); ++i )
+      VDBUG( ("\t%g-%g\n",
+              (float) ranges[i].mMinimum,
+              (float) ranges[i].mMaximum ) );
+#endif
+   VDBUG(("-----\n"));
+   
+   /* --- now pick the best available framesPerBuffer -- */
+   for( i=0; i<propsize/sizeof(AudioValueRange); ++i )
+   {
+      if( min == -1 || ranges[i].mMinimum < min ) min = ranges[i].mMinimum;
+      if( ranges[i].mMaximum < requestedFramesPerBuffer ) {
+         if( best < 0 )
+            best = ranges[i].mMaximum;
+         else if( ranges[i].mMaximum > best )
+            best = ranges[i].mMaximum;
+      }
+   }
+   if( best == -1 )
+      best = min;
+   VDBUG( ("Minimum FPB  %g. best is %g.\n", min, best ) );
+   free( ranges );
+
+   /* --- set the buffer size (ignore errors) -- */
+   requestedFramesPerBuffer = (UInt32) best ;
+   propsize = sizeof( UInt32 );
+   err = AudioDeviceSetProperty( device, NULL, 0, isInput,
+                                 kAudioDevicePropertyBufferSize,
+                                 propsize, &requestedFramesPerBuffer );
+   /* --- read the property to check that it was set -- */
+   err = AudioDeviceGetProperty( device, 0, isInput,
+                                 kAudioDevicePropertyBufferSize,
+                                 &propsize, actualFramesPerBuffer );
+
+   if( err )
+      return ERR( err );
+
+   return paNoError;
+}
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/pa_mac_core_utilities.h b/utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/pa_mac_core_utilities.h
new file mode 100644 (file)
index 0000000..7f1e162
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+ *
+ * pa_mac_core_utilities.c
+ *
+ * utilitiy functions for pa_mac_core.c
+ *
+ * This functions are more like helper functions than part of the core,
+ *  so I moved them to a separate file so the core code would be cleaner.
+ *
+ * by Bjorn Roche.
+ */
+
+#ifndef PA_MAC_CORE_UTILITIES_H__
+#define PA_MAC_CORE_UTILITIES_H__
+
+#include <pthread.h>
+#include "portaudio.h"
+#include "pa_util.h"
+#include <AudioUnit/AudioUnit.h>
+#include <AudioToolbox/AudioToolbox.h>
+
+#ifndef MIN
+#define MIN(a, b)  (((a)<(b))?(a):(b))
+#endif
+
+#ifndef MAX
+#define MAX(a, b)  (((a)<(b))?(b):(a))
+#endif
+
+#define ERR(mac_error) PaMacCore_SetError(mac_error, __LINE__, 1 ) 
+#define WARNING(mac_error) PaMacCore_SetError(mac_error, __LINE__, 0 )
+
+
+/* Help keep track of AUHAL element numbers */
+#define INPUT_ELEMENT  (1)
+#define OUTPUT_ELEMENT (0)
+
+/* Normal level of debugging: fine for most apps that don't mind the occational warning being printf'ed */
+/*
+ */
+#define MAC_CORE_DEBUG
+#ifdef MAC_CORE_DEBUG
+# define DBUG(MSG) do { printf("||PaMacCore (AUHAL)|| "); printf MSG ; fflush(stdout); } while(0)
+#else
+# define DBUG(MSG)
+#endif
+
+/* Verbose Debugging: useful for developement */
+/*
+#define MAC_CORE_VERBOSE_DEBUG
+*/
+#ifdef MAC_CORE_VERBOSE_DEBUG
+# define VDBUG(MSG) do { printf("||PaMacCore (v )|| "); printf MSG ; fflush(stdout); } while(0)
+#else
+# define VDBUG(MSG)
+#endif
+
+/* Very Verbose Debugging: Traces every call. */
+/*
+#define MAC_CORE_VERY_VERBOSE_DEBUG
+ */
+#ifdef MAC_CORE_VERY_VERBOSE_DEBUG
+# define VVDBUG(MSG) do { printf("||PaMacCore (vv)|| "); printf MSG ; fflush(stdout); } while(0)
+#else
+# define VVDBUG(MSG)
+#endif
+
+
+
+
+
+#define UNIX_ERR(err) PaMacCore_SetUnixError( err, __LINE__ )
+
+PaError PaMacCore_SetUnixError( int err, int line );
+
+/*
+ * Translates MacOS generated errors into PaErrors
+ */
+PaError PaMacCore_SetError(OSStatus error, int line, int isError);
+
+/*
+ * This function computes an appropriate ring buffer size given
+ * a requested latency (in seconds), sample rate and framesPerBuffer.
+ *
+ * The returned ringBufferSize is computed using the following
+ * constraints:
+ *   - it must be at least 4.
+ *   - it must be at least 3x framesPerBuffer.
+ *   - it must be at least 2x the suggestedLatency.
+ *   - it must be a power of 2.
+ * This function attempts to compute the minimum such size.
+ *
+ */
+long computeRingBufferSize( const PaStreamParameters *inputParameters,
+                                   const PaStreamParameters *outputParameters,
+                                   long inputFramesPerBuffer,
+                                   long outputFramesPerBuffer,
+                                   double sampleRate );
+
+/*
+ * Durring testing of core audio, I found that serious crashes could occur
+ * if properties such as sample rate were changed multiple times in rapid
+ * succession. The function below has some fancy logic to make sure that changes
+ * are acknowledged before another is requested. That seems to help a lot.
+ */
+
+typedef struct {
+   bool once; /* I didn't end up using this. bdr */
+   pthread_mutex_t mutex;
+} MutexAndBool ;
+
+OSStatus propertyProc(
+    AudioDeviceID inDevice, 
+    UInt32 inChannel, 
+    Boolean isInput, 
+    AudioDevicePropertyID inPropertyID, 
+    void* inClientData );
+
+/* sets the value of the given property and waits for the change to 
+   be acknowledged, and returns the final value, which is not guaranteed
+   by this function to be the same as the desired value. Obviously, this
+   function can only be used for data whose input and output are the
+   same size and format, and their size and format are known in advance.*/
+PaError AudioDeviceSetPropertyNowAndWaitForChange(
+    AudioDeviceID inDevice,
+    UInt32 inChannel, 
+    Boolean isInput, 
+    AudioDevicePropertyID inPropertyID,
+    UInt32 inPropertyDataSize, 
+    const void *inPropertyData,
+    void *outPropertyData );
+
+/*
+ * Sets the sample rate the HAL device.
+ * if requireExact: set the sample rate or fail.
+ *
+ * otherwise      : set the exact sample rate.
+ *             If that fails, check for available sample rates, and choose one
+ *             higher than the requested rate. If there isn't a higher one,
+ *             just use the highest available.
+ */
+PaError setBestSampleRateForDevice( const AudioDeviceID device,
+                                    const bool isOutput,
+                                    const bool requireExact,
+                                    const Float64 desiredSrate );
+/*
+   Attempts to set the requestedFramesPerBuffer. If it can't set the exact
+   value, it settles for something smaller if available. If nothing smaller
+   is available, it uses the smallest available size.
+   actualFramesPerBuffer will be set to the actual value on successful return.
+   OK to pass NULL to actualFramesPerBuffer.
+   The logic is very simmilar too setBestSampleRate only failure here is
+   not usually catastrophic.
+*/
+PaError setBestFramesPerBuffer( const AudioDeviceID device,
+                                       const bool isOutput,
+                                       unsigned long requestedFramesPerBuffer, 
+                                       unsigned long *actualFramesPerBuffer );
+#endif /* PA_MAC_CORE_UTILITIES_H__*/
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/ringbuffer.c b/utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/ringbuffer.c
new file mode 100644 (file)
index 0000000..5d787ff
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * $Id: ringbuffer.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * ringbuffer.c
+ * Ring Buffer utility..
+ *
+ * Author: Phil Burk, http://www.softsynth.com
+ * modified for SMP safety on Mac OS X by Bjorn Roche
+ * also, alowed for const where possible
+ * Note that this is safe only for a single-thread reader and a
+ * single-thread writer.
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "ringbuffer.h"
+#include <string.h>
+
+/*
+ * We can undefine this, to turn off memory barriers, but that
+ * is only useful if we know we don't need to be MP safe or
+ * we are interested in doing some kind of tests.
+ */
+#define MPSAFE
+
+/****************
+ * First, we'll define some memory barrier primitives based on the system.
+ * right now only OS X and FreeBSD are supported. In addition to providing
+ * memory barriers, these functions should ensure that data cached in registers
+ * is written out to cache where it can be snooped by other CPUs. (ie, the volatile
+ * keyword should not be required)
+ *
+ * the primitives that must be defined are:
+ *
+ * FullMemoryBarrier()
+ * ReadMemoryBarrier()
+ * WriteMemoryBarrier()
+ *
+ ****************/
+
+#if defined(__APPLE__) || defined(__FreeBSD__)
+//#   include <libkern/OSAtomic.h>
+    /* Here are the memory barrier functions. Mac OS X and FreeBSD only provide
+       full memory barriers, so the three types of barriers are the same.
+       The asm volatile may be redundant with the memory barrier, but
+       until I have proof of that, I'm leaving it. */
+/* Mihai: trying to compile without assembly, since gcc barfs on asm statements for some reason
+#   define FullMemoryBarrier()  do{ asm volatile("":::"memory"); OSMemoryBarrier(); }while(false)
+#   define ReadMemoryBarrier()  do{ asm volatile("":::"memory"); OSMemoryBarrier(); }while(false)
+#   define WriteMemoryBarrier() do{ asm volatile("":::"memory"); OSMemoryBarrier(); }while(false)
+
+#   define FullMemoryBarrier()  do{ OSMemoryBarrier(); }while(false)
+#   define ReadMemoryBarrier()  do{ OSMemoryBarrier(); }while(false)
+#   define WriteMemoryBarrier() do{ OSMemoryBarrier(); }while(false)
+*/
+
+/* 
+ * Mihai: OSMemoryBarrier is not available on 10.3.9 and I am not able to find a replacement
+ * As far as I can tell, not having synchronized memory acces will hurt only MP machines, and
+ * more specifically only weakly ordered memory models architectures (i.e. PowerPC).  In case
+ * this code runs on a MP PPC machine, worst I can see happening is a corruption of the sound
+ * buffer, which will lead to crappy sound, but not much more. 
+ * If anybody finds a 10.3.9 replacement for OSMemoryBarrier, I'd be glad to hear about it
+ */ 
+#define FullMemoryBarrier() 
+#define ReadMemoryBarrier()
+#define WriteMemoryBarrier()
+
+#else
+#   error Memory Barriers not defined on this system or system unknown
+#endif
+
+/***************************************************************************
+ * Initialize FIFO.
+ * numBytes must be power of 2, returns -1 if not.
+ */
+long RingBuffer_Init( RingBuffer *rbuf, long numBytes, void *dataPtr )
+{
+    if( ((numBytes-1) & numBytes) != 0) return -1; /* Not Power of two. */
+    rbuf->bufferSize = numBytes;
+    rbuf->buffer = (char *)dataPtr;
+    RingBuffer_Flush( rbuf );
+    rbuf->bigMask = (numBytes*2)-1;
+    rbuf->smallMask = (numBytes)-1;
+    return 0;
+}
+/***************************************************************************
+** Return number of bytes available for reading. */
+long RingBuffer_GetReadAvailable( RingBuffer *rbuf )
+{
+#ifdef MPSAFE
+    ReadMemoryBarrier();
+#endif
+    return ( (rbuf->writeIndex - rbuf->readIndex) & rbuf->bigMask );
+}
+/***************************************************************************
+** Return number of bytes available for writing. */
+long RingBuffer_GetWriteAvailable( RingBuffer *rbuf )
+{
+    /* Since we are calling RingBuffer_GetReadAvailable, we don't need an aditional MB */
+    return ( rbuf->bufferSize - RingBuffer_GetReadAvailable(rbuf));
+}
+
+/***************************************************************************
+** Clear buffer. Should only be called when buffer is NOT being read. */
+void RingBuffer_Flush( RingBuffer *rbuf )
+{
+    rbuf->writeIndex = rbuf->readIndex = 0;
+}
+
+/***************************************************************************
+** Get address of region(s) to which we can write data.
+** If the region is contiguous, size2 will be zero.
+** If non-contiguous, size2 will be the size of second region.
+** Returns room available to be written or numBytes, whichever is smaller.
+*/
+long RingBuffer_GetWriteRegions( RingBuffer *rbuf, long numBytes,
+                                 void **dataPtr1, long *sizePtr1,
+                                 void **dataPtr2, long *sizePtr2 )
+{
+    long   index;
+    long   available = RingBuffer_GetWriteAvailable( rbuf );
+    if( numBytes > available ) numBytes = available;
+    /* Check to see if write is not contiguous. */
+    index = rbuf->writeIndex & rbuf->smallMask;
+    if( (index + numBytes) > rbuf->bufferSize )
+    {
+        /* Write data in two blocks that wrap the buffer. */
+        long   firstHalf = rbuf->bufferSize - index;
+        *dataPtr1 = &rbuf->buffer[index];
+        *sizePtr1 = firstHalf;
+        *dataPtr2 = &rbuf->buffer[0];
+        *sizePtr2 = numBytes - firstHalf;
+    }
+    else
+    {
+        *dataPtr1 = &rbuf->buffer[index];
+        *sizePtr1 = numBytes;
+        *dataPtr2 = NULL;
+        *sizePtr2 = 0;
+    }
+    return numBytes;
+}
+
+
+/***************************************************************************
+*/
+long RingBuffer_AdvanceWriteIndex( RingBuffer *rbuf, long numBytes )
+{
+#ifdef MPSAFE
+    /* we need to ensure that previous writes are seen before we update the write index */
+    WriteMemoryBarrier();
+    return rbuf->writeIndex = (rbuf->writeIndex + numBytes) & rbuf->bigMask;
+#else
+    return rbuf->writeIndex = (rbuf->writeIndex + numBytes) & rbuf->bigMask;
+#endif
+}
+
+/***************************************************************************
+** Get address of region(s) from which we can read data.
+** If the region is contiguous, size2 will be zero.
+** If non-contiguous, size2 will be the size of second region.
+** Returns room available to be written or numBytes, whichever is smaller.
+*/
+long RingBuffer_GetReadRegions( RingBuffer *rbuf, long numBytes,
+                                void **dataPtr1, long *sizePtr1,
+                                void **dataPtr2, long *sizePtr2 )
+{
+    long   index;
+    long   available = RingBuffer_GetReadAvailable( rbuf );
+    if( numBytes > available ) numBytes = available;
+    /* Check to see if read is not contiguous. */
+    index = rbuf->readIndex & rbuf->smallMask;
+    if( (index + numBytes) > rbuf->bufferSize )
+    {
+        /* Write data in two blocks that wrap the buffer. */
+        long firstHalf = rbuf->bufferSize - index;
+        *dataPtr1 = &rbuf->buffer[index];
+        *sizePtr1 = firstHalf;
+        *dataPtr2 = &rbuf->buffer[0];
+        *sizePtr2 = numBytes - firstHalf;
+    }
+    else
+    {
+        *dataPtr1 = &rbuf->buffer[index];
+        *sizePtr1 = numBytes;
+        *dataPtr2 = NULL;
+        *sizePtr2 = 0;
+    }
+    return numBytes;
+}
+/***************************************************************************
+*/
+long RingBuffer_AdvanceReadIndex( RingBuffer *rbuf, long numBytes )
+{
+#ifdef MPSAFE
+    /* we need to ensure that previous writes are always seen before updating the index. */
+    WriteMemoryBarrier();
+    return rbuf->readIndex = (rbuf->readIndex + numBytes) & rbuf->bigMask;
+#else
+    return rbuf->readIndex = (rbuf->readIndex + numBytes) & rbuf->bigMask;
+#endif
+}
+
+/***************************************************************************
+** Return bytes written. */
+long RingBuffer_Write( RingBuffer *rbuf, const void *data, long numBytes )
+{
+    long size1, size2, numWritten;
+    void *data1, *data2;
+    numWritten = RingBuffer_GetWriteRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 );
+    if( size2 > 0 )
+    {
+
+        memcpy( data1, data, size1 );
+        data = ((char *)data) + size1;
+        memcpy( data2, data, size2 );
+    }
+    else
+    {
+        memcpy( data1, data, size1 );
+    }
+    RingBuffer_AdvanceWriteIndex( rbuf, numWritten );
+    return numWritten;
+}
+
+/***************************************************************************
+** Return bytes read. */
+long RingBuffer_Read( RingBuffer *rbuf, void *data, long numBytes )
+{
+    long size1, size2, numRead;
+    void *data1, *data2;
+    numRead = RingBuffer_GetReadRegions( rbuf, numBytes, &data1, &size1, &data2, &size2 );
+    if( size2 > 0 )
+    {
+        memcpy( data, data1, size1 );
+        data = ((char *)data) + size1;
+        memcpy( data, data2, size2 );
+    }
+    else
+    {
+        memcpy( data, data1, size1 );
+    }
+    RingBuffer_AdvanceReadIndex( rbuf, numRead );
+    return numRead;
+}
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/ringbuffer.h b/utils/iaxclient/lib/portaudio/src/hostapi/coreaudio/ringbuffer.h
new file mode 100644 (file)
index 0000000..1acdc2e
--- /dev/null
@@ -0,0 +1,105 @@
+#ifndef _RINGBUFFER_H
+#define _RINGBUFFER_H
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/*
+ * $Id: ringbuffer.h,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * ringbuffer.h
+ * Ring Buffer utility..
+ *
+ * Author: Phil Burk, http://www.softsynth.com
+ * modified for SMP safety on OS X by Bjorn Roche.
+ * also allowed for const where possible.
+ * Note that this is safe only for a single-thread reader
+ * and a single-thread writer.
+ *
+ * This program is distributed with the PortAudio Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "ringbuffer.h"
+#include <string.h>
+
+typedef struct
+{
+    long   bufferSize; /* Number of bytes in FIFO. Power of 2. Set by RingBuffer_Init. */
+    long   writeIndex; /* Index of next writable byte. Set by RingBuffer_AdvanceWriteIndex. */
+    long   readIndex;  /* Index of next readable byte. Set by RingBuffer_AdvanceReadIndex. */
+    long   bigMask;    /* Used for wrapping indices with extra bit to distinguish full/empty. */
+    long   smallMask;  /* Used for fitting indices to buffer. */
+    char * buffer;
+}
+RingBuffer;
+/*
+ * Initialize Ring Buffer.
+ * numBytes must be power of 2, returns -1 if not.
+ */
+long RingBuffer_Init( RingBuffer *rbuf, long numBytes, void *dataPtr );
+
+/* Clear buffer. Should only be called when buffer is NOT being read. */
+void RingBuffer_Flush( RingBuffer *rbuf );
+
+/* Return number of bytes available for writing. */
+long RingBuffer_GetWriteAvailable( RingBuffer *rbuf );
+/* Return number of bytes available for read. */
+long RingBuffer_GetReadAvailable( RingBuffer *rbuf );
+/* Return bytes written. */
+long RingBuffer_Write( RingBuffer *rbuf, const void *data, long numBytes );
+/* Return bytes read. */
+long RingBuffer_Read( RingBuffer *rbuf, void *data, long numBytes );
+
+/* Get address of region(s) to which we can write data.
+** If the region is contiguous, size2 will be zero.
+** If non-contiguous, size2 will be the size of second region.
+** Returns room available to be written or numBytes, whichever is smaller.
+*/
+long RingBuffer_GetWriteRegions( RingBuffer *rbuf, long numBytes,
+                                 void **dataPtr1, long *sizePtr1,
+                                 void **dataPtr2, long *sizePtr2 );
+long RingBuffer_AdvanceWriteIndex( RingBuffer *rbuf, long numBytes );
+
+/* Get address of region(s) from which we can read data.
+** If the region is contiguous, size2 will be zero.
+** If non-contiguous, size2 will be the size of second region.
+** Returns room available to be written or numBytes, whichever is smaller.
+*/
+long RingBuffer_GetReadRegions( RingBuffer *rbuf, long numBytes,
+                                void **dataPtr1, long *sizePtr1,
+                                void **dataPtr2, long *sizePtr2 );
+
+long RingBuffer_AdvanceReadIndex( RingBuffer *rbuf, long numBytes );
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* _RINGBUFFER_H */
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/dsound/pa_win_ds.c b/utils/iaxclient/lib/portaudio/src/hostapi/dsound/pa_win_ds.c
new file mode 100644 (file)
index 0000000..cc667b4
--- /dev/null
@@ -0,0 +1,2178 @@
+/*
+ * $Id: pa_win_ds.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * Portable Audio I/O Library DirectSound implementation
+ *
+ * Authors: Phil Burk, Robert Marsanyi & Ross Bencina
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2006 Ross Bencina, Phil Burk, Robert Marsanyi
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file
+
+    @todo implement paInputOverflow callback status flag
+    
+    @todo implement paNeverDropInput.
+
+    @todo implement host api specific extension to set i/o buffer sizes in frames
+
+    @todo implement initialisation of PaDeviceInfo default*Latency fields (currently set to 0.)
+
+    @todo implement ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable
+
+    @todo audit handling of DirectSound result codes - in many cases we could convert a HRESULT into
+        a native portaudio error code. Standard DirectSound result codes are documented at msdn.
+
+    @todo implement IsFormatSupported
+
+    @todo check that CoInitialize() CoUninitialize() are always correctly
+        paired, even in error cases.
+
+    @todo call PaUtil_SetLastHostErrorInfo with a specific error string (currently just "DSound error").
+
+    @todo make sure all buffers have been played before stopping the stream
+        when the stream callback returns paComplete
+
+    old TODOs from phil, need to work out if these have been done:
+        O- fix "patest_stop.c"
+*/
+
+#include <stdio.h>
+#include <string.h> /* strlen() */
+
+#include "pa_util.h"
+#include "pa_allocation.h"
+#include "pa_hostapi.h"
+#include "pa_stream.h"
+#include "pa_cpuload.h"
+#include "pa_process.h"
+
+#include "pa_win_ds_dynlink.h"
+
+#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */
+#pragma comment( lib, "dsound.lib" )
+#pragma comment( lib, "winmm.lib" )
+#endif
+
+/*
+ provided in newer platform sdks and x64
+ */
+#ifndef DWORD_PTR
+#define DWORD_PTR DWORD
+#endif
+
+#define PRINT(x) PA_DEBUG(x);
+#define ERR_RPT(x) PRINT(x)
+#define DBUG(x)   PRINT(x)
+#define DBUGX(x)  PRINT(x)
+
+#define PA_USE_HIGH_LATENCY   (0)
+#if PA_USE_HIGH_LATENCY
+#define PA_WIN_9X_LATENCY     (500)
+#define PA_WIN_NT_LATENCY     (600)
+#else
+#define PA_WIN_9X_LATENCY     (140)
+#define PA_WIN_NT_LATENCY     (280)
+#endif
+
+#define PA_WIN_WDM_LATENCY       (120)
+
+#define SECONDS_PER_MSEC      (0.001)
+#define MSEC_PER_SECOND       (1000)
+
+/* prototypes for functions declared in this file */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+static void Terminate( struct PaUtilHostApiRepresentation *hostApi );
+static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
+                           PaStream** s,
+                           const PaStreamParameters *inputParameters,
+                           const PaStreamParameters *outputParameters,
+                           double sampleRate,
+                           unsigned long framesPerBuffer,
+                           PaStreamFlags streamFlags,
+                           PaStreamCallback *streamCallback,
+                           void *userData );
+static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
+                                  const PaStreamParameters *inputParameters,
+                                  const PaStreamParameters *outputParameters,
+                                  double sampleRate );
+static PaError CloseStream( PaStream* stream );
+static PaError StartStream( PaStream *stream );
+static PaError StopStream( PaStream *stream );
+static PaError AbortStream( PaStream *stream );
+static PaError IsStreamStopped( PaStream *s );
+static PaError IsStreamActive( PaStream *stream );
+static PaTime GetStreamTime( PaStream *stream );
+static double GetStreamCpuLoad( PaStream* stream );
+static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames );
+static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames );
+static signed long GetStreamReadAvailable( PaStream* stream );
+static signed long GetStreamWriteAvailable( PaStream* stream );
+
+
+/* FIXME: should convert hr to a string */
+#define PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr ) \
+    PaUtil_SetLastHostErrorInfo( paDirectSound, hr, "DirectSound error" )
+
+/************************************************* DX Prototypes **********/
+static BOOL CALLBACK CollectGUIDsProc(LPGUID lpGUID,
+                                     LPCTSTR lpszDesc,
+                                     LPCTSTR lpszDrvName,
+                                     LPVOID lpContext );
+
+/************************************************************************************/
+/********************** Structures **************************************************/
+/************************************************************************************/
+/* PaWinDsHostApiRepresentation - host api datastructure specific to this implementation */
+
+typedef struct PaWinDsDeviceInfo
+{
+    GUID                             guid;
+    GUID                            *lpGUID;
+    double                           sampleRates[3];
+} PaWinDsDeviceInfo;
+
+typedef struct
+{
+    PaUtilHostApiRepresentation inheritedHostApiRep;
+    PaUtilStreamInterface    callbackStreamInterface;
+    PaUtilStreamInterface    blockingStreamInterface;
+
+    PaUtilAllocationGroup   *allocations;
+
+    /* implementation specific data goes here */
+    PaWinDsDeviceInfo       *winDsDeviceInfos;
+
+} PaWinDsHostApiRepresentation;
+
+
+/* PaWinDsStream - a stream data structure specifically for this implementation */
+
+typedef struct PaWinDsStream
+{
+    PaUtilStreamRepresentation streamRepresentation;
+    PaUtilCpuLoadMeasurer cpuLoadMeasurer;
+    PaUtilBufferProcessor bufferProcessor;
+
+/* DirectSound specific data. */
+
+/* Output */
+    LPDIRECTSOUND        pDirectSound;
+    LPDIRECTSOUNDBUFFER  pDirectSoundOutputBuffer;
+    DWORD                outputBufferWriteOffsetBytes;     /* last write position */
+    INT                  outputBufferSizeBytes;
+    INT                  bytesPerOutputFrame;
+    /* Try to detect play buffer underflows. */
+    LARGE_INTEGER        perfCounterTicksPerBuffer; /* counter ticks it should take to play a full buffer */
+    LARGE_INTEGER        previousPlayTime;
+    UINT                 previousPlayCursor;
+    UINT                 outputUnderflowCount;
+    BOOL                 outputIsRunning;
+    /* use double which lets us can play for several thousand years with enough precision */
+    double               dsw_framesWritten;
+    double               framesPlayed;
+/* Input */
+    LPDIRECTSOUNDCAPTURE pDirectSoundCapture;
+    LPDIRECTSOUNDCAPTUREBUFFER   pDirectSoundInputBuffer;
+    INT                  bytesPerInputFrame;
+    UINT                 readOffset;      /* last read position */
+    UINT                 inputSize;
+
+    
+    MMRESULT         timerID;
+    int              framesPerDSBuffer;
+    double           framesWritten;
+    double           secondsPerHostByte; /* Used to optimize latency calculation for outTime */
+
+    PaStreamCallbackFlags callbackFlags;
+    
+/* FIXME - move all below to PaUtilStreamRepresentation */
+    volatile int     isStarted;
+    volatile int     isActive;
+    volatile int     stopProcessing; /* stop thread once existing buffers have been returned */
+    volatile int     abortProcessing; /* stop thread immediately */
+} PaWinDsStream;
+
+
+/************************************************************************************
+** Duplicate the input string using the allocations allocator.
+** A NULL string is converted to a zero length string.
+** If memory cannot be allocated, NULL is returned.
+**/
+static char *DuplicateDeviceNameString( PaUtilAllocationGroup *allocations, const char* src )
+{
+    char *result = 0;
+    
+    if( src != NULL )
+    {
+        size_t len = strlen(src);
+        result = (char*)PaUtil_GroupAllocateMemory( allocations, (long)(len + 1) );
+        if( result )
+            memcpy( (void *) result, src, len+1 );
+    }
+    else
+    {
+        result = (char*)PaUtil_GroupAllocateMemory( allocations, 1 );
+        if( result )
+            result[0] = '\0';
+    }
+
+    return result;
+}
+
+/************************************************************************************
+** DSDeviceNameAndGUID, DSDeviceNameAndGUIDVector used for collecting preliminary
+** information during device enumeration.
+*/
+typedef struct DSDeviceNameAndGUID{
+    char *name; // allocated from parent's allocations, never deleted by this structure
+    GUID guid;
+    LPGUID lpGUID;
+} DSDeviceNameAndGUID;
+
+typedef struct DSDeviceNameAndGUIDVector{
+    PaUtilAllocationGroup *allocations;
+    PaError enumerationError;
+
+    int count;
+    int free;
+    DSDeviceNameAndGUID *items; // Allocated using LocalAlloc()
+} DSDeviceNameAndGUIDVector;
+
+static PaError InitializeDSDeviceNameAndGUIDVector(
+        DSDeviceNameAndGUIDVector *guidVector, PaUtilAllocationGroup *allocations )
+{
+    PaError result = paNoError;
+
+    guidVector->allocations = allocations;
+    guidVector->enumerationError = paNoError;
+
+    guidVector->count = 0;
+    guidVector->free = 8;
+    guidVector->items = (DSDeviceNameAndGUID*)LocalAlloc( LMEM_FIXED, sizeof(DSDeviceNameAndGUID) * guidVector->free );
+    if( guidVector->items == NULL )
+        result = paInsufficientMemory;
+    
+    return result;
+}
+
+static PaError ExpandDSDeviceNameAndGUIDVector( DSDeviceNameAndGUIDVector *guidVector )
+{
+    PaError result = paNoError;
+    DSDeviceNameAndGUID *newItems;
+    int i;
+    
+    /* double size of vector */
+    int size = guidVector->count + guidVector->free;
+    guidVector->free += size;
+
+    newItems = (DSDeviceNameAndGUID*)LocalAlloc( LMEM_FIXED, sizeof(DSDeviceNameAndGUID) * size * 2 );
+    if( newItems == NULL )
+    {
+        result = paInsufficientMemory;
+    }
+    else
+    {
+        for( i=0; i < guidVector->count; ++i )
+        {
+            newItems[i].name = guidVector->items[i].name;
+            if( guidVector->items[i].lpGUID == NULL )
+            {
+                newItems[i].lpGUID = NULL;
+            }
+            else
+            {
+                newItems[i].lpGUID = &newItems[i].guid;
+                memcpy( &newItems[i].guid, guidVector->items[i].lpGUID, sizeof(GUID) );;
+            }
+        }
+
+        LocalFree( guidVector->items );
+        guidVector->items = newItems;
+    }                                
+
+    return result;
+}
+
+/*
+    it's safe to call DSDeviceNameAndGUIDVector multiple times
+*/
+static PaError TerminateDSDeviceNameAndGUIDVector( DSDeviceNameAndGUIDVector *guidVector )
+{
+    PaError result = paNoError;
+
+    if( guidVector->items != NULL )
+    {
+        if( LocalFree( guidVector->items ) != NULL )
+            result = paInsufficientMemory;              /** @todo this isn't the correct error to return from a deallocation failure */
+
+        guidVector->items = NULL;
+    }
+
+    return result;
+}
+
+/************************************************************************************
+** Collect preliminary device information during DirectSound enumeration 
+*/
+static BOOL CALLBACK CollectGUIDsProc(LPGUID lpGUID,
+                                     LPCTSTR lpszDesc,
+                                     LPCTSTR lpszDrvName,
+                                     LPVOID lpContext )
+{
+    DSDeviceNameAndGUIDVector *namesAndGUIDs = (DSDeviceNameAndGUIDVector*)lpContext;
+    PaError error;
+
+    (void) lpszDrvName; /* unused variable */
+
+    if( namesAndGUIDs->free == 0 )
+    {
+        error = ExpandDSDeviceNameAndGUIDVector( namesAndGUIDs );
+        if( error != paNoError )
+        {
+            namesAndGUIDs->enumerationError = error;
+            return FALSE;
+        }
+    }
+    
+    /* Set GUID pointer, copy GUID to storage in DSDeviceNameAndGUIDVector. */
+    if( lpGUID == NULL )
+    {
+        namesAndGUIDs->items[namesAndGUIDs->count].lpGUID = NULL;
+    }
+    else
+    {
+        namesAndGUIDs->items[namesAndGUIDs->count].lpGUID =
+                &namesAndGUIDs->items[namesAndGUIDs->count].guid;
+      
+        memcpy( &namesAndGUIDs->items[namesAndGUIDs->count].guid, lpGUID, sizeof(GUID) );
+    }
+
+    namesAndGUIDs->items[namesAndGUIDs->count].name =
+            DuplicateDeviceNameString( namesAndGUIDs->allocations, lpszDesc );
+    if( namesAndGUIDs->items[namesAndGUIDs->count].name == NULL )
+    {
+        namesAndGUIDs->enumerationError = paInsufficientMemory;
+        return FALSE;
+    }
+
+    ++namesAndGUIDs->count;
+    --namesAndGUIDs->free;
+    
+    return TRUE;
+}
+
+
+/* 
+    GUIDs for emulated devices which we blacklist below.
+    are there more than two of them??
+*/
+
+GUID IID_IRolandVSCEmulated1 = {0xc2ad1800, 0xb243, 0x11ce, 0xa8, 0xa4, 0x00, 0xaa, 0x00, 0x6c, 0x45, 0x01};
+GUID IID_IRolandVSCEmulated2 = {0xc2ad1800, 0xb243, 0x11ce, 0xa8, 0xa4, 0x00, 0xaa, 0x00, 0x6c, 0x45, 0x02};
+
+
+#define PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_  (13) /* must match array length below */
+static double defaultSampleRateSearchOrder_[] =
+    { 44100.0, 48000.0, 32000.0, 24000.0, 22050.0, 88200.0, 96000.0, 192000.0,
+        16000.0, 12000.0, 11025.0, 9600.0, 8000.0 };
+
+
+/************************************************************************************
+** Extract capabilities from an output device, and add it to the device info list
+** if successful. This function assumes that there is enough room in the
+** device info list to accomodate all entries.
+**
+** The device will not be added to the device list if any errors are encountered.
+*/
+static PaError AddOutputDeviceInfoFromDirectSound(
+        PaWinDsHostApiRepresentation *winDsHostApi, char *name, LPGUID lpGUID )
+{
+    PaUtilHostApiRepresentation  *hostApi = &winDsHostApi->inheritedHostApiRep;
+    PaDeviceInfo                 *deviceInfo = hostApi->deviceInfos[hostApi->info.deviceCount];
+    PaWinDsDeviceInfo            *winDsDeviceInfo = &winDsHostApi->winDsDeviceInfos[hostApi->info.deviceCount];
+    HRESULT                       hr;
+    LPDIRECTSOUND                 lpDirectSound;
+    DSCAPS                        caps;
+    int                           deviceOK = TRUE;
+    PaError                       result = paNoError;
+    int                           i;
+    
+    /* Copy GUID to the device info structure. Set pointer. */
+    if( lpGUID == NULL )
+    {
+        winDsDeviceInfo->lpGUID = NULL;
+    }
+    else
+    {
+        memcpy( &winDsDeviceInfo->guid, lpGUID, sizeof(GUID) );
+        winDsDeviceInfo->lpGUID = &winDsDeviceInfo->guid;
+    }
+
+    
+    if( lpGUID )
+    {
+        if (IsEqualGUID (&IID_IRolandVSCEmulated1,lpGUID) ||
+            IsEqualGUID (&IID_IRolandVSCEmulated2,lpGUID) )
+        {
+            PA_DEBUG(("BLACKLISTED: %s \n",name));
+            return paNoError;
+        }
+    }
+
+    /* Create a DirectSound object for the specified GUID
+        Note that using CoCreateInstance doesn't work on windows CE.
+    */
+    hr = paWinDsDSoundEntryPoints.DirectSoundCreate( lpGUID, &lpDirectSound, NULL );
+
+    /** try using CoCreateInstance because DirectSoundCreate was hanging under
+        some circumstances - note this was probably related to the
+        #define BOOL short bug which has now been fixed
+        @todo delete this comment and the following code once we've ensured
+        there is no bug.
+    */
+    /*
+    hr = CoCreateInstance( &CLSID_DirectSound, NULL, CLSCTX_INPROC_SERVER,
+            &IID_IDirectSound, (void**)&lpDirectSound );
+
+    if( hr == S_OK )
+    {
+        hr = IDirectSound_Initialize( lpDirectSound, lpGUID );
+    }
+    */
+    
+    if( hr != DS_OK )
+    {
+        if (hr == DSERR_ALLOCATED)
+            PA_DEBUG(("AddOutputDeviceInfoFromDirectSound %s DSERR_ALLOCATED\n",name));
+        DBUG(("Cannot create DirectSound for %s. Result = 0x%x\n", name, hr ));
+        if (lpGUID)
+            DBUG(("%s's GUID: {0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x, 0x%x} \n",
+                 name,
+                 lpGUID->Data1,
+                 lpGUID->Data2,
+                 lpGUID->Data3,
+                 lpGUID->Data4[0],
+                 lpGUID->Data4[1],
+                 lpGUID->Data4[2],
+                 lpGUID->Data4[3],
+                 lpGUID->Data4[4],
+                 lpGUID->Data4[5],
+                 lpGUID->Data4[6],
+                 lpGUID->Data4[7]));
+
+        deviceOK = FALSE;
+    }
+    else
+    {
+        /* Query device characteristics. */
+        memset( &caps, 0, sizeof(caps) ); 
+        caps.dwSize = sizeof(caps);
+        hr = IDirectSound_GetCaps( lpDirectSound, &caps );
+        if( hr != DS_OK )
+        {
+            DBUG(("Cannot GetCaps() for DirectSound device %s. Result = 0x%x\n", name, hr ));
+            deviceOK = FALSE;
+        }
+        else
+        {
+
+#ifndef PA_NO_WMME
+            if( caps.dwFlags & DSCAPS_EMULDRIVER )
+            {
+                /* If WMME supported, then reject Emulated drivers because they are lousy. */
+                deviceOK = FALSE;
+            }
+#endif
+
+            if( deviceOK )
+            {
+                deviceInfo->maxInputChannels = 0;
+                /* Mono or stereo device? */
+                deviceInfo->maxOutputChannels = ( caps.dwFlags & DSCAPS_PRIMARYSTEREO ) ? 2 : 1;
+
+                deviceInfo->defaultLowInputLatency = 0.;    /** @todo IMPLEMENT ME */
+                deviceInfo->defaultLowOutputLatency = 0.;   /** @todo IMPLEMENT ME */
+                deviceInfo->defaultHighInputLatency = 0.;   /** @todo IMPLEMENT ME */
+                deviceInfo->defaultHighOutputLatency = 0.;  /** @todo IMPLEMENT ME */
+                
+                /* initialize defaultSampleRate */
+                
+                if( caps.dwFlags & DSCAPS_CONTINUOUSRATE )
+                {
+                    /* initialize to caps.dwMaxSecondarySampleRate incase none of the standard rates match */
+                    deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate;
+
+                    for( i = 0; i < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++i )
+                    {
+                        if( defaultSampleRateSearchOrder_[i] >= caps.dwMinSecondarySampleRate
+                                && defaultSampleRateSearchOrder_[i] <= caps.dwMaxSecondarySampleRate ){
+
+                            deviceInfo->defaultSampleRate = defaultSampleRateSearchOrder_[i];
+                            break;
+                        }
+                    }
+                }
+                else if( caps.dwMinSecondarySampleRate == caps.dwMaxSecondarySampleRate )
+                {
+                    if( caps.dwMinSecondarySampleRate == 0 )
+                    {
+                        /*
+                        ** On my Thinkpad 380Z, DirectSoundV6 returns min-max=0 !!
+                        ** But it supports continuous sampling.
+                        ** So fake range of rates, and hope it really supports it.
+                        */
+                        deviceInfo->defaultSampleRate = 44100.0f;
+
+                        DBUG(("PA - Reported rates both zero. Setting to fake values for device #%s\n", name ));
+                    }
+                    else
+                    {
+                           deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate;
+                    }
+                }
+                else if( (caps.dwMinSecondarySampleRate < 1000.0) && (caps.dwMaxSecondarySampleRate > 50000.0) )
+                {
+                    /* The EWS88MT drivers lie, lie, lie. The say they only support two rates, 100 & 100000.
+                    ** But we know that they really support a range of rates!
+                    ** So when we see a ridiculous set of rates, assume it is a range.
+                    */
+                  deviceInfo->defaultSampleRate = 44100.0f;
+                  DBUG(("PA - Sample rate range used instead of two odd values for device #%s\n", name ));
+                }
+                else deviceInfo->defaultSampleRate = caps.dwMaxSecondarySampleRate;
+
+
+                //printf( "min %d max %d\n", caps.dwMinSecondarySampleRate, caps.dwMaxSecondarySampleRate );
+                // dwFlags | DSCAPS_CONTINUOUSRATE 
+            }
+        }
+
+        IDirectSound_Release( lpDirectSound );
+    }
+
+    if( deviceOK )
+    {
+        deviceInfo->name = name;
+
+        if( lpGUID == NULL )
+            hostApi->info.defaultOutputDevice = hostApi->info.deviceCount;
+            
+        hostApi->info.deviceCount++;
+    }
+
+    return result;
+}
+
+
+/************************************************************************************
+** Extract capabilities from an input device, and add it to the device info list
+** if successful. This function assumes that there is enough room in the
+** device info list to accomodate all entries.
+**
+** The device will not be added to the device list if any errors are encountered.
+*/
+static PaError AddInputDeviceInfoFromDirectSoundCapture(
+        PaWinDsHostApiRepresentation *winDsHostApi, char *name, LPGUID lpGUID )
+{
+    PaUtilHostApiRepresentation  *hostApi = &winDsHostApi->inheritedHostApiRep;
+    PaDeviceInfo                 *deviceInfo = hostApi->deviceInfos[hostApi->info.deviceCount];
+    PaWinDsDeviceInfo            *winDsDeviceInfo = &winDsHostApi->winDsDeviceInfos[hostApi->info.deviceCount];
+    HRESULT                       hr;
+    LPDIRECTSOUNDCAPTURE          lpDirectSoundCapture;
+    DSCCAPS                       caps;
+    int                           deviceOK = TRUE;
+    PaError                       result = paNoError;
+    
+    /* Copy GUID to the device info structure. Set pointer. */
+    if( lpGUID == NULL )
+    {
+        winDsDeviceInfo->lpGUID = NULL;
+    }
+    else
+    {
+        winDsDeviceInfo->lpGUID = &winDsDeviceInfo->guid;
+        memcpy( &winDsDeviceInfo->guid, lpGUID, sizeof(GUID) );
+    }
+
+
+    hr = paWinDsDSoundEntryPoints.DirectSoundCaptureCreate( lpGUID, &lpDirectSoundCapture, NULL );
+
+    /** try using CoCreateInstance because DirectSoundCreate was hanging under
+        some circumstances - note this was probably related to the
+        #define BOOL short bug which has now been fixed
+        @todo delete this comment and the following code once we've ensured
+        there is no bug.
+    */
+    /*
+    hr = CoCreateInstance( &CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER,
+            &IID_IDirectSoundCapture, (void**)&lpDirectSoundCapture );
+    */
+    if( hr != DS_OK )
+    {
+        DBUG(("Cannot create Capture for %s. Result = 0x%x\n", name, hr ));
+        deviceOK = FALSE;
+    }
+    else
+    {
+        /* Query device characteristics. */
+        memset( &caps, 0, sizeof(caps) );
+        caps.dwSize = sizeof(caps);
+        hr = IDirectSoundCapture_GetCaps( lpDirectSoundCapture, &caps );
+        if( hr != DS_OK )
+        {
+            DBUG(("Cannot GetCaps() for Capture device %s. Result = 0x%x\n", name, hr ));
+            deviceOK = FALSE;
+        }
+        else
+        {
+#ifndef PA_NO_WMME
+            if( caps.dwFlags & DSCAPS_EMULDRIVER )
+            {
+                /* If WMME supported, then reject Emulated drivers because they are lousy. */
+                deviceOK = FALSE;
+            }
+#endif
+
+            if( deviceOK )
+            {
+                deviceInfo->maxInputChannels = caps.dwChannels;
+                deviceInfo->maxOutputChannels = 0;
+
+                deviceInfo->defaultLowInputLatency = 0.;    /** @todo IMPLEMENT ME */
+                deviceInfo->defaultLowOutputLatency = 0.;   /** @todo IMPLEMENT ME */
+                deviceInfo->defaultHighInputLatency = 0.;   /** @todo IMPLEMENT ME */
+                deviceInfo->defaultHighOutputLatency = 0.;  /** @todo IMPLEMENT ME */
+
+/*  constants from a WINE patch by Francois Gouget, see:
+    http://www.winehq.com/hypermail/wine-patches/2003/01/0290.html
+
+    ---
+    Date: Fri, 14 May 2004 10:38:12 +0200 (CEST)
+    From: Francois Gouget <fgouget@ ... .fr>
+    To: Ross Bencina <rbencina@ ... .au>
+    Subject: Re: Permission to use wine 48/96 wave patch in BSD licensed library
+
+    [snip]
+
+    I give you permission to use the patch below under the BSD license.
+    http://www.winehq.com/hypermail/wine-patches/2003/01/0290.html
+
+    [snip]
+*/
+#ifndef WAVE_FORMAT_48M08
+#define WAVE_FORMAT_48M08      0x00001000    /* 48     kHz, Mono,   8-bit  */
+#define WAVE_FORMAT_48S08      0x00002000    /* 48     kHz, Stereo, 8-bit  */
+#define WAVE_FORMAT_48M16      0x00004000    /* 48     kHz, Mono,   16-bit */
+#define WAVE_FORMAT_48S16      0x00008000    /* 48     kHz, Stereo, 16-bit */
+#define WAVE_FORMAT_96M08      0x00010000    /* 96     kHz, Mono,   8-bit  */
+#define WAVE_FORMAT_96S08      0x00020000    /* 96     kHz, Stereo, 8-bit  */
+#define WAVE_FORMAT_96M16      0x00040000    /* 96     kHz, Mono,   16-bit */
+#define WAVE_FORMAT_96S16      0x00080000    /* 96     kHz, Stereo, 16-bit */
+#endif
+
+                /* defaultSampleRate */
+                if( caps.dwChannels == 2 )
+                {
+                    if( caps.dwFormats & WAVE_FORMAT_4S16 )
+                        deviceInfo->defaultSampleRate = 44100.0;
+                    else if( caps.dwFormats & WAVE_FORMAT_48S16 )
+                        deviceInfo->defaultSampleRate = 48000.0;
+                    else if( caps.dwFormats & WAVE_FORMAT_2S16 )
+                        deviceInfo->defaultSampleRate = 22050.0;
+                    else if( caps.dwFormats & WAVE_FORMAT_1S16 )
+                        deviceInfo->defaultSampleRate = 11025.0;
+                    else if( caps.dwFormats & WAVE_FORMAT_96S16 )
+                        deviceInfo->defaultSampleRate = 96000.0;
+                    else
+                        deviceInfo->defaultSampleRate = 0.;
+                }
+                else if( caps.dwChannels == 1 )
+                {
+                    if( caps.dwFormats & WAVE_FORMAT_4M16 )
+                        deviceInfo->defaultSampleRate = 44100.0;
+                    else if( caps.dwFormats & WAVE_FORMAT_48M16 )
+                        deviceInfo->defaultSampleRate = 48000.0;
+                    else if( caps.dwFormats & WAVE_FORMAT_2M16 )
+                        deviceInfo->defaultSampleRate = 22050.0;
+                    else if( caps.dwFormats & WAVE_FORMAT_1M16 )
+                        deviceInfo->defaultSampleRate = 11025.0;
+                    else if( caps.dwFormats & WAVE_FORMAT_96M16 )
+                        deviceInfo->defaultSampleRate = 96000.0;
+                    else
+                        deviceInfo->defaultSampleRate = 0.;
+                }
+                else deviceInfo->defaultSampleRate = 0.;
+            }
+        }
+        
+        IDirectSoundCapture_Release( lpDirectSoundCapture );
+    }
+
+    if( deviceOK )
+    {
+        deviceInfo->name = name;
+
+        if( lpGUID == NULL )
+            hostApi->info.defaultInputDevice = hostApi->info.deviceCount;
+
+        hostApi->info.deviceCount++;
+    }
+
+    return result;
+}
+
+
+/***********************************************************************************/
+PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
+{
+    PaError result = paNoError;
+    int i, deviceCount;
+    PaWinDsHostApiRepresentation *winDsHostApi;
+    DSDeviceNameAndGUIDVector inputNamesAndGUIDs, outputNamesAndGUIDs;
+    PaDeviceInfo *deviceInfoArray;
+
+    HRESULT hr = CoInitialize(NULL);        /** @todo: should uninitialize too */
+    if( FAILED(hr) ){
+        return paUnanticipatedHostError;
+    }            
+
+    /* initialise guid vectors so they can be safely deleted on error */
+    inputNamesAndGUIDs.items = NULL;
+    outputNamesAndGUIDs.items = NULL;
+
+    PaWinDs_InitializeDSoundEntryPoints();
+
+    winDsHostApi = (PaWinDsHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaWinDsHostApiRepresentation) );
+    if( !winDsHostApi )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+
+    winDsHostApi->allocations = PaUtil_CreateAllocationGroup();
+    if( !winDsHostApi->allocations )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+
+    *hostApi = &winDsHostApi->inheritedHostApiRep;
+    (*hostApi)->info.structVersion = 1;
+    (*hostApi)->info.type = paDirectSound;
+    (*hostApi)->info.name = "Windows DirectSound";
+    
+    (*hostApi)->info.deviceCount = 0;
+    (*hostApi)->info.defaultInputDevice = paNoDevice;
+    (*hostApi)->info.defaultOutputDevice = paNoDevice;
+
+    
+/* DSound - enumerate devices to count them and to gather their GUIDs */
+
+
+    result = InitializeDSDeviceNameAndGUIDVector( &inputNamesAndGUIDs, winDsHostApi->allocations );
+    if( result != paNoError )
+        goto error;
+
+    result = InitializeDSDeviceNameAndGUIDVector( &outputNamesAndGUIDs, winDsHostApi->allocations );
+    if( result != paNoError )
+        goto error;
+
+    paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerate( (LPDSENUMCALLBACK)CollectGUIDsProc, (void *)&inputNamesAndGUIDs );
+
+    paWinDsDSoundEntryPoints.DirectSoundEnumerate( (LPDSENUMCALLBACK)CollectGUIDsProc, (void *)&outputNamesAndGUIDs );
+
+    if( inputNamesAndGUIDs.enumerationError != paNoError )
+    {
+        result = inputNamesAndGUIDs.enumerationError;
+        goto error;
+    }
+
+    if( outputNamesAndGUIDs.enumerationError != paNoError )
+    {
+        result = outputNamesAndGUIDs.enumerationError;
+        goto error;
+    }
+
+    deviceCount = inputNamesAndGUIDs.count + outputNamesAndGUIDs.count;
+
+    if( deviceCount > 0 )
+    {
+        /* allocate array for pointers to PaDeviceInfo structs */
+        (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
+                winDsHostApi->allocations, sizeof(PaDeviceInfo*) * deviceCount );
+        if( !(*hostApi)->deviceInfos )
+        {
+            result = paInsufficientMemory;
+            goto error;
+        }
+
+        /* allocate all PaDeviceInfo structs in a contiguous block */
+        deviceInfoArray = (PaDeviceInfo*)PaUtil_GroupAllocateMemory(
+                winDsHostApi->allocations, sizeof(PaDeviceInfo) * deviceCount );
+        if( !deviceInfoArray )
+        {
+            result = paInsufficientMemory;
+            goto error;
+        }
+
+        /* allocate all DSound specific info structs in a contiguous block */
+        winDsHostApi->winDsDeviceInfos = (PaWinDsDeviceInfo*)PaUtil_GroupAllocateMemory(
+                winDsHostApi->allocations, sizeof(PaWinDsDeviceInfo) * deviceCount );
+        if( !winDsHostApi->winDsDeviceInfos )
+        {
+            result = paInsufficientMemory;
+            goto error;
+        }
+
+        for( i=0; i < deviceCount; ++i )
+        {
+            PaDeviceInfo *deviceInfo = &deviceInfoArray[i];
+            deviceInfo->structVersion = 2;
+            deviceInfo->hostApi = hostApiIndex;
+            deviceInfo->name = 0;
+            (*hostApi)->deviceInfos[i] = deviceInfo;
+        }
+
+        for( i=0; i< inputNamesAndGUIDs.count; ++i )
+        {
+            result = AddInputDeviceInfoFromDirectSoundCapture( winDsHostApi,
+                    inputNamesAndGUIDs.items[i].name,
+                    inputNamesAndGUIDs.items[i].lpGUID );
+            if( result != paNoError )
+                goto error;
+        }
+
+        for( i=0; i< outputNamesAndGUIDs.count; ++i )
+        {
+            result = AddOutputDeviceInfoFromDirectSound( winDsHostApi,
+                    outputNamesAndGUIDs.items[i].name,
+                    outputNamesAndGUIDs.items[i].lpGUID );
+            if( result != paNoError )
+                goto error;
+        }
+    }    
+
+    result = TerminateDSDeviceNameAndGUIDVector( &inputNamesAndGUIDs );
+    if( result != paNoError )
+        goto error;
+
+    result = TerminateDSDeviceNameAndGUIDVector( &outputNamesAndGUIDs );
+    if( result != paNoError )
+        goto error;
+
+    
+    (*hostApi)->Terminate = Terminate;
+    (*hostApi)->OpenStream = OpenStream;
+    (*hostApi)->IsFormatSupported = IsFormatSupported;
+
+    PaUtil_InitializeStreamInterface( &winDsHostApi->callbackStreamInterface, CloseStream, StartStream,
+                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
+                                      GetStreamTime, GetStreamCpuLoad,
+                                      PaUtil_DummyRead, PaUtil_DummyWrite,
+                                      PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable );
+
+    PaUtil_InitializeStreamInterface( &winDsHostApi->blockingStreamInterface, CloseStream, StartStream,
+                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
+                                      GetStreamTime, PaUtil_DummyGetCpuLoad,
+                                      ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );
+
+    return result;
+
+error:
+    if( winDsHostApi )
+    {
+        if( winDsHostApi->allocations )
+        {
+            PaUtil_FreeAllAllocations( winDsHostApi->allocations );
+            PaUtil_DestroyAllocationGroup( winDsHostApi->allocations );
+        }
+                
+        PaUtil_FreeMemory( winDsHostApi );
+    }
+
+    TerminateDSDeviceNameAndGUIDVector( &inputNamesAndGUIDs );
+    TerminateDSDeviceNameAndGUIDVector( &outputNamesAndGUIDs );
+
+    return result;
+}
+
+
+/***********************************************************************************/
+static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
+{
+    PaWinDsHostApiRepresentation *winDsHostApi = (PaWinDsHostApiRepresentation*)hostApi;
+
+    /*
+        IMPLEMENT ME:
+            - clean up any resources not handled by the allocation group
+    */
+
+    if( winDsHostApi->allocations )
+    {
+        PaUtil_FreeAllAllocations( winDsHostApi->allocations );
+        PaUtil_DestroyAllocationGroup( winDsHostApi->allocations );
+    }
+
+    PaUtil_FreeMemory( winDsHostApi );
+
+    PaWinDs_TerminateDSoundEntryPoints();
+
+    CoUninitialize();
+}
+
+
+/* Set minimal latency based on whether NT or Win95.
+ * NT has higher latency.
+ */
+static int PaWinDS_GetMinSystemLatency( void )
+{
+    int minLatencyMsec;
+    /* Set minimal latency based on whether NT or other OS.
+     * NT has higher latency.
+     */
+    OSVERSIONINFO osvi;
+       osvi.dwOSVersionInfoSize = sizeof( osvi );
+       GetVersionEx( &osvi );
+    DBUG(("PA - PlatformId = 0x%x\n", osvi.dwPlatformId ));
+    DBUG(("PA - MajorVersion = 0x%x\n", osvi.dwMajorVersion ));
+    DBUG(("PA - MinorVersion = 0x%x\n", osvi.dwMinorVersion ));
+    /* Check for NT */
+       if( (osvi.dwMajorVersion == 4) && (osvi.dwPlatformId == 2) )
+       {
+               minLatencyMsec = PA_WIN_NT_LATENCY;
+       }
+       else if(osvi.dwMajorVersion >= 5)
+       {
+               minLatencyMsec = PA_WIN_WDM_LATENCY;
+       }
+       else
+       {
+               minLatencyMsec = PA_WIN_9X_LATENCY;
+       }
+    return minLatencyMsec;
+}
+
+/***********************************************************************************/
+static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
+                                  const PaStreamParameters *inputParameters,
+                                  const PaStreamParameters *outputParameters,
+                                  double sampleRate )
+{
+    int inputChannelCount, outputChannelCount;
+    PaSampleFormat inputSampleFormat, outputSampleFormat;
+    
+    if( inputParameters )
+    {
+        inputChannelCount = inputParameters->channelCount;
+        inputSampleFormat = inputParameters->sampleFormat;
+
+        /* unless alternate device specification is supported, reject the use of
+            paUseHostApiSpecificDeviceSpecification */
+
+        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
+            return paInvalidDevice;
+
+        /* check that input device can support inputChannelCount */
+        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )
+            return paInvalidChannelCount;
+
+        /* validate inputStreamInfo */
+        if( inputParameters->hostApiSpecificStreamInfo )
+            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
+    }
+    else
+    {
+        inputChannelCount = 0;
+    }
+
+    if( outputParameters )
+    {
+        outputChannelCount = outputParameters->channelCount;
+        outputSampleFormat = outputParameters->sampleFormat;
+        
+        /* unless alternate device specification is supported, reject the use of
+            paUseHostApiSpecificDeviceSpecification */
+
+        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
+            return paInvalidDevice;
+
+        /* check that output device can support inputChannelCount */
+        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )
+            return paInvalidChannelCount;
+
+        /* validate outputStreamInfo */
+        if( outputParameters->hostApiSpecificStreamInfo )
+            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
+    }
+    else
+    {
+        outputChannelCount = 0;
+    }
+    
+    /*
+        IMPLEMENT ME:
+
+            - if a full duplex stream is requested, check that the combination
+                of input and output parameters is supported if necessary
+
+            - check that the device supports sampleRate
+
+        Because the buffer adapter handles conversion between all standard
+        sample formats, the following checks are only required if paCustomFormat
+        is implemented, or under some other unusual conditions.
+
+            - check that input device can support inputSampleFormat, or that
+                we have the capability to convert from outputSampleFormat to
+                a native format
+
+            - check that output device can support outputSampleFormat, or that
+                we have the capability to convert from outputSampleFormat to
+                a native format
+    */
+
+    return paFormatIsSupported;
+}
+
+
+/*************************************************************************
+** Determine minimum number of buffers required for this host based
+** on minimum latency. Latency can be optionally set by user by setting
+** an environment variable. For example, to set latency to 200 msec, put:
+**
+**    set PA_MIN_LATENCY_MSEC=200
+**
+** in the AUTOEXEC.BAT file and reboot.
+** If the environment variable is not set, then the latency will be determined
+** based on the OS. Windows NT has higher latency than Win95.
+*/
+#define PA_LATENCY_ENV_NAME  ("PA_MIN_LATENCY_MSEC")
+#define PA_ENV_BUF_SIZE  (32)
+
+static int PaWinDs_GetMinLatencyFrames( double sampleRate )
+{
+    char      envbuf[PA_ENV_BUF_SIZE];
+    DWORD     hresult;
+    int       minLatencyMsec = 0;
+
+    /* Let user determine minimal latency by setting environment variable. */
+    hresult = GetEnvironmentVariable( PA_LATENCY_ENV_NAME, envbuf, PA_ENV_BUF_SIZE );
+    if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) )
+    {
+        minLatencyMsec = atoi( envbuf );
+    }
+    else
+    {
+        minLatencyMsec = PaWinDS_GetMinSystemLatency();
+#if PA_USE_HIGH_LATENCY
+        PRINT(("PA - Minimum Latency set to %d msec!\n", minLatencyMsec ));
+#endif
+
+    }
+
+    return (int) (minLatencyMsec * sampleRate * SECONDS_PER_MSEC);
+}
+
+
+static HRESULT InitInputBuffer( PaWinDsStream *stream, unsigned long nFrameRate, WORD nChannels, int bytesPerBuffer )
+{
+    DSCBUFFERDESC  captureDesc;
+    WAVEFORMATEX   wfFormat;
+    HRESULT        result;
+    
+    stream->bytesPerInputFrame = nChannels * sizeof(short);
+
+    // Define the buffer format
+    wfFormat.wFormatTag      = WAVE_FORMAT_PCM;
+    wfFormat.nChannels       = nChannels;
+    wfFormat.nSamplesPerSec  = nFrameRate;
+    wfFormat.wBitsPerSample  = 8 * sizeof(short);
+    wfFormat.nBlockAlign     = (WORD)(wfFormat.nChannels * (wfFormat.wBitsPerSample / 8));
+    wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign;
+    wfFormat.cbSize          = 0;   /* No extended format info. */
+    stream->inputSize = bytesPerBuffer;
+    // ----------------------------------------------------------------------
+    // Setup the secondary buffer description
+    ZeroMemory(&captureDesc, sizeof(DSCBUFFERDESC));
+    captureDesc.dwSize = sizeof(DSCBUFFERDESC);
+    captureDesc.dwFlags =  0;
+    captureDesc.dwBufferBytes = bytesPerBuffer;
+    captureDesc.lpwfxFormat = &wfFormat;
+    // Create the capture buffer
+    if ((result = IDirectSoundCapture_CreateCaptureBuffer( stream->pDirectSoundCapture,
+                  &captureDesc, &stream->pDirectSoundInputBuffer, NULL)) != DS_OK) return result;
+    stream->readOffset = 0;  // reset last read position to start of buffer
+    return DS_OK;
+}
+
+
+static HRESULT InitOutputBuffer( PaWinDsStream *stream, unsigned long nFrameRate, WORD nChannels, int bytesPerBuffer )
+{
+    DWORD          dwDataLen;
+    DWORD          playCursor;
+    HRESULT        result;
+    LPDIRECTSOUNDBUFFER pPrimaryBuffer;
+    HWND           hWnd;
+    HRESULT        hr;
+    WAVEFORMATEX   wfFormat;
+    DSBUFFERDESC   primaryDesc;
+    DSBUFFERDESC   secondaryDesc;
+    unsigned char* pDSBuffData;
+    LARGE_INTEGER  counterFrequency;
+
+    stream->outputBufferSizeBytes = bytesPerBuffer;
+    stream->outputIsRunning = FALSE;
+    stream->outputUnderflowCount = 0;
+    stream->dsw_framesWritten = 0;
+    stream->bytesPerOutputFrame = nChannels * sizeof(short);
+
+    // We were using getForegroundWindow() but sometimes the ForegroundWindow may not be the
+    // applications's window. Also if that window is closed before the Buffer is closed
+    // then DirectSound can crash. (Thanks for Scott Patterson for reporting this.)
+    // So we will use GetDesktopWindow() which was suggested by Miller Puckette.
+    // hWnd = GetForegroundWindow();
+    //
+    //  FIXME: The example code I have on the net creates a hidden window that
+    //      is managed by our code - I think we should do that - one hidden
+    //      window for the whole of Pa_DS
+    //
+    hWnd = GetDesktopWindow();
+
+    // Set cooperative level to DSSCL_EXCLUSIVE so that we can get 16 bit output, 44.1 KHz.
+    // Exclusize also prevents unexpected sounds from other apps during a performance.
+    if ((hr = IDirectSound_SetCooperativeLevel( stream->pDirectSound,
+              hWnd, DSSCL_EXCLUSIVE)) != DS_OK)
+    {
+        return hr;
+    }
+
+    // -----------------------------------------------------------------------
+    // Create primary buffer and set format just so we can specify our custom format.
+    // Otherwise we would be stuck with the default which might be 8 bit or 22050 Hz.
+    // Setup the primary buffer description
+    ZeroMemory(&primaryDesc, sizeof(DSBUFFERDESC));
+    primaryDesc.dwSize        = sizeof(DSBUFFERDESC);
+    primaryDesc.dwFlags       = DSBCAPS_PRIMARYBUFFER; // all panning, mixing, etc done by synth
+    primaryDesc.dwBufferBytes = 0;
+    primaryDesc.lpwfxFormat   = NULL;
+    // Create the buffer
+    if ((result = IDirectSound_CreateSoundBuffer( stream->pDirectSound,
+                  &primaryDesc, &pPrimaryBuffer, NULL)) != DS_OK) return result;
+    // Define the buffer format
+    wfFormat.wFormatTag = WAVE_FORMAT_PCM;
+    wfFormat.nChannels = nChannels;
+    wfFormat.nSamplesPerSec = nFrameRate;
+    wfFormat.wBitsPerSample = 8 * sizeof(short);
+    wfFormat.nBlockAlign = (WORD)(wfFormat.nChannels * (wfFormat.wBitsPerSample / 8));
+    wfFormat.nAvgBytesPerSec = wfFormat.nSamplesPerSec * wfFormat.nBlockAlign;
+    wfFormat.cbSize = 0;  /* No extended format info. */
+    // Set the primary buffer's format
+    if((result = IDirectSoundBuffer_SetFormat( pPrimaryBuffer, &wfFormat)) != DS_OK) return result;
+
+    // ----------------------------------------------------------------------
+    // Setup the secondary buffer description
+    ZeroMemory(&secondaryDesc, sizeof(DSBUFFERDESC));
+    secondaryDesc.dwSize = sizeof(DSBUFFERDESC);
+    secondaryDesc.dwFlags =  DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2;
+    secondaryDesc.dwBufferBytes = bytesPerBuffer;
+    secondaryDesc.lpwfxFormat = &wfFormat;
+    // Create the secondary buffer
+    if ((result = IDirectSound_CreateSoundBuffer( stream->pDirectSound,
+                  &secondaryDesc, &stream->pDirectSoundOutputBuffer, NULL)) != DS_OK) return result;
+    // Lock the DS buffer
+    if ((result = IDirectSoundBuffer_Lock( stream->pDirectSoundOutputBuffer, 0, stream->outputBufferSizeBytes, (LPVOID*)&pDSBuffData,
+                                           &dwDataLen, NULL, 0, 0)) != DS_OK) return result;
+    // Zero the DS buffer
+    ZeroMemory(pDSBuffData, dwDataLen);
+    // Unlock the DS buffer
+    if ((result = IDirectSoundBuffer_Unlock( stream->pDirectSoundOutputBuffer, pDSBuffData, dwDataLen, NULL, 0)) != DS_OK) return result;
+    if( QueryPerformanceFrequency( &counterFrequency ) )
+    {
+        int framesInBuffer = bytesPerBuffer / (nChannels * sizeof(short));
+        stream->perfCounterTicksPerBuffer.QuadPart = (counterFrequency.QuadPart * framesInBuffer) / nFrameRate;
+    }
+    else
+    {
+        stream->perfCounterTicksPerBuffer.QuadPart = 0;
+    }
+    // Let DSound set the starting write position because if we set it to zero, it looks like the
+    // buffer is full to begin with. This causes a long pause before sound starts when using large buffers.
+    hr = IDirectSoundBuffer_GetCurrentPosition( stream->pDirectSoundOutputBuffer,
+            &playCursor, &stream->outputBufferWriteOffsetBytes );
+    if( hr != DS_OK )
+    {
+        return hr;
+    }
+    stream->dsw_framesWritten = stream->outputBufferWriteOffsetBytes / stream->bytesPerOutputFrame;
+    /* printf("DSW_InitOutputBuffer: playCursor = %d, writeCursor = %d\n", playCursor, dsw->dsw_WriteOffset ); */
+    return DS_OK;
+}
+
+
+/***********************************************************************************/
+/* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */
+
+static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
+                           PaStream** s,
+                           const PaStreamParameters *inputParameters,
+                           const PaStreamParameters *outputParameters,
+                           double sampleRate,
+                           unsigned long framesPerBuffer,
+                           PaStreamFlags streamFlags,
+                           PaStreamCallback *streamCallback,
+                           void *userData )
+{
+    PaError result = paNoError;
+    PaWinDsHostApiRepresentation *winDsHostApi = (PaWinDsHostApiRepresentation*)hostApi;
+    PaWinDsStream *stream = 0;
+    int inputChannelCount, outputChannelCount;
+    PaSampleFormat inputSampleFormat, outputSampleFormat;
+    PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat;
+    unsigned long suggestedInputLatencyFrames, suggestedOutputLatencyFrames;
+
+    if( inputParameters )
+    {
+        inputChannelCount = inputParameters->channelCount;
+        inputSampleFormat = inputParameters->sampleFormat;
+        suggestedInputLatencyFrames = (unsigned long)(inputParameters->suggestedLatency * sampleRate);
+
+        /* IDEA: the following 3 checks could be performed by default by pa_front
+            unless some flag indicated otherwise */
+            
+        /* unless alternate device specification is supported, reject the use of
+            paUseHostApiSpecificDeviceSpecification */
+        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
+            return paInvalidDevice;
+
+        /* check that input device can support inputChannelCount */
+        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )
+            return paInvalidChannelCount;
+            
+        /* validate hostApiSpecificStreamInfo */
+        if( inputParameters->hostApiSpecificStreamInfo )
+            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
+    }
+    else
+    {
+        inputChannelCount = 0;
+        suggestedInputLatencyFrames = 0;
+    }
+
+
+    if( outputParameters )
+    {
+        outputChannelCount = outputParameters->channelCount;
+        outputSampleFormat = outputParameters->sampleFormat;
+        suggestedOutputLatencyFrames = (unsigned long)(outputParameters->suggestedLatency * sampleRate);
+
+        /* unless alternate device specification is supported, reject the use of
+            paUseHostApiSpecificDeviceSpecification */
+        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
+            return paInvalidDevice;
+
+        /* check that output device can support inputChannelCount */
+        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )
+            return paInvalidChannelCount;
+
+        /* validate hostApiSpecificStreamInfo */
+        if( outputParameters->hostApiSpecificStreamInfo )
+            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */            
+    }
+    else
+    {
+        outputChannelCount = 0;
+        suggestedOutputLatencyFrames = 0;
+    }
+
+
+    /*
+        IMPLEMENT ME:
+
+        ( the following two checks are taken care of by PaUtil_InitializeBufferProcessor() )
+
+            - check that input device can support inputSampleFormat, or that
+                we have the capability to convert from outputSampleFormat to
+                a native format
+
+            - check that output device can support outputSampleFormat, or that
+                we have the capability to convert from outputSampleFormat to
+                a native format
+
+            - if a full duplex stream is requested, check that the combination
+                of input and output parameters is supported
+
+            - check that the device supports sampleRate
+
+            - alter sampleRate to a close allowable rate if possible / necessary
+
+            - validate suggestedInputLatency and suggestedOutputLatency parameters,
+                use default values where necessary
+    */
+
+
+    /* validate platform specific flags */
+    if( (streamFlags & paPlatformSpecificFlags) != 0 )
+        return paInvalidFlag; /* unexpected platform specific flag */
+
+
+    stream = (PaWinDsStream*)PaUtil_AllocateMemory( sizeof(PaWinDsStream) );
+    if( !stream )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+
+    memset( stream, 0, sizeof(PaWinDsStream) ); /* initialize all stream variables to 0 */
+
+    if( streamCallback )
+    {
+        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
+                                               &winDsHostApi->callbackStreamInterface, streamCallback, userData );
+    }
+    else
+    {
+        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
+                                               &winDsHostApi->blockingStreamInterface, streamCallback, userData );
+    }
+    
+    PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );
+
+
+    if( inputParameters )
+    {
+        /* IMPLEMENT ME - establish which  host formats are available */
+        hostInputSampleFormat =
+            PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, inputParameters->sampleFormat );
+    }
+
+    if( outputParameters )
+    {
+        /* IMPLEMENT ME - establish which  host formats are available */
+        hostOutputSampleFormat =
+            PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, outputParameters->sampleFormat );
+    }
+    
+    result =  PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
+                    inputChannelCount, inputSampleFormat, hostInputSampleFormat,
+                    outputChannelCount, outputSampleFormat, hostOutputSampleFormat,
+                    sampleRate, streamFlags, framesPerBuffer,
+                    framesPerBuffer, /* ignored in paUtilVariableHostBufferSizePartialUsageAllowed mode. */
+                /* This next mode is required because DS can split the host buffer when it wraps around. */
+                    paUtilVariableHostBufferSizePartialUsageAllowed,
+                    streamCallback, userData );
+    if( result != paNoError )
+        goto error;
+
+
+    stream->streamRepresentation.streamInfo.inputLatency =
+            PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor);   /* FIXME: not initialised anywhere else */
+    stream->streamRepresentation.streamInfo.outputLatency =
+            PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor);    /* FIXME: not initialised anywhere else */
+    stream->streamRepresentation.streamInfo.sampleRate = sampleRate;
+
+    
+/* DirectSound specific initialization */ 
+    {
+        HRESULT          hr;
+        int              bytesPerDirectSoundBuffer;
+        int              userLatencyFrames;
+        int              minLatencyFrames;
+
+        stream->timerID = 0;
+
+    /* Get system minimum latency. */
+        minLatencyFrames = PaWinDs_GetMinLatencyFrames( sampleRate );
+
+    /* Let user override latency by passing latency parameter. */
+        userLatencyFrames = (suggestedInputLatencyFrames > suggestedOutputLatencyFrames)
+                    ? suggestedInputLatencyFrames
+                    : suggestedOutputLatencyFrames;
+        if( userLatencyFrames > 0 ) minLatencyFrames = userLatencyFrames;
+
+    /* Calculate stream->framesPerDSBuffer depending on framesPerBuffer */
+        if( framesPerBuffer == paFramesPerBufferUnspecified )
+        {
+        /* App support variable framesPerBuffer */
+            stream->framesPerDSBuffer = minLatencyFrames;
+
+            stream->streamRepresentation.streamInfo.outputLatency = (double)(minLatencyFrames - 1) / sampleRate;
+        }
+        else
+        {
+        /* Round up to number of buffers needed to guarantee that latency. */
+            int numUserBuffers = (minLatencyFrames + framesPerBuffer - 1) / framesPerBuffer;
+            if( numUserBuffers < 1 ) numUserBuffers = 1;
+            numUserBuffers += 1; /* So we have latency worth of buffers ahead of current buffer. */
+            stream->framesPerDSBuffer = framesPerBuffer * numUserBuffers;
+
+            stream->streamRepresentation.streamInfo.outputLatency = (double)(framesPerBuffer * (numUserBuffers-1)) / sampleRate;
+        }
+
+        {
+            /** @todo REVIEW: this calculation seems incorrect to me - rossb. */
+            int msecLatency = (int) ((stream->framesPerDSBuffer * MSEC_PER_SECOND) / sampleRate);
+            PRINT(("PortAudio on DirectSound - Latency = %d frames, %d msec\n", stream->framesPerDSBuffer, msecLatency ));
+        }
+
+
+        /* ------------------ OUTPUT */
+        if( outputParameters )
+        {
+            /*
+            PaDeviceInfo *deviceInfo = hostApi->deviceInfos[ outputParameters->device ];
+            DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", outputParameters->device));
+            */
+            
+            bytesPerDirectSoundBuffer = stream->framesPerDSBuffer * outputParameters->channelCount * sizeof(short);
+            if( bytesPerDirectSoundBuffer < DSBSIZE_MIN )
+            {
+                result = paBufferTooSmall;
+                goto error;
+            }
+            else if( bytesPerDirectSoundBuffer > DSBSIZE_MAX )
+            {
+                result = paBufferTooBig;
+                goto error;
+            }
+
+
+            hr = paWinDsDSoundEntryPoints.DirectSoundCreate( winDsHostApi->winDsDeviceInfos[outputParameters->device].lpGUID,
+                        &stream->pDirectSound, NULL );
+            if( hr != DS_OK )
+            {
+                ERR_RPT(("PortAudio: DirectSoundCreate() failed!\n"));
+                result = paUnanticipatedHostError;
+                PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr );
+                goto error;
+            }
+            hr = InitOutputBuffer( stream,
+                                       (unsigned long) (sampleRate + 0.5),
+                                       (WORD)outputParameters->channelCount, bytesPerDirectSoundBuffer );
+            DBUG(("InitOutputBuffer() returns %x\n", hr));
+            if( hr != DS_OK )
+            {
+                result = paUnanticipatedHostError;
+                PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr );
+                goto error;
+            }
+            /* Calculate value used in latency calculation to avoid real-time divides. */
+            stream->secondsPerHostByte = 1.0 /
+                (stream->bufferProcessor.bytesPerHostOutputSample *
+                outputChannelCount * sampleRate);
+        }
+
+        /* ------------------ INPUT */
+        if( inputParameters )
+        {
+            /*
+            PaDeviceInfo *deviceInfo = hostApi->deviceInfos[ inputParameters->device ];
+            DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", inputParameters->device));
+            */
+            
+            bytesPerDirectSoundBuffer = stream->framesPerDSBuffer * inputParameters->channelCount * sizeof(short);
+            if( bytesPerDirectSoundBuffer < DSBSIZE_MIN )
+            {
+                result = paBufferTooSmall;
+                goto error;
+            }
+            else if( bytesPerDirectSoundBuffer > DSBSIZE_MAX )
+            {
+                result = paBufferTooBig;
+                goto error;
+            }
+
+            hr = paWinDsDSoundEntryPoints.DirectSoundCaptureCreate( winDsHostApi->winDsDeviceInfos[inputParameters->device].lpGUID,
+                        &stream->pDirectSoundCapture,   NULL );
+            if( hr != DS_OK )
+            {
+                ERR_RPT(("PortAudio: DirectSoundCaptureCreate() failed!\n"));
+                result = paUnanticipatedHostError;
+                PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr );
+                goto error;
+            }
+            hr = InitInputBuffer( stream,
+                                      (unsigned long) (sampleRate + 0.5),
+                                      (WORD)inputParameters->channelCount, bytesPerDirectSoundBuffer );
+            DBUG(("InitInputBuffer() returns %x\n", hr));
+            if( hr != DS_OK )
+            {
+                ERR_RPT(("PortAudio: DSW_InitInputBuffer() returns %x\n", hr));
+                result = paUnanticipatedHostError;
+                PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr );
+                goto error;
+            }
+        }
+
+    }
+
+    *s = (PaStream*)stream;
+
+    return result;
+
+error:
+    if( stream )
+        PaUtil_FreeMemory( stream );
+
+    return result;
+}
+
+
+/************************************************************************************
+ * Determine how much space can be safely written to in DS buffer.
+ * Detect underflows and overflows.
+ * Does not allow writing into safety gap maintained by DirectSound.
+ */
+static HRESULT QueryOutputSpace( PaWinDsStream *stream, long *bytesEmpty )
+{
+    HRESULT hr;
+    DWORD   playCursor;
+    DWORD   writeCursor;
+    long    numBytesEmpty;
+    long    playWriteGap;
+    // Query to see how much room is in buffer.
+    hr = IDirectSoundBuffer_GetCurrentPosition( stream->pDirectSoundOutputBuffer,
+            &playCursor, &writeCursor );
+    if( hr != DS_OK )
+    {
+        return hr;
+    }
+    // Determine size of gap between playIndex and WriteIndex that we cannot write into.
+    playWriteGap = writeCursor - playCursor;
+    if( playWriteGap < 0 ) playWriteGap += stream->outputBufferSizeBytes; // unwrap
+    /* DirectSound doesn't have a large enough playCursor so we cannot detect wrap-around. */
+    /* Attempt to detect playCursor wrap-around and correct it. */
+    if( stream->outputIsRunning && (stream->perfCounterTicksPerBuffer.QuadPart != 0) )
+    {
+        /* How much time has elapsed since last check. */
+        LARGE_INTEGER   currentTime;
+        LARGE_INTEGER   elapsedTime;
+        long            bytesPlayed;
+        long            bytesExpected;
+        long            buffersWrapped;
+        QueryPerformanceCounter( &currentTime );
+        elapsedTime.QuadPart = currentTime.QuadPart - stream->previousPlayTime.QuadPart;
+        stream->previousPlayTime = currentTime;
+        /* How many bytes does DirectSound say have been played. */
+        bytesPlayed = playCursor - stream->previousPlayCursor;
+        if( bytesPlayed < 0 ) bytesPlayed += stream->outputBufferSizeBytes; // unwrap
+        stream->previousPlayCursor = playCursor;
+        /* Calculate how many bytes we would have expected to been played by now. */
+        bytesExpected = (long) ((elapsedTime.QuadPart * stream->outputBufferSizeBytes) / stream->perfCounterTicksPerBuffer.QuadPart);
+        buffersWrapped = (bytesExpected - bytesPlayed) / stream->outputBufferSizeBytes;
+        if( buffersWrapped > 0 )
+        {
+            playCursor += (buffersWrapped * stream->outputBufferSizeBytes);
+            bytesPlayed += (buffersWrapped * stream->outputBufferSizeBytes);
+        }
+        /* Maintain frame output cursor. */
+        stream->framesPlayed += (bytesPlayed / stream->bytesPerOutputFrame);
+    }
+    numBytesEmpty = playCursor - stream->outputBufferWriteOffsetBytes;
+    if( numBytesEmpty < 0 ) numBytesEmpty += stream->outputBufferSizeBytes; // unwrap offset
+    /* Have we underflowed? */
+    if( numBytesEmpty > (stream->outputBufferSizeBytes - playWriteGap) )
+    {
+        if( stream->outputIsRunning )
+        {
+            stream->outputUnderflowCount += 1;
+        }
+        stream->outputBufferWriteOffsetBytes = writeCursor;
+        numBytesEmpty = stream->outputBufferSizeBytes - playWriteGap;
+    }
+    *bytesEmpty = numBytesEmpty;
+    return hr;
+}
+
+/***********************************************************************************/
+static PaError Pa_TimeSlice( PaWinDsStream *stream )
+{
+    PaError           result = 0;   /* FIXME: this should be declared int and this function should also return that type (same as stream callback return type)*/
+    long              numFrames = 0;
+    long              bytesEmpty = 0;
+    long              bytesFilled = 0;
+    long              bytesToXfer = 0;
+    long              framesToXfer = 0;
+    long              numInFramesReady = 0;
+    long              numOutFramesReady = 0;
+    long              bytesProcessed;
+    HRESULT           hresult;
+    double            outputLatency = 0;
+    PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /** @todo implement inputBufferAdcTime */
+    
+/* Input */
+    LPBYTE            lpInBuf1 = NULL;
+    LPBYTE            lpInBuf2 = NULL;
+    DWORD             dwInSize1 = 0;
+    DWORD             dwInSize2 = 0;
+/* Output */
+    LPBYTE            lpOutBuf1 = NULL;
+    LPBYTE            lpOutBuf2 = NULL;
+    DWORD             dwOutSize1 = 0;
+    DWORD             dwOutSize2 = 0;
+
+    /* How much input data is available? */
+    if( stream->bufferProcessor.inputChannelCount > 0 )
+    {
+        HRESULT hr;
+        DWORD capturePos;
+        DWORD readPos;
+        long  filled = 0;
+        // Query to see how much data is in buffer.
+        // We don't need the capture position but sometimes DirectSound doesn't handle NULLS correctly
+        // so let's pass a pointer just to be safe.
+        hr = IDirectSoundCaptureBuffer_GetCurrentPosition( stream->pDirectSoundInputBuffer, &capturePos, &readPos );
+        if( hr == DS_OK )
+        {
+            filled = readPos - stream->readOffset;
+            if( filled < 0 ) filled += stream->inputSize; // unwrap offset
+            bytesFilled = filled;
+        }
+            // FIXME: what happens if IDirectSoundCaptureBuffer_GetCurrentPosition fails?
+
+        framesToXfer = numInFramesReady = bytesFilled / stream->bytesPerInputFrame;
+        outputLatency = ((double)bytesFilled) * stream->secondsPerHostByte;
+
+        /** @todo Check for overflow */
+    }
+
+    /* How much output room is available? */
+    if( stream->bufferProcessor.outputChannelCount > 0 )
+    {
+        UINT previousUnderflowCount = stream->outputUnderflowCount;
+        QueryOutputSpace( stream, &bytesEmpty );
+        framesToXfer = numOutFramesReady = bytesEmpty / stream->bytesPerOutputFrame;
+
+        /* Check for underflow */
+        if( stream->outputUnderflowCount != previousUnderflowCount )
+            stream->callbackFlags |= paOutputUnderflow;
+    }
+
+    if( (numInFramesReady > 0) && (numOutFramesReady > 0) )
+    {
+        framesToXfer = (numOutFramesReady < numInFramesReady) ? numOutFramesReady : numInFramesReady;
+    }
+
+    if( framesToXfer > 0 )
+    {
+
+        PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
+
+    /* The outputBufferDacTime parameter should indicates the time at which
+        the first sample of the output buffer is heard at the DACs. */
+        timeInfo.currentTime = PaUtil_GetTime();
+        timeInfo.outputBufferDacTime = timeInfo.currentTime + outputLatency;
+
+
+        PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, stream->callbackFlags );
+        stream->callbackFlags = 0;
+        
+    /* Input */
+        if( stream->bufferProcessor.inputChannelCount > 0 )
+        {
+            bytesToXfer = framesToXfer * stream->bytesPerInputFrame;
+            hresult = IDirectSoundCaptureBuffer_Lock ( stream->pDirectSoundInputBuffer,
+                stream->readOffset, bytesToXfer,
+                (void **) &lpInBuf1, &dwInSize1,
+                (void **) &lpInBuf2, &dwInSize2, 0);
+            if (hresult != DS_OK)
+            {
+                ERR_RPT(("DirectSound IDirectSoundCaptureBuffer_Lock failed, hresult = 0x%x\n",hresult));
+                result = paUnanticipatedHostError;
+                PA_DS_SET_LAST_DIRECTSOUND_ERROR( hresult );
+                goto error2;
+            }
+
+            numFrames = dwInSize1 / stream->bytesPerInputFrame;
+            PaUtil_SetInputFrameCount( &stream->bufferProcessor, numFrames );
+            PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, 0, lpInBuf1, 0 );
+        /* Is input split into two regions. */
+            if( dwInSize2 > 0 )
+            {
+                numFrames = dwInSize2 / stream->bytesPerInputFrame;
+                PaUtil_Set2ndInputFrameCount( &stream->bufferProcessor, numFrames );
+                PaUtil_Set2ndInterleavedInputChannels( &stream->bufferProcessor, 0, lpInBuf2, 0 );
+            }
+        }
+
+    /* Output */
+        if( stream->bufferProcessor.outputChannelCount > 0 )
+        {
+            bytesToXfer = framesToXfer * stream->bytesPerOutputFrame;
+            hresult = IDirectSoundBuffer_Lock ( stream->pDirectSoundOutputBuffer,
+                stream->outputBufferWriteOffsetBytes, bytesToXfer,
+                (void **) &lpOutBuf1, &dwOutSize1,
+                (void **) &lpOutBuf2, &dwOutSize2, 0);
+            if (hresult != DS_OK)
+            {
+                ERR_RPT(("DirectSound IDirectSoundBuffer_Lock failed, hresult = 0x%x\n",hresult));
+                result = paUnanticipatedHostError;
+                PA_DS_SET_LAST_DIRECTSOUND_ERROR( hresult );
+                goto error1;
+            }
+
+            numFrames = dwOutSize1 / stream->bytesPerOutputFrame;
+            PaUtil_SetOutputFrameCount( &stream->bufferProcessor, numFrames );
+            PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, 0, lpOutBuf1, 0 );
+
+        /* Is output split into two regions. */
+            if( dwOutSize2 > 0 )
+            {
+                numFrames = dwOutSize2 / stream->bytesPerOutputFrame;
+                PaUtil_Set2ndOutputFrameCount( &stream->bufferProcessor, numFrames );
+                PaUtil_Set2ndInterleavedOutputChannels( &stream->bufferProcessor, 0, lpOutBuf2, 0 );
+            }
+        }
+
+        result = paContinue;
+        numFrames = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &result );
+        stream->framesWritten += numFrames;
+        
+        if( stream->bufferProcessor.outputChannelCount > 0 )
+        {
+        /* FIXME: an underflow could happen here */
+
+        /* Update our buffer offset and unlock sound buffer */
+            bytesProcessed = numFrames * stream->bytesPerOutputFrame;
+            stream->outputBufferWriteOffsetBytes = (stream->outputBufferWriteOffsetBytes + bytesProcessed) % stream->outputBufferSizeBytes;
+            IDirectSoundBuffer_Unlock( stream->pDirectSoundOutputBuffer, lpOutBuf1, dwOutSize1, lpOutBuf2, dwOutSize2);
+            stream->dsw_framesWritten += numFrames;
+        }
+
+error1:
+        if( stream->bufferProcessor.inputChannelCount > 0 )
+        {
+        /* FIXME: an overflow could happen here */
+
+        /* Update our buffer offset and unlock sound buffer */
+            bytesProcessed = numFrames * stream->bytesPerInputFrame;
+            stream->readOffset = (stream->readOffset + bytesProcessed) % stream->inputSize;
+            IDirectSoundCaptureBuffer_Unlock( stream->pDirectSoundInputBuffer, lpInBuf1, dwInSize1, lpInBuf2, dwInSize2);
+        }
+error2:
+
+        PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, numFrames );
+
+    }
+    
+    return result;
+}
+/*******************************************************************/
+
+static HRESULT ZeroAvailableOutputSpace( PaWinDsStream *stream )
+{
+    HRESULT hr;
+    LPBYTE lpbuf1 = NULL;
+    LPBYTE lpbuf2 = NULL;
+    DWORD dwsize1 = 0;
+    DWORD dwsize2 = 0;
+    long  bytesEmpty;
+    hr = QueryOutputSpace( stream, &bytesEmpty ); // updates framesPlayed
+    if (hr != DS_OK) return hr;
+    if( bytesEmpty == 0 ) return DS_OK;
+    // Lock free space in the DS
+    hr = IDirectSoundBuffer_Lock( stream->pDirectSoundOutputBuffer, stream->outputBufferWriteOffsetBytes,
+                                    bytesEmpty, (void **) &lpbuf1, &dwsize1,
+                                    (void **) &lpbuf2, &dwsize2, 0);
+    if (hr == DS_OK)
+    {
+        // Copy the buffer into the DS
+        ZeroMemory(lpbuf1, dwsize1);
+        if(lpbuf2 != NULL)
+        {
+            ZeroMemory(lpbuf2, dwsize2);
+        }
+        // Update our buffer offset and unlock sound buffer
+        stream->outputBufferWriteOffsetBytes = (stream->outputBufferWriteOffsetBytes + dwsize1 + dwsize2) % stream->outputBufferSizeBytes;
+        IDirectSoundBuffer_Unlock( stream->pDirectSoundOutputBuffer, lpbuf1, dwsize1, lpbuf2, dwsize2);
+        stream->dsw_framesWritten += bytesEmpty / stream->bytesPerOutputFrame;
+    }
+    return hr;
+}
+
+
+static void CALLBACK Pa_TimerCallback(UINT uID, UINT uMsg, DWORD_PTR dwUser, DWORD dw1, DWORD dw2)
+{
+    PaWinDsStream *stream;
+
+    /* suppress unused variable warnings */
+    (void) uID;
+    (void) uMsg;
+    (void) dw1;
+    (void) dw2;
+    
+    stream = (PaWinDsStream *) dwUser;
+    if( stream == NULL ) return;
+
+    if( stream->isActive )
+    {
+        if( stream->abortProcessing )
+        {
+            stream->isActive = 0;
+        }
+        else if( stream->stopProcessing )
+        {
+            if( stream->bufferProcessor.outputChannelCount > 0 )
+            {
+                ZeroAvailableOutputSpace( stream );
+                /* clear isActive when all sound played */
+                if( stream->framesPlayed >= stream->framesWritten )
+                {
+                    stream->isActive = 0;
+                }
+            }
+            else
+            {
+                stream->isActive = 0;
+            }
+        }
+        else
+        {
+            if( Pa_TimeSlice( stream ) != 0)  /* Call time slice independant of timing method. */
+            {
+                /* FIXME implement handling of paComplete and paAbort if possible */
+                stream->stopProcessing = 1;
+            }
+        }
+
+        if( !stream->isActive ){
+            if( stream->streamRepresentation.streamFinishedCallback != 0 )
+                stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
+        }
+    }
+}
+
+/***********************************************************************************
+    When CloseStream() is called, the multi-api layer ensures that
+    the stream has already been stopped or aborted.
+*/
+static PaError CloseStream( PaStream* s )
+{
+    PaError result = paNoError;
+    PaWinDsStream *stream = (PaWinDsStream*)s;
+
+    // Cleanup the sound buffers
+    if( stream->pDirectSoundOutputBuffer )
+    {
+        IDirectSoundBuffer_Stop( stream->pDirectSoundOutputBuffer );
+        IDirectSoundBuffer_Release( stream->pDirectSoundOutputBuffer );
+        stream->pDirectSoundOutputBuffer = NULL;
+    }
+
+    if( stream->pDirectSoundInputBuffer )
+    {
+        IDirectSoundCaptureBuffer_Stop( stream->pDirectSoundInputBuffer );
+        IDirectSoundCaptureBuffer_Release( stream->pDirectSoundInputBuffer );
+        stream->pDirectSoundInputBuffer = NULL;
+    }
+
+    if( stream->pDirectSoundCapture )
+    {
+        IDirectSoundCapture_Release( stream->pDirectSoundCapture );
+        stream->pDirectSoundCapture = NULL;
+    }
+
+    if( stream->pDirectSound )
+    {
+        IDirectSound_Release( stream->pDirectSound );
+        stream->pDirectSound = NULL;
+    }
+
+    PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
+    PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
+    PaUtil_FreeMemory( stream );
+
+    return result;
+}
+
+/***********************************************************************************/
+static PaError StartStream( PaStream *s )
+{
+    PaError          result = paNoError;
+    PaWinDsStream   *stream = (PaWinDsStream*)s;
+    HRESULT          hr;
+
+    PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
+    
+    if( stream->bufferProcessor.inputChannelCount > 0 )
+    {
+        // Start the buffer playback
+        if( stream->pDirectSoundInputBuffer != NULL ) // FIXME: not sure this check is necessary
+        {
+            hr = IDirectSoundCaptureBuffer_Start( stream->pDirectSoundInputBuffer, DSCBSTART_LOOPING );
+        }
+
+        DBUG(("StartStream: DSW_StartInput returned = 0x%X.\n", hr));
+        if( hr != DS_OK )
+        {
+            result = paUnanticipatedHostError;
+            PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr );
+            goto error;
+        }
+    }
+
+    stream->framesWritten = 0;
+    stream->callbackFlags = 0;
+
+    stream->abortProcessing = 0;
+    stream->stopProcessing = 0;
+    stream->isActive = 1;
+
+    if( stream->bufferProcessor.outputChannelCount > 0 )
+    {
+        /* Give user callback a chance to pre-fill buffer. REVIEW - i thought we weren't pre-filling, rb. */
+        result = Pa_TimeSlice( stream );
+        if( result != paNoError ) return result; // FIXME - what if finished?
+
+        QueryPerformanceCounter( &stream->previousPlayTime );
+        stream->previousPlayCursor = 0;
+        stream->framesPlayed = 0;
+        hr = IDirectSoundBuffer_SetCurrentPosition( stream->pDirectSoundOutputBuffer, 0 );
+        DBUG(("PaHost_StartOutput: IDirectSoundBuffer_SetCurrentPosition returned = 0x%X.\n", hr));
+        if( hr != DS_OK )
+        {
+            result = paUnanticipatedHostError;
+            PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr );
+            goto error;
+        }
+
+        // Start the buffer playback in a loop.
+        if( stream->pDirectSoundOutputBuffer != NULL ) // FIXME: not sure this needs to be checked here
+        {
+            hr = IDirectSoundBuffer_Play( stream->pDirectSoundOutputBuffer, 0, 0, DSBPLAY_LOOPING );
+            DBUG(("PaHost_StartOutput: IDirectSoundBuffer_Play returned = 0x%X.\n", hr));
+            if( hr != DS_OK )
+            {
+                result = paUnanticipatedHostError;
+                PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr );
+                goto error;
+            }
+            stream->outputIsRunning = TRUE;
+        }
+    }
+
+
+    /* Create timer that will wake us up so we can fill the DSound buffer. */
+    {
+        int resolution;
+        int framesPerWakeup = stream->framesPerDSBuffer / 4;
+        int msecPerWakeup = MSEC_PER_SECOND * framesPerWakeup / (int) stream->streamRepresentation.streamInfo.sampleRate;
+        if( msecPerWakeup < 10 ) msecPerWakeup = 10;
+        else if( msecPerWakeup > 100 ) msecPerWakeup = 100;
+        resolution = msecPerWakeup/4;
+        stream->timerID = timeSetEvent( msecPerWakeup, resolution, (LPTIMECALLBACK) Pa_TimerCallback,
+                                             (DWORD_PTR) stream, TIME_PERIODIC );
+    }
+    if( stream->timerID == 0 )
+    {
+        stream->isActive = 0;
+        result = paUnanticipatedHostError;
+        PA_DS_SET_LAST_DIRECTSOUND_ERROR( hr );
+        goto error;
+    }
+
+    stream->isStarted = TRUE;
+
+error:
+    return result;
+}
+
+
+/***********************************************************************************/
+static PaError StopStream( PaStream *s )
+{
+    PaError result = paNoError;
+    PaWinDsStream *stream = (PaWinDsStream*)s;
+    HRESULT          hr;
+    int timeoutMsec;
+
+    stream->stopProcessing = 1;
+    /* Set timeout at 20% beyond maximum time we might wait. */
+    timeoutMsec = (int) (1200.0 * stream->framesPerDSBuffer / stream->streamRepresentation.streamInfo.sampleRate);
+    while( stream->isActive && (timeoutMsec > 0)  )
+    {
+        Sleep(10);
+        timeoutMsec -= 10;
+    }
+    if( stream->timerID != 0 )
+    {
+        timeKillEvent(stream->timerID);  /* Stop callback timer. */
+        stream->timerID = 0;
+    }
+
+
+    if( stream->bufferProcessor.outputChannelCount > 0 )
+    {
+        // Stop the buffer playback
+        if( stream->pDirectSoundOutputBuffer != NULL )
+        {
+            stream->outputIsRunning = FALSE;
+            // FIXME: what happens if IDirectSoundBuffer_Stop returns an error?
+            hr = IDirectSoundBuffer_Stop( stream->pDirectSoundOutputBuffer );
+        }
+    }
+
+    if( stream->bufferProcessor.inputChannelCount > 0 )
+    {
+        // Stop the buffer capture
+        if( stream->pDirectSoundInputBuffer != NULL )
+        {
+            // FIXME: what happens if IDirectSoundCaptureBuffer_Stop returns an error?
+            hr = IDirectSoundCaptureBuffer_Stop( stream->pDirectSoundInputBuffer );
+        }
+    }
+
+    stream->isStarted = FALSE;
+
+    return result;
+}
+
+
+/***********************************************************************************/
+static PaError AbortStream( PaStream *s )
+{
+    PaWinDsStream *stream = (PaWinDsStream*)s;
+
+    stream->abortProcessing = 1;
+    return StopStream( s );
+}
+
+
+/***********************************************************************************/
+static PaError IsStreamStopped( PaStream *s )
+{
+    PaWinDsStream *stream = (PaWinDsStream*)s;
+
+    return !stream->isStarted;
+}
+
+
+/***********************************************************************************/
+static PaError IsStreamActive( PaStream *s )
+{
+    PaWinDsStream *stream = (PaWinDsStream*)s;
+
+    return stream->isActive;
+}
+
+/***********************************************************************************/
+static PaTime GetStreamTime( PaStream *s )
+{
+    /* suppress unused variable warnings */
+    (void) s;
+
+    return PaUtil_GetTime();
+}
+
+
+/***********************************************************************************/
+static double GetStreamCpuLoad( PaStream* s )
+{
+    PaWinDsStream *stream = (PaWinDsStream*)s;
+
+    return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
+}
+
+
+/***********************************************************************************
+    As separate stream interfaces are used for blocking and callback
+    streams, the following functions can be guaranteed to only be called
+    for blocking streams.
+*/
+
+static PaError ReadStream( PaStream* s,
+                           void *buffer,
+                           unsigned long frames )
+{
+    PaWinDsStream *stream = (PaWinDsStream*)s;
+
+    /* suppress unused variable warnings */
+    (void) buffer;
+    (void) frames;
+    (void) stream;
+
+    /* IMPLEMENT ME, see portaudio.h for required behavior*/
+
+    return paNoError;
+}
+
+
+/***********************************************************************************/
+static PaError WriteStream( PaStream* s,
+                            const void *buffer,
+                            unsigned long frames )
+{
+    PaWinDsStream *stream = (PaWinDsStream*)s;
+
+    /* suppress unused variable warnings */
+    (void) buffer;
+    (void) frames;
+    (void) stream;
+
+    /* IMPLEMENT ME, see portaudio.h for required behavior*/
+
+    return paNoError;
+}
+
+
+/***********************************************************************************/
+static signed long GetStreamReadAvailable( PaStream* s )
+{
+    PaWinDsStream *stream = (PaWinDsStream*)s;
+
+    /* suppress unused variable warnings */
+    (void) stream;
+
+    /* IMPLEMENT ME, see portaudio.h for required behavior*/
+
+    return 0;
+}
+
+
+/***********************************************************************************/
+static signed long GetStreamWriteAvailable( PaStream* s )
+{
+    PaWinDsStream *stream = (PaWinDsStream*)s;
+
+    /* suppress unused variable warnings */
+    (void) stream;
+    
+    /* IMPLEMENT ME, see portaudio.h for required behavior*/
+
+    return 0;
+}
+
+
+
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/dsound/pa_win_ds_dynlink.c b/utils/iaxclient/lib/portaudio/src/hostapi/dsound/pa_win_ds_dynlink.c
new file mode 100644 (file)
index 0000000..ef8a41c
--- /dev/null
@@ -0,0 +1,121 @@
+#include "pa_win_ds_dynlink.h"
+
+
+PaWinDsDSoundEntryPoints paWinDsDSoundEntryPoints = { 0, 0, 0, 0, 0, 0, 0 };
+
+
+static HRESULT WINAPI DummyDirectSoundCreate(LPGUID lpcGuidDevice, LPDIRECTSOUND *ppDS, LPUNKNOWN pUnkOuter)
+{
+    (void)lpcGuidDevice; /* unused parameter */
+    (void)ppDS; /* unused parameter */
+    (void)pUnkOuter; /* unused parameter */
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DummyDirectSoundEnumerateW(LPDSENUMCALLBACKW lpDSEnumCallback, LPVOID lpContext)
+{
+    (void)lpDSEnumCallback; /* unused parameter */
+    (void)lpContext; /* unused parameter */
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DummyDirectSoundEnumerateA(LPDSENUMCALLBACKA lpDSEnumCallback, LPVOID lpContext)
+{
+    (void)lpDSEnumCallback; /* unused parameter */
+    (void)lpContext; /* unused parameter */
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DummyDirectSoundCaptureCreate(LPGUID lpcGUID, LPDIRECTSOUNDCAPTURE *lplpDSC, LPUNKNOWN pUnkOuter)
+{
+    (void)lpcGUID; /* unused parameter */
+    (void)lplpDSC; /* unused parameter */
+    (void)pUnkOuter; /* unused parameter */
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DummyDirectSoundCaptureEnumerateW(LPDSENUMCALLBACKW lpDSCEnumCallback, LPVOID lpContext)
+{
+    (void)lpDSCEnumCallback; /* unused parameter */
+    (void)lpContext; /* unused parameter */
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DummyDirectSoundCaptureEnumerateA(LPDSENUMCALLBACKA lpDSCEnumCallback, LPVOID lpContext)
+{
+    (void)lpDSCEnumCallback; /* unused parameter */
+    (void)lpContext; /* unused parameter */
+    return E_NOTIMPL;
+}
+
+
+void PaWinDs_InitializeDSoundEntryPoints(void)
+{
+    paWinDsDSoundEntryPoints.hInstance_ = LoadLibrary("dsound.dll");
+    if( paWinDsDSoundEntryPoints.hInstance_ != NULL )
+    {
+        paWinDsDSoundEntryPoints.DirectSoundCreate =
+                (HRESULT (WINAPI *)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN))
+                GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundCreate" );
+        if( paWinDsDSoundEntryPoints.DirectSoundCreate == NULL )
+            paWinDsDSoundEntryPoints.DirectSoundCreate = DummyDirectSoundCreate;
+
+        paWinDsDSoundEntryPoints.DirectSoundEnumerateW =
+                (HRESULT (WINAPI *)(LPDSENUMCALLBACKW, LPVOID))
+                GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundEnumerateW" );
+        if( paWinDsDSoundEntryPoints.DirectSoundEnumerateW == NULL )
+            paWinDsDSoundEntryPoints.DirectSoundEnumerateW = DummyDirectSoundEnumerateW;
+
+        paWinDsDSoundEntryPoints.DirectSoundEnumerateA =
+                (HRESULT (WINAPI *)(LPDSENUMCALLBACKA, LPVOID))
+                GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundEnumerateA" );
+        if( paWinDsDSoundEntryPoints.DirectSoundEnumerateA == NULL )
+            paWinDsDSoundEntryPoints.DirectSoundEnumerateA = DummyDirectSoundEnumerateA;
+
+        paWinDsDSoundEntryPoints.DirectSoundCaptureCreate =
+                (HRESULT (WINAPI *)(LPGUID, LPDIRECTSOUNDCAPTURE *, LPUNKNOWN))
+                GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundCaptureCreate" );
+        if( paWinDsDSoundEntryPoints.DirectSoundCaptureCreate == NULL )
+            paWinDsDSoundEntryPoints.DirectSoundCaptureCreate = DummyDirectSoundCaptureCreate;
+
+        paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW =
+                (HRESULT (WINAPI *)(LPDSENUMCALLBACKW, LPVOID))
+                GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundCaptureEnumerateW" );
+        if( paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW == NULL )
+            paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW = DummyDirectSoundCaptureEnumerateW;
+
+        paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA =
+                (HRESULT (WINAPI *)(LPDSENUMCALLBACKA, LPVOID))
+                GetProcAddress( paWinDsDSoundEntryPoints.hInstance_, "DirectSoundCaptureEnumerateA" );
+        if( paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA == NULL )
+            paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA = DummyDirectSoundCaptureEnumerateA;
+    }
+    else
+    {
+        /* initialize with dummy entry points to make live easy when ds isn't present */
+        paWinDsDSoundEntryPoints.DirectSoundCreate = DummyDirectSoundCreate;
+        paWinDsDSoundEntryPoints.DirectSoundEnumerateW = DummyDirectSoundEnumerateW;
+        paWinDsDSoundEntryPoints.DirectSoundEnumerateA = DummyDirectSoundEnumerateA;
+        paWinDsDSoundEntryPoints.DirectSoundCaptureCreate = DummyDirectSoundCaptureCreate;
+        paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW = DummyDirectSoundCaptureEnumerateW;
+        paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA = DummyDirectSoundCaptureEnumerateA;
+    }
+}
+
+
+void PaWinDs_TerminateDSoundEntryPoints(void)
+{
+    if( paWinDsDSoundEntryPoints.hInstance_ != NULL )
+    {
+        /* ensure that we crash reliably if the entry points arent initialised */
+        paWinDsDSoundEntryPoints.DirectSoundCreate = 0;
+        paWinDsDSoundEntryPoints.DirectSoundEnumerateW = 0;
+        paWinDsDSoundEntryPoints.DirectSoundEnumerateA = 0;
+        paWinDsDSoundEntryPoints.DirectSoundCaptureCreate = 0;
+        paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateW = 0;
+        paWinDsDSoundEntryPoints.DirectSoundCaptureEnumerateA = 0;
+
+        FreeLibrary( paWinDsDSoundEntryPoints.hInstance_ );
+        paWinDsDSoundEntryPoints.hInstance_ = NULL;
+    }
+}
\ No newline at end of file
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/dsound/pa_win_ds_dynlink.h b/utils/iaxclient/lib/portaudio/src/hostapi/dsound/pa_win_ds_dynlink.h
new file mode 100644 (file)
index 0000000..281287b
--- /dev/null
@@ -0,0 +1,82 @@
+#ifndef INCLUDED_PA_DSOUND_DYNLINK_H
+#define INCLUDED_PA_DSOUND_DYNLINK_H
+/*
+ * Interface for dynamically loading directsound and providing a dummy
+ * implementation if it isn't present.
+ *
+ * Author: Ross Bencina (some portions Phil Burk & Robert Marsanyi
+ *
+ * For PortAudio Portable Real-Time Audio Library
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2006 Phil Burk, Robert Marsanyi and Ross Bencina
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/* on Borland compilers, WIN32 doesn't seem to be defined by default, which
+    breaks DSound.h. Adding the define here fixes the problem. - rossb. */
+#ifdef __BORLANDC__
+#if !defined(WIN32)
+#define WIN32
+#endif
+#endif
+
+/*
+  We are only using DX3 in here, no need to polute the namespace - davidv
+*/
+#define DIRECTSOUND_VERSION 0x0300
+
+#include <DSound.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+
+typedef struct
+{
+    HINSTANCE hInstance_;
+    
+    HRESULT (WINAPI *DirectSoundCreate)(LPGUID, LPDIRECTSOUND *, LPUNKNOWN);
+    HRESULT (WINAPI *DirectSoundEnumerateW)(LPDSENUMCALLBACKW, LPVOID);
+    HRESULT (WINAPI *DirectSoundEnumerateA)(LPDSENUMCALLBACKA, LPVOID);
+
+    HRESULT (WINAPI *DirectSoundCaptureCreate)(LPGUID, LPDIRECTSOUNDCAPTURE *, LPUNKNOWN);
+    HRESULT (WINAPI *DirectSoundCaptureEnumerateW)(LPDSENUMCALLBACKW, LPVOID);
+    HRESULT (WINAPI *DirectSoundCaptureEnumerateA)(LPDSENUMCALLBACKA, LPVOID);
+}PaWinDsDSoundEntryPoints;
+
+extern PaWinDsDSoundEntryPoints paWinDsDSoundEntryPoints;
+
+void PaWinDs_InitializeDSoundEntryPoints(void);
+void PaWinDs_TerminateDSoundEntryPoints(void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* INCLUDED_PA_DSOUND_DYNLINK_H */
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/jack/pa_jack.c b/utils/iaxclient/lib/portaudio/src/hostapi/jack/pa_jack.c
new file mode 100644 (file)
index 0000000..8f402bc
--- /dev/null
@@ -0,0 +1,1730 @@
+/*
+ * $Id: pa_jack.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * PortAudio Portable Real-Time Audio Library
+ * Latest Version at: http://www.portaudio.com
+ * JACK Implementation by Joshua Haberman
+ *
+ * Copyright (c) 2004 Stefan Westerfeld <stefan@space.twc.de>
+ * Copyright (c) 2004 Arve Knudsen <aknuds-1@broadpark.no>
+ * Copyright (c) 2002 Joshua Haberman <joshua@haberman.com>
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2002 Ross Bencina, Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <string.h>
+#include <regex.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>  /* EBUSY */
+#include <signal.h> /* sig_atomic_t */
+#include <math.h>
+#include <semaphore.h>
+
+#include <jack/types.h>
+#include <jack/jack.h>
+
+#include "pa_util.h"
+#include "pa_hostapi.h"
+#include "pa_stream.h"
+#include "pa_process.h"
+#include "pa_allocation.h"
+#include "pa_cpuload.h"
+#include "../pablio/ringbuffer.c"
+
+static int aErr_;
+static PaError paErr_;     /* For use with ENSURE_PA */
+static pthread_t mainThread_;
+static char *jackErr_ = NULL;
+
+#define STRINGIZE_HELPER(expr) #expr
+#define STRINGIZE(expr) STRINGIZE_HELPER(expr)
+
+/* Check PaError */
+#define ENSURE_PA(expr) \
+    do { \
+        if( (paErr_ = (expr)) < paNoError ) \
+        { \
+            if( (paErr_) == paUnanticipatedHostError && pthread_self() == mainThread_ ) \
+            { \
+                assert( jackErr_ ); \
+                PaUtil_SetLastHostErrorInfo( paJACK, -1, jackErr_ ); \
+            } \
+            PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
+            result = paErr_; \
+            goto error; \
+        } \
+    } while( 0 )
+
+#define UNLESS(expr, code) \
+    do { \
+        if( (expr) == 0 ) \
+        { \
+            if( (code) == paUnanticipatedHostError && pthread_self() == mainThread_ ) \
+            { \
+                assert( jackErr_ ); \
+                PaUtil_SetLastHostErrorInfo( paJACK, -1, jackErr_ ); \
+            } \
+            PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
+            result = (code); \
+            goto error; \
+        } \
+    } while( 0 )
+
+#define ASSERT_CALL(expr, success) \
+    aErr_ = (expr); \
+    assert( aErr_ == success );
+
+/*
+ * Functions that directly map to the PortAudio stream interface
+ */
+
+static void Terminate( struct PaUtilHostApiRepresentation *hostApi );
+static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
+                                  const PaStreamParameters *inputParameters,
+                                  const PaStreamParameters *outputParameters,
+                                  double sampleRate );
+static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
+                           PaStream** s,
+                           const PaStreamParameters *inputParameters,
+                           const PaStreamParameters *outputParameters,
+                           double sampleRate,
+                           unsigned long framesPerBuffer,
+                           PaStreamFlags streamFlags,
+                           PaStreamCallback *streamCallback,
+                           void *userData );
+static PaError CloseStream( PaStream* stream );
+static PaError StartStream( PaStream *stream );
+static PaError StopStream( PaStream *stream );
+static PaError AbortStream( PaStream *stream );
+static PaError IsStreamStopped( PaStream *s );
+static PaError IsStreamActive( PaStream *stream );
+/*static PaTime GetStreamInputLatency( PaStream *stream );*/
+/*static PaTime GetStreamOutputLatency( PaStream *stream );*/
+static PaTime GetStreamTime( PaStream *stream );
+static double GetStreamCpuLoad( PaStream* stream );
+
+
+/*
+ * Data specific to this API
+ */
+
+struct PaJackStream;
+
+typedef struct
+{
+    PaUtilHostApiRepresentation commonHostApiRep;
+    PaUtilStreamInterface callbackStreamInterface;
+    PaUtilStreamInterface blockingStreamInterface;
+
+    PaUtilAllocationGroup *deviceInfoMemory;
+
+    jack_client_t *jack_client;
+    int jack_buffer_size;
+    PaHostApiIndex hostApiIndex;
+
+    pthread_mutex_t mtx;
+    pthread_cond_t cond;
+    unsigned long inputBase, outputBase;
+
+    /* For dealing with the process thread */
+    volatile int xrun;     /* Received xrun notification from JACK? */
+    struct PaJackStream * volatile toAdd, * volatile toRemove;
+    struct PaJackStream *processQueue;
+    volatile sig_atomic_t jackIsDown;
+}
+PaJackHostApiRepresentation;
+
+/* PaJackStream - a stream data structure specifically for this implementation */
+
+typedef struct PaJackStream
+{
+    PaUtilStreamRepresentation streamRepresentation;
+    PaUtilBufferProcessor bufferProcessor;
+    PaUtilCpuLoadMeasurer cpuLoadMeasurer;
+    PaJackHostApiRepresentation *hostApi;
+
+    /* our input and output ports */
+    jack_port_t **local_input_ports;
+    jack_port_t **local_output_ports;
+
+    /* the input and output ports of the client we are connecting to */
+    jack_port_t **remote_input_ports;
+    jack_port_t **remote_output_ports;
+
+    int num_incoming_connections;
+    int num_outgoing_connections;
+
+    jack_client_t *jack_client;
+
+    /* The stream is running if it's still producing samples.
+     * The stream is active if samples it produced are still being heard.
+     */
+    volatile sig_atomic_t is_running;
+    volatile sig_atomic_t is_active;
+    /* Used to signal processing thread that stream should start or stop, respectively */
+    volatile sig_atomic_t doStart, doStop, doAbort;
+
+    jack_nframes_t t0;
+
+    PaUtilAllocationGroup *stream_memory;
+
+    /* These are useful in the process callback */
+
+    int callbackResult;
+    int isSilenced;
+    int xrun;
+
+    /* These are useful for the blocking API */
+
+    int                     isBlockingStream;
+    RingBuffer              inFIFO;
+    RingBuffer              outFIFO;
+    volatile sig_atomic_t   data_available;
+    sem_t                   data_semaphore;
+    int                     bytesPerFrame;
+    int                     samplesPerFrame;
+
+    struct PaJackStream *next;
+}
+PaJackStream;
+
+#define TRUE 1
+#define FALSE 0
+
+/*
+ * Functions specific to this API
+ */
+
+static int JackCallback( jack_nframes_t frames, void *userData );
+
+
+/*
+ *
+ * Implementation
+ *
+ */
+
+/* ---- blocking emulation layer ---- */
+
+/* Allocate buffer. */
+static PaError BlockingInitFIFO( RingBuffer *rbuf, long numFrames, long bytesPerFrame )
+{
+    long numBytes = numFrames * bytesPerFrame;
+    char *buffer = (char *) malloc( numBytes );
+    if( buffer == NULL ) return paInsufficientMemory;
+    memset( buffer, 0, numBytes );
+    return (PaError) RingBuffer_Init( rbuf, numBytes, buffer );
+}
+
+/* Free buffer. */
+static PaError BlockingTermFIFO( RingBuffer *rbuf )
+{
+    if( rbuf->buffer ) free( rbuf->buffer );
+    rbuf->buffer = NULL;
+    return paNoError;
+}
+
+static int
+BlockingCallback( const void                      *inputBuffer,
+                  void                            *outputBuffer,
+                 unsigned long                    framesPerBuffer,
+                 const PaStreamCallbackTimeInfo*  timeInfo,
+                 PaStreamCallbackFlags            statusFlags,
+                 void                             *userData )
+{
+    struct PaJackStream *stream = (PaJackStream *)userData;
+    long numBytes = stream->bytesPerFrame * framesPerBuffer;
+
+    /* This may get called with NULL inputBuffer during initial setup. */
+    if( inputBuffer != NULL )
+    {
+        RingBuffer_Write( &stream->inFIFO, inputBuffer, numBytes );
+    }
+    if( outputBuffer != NULL )
+    {
+        int numRead = RingBuffer_Read( &stream->outFIFO, outputBuffer, numBytes );
+        /* Zero out remainder of buffer if we run out of data. */
+        memset( (char *)outputBuffer + numRead, 0, numBytes - numRead );
+    }
+
+    if( !stream->data_available )
+    {
+        stream->data_available = 1;
+        sem_post( &stream->data_semaphore );
+    }
+    return paContinue;
+}
+
+static PaError
+BlockingBegin( PaJackStream *stream, int minimum_buffer_size )
+{
+    long    doRead = 0;
+    long    doWrite = 0;
+    PaError result = paNoError;
+    long    numFrames;
+
+    doRead = stream->local_input_ports != NULL;
+    doWrite = stream->local_output_ports != NULL;
+    /* <FIXME> */
+    stream->samplesPerFrame = 2;
+    stream->bytesPerFrame = sizeof(float) * stream->samplesPerFrame;
+    /* </FIXME> */
+    numFrames = 32;
+    while (numFrames < minimum_buffer_size)
+        numFrames *= 2;
+
+    if( doRead )
+    {
+        ENSURE_PA( BlockingInitFIFO( &stream->inFIFO, numFrames, stream->bytesPerFrame ) );
+    }
+    if( doWrite )
+    {
+        long numBytes;
+
+        ENSURE_PA( BlockingInitFIFO( &stream->outFIFO, numFrames, stream->bytesPerFrame ) );
+
+        /* Make Write FIFO appear full initially. */
+        numBytes = RingBuffer_GetWriteAvailable( &stream->outFIFO );
+        RingBuffer_AdvanceWriteIndex( &stream->outFIFO, numBytes );
+    }
+
+    stream->data_available = 0;
+    sem_init( &stream->data_semaphore, 0, 0 );
+
+error:
+    return result;
+}
+
+static void
+BlockingEnd( PaJackStream *stream )
+{
+    BlockingTermFIFO( &stream->inFIFO );
+    BlockingTermFIFO( &stream->outFIFO );
+
+    sem_destroy( &stream->data_semaphore );
+}
+
+static PaError BlockingReadStream( PaStream* s, void *data, unsigned long numFrames )
+{
+    PaError result = paNoError;
+    PaJackStream *stream = (PaJackStream *)s;
+
+    long bytesRead;
+    char *p = (char *) data;
+    long numBytes = stream->bytesPerFrame * numFrames;
+    while( numBytes > 0 )
+    {
+        bytesRead = RingBuffer_Read( &stream->inFIFO, p, numBytes );
+        numBytes -= bytesRead;
+        p += bytesRead;
+        if( numBytes > 0 )
+        {
+            /* see write for an explanation */
+            if( stream->data_available )
+                stream->data_available = 0;
+            else
+                sem_wait( &stream->data_semaphore );
+        }
+    }
+
+    return result;
+}
+
+static PaError BlockingWriteStream( PaStream* s, const void *data, unsigned long numFrames )
+{
+    PaError result = paNoError;
+    PaJackStream *stream = (PaJackStream *)s;
+    long bytesWritten;
+    char *p = (char *) data;
+    long numBytes = stream->bytesPerFrame * numFrames;
+    while( numBytes > 0 )
+    {
+        bytesWritten = RingBuffer_Write( &stream->outFIFO, p, numBytes );
+        numBytes -= bytesWritten;
+        p += bytesWritten;
+        if( numBytes > 0 ) 
+        {
+            /* we use the following algorithm: 
+             *   (1) write data
+             *   (2) if some data didn't fit into the ringbuffer, set data_available to 0
+             *       to indicate to the audio that if space becomes available, we want to know
+             *   (3) retry to write data (because it might be that between (1) and (2)
+             *       new space in the buffer became available)
+             *   (4) if this failed, we are sure that the buffer is really empty and
+             *       we will definitely receive a notification when it becomes available
+             *       thus we can safely sleep
+             *
+             * if the algorithm bailed out in step (3) before, it leaks a count of 1
+             * on the semaphore; however, it doesn't matter, because if we block in (4),
+             * we also do it in a loop
+             */
+            if( stream->data_available )
+                stream->data_available = 0;
+            else
+                sem_wait( &stream->data_semaphore );
+        }
+    }
+
+    return result;
+}
+
+static signed long
+BlockingGetStreamReadAvailable( PaStream* s )
+{
+    PaJackStream *stream = (PaJackStream *)s;
+
+    int bytesFull = RingBuffer_GetReadAvailable( &stream->inFIFO );
+    return bytesFull / stream->bytesPerFrame;
+}
+
+static signed long
+BlockingGetStreamWriteAvailable( PaStream* s )
+{
+    PaJackStream *stream = (PaJackStream *)s;
+
+    int bytesEmpty = RingBuffer_GetWriteAvailable( &stream->outFIFO );
+    return bytesEmpty / stream->bytesPerFrame;
+}
+
+static PaError
+BlockingWaitEmpty( PaStream *s )
+{
+    PaJackStream *stream = (PaJackStream *)s;
+
+    while( RingBuffer_GetReadAvailable( &stream->outFIFO ) > 0 )
+    {
+        stream->data_available = 0;
+        sem_wait( &stream->data_semaphore );
+    }
+    return 0;
+}
+
+/* ---- jack driver ---- */
+
+/* BuildDeviceList():
+ *
+ * The process of determining a list of PortAudio "devices" from
+ * JACK's client/port system is fairly involved, so it is separated
+ * into its own routine.
+ */
+
+static PaError BuildDeviceList( PaJackHostApiRepresentation *jackApi )
+{
+    /* Utility macros for the repetitive process of allocating memory */
+
+    /* ... MALLOC: allocate memory as part of the device list
+     * allocation group */
+#define MALLOC(size) \
+     (PaUtil_GroupAllocateMemory( jackApi->deviceInfoMemory, (size) ))
+
+    /* JACK has no concept of a device.  To JACK, there are clients
+     * which have an arbitrary number of ports.  To make this
+     * intelligible to PortAudio clients, we will group each JACK client
+     * into a device, and make each port of that client a channel */
+
+    PaError result = paNoError;
+    PaUtilHostApiRepresentation *commonApi = &jackApi->commonHostApiRep;
+
+    const char **jack_ports = NULL;
+    char **client_names = NULL;
+    char *regex_pattern = alloca( jack_client_name_size() + 3 );
+    int port_index, client_index, i;
+    double globalSampleRate;
+    regex_t port_regex;
+    unsigned long numClients = 0, numPorts = 0;
+    char *tmp_client_name = alloca( jack_client_name_size() );
+
+    commonApi->info.defaultInputDevice = paNoDevice;
+    commonApi->info.defaultOutputDevice = paNoDevice;
+    commonApi->info.deviceCount = 0;
+
+    /* Parse the list of ports, using a regex to grab the client names */
+    ASSERT_CALL( regcomp( &port_regex, "^[^:]*", REG_EXTENDED ), 0 );
+
+    /* since we are rebuilding the list of devices, free all memory
+     * associated with the previous list */
+    PaUtil_FreeAllAllocations( jackApi->deviceInfoMemory );
+
+    /* We can only retrieve the list of clients indirectly, by first
+     * asking for a list of all ports, then parsing the port names
+     * according to the client_name:port_name convention (which is
+     * enforced by jackd)
+     * A: If jack_get_ports returns NULL, there's nothing for us to do */
+    UNLESS( (jack_ports = jack_get_ports( jackApi->jack_client, "", "", 0 )) && jack_ports[0], paNoError );
+    /* Find number of ports */
+    while( jack_ports[numPorts] )
+        ++numPorts;
+    /* At least there will be one port per client :) */
+    UNLESS( client_names = alloca( numPorts * sizeof (char *) ), paInsufficientMemory );
+
+    /* Build a list of clients from the list of ports */
+    for( numClients = 0, port_index = 0; jack_ports[port_index] != NULL; port_index++ )
+    {
+        int client_seen = FALSE;
+        regmatch_t match_info;
+        const char *port = jack_ports[port_index];
+
+        /* extract the client name from the port name, using a regex
+         * that parses the clientname:portname syntax */
+        UNLESS( !regexec( &port_regex, port, 1, &match_info, 0 ), paInternalError );
+        assert(match_info.rm_eo - match_info.rm_so < jack_client_name_size());
+        memcpy( tmp_client_name, port + match_info.rm_so,
+                match_info.rm_eo - match_info.rm_so );
+        tmp_client_name[match_info.rm_eo - match_info.rm_so] = '\0';
+
+        /* do we know about this port's client yet? */
+        for( i = 0; i < numClients; i++ )
+        {
+            if( strcmp( tmp_client_name, client_names[i] ) == 0 )
+                client_seen = TRUE;
+        }
+
+        if (client_seen)
+            continue;   /* A: Nothing to see here, move along */
+
+        UNLESS( client_names[numClients] = (char*)MALLOC(strlen(tmp_client_name) + 1), paInsufficientMemory );
+
+        /* The alsa_pcm client should go in spot 0.  If this
+         * is the alsa_pcm client AND we are NOT about to put
+         * it in spot 0 put it in spot 0 and move whatever
+         * was already in spot 0 to the end. */
+        if( strcmp( "alsa_pcm", tmp_client_name ) == 0 && numClients > 0 )
+        {
+            /* alsa_pcm goes in spot 0 */
+            strcpy( client_names[ numClients ], client_names[0] );
+            strcpy( client_names[0], tmp_client_name );
+        }
+        else
+        {
+            /* put the new client at the end of the client list */
+            strcpy( client_names[ numClients ], tmp_client_name );
+        }
+        ++numClients;
+    }
+
+    /* Now we have a list of clients, which will become the list of
+     * PortAudio devices. */
+
+    /* there is one global sample rate all clients must conform to */
+
+    globalSampleRate = jack_get_sample_rate( jackApi->jack_client );
+    UNLESS( commonApi->deviceInfos = (PaDeviceInfo**)MALLOC( sizeof(PaDeviceInfo*) *
+                                                     numClients ), paInsufficientMemory );
+
+    assert( commonApi->info.deviceCount == 0 );
+
+    /* Create a PaDeviceInfo structure for every client */
+    for( client_index = 0; client_index < numClients; client_index++ )
+    {
+        PaDeviceInfo *curDevInfo;
+        const char **clientPorts = NULL;
+
+        UNLESS( curDevInfo = (PaDeviceInfo*)MALLOC( sizeof(PaDeviceInfo) ), paInsufficientMemory );
+        UNLESS( curDevInfo->name = (char*)MALLOC( strlen(client_names[client_index]) + 1 ), paInsufficientMemory );
+        strcpy( (char *)curDevInfo->name, client_names[client_index] );
+
+        curDevInfo->structVersion = 2;
+        curDevInfo->hostApi = jackApi->hostApiIndex;
+
+        /* JACK is very inflexible: there is one sample rate the whole
+         * system must run at, and all clients must speak IEEE float. */
+        curDevInfo->defaultSampleRate = globalSampleRate;
+
+        /* To determine how many input and output channels are available,
+         * we re-query jackd with more specific parameters. */
+
+        sprintf( regex_pattern, "%s:.*", client_names[client_index] );
+
+        /* ... what are your output ports (that we could input from)? */
+        clientPorts = jack_get_ports( jackApi->jack_client, regex_pattern,
+                                     NULL, JackPortIsOutput);
+        curDevInfo->maxInputChannels = 0;
+        curDevInfo->defaultLowInputLatency = 0.;
+        curDevInfo->defaultHighInputLatency = 0.;
+        if( clientPorts )
+        {
+            jack_port_t *p = jack_port_by_name( jackApi->jack_client, clientPorts[0] );
+            curDevInfo->defaultLowInputLatency = curDevInfo->defaultHighInputLatency =
+                jack_port_get_latency( p ) / globalSampleRate;
+
+            for( i = 0; clientPorts[i] != NULL; i++)
+            {
+                /* The number of ports returned is the number of output channels.
+                 * We don't care what they are, we just care how many */
+                curDevInfo->maxInputChannels++;
+            }
+            free(clientPorts);
+        }
+
+        /* ... what are your input ports (that we could output to)? */
+        clientPorts = jack_get_ports( jackApi->jack_client, regex_pattern,
+                                     NULL, JackPortIsInput);
+        curDevInfo->maxOutputChannels = 0;
+        curDevInfo->defaultLowOutputLatency = 0.;
+        curDevInfo->defaultHighOutputLatency = 0.;
+        if( clientPorts )
+        {
+            jack_port_t *p = jack_port_by_name( jackApi->jack_client, clientPorts[0] );
+            curDevInfo->defaultLowOutputLatency = curDevInfo->defaultHighOutputLatency =
+                jack_port_get_latency( p ) / globalSampleRate;
+
+            for( i = 0; clientPorts[i] != NULL; i++)
+            {
+                /* The number of ports returned is the number of input channels.
+                 * We don't care what they are, we just care how many */
+                curDevInfo->maxOutputChannels++;
+            }
+            free(clientPorts);
+        }
+
+        /* Add this client to the list of devices */
+        commonApi->deviceInfos[client_index] = curDevInfo;
+        ++commonApi->info.deviceCount;
+        if( commonApi->info.defaultInputDevice == paNoDevice && curDevInfo->maxInputChannels > 0 )
+            commonApi->info.defaultInputDevice = client_index;
+        if( commonApi->info.defaultOutputDevice == paNoDevice && curDevInfo->maxOutputChannels > 0 )
+            commonApi->info.defaultOutputDevice = client_index;
+    }
+
+error:
+    regfree( &port_regex );
+    free( jack_ports );
+    return result;
+}
+#undef MALLOC
+
+static void UpdateSampleRate( PaJackStream *stream, double sampleRate )
+{
+    /* XXX: Maybe not the cleanest way of going about this? */
+    stream->cpuLoadMeasurer.samplingPeriod = stream->bufferProcessor.samplePeriod = 1. / sampleRate;
+    stream->streamRepresentation.streamInfo.sampleRate = sampleRate;
+}
+
+static void JackErrorCallback( const char *msg )
+{
+    if( pthread_self() == mainThread_ )
+    {
+        assert( msg );
+        free( jackErr_ );
+        jackErr_ = malloc( strlen( msg ) );
+        sprintf( jackErr_, msg );
+    }
+}
+
+static void JackOnShutdown( void *arg )
+{
+    PaJackHostApiRepresentation *jackApi = (PaJackHostApiRepresentation *)arg;
+    PaJackStream *stream = jackApi->processQueue;
+
+    PA_DEBUG(( "%s: JACK server is shutting down\n", __FUNCTION__ ));
+    for( ; stream; stream = stream->next )
+    {
+        stream->is_active = 0;
+    }
+
+    /* Make sure that the main thread doesn't get stuck waiting on the condition */
+    ASSERT_CALL( pthread_mutex_lock( &jackApi->mtx ), 0 );
+    jackApi->jackIsDown = 1;
+    ASSERT_CALL( pthread_cond_signal( &jackApi->cond ), 0 );
+    ASSERT_CALL( pthread_mutex_unlock( &jackApi->mtx ), 0 );
+
+}
+
+static int JackSrCb( jack_nframes_t nframes, void *arg )
+{
+    PaJackHostApiRepresentation *jackApi = (PaJackHostApiRepresentation *)arg;
+    double sampleRate = (double)nframes;
+    PaJackStream *stream = jackApi->processQueue;
+
+    /* Update all streams in process queue */
+    PA_DEBUG(( "%s: Acting on change in JACK samplerate: %f\n", __FUNCTION__, sampleRate ));
+    for( ; stream; stream = stream->next )
+    {
+        if( stream->streamRepresentation.streamInfo.sampleRate != sampleRate )
+        {
+            PA_DEBUG(( "%s: Updating samplerate\n", __FUNCTION__ ));
+            UpdateSampleRate( stream, sampleRate );
+        }
+    }
+
+    return 0;
+}
+
+static int JackXRunCb(void *arg) {
+    PaJackHostApiRepresentation *hostApi = (PaJackHostApiRepresentation *)arg;
+    assert( hostApi );
+    hostApi->xrun = TRUE;
+    PA_DEBUG(( "%s: JACK signalled xrun\n", __FUNCTION__ ));
+    return 0;
+}
+
+PaError PaJack_Initialize( PaUtilHostApiRepresentation **hostApi,
+                           PaHostApiIndex hostApiIndex )
+{
+    PaError result = paNoError;
+    PaJackHostApiRepresentation *jackHostApi;
+    int activated = 0;
+    char *clientName;
+    int written;
+    *hostApi = NULL;    /* Initialize to NULL */
+
+    UNLESS( jackHostApi = (PaJackHostApiRepresentation*)
+        PaUtil_AllocateMemory( sizeof(PaJackHostApiRepresentation) ), paInsufficientMemory );
+    jackHostApi->deviceInfoMemory = NULL;
+
+    mainThread_ = pthread_self();
+    ASSERT_CALL( pthread_mutex_init( &jackHostApi->mtx, NULL ), 0 );
+    ASSERT_CALL( pthread_cond_init( &jackHostApi->cond, NULL ), 0 );
+
+    /* Try to become a client of the JACK server.  If we cannot do
+     * this, then this API cannot be used. */
+
+    clientName = alloca( jack_client_name_size() );
+    written = snprintf( clientName, jack_client_name_size(), "PortAudio-%d", getpid() );
+    assert( written < jack_client_name_size() );
+    jackHostApi->jack_client = jack_client_new( clientName );
+    if( jackHostApi->jack_client == NULL )
+    {
+       /* the V19 development docs say that if an implementation
+        * detects that it cannot be used, it should return a NULL
+        * interface and paNoError */
+       result = paNoError;
+       goto error;
+    }
+
+    UNLESS( jackHostApi->deviceInfoMemory = PaUtil_CreateAllocationGroup(), paInsufficientMemory );
+    jackHostApi->hostApiIndex = hostApiIndex;
+
+    *hostApi = &jackHostApi->commonHostApiRep;
+    (*hostApi)->info.structVersion = 1;
+    (*hostApi)->info.type = paJACK;
+    (*hostApi)->info.name = "JACK Audio Connection Kit";
+
+    /* Build a device list by querying the JACK server */
+
+    ENSURE_PA( BuildDeviceList( jackHostApi ) );
+
+    /* Register functions */
+
+    (*hostApi)->Terminate = Terminate;
+    (*hostApi)->OpenStream = OpenStream;
+    (*hostApi)->IsFormatSupported = IsFormatSupported;
+
+    PaUtil_InitializeStreamInterface( &jackHostApi->callbackStreamInterface,
+                                      CloseStream, StartStream,
+                                      StopStream, AbortStream,
+                                      IsStreamStopped, IsStreamActive,
+                                      GetStreamTime, GetStreamCpuLoad,
+                                      PaUtil_DummyRead, PaUtil_DummyWrite,
+                                      PaUtil_DummyGetReadAvailable,
+                                      PaUtil_DummyGetWriteAvailable );
+
+    PaUtil_InitializeStreamInterface( &jackHostApi->blockingStreamInterface, CloseStream, StartStream,
+                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
+                                      GetStreamTime, PaUtil_DummyGetCpuLoad,
+                                      BlockingReadStream, BlockingWriteStream,
+                                      BlockingGetStreamReadAvailable, BlockingGetStreamWriteAvailable );
+
+    jackHostApi->inputBase = jackHostApi->outputBase = 0;
+    jackHostApi->xrun = 0;
+    jackHostApi->toAdd = jackHostApi->toRemove = NULL;
+    jackHostApi->processQueue = NULL;
+    jackHostApi->jackIsDown = 0;
+
+    jack_on_shutdown( jackHostApi->jack_client, JackOnShutdown, jackHostApi );
+    jack_set_error_function( JackErrorCallback );
+    jackHostApi->jack_buffer_size = jack_get_buffer_size ( jackHostApi->jack_client );
+    UNLESS( !jack_set_sample_rate_callback( jackHostApi->jack_client, JackSrCb, jackHostApi ), paUnanticipatedHostError );
+    UNLESS( !jack_set_xrun_callback( jackHostApi->jack_client, JackXRunCb, jackHostApi ), paUnanticipatedHostError );
+    UNLESS( !jack_set_process_callback( jackHostApi->jack_client, JackCallback, jackHostApi ), paUnanticipatedHostError );
+    UNLESS( !jack_activate( jackHostApi->jack_client ), paUnanticipatedHostError );
+    activated = 1;
+
+    return result;
+
+error:
+    if( activated )
+        ASSERT_CALL( jack_deactivate( jackHostApi->jack_client ), 0 );
+
+    if( jackHostApi )
+    {
+        if( jackHostApi->jack_client )
+            ASSERT_CALL( jack_client_close( jackHostApi->jack_client ), 0 );
+
+        if( jackHostApi->deviceInfoMemory )
+        {
+            PaUtil_FreeAllAllocations( jackHostApi->deviceInfoMemory );
+            PaUtil_DestroyAllocationGroup( jackHostApi->deviceInfoMemory );
+        }
+
+        PaUtil_FreeMemory( jackHostApi );
+    }
+    return result;
+}
+
+
+static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
+{
+    PaJackHostApiRepresentation *jackHostApi = (PaJackHostApiRepresentation*)hostApi;
+
+    /* note: this automatically disconnects all ports, since a deactivated
+     * client is not allowed to have any ports connected */
+    ASSERT_CALL( jack_deactivate( jackHostApi->jack_client ), 0 );
+
+    ASSERT_CALL( pthread_mutex_destroy( &jackHostApi->mtx ), 0 );
+    ASSERT_CALL( pthread_cond_destroy( &jackHostApi->cond ), 0 );
+
+    ASSERT_CALL( jack_client_close( jackHostApi->jack_client ), 0 );
+
+    if( jackHostApi->deviceInfoMemory )
+    {
+        PaUtil_FreeAllAllocations( jackHostApi->deviceInfoMemory );
+        PaUtil_DestroyAllocationGroup( jackHostApi->deviceInfoMemory );
+    }
+
+    PaUtil_FreeMemory( jackHostApi );
+
+    free( jackErr_ );
+}
+
+static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
+                                  const PaStreamParameters *inputParameters,
+                                  const PaStreamParameters *outputParameters,
+                                  double sampleRate )
+{
+    int inputChannelCount = 0, outputChannelCount = 0;
+    PaSampleFormat inputSampleFormat, outputSampleFormat;
+
+    if( inputParameters )
+    {
+        inputChannelCount = inputParameters->channelCount;
+        inputSampleFormat = inputParameters->sampleFormat;
+
+        /* unless alternate device specification is supported, reject the use of
+            paUseHostApiSpecificDeviceSpecification */
+
+        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
+            return paInvalidDevice;
+
+        /* check that input device can support inputChannelCount */
+        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )
+            return paInvalidChannelCount;
+
+        /* validate inputStreamInfo */
+        if( inputParameters->hostApiSpecificStreamInfo )
+            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
+    }
+    else
+    {
+        inputChannelCount = 0;
+    }
+
+    if( outputParameters )
+    {
+        outputChannelCount = outputParameters->channelCount;
+        outputSampleFormat = outputParameters->sampleFormat;
+
+        /* unless alternate device specification is supported, reject the use of
+            paUseHostApiSpecificDeviceSpecification */
+
+        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
+            return paInvalidDevice;
+
+        /* check that output device can support inputChannelCount */
+        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )
+            return paInvalidChannelCount;
+
+        /* validate outputStreamInfo */
+        if( outputParameters->hostApiSpecificStreamInfo )
+            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
+    }
+    else
+    {
+        outputChannelCount = 0;
+    }
+
+    /*
+        The following check is not necessary for JACK.
+        
+            - if a full duplex stream is requested, check that the combination
+                of input and output parameters is supported
+
+
+        Because the buffer adapter handles conversion between all standard
+        sample formats, the following checks are only required if paCustomFormat
+        is implemented, or under some other unusual conditions.
+        
+            - check that input device can support inputSampleFormat, or that
+                we have the capability to convert from outputSampleFormat to
+                a native format
+
+            - check that output device can support outputSampleFormat, or that
+                we have the capability to convert from outputSampleFormat to
+                a native format
+    */
+
+    /* check that the device supports sampleRate */
+    
+#define ABS(x) ( (x) > 0 ? (x) : -(x) )
+    if( ABS(sampleRate - jack_get_sample_rate(((PaJackHostApiRepresentation *) hostApi)->jack_client )) > 1 )
+       return paInvalidSampleRate;
+#undef ABS
+
+    return paFormatIsSupported;
+}
+
+/* Basic stream initialization */
+static PaError InitializeStream( PaJackStream *stream, PaJackHostApiRepresentation *hostApi, int numInputChannels,
+        int numOutputChannels )
+{
+    PaError result = paNoError;
+    assert( stream );
+
+    memset( stream, 0, sizeof (PaJackStream) );
+    UNLESS( stream->stream_memory = PaUtil_CreateAllocationGroup(), paInsufficientMemory );
+    stream->jack_client = hostApi->jack_client;
+    stream->hostApi = hostApi;
+
+    if( numInputChannels > 0 )
+    {
+        UNLESS( stream->local_input_ports =
+                (jack_port_t**) PaUtil_GroupAllocateMemory( stream->stream_memory, sizeof(jack_port_t*) * numInputChannels ),
+                paInsufficientMemory );
+        memset( stream->local_input_ports, 0, sizeof(jack_port_t*) * numInputChannels );
+        UNLESS( stream->remote_output_ports =
+                (jack_port_t**) PaUtil_GroupAllocateMemory( stream->stream_memory, sizeof(jack_port_t*) * numInputChannels ),
+                paInsufficientMemory );
+        memset( stream->remote_output_ports, 0, sizeof(jack_port_t*) * numInputChannels );
+    }
+    if( numOutputChannels > 0 )
+    {
+        UNLESS( stream->local_output_ports =
+                (jack_port_t**) PaUtil_GroupAllocateMemory( stream->stream_memory, sizeof(jack_port_t*) * numOutputChannels ),
+                paInsufficientMemory );
+        memset( stream->local_output_ports, 0, sizeof(jack_port_t*) * numOutputChannels );
+        UNLESS( stream->remote_input_ports =
+                (jack_port_t**) PaUtil_GroupAllocateMemory( stream->stream_memory, sizeof(jack_port_t*) * numOutputChannels ),
+                paInsufficientMemory );
+        memset( stream->remote_input_ports, 0, sizeof(jack_port_t*) * numOutputChannels );
+    }
+
+    stream->num_incoming_connections = numInputChannels;
+    stream->num_outgoing_connections = numOutputChannels;
+
+error:
+    return result;
+}
+
+/*!
+ * Free resources associated with stream, and eventually stream itself.
+ *
+ * Frees allocated memory, and closes opened pcms.
+ */
+static void CleanUpStream( PaJackStream *stream, int terminateStreamRepresentation, int terminateBufferProcessor )
+{
+    int i;
+    assert( stream );
+
+    if( stream->isBlockingStream )
+        BlockingEnd( stream );
+
+    for( i = 0; i < stream->num_incoming_connections; ++i )
+    {
+        if( stream->local_input_ports[i] )
+            ASSERT_CALL( jack_port_unregister( stream->jack_client, stream->local_input_ports[i] ), 0 );
+    }
+    for( i = 0; i < stream->num_outgoing_connections; ++i )
+    {
+        if( stream->local_output_ports[i] )
+            ASSERT_CALL( jack_port_unregister( stream->jack_client, stream->local_output_ports[i] ), 0 );
+    }
+
+    if( terminateStreamRepresentation )
+        PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
+    if( terminateBufferProcessor )
+        PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
+
+    if( stream->stream_memory )
+    {
+        PaUtil_FreeAllAllocations( stream->stream_memory );
+        PaUtil_DestroyAllocationGroup( stream->stream_memory );
+    }
+    PaUtil_FreeMemory( stream );
+}
+
+static PaError WaitCondition( PaJackHostApiRepresentation *hostApi )
+{
+    PaError result = paNoError;
+    int err = 0;
+    PaTime pt = PaUtil_GetTime();
+    struct timespec ts;
+
+    ts.tv_sec = (time_t) floor( pt + 1 );
+    ts.tv_nsec = (long) ((pt - floor( pt )) * 1000000000);
+    /* XXX: Best enclose in loop, in case of spurious wakeups? */
+    err = pthread_cond_timedwait( &hostApi->cond, &hostApi->mtx, &ts );
+
+    /* Make sure we didn't time out */
+    UNLESS( err != ETIMEDOUT, paTimedOut );
+    UNLESS( !err, paInternalError );
+
+error:
+    return result;
+}
+
+static PaError AddStream( PaJackStream *stream )
+{
+    PaError result = paNoError;
+    PaJackHostApiRepresentation *hostApi = stream->hostApi;
+    /* Add to queue of streams that should be processed */
+    ASSERT_CALL( pthread_mutex_lock( &hostApi->mtx ), 0 );
+    if( !hostApi->jackIsDown )
+    {
+        hostApi->toAdd = stream;
+        /* Unlock mutex and await signal from processing thread */
+        result = WaitCondition( stream->hostApi );
+    }
+    ASSERT_CALL( pthread_mutex_unlock( &hostApi->mtx ), 0 );
+    ENSURE_PA( result );
+
+    UNLESS( !hostApi->jackIsDown, paDeviceUnavailable );
+
+error:
+    return result;
+}
+
+/* Remove stream from processing queue */
+static PaError RemoveStream( PaJackStream *stream )
+{
+    PaError result = paNoError;
+    PaJackHostApiRepresentation *hostApi = stream->hostApi;
+
+    /* Add to queue over streams that should be processed */
+    ASSERT_CALL( pthread_mutex_lock( &hostApi->mtx ), 0 );
+    if( !hostApi->jackIsDown )
+    {
+        hostApi->toRemove = stream;
+        /* Unlock mutex and await signal from processing thread */
+        result = WaitCondition( stream->hostApi );
+    }
+    ASSERT_CALL( pthread_mutex_unlock( &hostApi->mtx ), 0 );
+    ENSURE_PA( result );
+
+error:
+    return result;
+}
+
+/* Add stream to processing queue */
+static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
+                           PaStream** s,
+                           const PaStreamParameters *inputParameters,
+                           const PaStreamParameters *outputParameters,
+                           double sampleRate,
+                           unsigned long framesPerBuffer,
+                           PaStreamFlags streamFlags,
+                           PaStreamCallback *streamCallback,
+                           void *userData )
+{
+    PaError result = paNoError;
+    PaJackHostApiRepresentation *jackHostApi = (PaJackHostApiRepresentation*)hostApi;
+    PaJackStream *stream = NULL;
+    char *port_string = alloca( jack_port_name_size() );
+    unsigned long regexSz = jack_client_name_size() + 3;
+    char *regex_pattern = alloca( regexSz );
+    const char **jack_ports = NULL;
+    /* int jack_max_buffer_size = jack_get_buffer_size( jackHostApi->jack_client ); */
+    int i;
+    int inputChannelCount, outputChannelCount;
+    const double jackSr = jack_get_sample_rate( jackHostApi->jack_client );
+    PaSampleFormat inputSampleFormat = 0, outputSampleFormat = 0;
+    int bpInitialized = 0, srInitialized = 0;   /* Initialized buffer processor and stream representation? */
+    unsigned long ofs;
+
+    /* validate platform specific flags */
+    if( (streamFlags & paPlatformSpecificFlags) != 0 )
+        return paInvalidFlag; /* unexpected platform specific flag */
+    if( (streamFlags & paPrimeOutputBuffersUsingStreamCallback) != 0 )
+    {
+        streamFlags &= ~paPrimeOutputBuffersUsingStreamCallback;
+        /*return paInvalidFlag;*/   /* This implementation does not support buffer priming */
+    }
+
+    if( framesPerBuffer != paFramesPerBufferUnspecified )
+    {
+        /* Jack operates with power of two buffers, and we don't support non-integer buffer adaption (yet) */
+        /*UNLESS( !(framesPerBuffer & (framesPerBuffer - 1)), paBufferTooBig );*/  /* TODO: Add descriptive error code? */
+    }
+
+    /* Preliminary checks */
+
+    if( inputParameters )
+    {
+        inputChannelCount = inputParameters->channelCount;
+        inputSampleFormat = inputParameters->sampleFormat;
+
+        /* unless alternate device specification is supported, reject the use of
+            paUseHostApiSpecificDeviceSpecification */
+
+        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
+            return paInvalidDevice;
+
+        /* check that input device can support inputChannelCount */
+        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )
+            return paInvalidChannelCount;
+
+        /* validate inputStreamInfo */
+        if( inputParameters->hostApiSpecificStreamInfo )
+            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
+    }
+    else
+    {
+        inputChannelCount = 0;
+    }
+
+    if( outputParameters )
+    {
+        outputChannelCount = outputParameters->channelCount;
+        outputSampleFormat = outputParameters->sampleFormat;
+
+        /* unless alternate device specification is supported, reject the use of
+            paUseHostApiSpecificDeviceSpecification */
+
+        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
+            return paInvalidDevice;
+
+        /* check that output device can support inputChannelCount */
+        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )
+            return paInvalidChannelCount;
+
+        /* validate outputStreamInfo */
+        if( outputParameters->hostApiSpecificStreamInfo )
+            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
+    }
+    else
+    {
+        outputChannelCount = 0;
+    }
+
+    /* ... check that the sample rate exactly matches the ONE acceptable rate
+     * A: This rate isn't necessarily constant though? */
+
+#define ABS(x) ( (x) > 0 ? (x) : -(x) )
+    if( ABS(sampleRate - jackSr) > 1 )
+       return paInvalidSampleRate;
+#undef ABS
+
+    UNLESS( stream = (PaJackStream*)PaUtil_AllocateMemory( sizeof(PaJackStream) ), paInsufficientMemory );
+    ENSURE_PA( InitializeStream( stream, jackHostApi, inputChannelCount, outputChannelCount ) );
+
+    /* the blocking emulation, if necessary */
+    stream->isBlockingStream = !streamCallback;
+    if( stream->isBlockingStream )
+    {
+        float latency = 0.001; /* 1ms is the absolute minimum we support */
+        int   minimum_buffer_frames = 0;
+
+        if( inputParameters && inputParameters->suggestedLatency > latency )
+            latency = inputParameters->suggestedLatency;
+        else if( outputParameters && outputParameters->suggestedLatency > latency )
+            latency = outputParameters->suggestedLatency;
+
+        /* the latency the user asked for indicates the minimum buffer size in frames */
+        minimum_buffer_frames = (int) (latency * jack_get_sample_rate( jackHostApi->jack_client ));
+
+        /* we also need to be able to store at least three full jack buffers to avoid dropouts */
+        if( jackHostApi->jack_buffer_size * 3 > minimum_buffer_frames )
+            minimum_buffer_frames = jackHostApi->jack_buffer_size * 3;
+
+        /* setup blocking API data structures (FIXME: can fail) */
+       BlockingBegin( stream, minimum_buffer_frames );
+
+        /* install our own callback for the blocking API */
+        streamCallback = BlockingCallback;
+        userData = stream;
+
+        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
+                                               &jackHostApi->blockingStreamInterface, streamCallback, userData );
+    }
+    else
+    {
+        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
+                                               &jackHostApi->callbackStreamInterface, streamCallback, userData );
+    }
+    srInitialized = 1;
+    PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, jackSr );
+
+    /* create the JACK ports.  We cannot connect them until audio
+     * processing begins */
+
+    /* Register a unique set of ports for this stream
+     * TODO: Robust allocation of new port names */
+
+    ofs = jackHostApi->inputBase;
+    for( i = 0; i < inputChannelCount; i++ )
+    {
+        snprintf( port_string, jack_port_name_size(), "in_%lu", ofs + i );
+        UNLESS( stream->local_input_ports[i] = jack_port_register(
+              jackHostApi->jack_client, port_string,
+              JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 ), paInsufficientMemory );
+    }
+    jackHostApi->inputBase += inputChannelCount;
+
+    ofs = jackHostApi->outputBase;
+    for( i = 0; i < outputChannelCount; i++ )
+    {
+        snprintf( port_string, jack_port_name_size(), "out_%lu", ofs + i );
+        UNLESS( stream->local_output_ports[i] = jack_port_register(
+             jackHostApi->jack_client, port_string,
+             JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 ), paInsufficientMemory );
+    }
+    jackHostApi->outputBase += outputChannelCount;
+
+    /* look up the jack_port_t's for the remote ports.  We could do
+     * this at stream start time, but doing it here ensures the
+     * name lookup only happens once. */
+
+    if( inputChannelCount > 0 )
+    {
+        int err = 0;
+        
+        /* ... remote output ports (that we input from) */
+        snprintf( regex_pattern, regexSz, "%s:.*", hostApi->deviceInfos[ inputParameters->device ]->name );
+        UNLESS( jack_ports = jack_get_ports( jackHostApi->jack_client, regex_pattern,
+                                     NULL, JackPortIsOutput ), paUnanticipatedHostError );
+        for( i = 0; i < inputChannelCount && jack_ports[i]; i++ )
+        {
+            if( (stream->remote_output_ports[i] = jack_port_by_name(
+                 jackHostApi->jack_client, jack_ports[i] )) == NULL ) 
+            {
+                err = 1;
+                break;
+            }
+        }
+        free( jack_ports );
+        UNLESS( !err, paInsufficientMemory );
+
+        /* Fewer ports than expected? */
+        UNLESS( i == inputChannelCount, paInternalError );
+    }
+
+    if( outputChannelCount > 0 )
+    {
+        int err = 0;
+
+        /* ... remote input ports (that we output to) */
+        snprintf( regex_pattern, regexSz, "%s:.*", hostApi->deviceInfos[ outputParameters->device ]->name );
+        UNLESS( jack_ports = jack_get_ports( jackHostApi->jack_client, regex_pattern,
+                                     NULL, JackPortIsInput ), paUnanticipatedHostError );
+        for( i = 0; i < outputChannelCount && jack_ports[i]; i++ )
+        {
+            if( (stream->remote_input_ports[i] = jack_port_by_name(
+                 jackHostApi->jack_client, jack_ports[i] )) == 0 )
+            {
+                err = 1;
+                break;
+            }
+        }
+        free( jack_ports );
+        UNLESS( !err , paInsufficientMemory );
+
+        /* Fewer ports than expected? */
+        UNLESS( i == outputChannelCount, paInternalError );
+    }
+
+    ENSURE_PA( PaUtil_InitializeBufferProcessor(
+                  &stream->bufferProcessor,
+                  inputChannelCount,
+                  inputSampleFormat,
+                  paFloat32,            /* hostInputSampleFormat */
+                  outputChannelCount,
+                  outputSampleFormat,
+                  paFloat32,            /* hostOutputSampleFormat */
+                  jackSr,
+                  streamFlags,
+                  framesPerBuffer,
+                  0,                            /* Ignored */
+                  paUtilUnknownHostBufferSize,  /* Buffer size may vary on JACK's discretion */
+                  streamCallback,
+                  userData ) );
+    bpInitialized = 1;
+
+    if( stream->num_incoming_connections > 0 )
+        stream->streamRepresentation.streamInfo.inputLatency = (jack_port_get_latency( stream->remote_output_ports[0] )
+                - jack_get_buffer_size( jackHostApi->jack_client )  /* One buffer is not counted as latency */
+            + PaUtil_GetBufferProcessorInputLatency( &stream->bufferProcessor )) / sampleRate;
+    if( stream->num_outgoing_connections > 0 )
+        stream->streamRepresentation.streamInfo.outputLatency = (jack_port_get_latency( stream->remote_input_ports[0] )
+                - jack_get_buffer_size( jackHostApi->jack_client )  /* One buffer is not counted as latency */
+            + PaUtil_GetBufferProcessorOutputLatency( &stream->bufferProcessor )) / sampleRate;
+
+    stream->streamRepresentation.streamInfo.sampleRate = jackSr;
+    stream->t0 = jack_frame_time( jackHostApi->jack_client );   /* A: Time should run from Pa_OpenStream */
+
+    ENSURE_PA( AddStream( stream ) );  /* Add to queue over opened streams */
+    
+    *s = (PaStream*)stream;
+
+    return result;
+
+error:
+    if( stream )
+        CleanUpStream( stream, srInitialized, bpInitialized );
+
+    return result;
+}
+
+/*
+    When CloseStream() is called, the multi-api layer ensures that
+    the stream has already been stopped or aborted.
+*/
+static PaError CloseStream( PaStream* s )
+{
+    PaError result = paNoError;
+    PaJackStream *stream = (PaJackStream*)s;
+
+    /* Remove this stream from the processing queue */
+    ENSURE_PA( RemoveStream( stream ) );
+
+error:
+    CleanUpStream( stream, 1, 1 );
+    return result;
+}
+
+static PaError RealProcess( PaJackStream *stream, jack_nframes_t frames )
+{
+    PaError result = paNoError;
+    PaStreamCallbackTimeInfo timeInfo = {0,0,0};
+    int chn;
+    int framesProcessed;
+    const double sr = jack_get_sample_rate( stream->jack_client );    /* Shouldn't change during the process callback */
+    PaStreamCallbackFlags cbFlags = 0;
+
+    /* If the user has returned !paContinue from the callback we'll want to flush the internal buffers,
+     * when these are empty we can finally mark the stream as inactive */
+    if( stream->callbackResult != paContinue &&
+            PaUtil_IsBufferProcessorOutputEmpty( &stream->bufferProcessor ) )
+    {
+        stream->is_active = 0;
+        if( stream->streamRepresentation.streamFinishedCallback )
+            stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
+        PA_DEBUG(( "%s: Callback finished\n", __FUNCTION__ ));
+
+        goto end;
+    }
+
+    timeInfo.currentTime = (jack_frame_time( stream->jack_client ) - stream->t0) / sr;
+    if( stream->num_incoming_connections > 0 )
+        timeInfo.inputBufferAdcTime = timeInfo.currentTime - jack_port_get_latency( stream->remote_output_ports[0] )
+            / sr;
+    if( stream->num_outgoing_connections > 0 )
+        timeInfo.outputBufferDacTime = timeInfo.currentTime + jack_port_get_latency( stream->remote_input_ports[0] )
+            / sr;
+
+    PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
+
+    if( stream->xrun )
+    {
+        /* XXX: Any way to tell which of these occurred? */
+        cbFlags = paOutputUnderflow | paInputOverflow;
+        stream->xrun = FALSE;
+    }
+    PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo,
+            cbFlags );
+
+    if( stream->num_incoming_connections > 0 )
+        PaUtil_SetInputFrameCount( &stream->bufferProcessor, frames );
+    if( stream->num_outgoing_connections > 0 )
+        PaUtil_SetOutputFrameCount( &stream->bufferProcessor, frames );
+
+    for( chn = 0; chn < stream->num_incoming_connections; chn++ )
+    {
+        jack_default_audio_sample_t *channel_buf = (jack_default_audio_sample_t*)
+            jack_port_get_buffer( stream->local_input_ports[chn],
+                    frames );
+
+        PaUtil_SetNonInterleavedInputChannel( &stream->bufferProcessor,
+                chn,
+                channel_buf );
+    }
+
+    for( chn = 0; chn < stream->num_outgoing_connections; chn++ )
+    {
+        jack_default_audio_sample_t *channel_buf = (jack_default_audio_sample_t*)
+            jack_port_get_buffer( stream->local_output_ports[chn],
+                    frames );
+
+        PaUtil_SetNonInterleavedOutputChannel( &stream->bufferProcessor,
+                chn,
+                channel_buf );
+    }
+
+    framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor,
+            &stream->callbackResult );
+    /* We've specified a host buffer size mode where every frame should be consumed by the buffer processor */
+    assert( framesProcessed == frames );
+
+    PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed );
+
+end:
+    return result;
+}
+
+/* Alter the processing queue if necessary */
+static PaError UpdateQueue( PaJackHostApiRepresentation *hostApi )
+{
+    PaError result = paNoError;
+    int queueModified = 0;
+    const double jackSr = jack_get_sample_rate( hostApi->jack_client );
+    int err;
+
+    if( (err = pthread_mutex_trylock( &hostApi->mtx )) != 0 )
+    {
+        assert( err == EBUSY );
+        return paNoError;
+    }
+
+    if( hostApi->toAdd )
+    {
+        if( hostApi->processQueue )
+        {
+            PaJackStream *node = hostApi->processQueue;
+            /* Advance to end of queue */
+            while( node->next )
+                node = node->next;
+
+            node->next = hostApi->toAdd;
+        }
+        else
+            hostApi->processQueue = (PaJackStream *)hostApi->toAdd;
+
+        /* If necessary, update stream state */
+        if( hostApi->toAdd->streamRepresentation.streamInfo.sampleRate != jackSr )
+            UpdateSampleRate( hostApi->toAdd, jackSr );
+
+        hostApi->toAdd = NULL;
+        queueModified = 1;
+    }
+    if( hostApi->toRemove )
+    {
+        int removed = 0;
+        PaJackStream *node = hostApi->processQueue, *prev = NULL;
+        assert( hostApi->processQueue );
+
+        while( node )
+        {
+            if( node == hostApi->toRemove )
+            {
+                if( prev )
+                    prev->next = node->next;
+                else
+                    hostApi->processQueue = (PaJackStream *)node->next;
+
+                removed = 1;
+                break;
+            }
+
+            prev = node;
+            node = node->next;
+        }
+        UNLESS( removed, paInternalError );
+        hostApi->toRemove = NULL;
+        PA_DEBUG(( "%s: Removed stream from processing queue\n", __FUNCTION__ ));
+        queueModified = 1;
+    }
+
+    if( queueModified )
+    {
+        /* Signal that we've done what was asked of us */
+        ASSERT_CALL( pthread_cond_signal( &hostApi->cond ), 0 );
+    }
+
+error:
+    ASSERT_CALL( pthread_mutex_unlock( &hostApi->mtx ), 0 );
+
+    return result;
+}
+
+static int JackCallback( jack_nframes_t frames, void *userData )
+{
+    PaError result = paNoError;
+    PaJackHostApiRepresentation *hostApi = (PaJackHostApiRepresentation *)userData;
+    PaJackStream *stream = NULL;
+    int xrun = hostApi->xrun;
+    hostApi->xrun = 0;
+
+    assert( hostApi );
+
+    ENSURE_PA( UpdateQueue( hostApi ) );
+
+    /* Process each stream */
+    stream = hostApi->processQueue;
+    for( ; stream; stream = stream->next )
+    {
+        if( xrun )  /* Don't override if already set */
+            stream->xrun = 1;
+
+        /* See if this stream is to be started */
+        if( stream->doStart )
+        {
+            /* If we can't obtain a lock, we'll try next time */
+            int err = pthread_mutex_trylock( &stream->hostApi->mtx );
+            if( !err )
+            {
+                if( stream->doStart )   /* Could potentially change before obtaining the lock */
+                {
+                    stream->is_active = 1;
+                    stream->doStart = 0;
+                    PA_DEBUG(( "%s: Starting stream\n", __FUNCTION__ ));
+                    ASSERT_CALL( pthread_cond_signal( &stream->hostApi->cond ), 0 );
+                    stream->callbackResult = paContinue;
+                    stream->isSilenced = 0;
+                }
+
+                ASSERT_CALL( pthread_mutex_unlock( &stream->hostApi->mtx ), 0 );
+            }
+            else
+                assert( err == EBUSY );
+        }
+        else if( stream->doStop || stream->doAbort )    /* Should we stop/abort stream? */
+        {
+            if( stream->callbackResult == paContinue )     /* Ok, make it stop */
+            {
+                PA_DEBUG(( "%s: Stopping stream\n", __FUNCTION__ ));
+                stream->callbackResult = stream->doStop ? paComplete : paAbort;
+            }
+        }
+
+        if( stream->is_active )
+            ENSURE_PA( RealProcess( stream, frames ) );
+        /* If we have just entered inactive state, silence output */
+        if( !stream->is_active && !stream->isSilenced )
+        {
+            int i;
+
+            /* Silence buffer after entering inactive state */
+            PA_DEBUG(( "Silencing the output\n" ));
+            for( i = 0; i < stream->num_outgoing_connections; ++i )
+            {
+                jack_default_audio_sample_t *buffer = jack_port_get_buffer( stream->local_output_ports[i], frames );
+                memset( buffer, 0, sizeof (jack_default_audio_sample_t) * frames );
+            }
+
+            stream->isSilenced = 1;
+        }
+
+        if( stream->doStop || stream->doAbort )
+        {
+            /* See if RealProcess has acted on the request */
+            if( !stream->is_active )   /* Ok, signal to the main thread that we've carried out the operation */
+            {
+                /* If we can't obtain a lock, we'll try next time */
+                int err = pthread_mutex_trylock( &stream->hostApi->mtx );
+                if( !err )
+                {
+                    stream->doStop = stream->doAbort = 0;
+                    ASSERT_CALL( pthread_cond_signal( &stream->hostApi->cond ), 0 );
+                    ASSERT_CALL( pthread_mutex_unlock( &stream->hostApi->mtx ), 0 );
+                }
+                else
+                    assert( err == EBUSY );
+            }
+        }
+    }
+
+    return 0;
+error:
+    return -1;
+}
+
+static PaError StartStream( PaStream *s )
+{
+    PaError result = paNoError;
+    PaJackStream *stream = (PaJackStream*)s;
+    int i;
+
+    /* Ready the processor */
+    PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
+
+    /* connect the ports */
+
+    /* NOTE: I would rather use jack_port_connect which uses jack_port_t's
+     * instead of port names, but it is not implemented yet. */
+    if( stream->num_incoming_connections > 0 )
+    {
+        for( i = 0; i < stream->num_incoming_connections; i++ )
+            UNLESS( jack_connect( stream->jack_client,
+                    jack_port_name( stream->remote_output_ports[i] ),
+                    jack_port_name( stream->local_input_ports[i] ) ) == 0, paUnanticipatedHostError );
+    }
+
+    if( stream->num_outgoing_connections > 0 )
+    {
+        for( i = 0; i < stream->num_outgoing_connections; i++ )
+            UNLESS( jack_connect( stream->jack_client,
+                    jack_port_name( stream->local_output_ports[i] ),
+                    jack_port_name( stream->remote_input_ports[i] ) ) == 0, paUnanticipatedHostError );
+    }
+
+    stream->xrun = FALSE;
+
+    /* Enable processing */
+
+    ASSERT_CALL( pthread_mutex_lock( &stream->hostApi->mtx ), 0 );
+    stream->doStart = 1;
+
+    /* Wait for stream to be started */
+    result = WaitCondition( stream->hostApi );
+    /*
+    do
+    {
+        err = pthread_cond_timedwait( &stream->hostApi->cond, &stream->hostApi->mtx, &ts );
+    } while( !stream->is_active && !err );
+    */
+    if( result != paNoError )   /* Something went wrong, call off the stream start */
+    {
+        stream->doStart = 0;
+        stream->is_active = 0;  /* Cancel any processing */
+    }
+    ASSERT_CALL( pthread_mutex_unlock( &stream->hostApi->mtx ), 0 );
+
+    ENSURE_PA( result );
+
+    stream->is_running = TRUE;
+    PA_DEBUG(( "%s: Stream started\n", __FUNCTION__ ));
+
+error:
+    return result;
+}
+
+static PaError RealStop( PaJackStream *stream, int abort )
+{
+    PaError result = paNoError;
+    int i;
+
+    if( stream->isBlockingStream )
+        BlockingWaitEmpty ( stream );
+
+    ASSERT_CALL( pthread_mutex_lock( &stream->hostApi->mtx ), 0 );
+    if( abort )
+        stream->doAbort = 1;
+    else
+        stream->doStop = 1;
+
+    /* Wait for stream to be stopped */
+    result = WaitCondition( stream->hostApi );
+    ASSERT_CALL( pthread_mutex_unlock( &stream->hostApi->mtx ), 0 );
+    ENSURE_PA( result );
+
+    UNLESS( !stream->is_active, paInternalError );
+    
+    PA_DEBUG(( "%s: Stream stopped\n", __FUNCTION__ ));
+
+error:
+    stream->is_running = FALSE;
+
+    /* Disconnect ports belonging to this stream */
+
+    if( !stream->hostApi->jackIsDown )  /* XXX: Well? */
+    {
+        if( stream->num_incoming_connections > 0 )
+        {
+            int failed = 0;
+            for( i = 0; i < stream->num_incoming_connections; i++ )
+            {
+                if( jack_port_disconnect( stream->jack_client, stream->local_input_ports[i] ) )
+                {
+                    failed = 1;
+                }
+            }
+            if( failed )
+            {
+                PA_DEBUG(( "%s: Failed to disconnect input, already done externally?\n", __FUNCTION__ ));
+            }
+        }
+        if( stream->num_outgoing_connections > 0 )
+        {
+            int failed = 0;
+            for( i = 0; i < stream->num_outgoing_connections; i++ )
+            {
+                if( jack_port_disconnect( stream->jack_client, stream->local_output_ports[i] ) )
+                {
+                    failed = 1;
+                }
+            }
+            if( failed )
+            {
+                PA_DEBUG(( "%s: Failed to disconnect output, already done externally?\n", __FUNCTION__ ));
+            }
+        }
+    }
+
+    return result;
+}
+
+static PaError StopStream( PaStream *s )
+{
+    assert(s);
+    return RealStop( (PaJackStream *)s, 0 );
+}
+
+static PaError AbortStream( PaStream *s )
+{
+    assert(s);
+    return RealStop( (PaJackStream *)s, 1 );
+}
+
+static PaError IsStreamStopped( PaStream *s )
+{
+    PaJackStream *stream = (PaJackStream*)s;
+    return !stream->is_running;
+}
+
+
+static PaError IsStreamActive( PaStream *s )
+{
+    PaJackStream *stream = (PaJackStream*)s;
+    return stream->is_active;
+}
+
+
+static PaTime GetStreamTime( PaStream *s )
+{
+    PaJackStream *stream = (PaJackStream*)s;
+
+    /* A: Is this relevant?? --> TODO: what if we're recording-only? */
+    return (jack_frame_time( stream->jack_client ) - stream->t0) / (PaTime)jack_get_sample_rate( stream->jack_client );
+}
+
+
+static double GetStreamCpuLoad( PaStream* s )
+{
+    PaJackStream *stream = (PaJackStream*)s;
+    return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
+}
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/oss/low_latency_tip.txt b/utils/iaxclient/lib/portaudio/src/hostapi/oss/low_latency_tip.txt
new file mode 100644 (file)
index 0000000..2d982b7
Binary files /dev/null and b/utils/iaxclient/lib/portaudio/src/hostapi/oss/low_latency_tip.txt differ
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/oss/pa_unix_oss.c b/utils/iaxclient/lib/portaudio/src/hostapi/oss/pa_unix_oss.c
new file mode 100644 (file)
index 0000000..a783d29
--- /dev/null
@@ -0,0 +1,1925 @@
+/*
+ * $Id: pa_unix_oss.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * PortAudio Portable Real-Time Audio Library
+ * Latest Version at: http://www.portaudio.com
+ * OSS implementation by:
+ *   Douglas Repetto
+ *   Phil Burk
+ *   Dominic Mazzoni
+ *   Arve Knudsen
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2002 Ross Bencina, Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <alloca.h>
+#include <malloc.h>
+#include <assert.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/poll.h>
+#include <sys/select.h>
+#include <limits.h>
+#include <semaphore.h>
+
+#ifdef __FreeBSD__
+# include <sys/soundcard.h>
+# define DEVICE_NAME_BASE            "/dev/dsp"
+#elif defined __linux__
+# include <linux/soundcard.h>
+# define DEVICE_NAME_BASE            "/dev/dsp"
+#else
+# include <machine/soundcard.h> /* JH20010905 */
+# define DEVICE_NAME_BASE            "/dev/audio"
+#endif
+
+#include "portaudio.h"
+#include "pa_util.h"
+#include "pa_allocation.h"
+#include "pa_hostapi.h"
+#include "pa_stream.h"
+#include "pa_cpuload.h"
+#include "pa_process.h"
+#include "pa_unix_util.h"
+
+static int sysErr_;
+static pthread_t mainThread_;
+
+/* Check return value of system call, and map it to PaError */
+#define ENSURE_(expr, code) \
+    do { \
+        if( UNLIKELY( (sysErr_ = (expr)) < 0 ) ) \
+        { \
+            /* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \
+            if( (code) == paUnanticipatedHostError && pthread_self() == mainThread_ ) \
+            { \
+                PaUtil_SetLastHostErrorInfo( paALSA, sysErr_, strerror( errno ) ); \
+            } \
+            \
+            PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
+            result = (code); \
+            goto error; \
+        } \
+    } while( 0 );
+
+#ifndef AFMT_S16_NE
+#define AFMT_S16_NE  Get_AFMT_S16_NE()
+/*********************************************************************
+ * Some versions of OSS do not define AFMT_S16_NE. So check CPU.
+ * PowerPC is Big Endian. X86 is Little Endian.
+ */
+static int Get_AFMT_S16_NE( void )
+{
+    long testData = 1; 
+    char *ptr = (char *) &testData;
+    int isLittle = ( *ptr == 1 ); /* Does address point to least significant byte? */
+    return isLittle ? AFMT_S16_LE : AFMT_S16_BE;
+}
+#endif
+
+/* PaOSSHostApiRepresentation - host api datastructure specific to this implementation */
+
+typedef struct
+{
+    PaUtilHostApiRepresentation inheritedHostApiRep;
+    PaUtilStreamInterface callbackStreamInterface;
+    PaUtilStreamInterface blockingStreamInterface;
+
+    PaUtilAllocationGroup *allocations;
+
+    PaHostApiIndex hostApiIndex;
+}
+PaOSSHostApiRepresentation;
+
+/** Per-direction structure for PaOssStream.
+ *
+ * Aspect StreamChannels: In case the user requests to open the same device for both capture and playback,
+ * but with different number of channels we will have to adapt between the number of user and host
+ * channels for at least one direction, since the configuration space is the same for both directions
+ * of an OSS device.
+ */
+typedef struct
+{
+    int fd;
+    const char *devName;
+    int userChannelCount, hostChannelCount;
+    int userInterleaved;
+    void *buffer;
+    PaSampleFormat userFormat, hostFormat;
+    double latency;
+    unsigned long hostFrames, numBufs;
+    void **userBuffers; /* For non-interleaved blocking */
+} PaOssStreamComponent;
+
+/** Implementation specific representation of a PaStream.
+ *
+ */
+typedef struct PaOssStream
+{
+    PaUtilStreamRepresentation streamRepresentation;
+    PaUtilCpuLoadMeasurer cpuLoadMeasurer;
+    PaUtilBufferProcessor bufferProcessor;
+
+    PaUtilThreading threading;
+
+    int sharedDevice;
+    unsigned long framesPerHostBuffer;
+    int triggered;  /* Have the devices been triggered yet (first start) */
+
+    int isActive;
+    int isStopped;
+
+    int lastPosPtr;
+    double lastStreamBytes;
+
+    int framesProcessed;
+
+    double sampleRate;
+
+    int callbackMode;
+    int callbackStop, callbackAbort;
+
+    PaOssStreamComponent *capture, *playback;
+    unsigned long pollTimeout;
+    sem_t semaphore;
+}
+PaOssStream;
+
+typedef enum {
+    StreamMode_In,
+    StreamMode_Out
+} StreamMode;
+
+/* prototypes for functions declared in this file */
+
+static void Terminate( struct PaUtilHostApiRepresentation *hostApi );
+static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
+                                  const PaStreamParameters *inputParameters,
+                                  const PaStreamParameters *outputParameters,
+                                  double sampleRate );
+static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
+                           PaStream** s,
+                           const PaStreamParameters *inputParameters,
+                           const PaStreamParameters *outputParameters,
+                           double sampleRate,
+                           unsigned long framesPerBuffer,
+                           PaStreamFlags streamFlags,
+                           PaStreamCallback *streamCallback,
+                           void *userData );
+static PaError CloseStream( PaStream* stream );
+static PaError StartStream( PaStream *stream );
+static PaError StopStream( PaStream *stream );
+static PaError AbortStream( PaStream *stream );
+static PaError IsStreamStopped( PaStream *s );
+static PaError IsStreamActive( PaStream *stream );
+static PaTime GetStreamTime( PaStream *stream );
+static double GetStreamCpuLoad( PaStream* stream );
+static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames );
+static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames );
+static signed long GetStreamReadAvailable( PaStream* stream );
+static signed long GetStreamWriteAvailable( PaStream* stream );
+static PaError BuildDeviceList( PaOSSHostApiRepresentation *hostApi );
+
+
+/** Initialize the OSS API implementation.
+ *
+ * This function will initialize host API datastructures and query host devices for information.
+ *
+ * Aspect DeviceCapabilities: Enumeration of host API devices is initiated from here
+ *
+ * Aspect FreeResources: If an error is encountered under way we have to free each resource allocated in this function,
+ * this happens with the usual "error" label.
+ */
+PaError PaOSS_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
+{
+    PaError result = paNoError;
+    PaOSSHostApiRepresentation *ossHostApi = NULL;
+
+    PA_UNLESS( ossHostApi = (PaOSSHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaOSSHostApiRepresentation) ),
+            paInsufficientMemory );
+    PA_UNLESS( ossHostApi->allocations = PaUtil_CreateAllocationGroup(), paInsufficientMemory );
+    ossHostApi->hostApiIndex = hostApiIndex;
+
+    /* Initialize host API structure */
+    *hostApi = &ossHostApi->inheritedHostApiRep;
+    (*hostApi)->info.structVersion = 1;
+    (*hostApi)->info.type = paOSS;
+    (*hostApi)->info.name = "OSS";
+    (*hostApi)->Terminate = Terminate;
+    (*hostApi)->OpenStream = OpenStream;
+    (*hostApi)->IsFormatSupported = IsFormatSupported;
+
+    PA_ENSURE( BuildDeviceList( ossHostApi ) );
+
+    PaUtil_InitializeStreamInterface( &ossHostApi->callbackStreamInterface, CloseStream, StartStream,
+                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
+                                      GetStreamTime, GetStreamCpuLoad,
+                                      PaUtil_DummyRead, PaUtil_DummyWrite,
+                                      PaUtil_DummyGetReadAvailable,
+                                      PaUtil_DummyGetWriteAvailable );
+
+    PaUtil_InitializeStreamInterface( &ossHostApi->blockingStreamInterface, CloseStream, StartStream,
+                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
+                                      GetStreamTime, PaUtil_DummyGetCpuLoad,
+                                      ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );
+
+    mainThread_ = pthread_self();
+
+    return result;
+
+error:
+    if( ossHostApi )
+    {
+        if( ossHostApi->allocations )
+        {
+            PaUtil_FreeAllAllocations( ossHostApi->allocations );
+            PaUtil_DestroyAllocationGroup( ossHostApi->allocations );
+        }
+                
+        PaUtil_FreeMemory( ossHostApi );
+    }
+    return result;
+}
+
+PaError PaUtil_InitializeDeviceInfo( PaDeviceInfo *deviceInfo, const char *name, PaHostApiIndex hostApiIndex, int maxInputChannels,
+        int maxOutputChannels, PaTime defaultLowInputLatency, PaTime defaultLowOutputLatency, PaTime defaultHighInputLatency,
+        PaTime defaultHighOutputLatency, double defaultSampleRate, PaUtilAllocationGroup *allocations  )
+{
+    PaError result = paNoError;
+    
+    deviceInfo->structVersion = 2;
+    if( allocations )
+    {
+        size_t len = strlen( name ) + 1;
+        PA_UNLESS( deviceInfo->name = PaUtil_GroupAllocateMemory( allocations, len ), paInsufficientMemory );
+        strncpy( (char *)deviceInfo->name, name, len );
+    }
+    else
+        deviceInfo->name = name;
+
+    deviceInfo->hostApi = hostApiIndex;
+    deviceInfo->maxInputChannels = maxInputChannels;
+    deviceInfo->maxOutputChannels = maxOutputChannels;
+    deviceInfo->defaultLowInputLatency = defaultLowInputLatency;
+    deviceInfo->defaultLowOutputLatency = defaultLowOutputLatency;
+    deviceInfo->defaultHighInputLatency = defaultHighInputLatency;
+    deviceInfo->defaultHighOutputLatency = defaultHighOutputLatency;
+    deviceInfo->defaultSampleRate = defaultSampleRate;
+
+error:
+    return result;
+}
+
+static PaError QueryDirection( const char *deviceName, StreamMode mode, double *defaultSampleRate, int *maxChannelCount,
+        double *defaultLowLatency, double *defaultHighLatency )
+{
+    PaError result = paNoError;
+    int numChannels, maxNumChannels;
+    int busy = 0;
+    int devHandle = -1;
+    int sr;
+    *maxChannelCount = 0;  /* Default value in case this fails */
+
+    if ( (devHandle = open( deviceName, (mode == StreamMode_In ? O_RDONLY : O_WRONLY) | O_NONBLOCK ))  < 0 )
+    {
+        if( errno == EBUSY || errno == EAGAIN )
+        {
+            PA_DEBUG(( "%s: Device %s busy\n", __FUNCTION__, deviceName ));
+        }
+        else
+        {
+            PA_DEBUG(( "%s: Can't access device: %s\n", __FUNCTION__, strerror( errno ) ));
+        }
+
+        return paDeviceUnavailable;
+    }
+
+    /* Negotiate for the maximum number of channels for this device. PLB20010927
+     * Consider up to 16 as the upper number of channels.
+     * Variable maxNumChannels should contain the actual upper limit after the call.
+     * Thanks to John Lazzaro and Heiko Purnhagen for suggestions.
+     */
+    maxNumChannels = 0;
+    for( numChannels = 1; numChannels <= 16; numChannels++ )
+    {
+        int temp = numChannels;
+        if( ioctl( devHandle, SNDCTL_DSP_CHANNELS, &temp ) < 0 )
+        {
+            busy = EAGAIN == errno || EBUSY == errno;
+            /* ioctl() failed so bail out if we already have stereo */
+            if( maxNumChannels >= 2 )
+                break;
+        }
+        else
+        {
+            /* ioctl() worked but bail out if it does not support numChannels.
+             * We don't want to leave gaps in the numChannels supported.
+             */
+            if( (numChannels > 2) && (temp != numChannels) )
+                break;
+            if( temp > maxNumChannels )
+                maxNumChannels = temp; /* Save maximum. */
+        }
+    }
+    /* A: We're able to open a device for capture if it's busy playing back and vice versa,
+     * but we can't configure anything */
+    if( 0 == maxNumChannels && busy )
+    {
+        result = paDeviceUnavailable;
+        goto error;
+    }
+
+    /* The above negotiation may fail for an old driver so try this older technique. */
+    if( maxNumChannels < 1 )
+    {
+        int stereo = 1;
+        if( ioctl( devHandle, SNDCTL_DSP_STEREO, &stereo ) < 0 )
+        {
+            maxNumChannels = 1;
+        }
+        else
+        {
+            maxNumChannels = (stereo) ? 2 : 1;
+        }
+        PA_DEBUG(( "%s: use SNDCTL_DSP_STEREO, maxNumChannels = %d\n", __FUNCTION__, maxNumChannels ))
+    }
+
+    /* During channel negotiation, the last ioctl() may have failed. This can
+     * also cause sample rate negotiation to fail. Hence the following, to return
+     * to a supported number of channels. SG20011005 */
+    {
+        /* use most reasonable default value */
+        int temp = PA_MIN( maxNumChannels, 2 );
+        ENSURE_( ioctl( devHandle, SNDCTL_DSP_CHANNELS, &temp ), paUnanticipatedHostError );
+    }
+
+    /* Get supported sample rate closest to 44100 Hz */
+    if( *defaultSampleRate < 0 )
+    {
+        sr = 44100;
+        if( ioctl( devHandle, SNDCTL_DSP_SPEED, &sr ) < 0 )
+        {
+            result = paUnanticipatedHostError;
+            goto error;
+        }
+
+        *defaultSampleRate = sr;
+    }
+
+    *maxChannelCount = maxNumChannels;
+    /* TODO */
+    *defaultLowLatency = 512. / *defaultSampleRate;
+    *defaultHighLatency = 2048. / *defaultSampleRate;
+
+error:
+    if( devHandle >= 0 )
+        close( devHandle );
+
+    return result;
+}
+
+/** Query OSS device.
+ *
+ * This is where PaDeviceInfo objects are constructed and filled in with relevant information.
+ *
+ * Aspect DeviceCapabilities: The inferred device capabilities are recorded in a PaDeviceInfo object that is constructed
+ * in place.
+ */
+static PaError QueryDevice( char *deviceName, PaOSSHostApiRepresentation *ossApi, PaDeviceInfo **deviceInfo )
+{
+    PaError result = paNoError;
+    double sampleRate = -1.;
+    int maxInputChannels, maxOutputChannels;
+    PaTime defaultLowInputLatency, defaultLowOutputLatency, defaultHighInputLatency, defaultHighOutputLatency;
+    PaError tmpRes = paNoError;
+    int busy = 0;
+    *deviceInfo = NULL;
+
+    /* douglas:
+       we have to do this querying in a slightly different order. apparently
+       some sound cards will give you different info based on their settins. 
+       e.g. a card might give you stereo at 22kHz but only mono at 44kHz.
+       the correct order for OSS is: format, channels, sample rate
+    */
+
+    /* Aspect StreamChannels: The number of channels supported for a device may depend on the mode it is
+     * opened in, it may have more channels available for capture than playback and vice versa. Therefore
+     * we will open the device in both read- and write-only mode to determine the supported number.
+     */
+    if( (tmpRes = QueryDirection( deviceName, StreamMode_In, &sampleRate, &maxInputChannels, &defaultLowInputLatency,
+                &defaultHighInputLatency )) != paNoError )
+    {
+        if( tmpRes != paDeviceUnavailable )
+        {
+            PA_DEBUG(( "%s: Querying device %s for capture failed!\n", __FUNCTION__, deviceName ));
+            /* PA_ENSURE( tmpRes ); */
+        }
+        ++busy;
+    }
+    if( (tmpRes = QueryDirection( deviceName, StreamMode_Out, &sampleRate, &maxOutputChannels, &defaultLowOutputLatency,
+                &defaultHighOutputLatency )) != paNoError )
+    {
+        if( tmpRes != paDeviceUnavailable )
+        {
+            PA_DEBUG(( "%s: Querying device %s for playback failed!\n", __FUNCTION__, deviceName ));
+            /* PA_ENSURE( tmpRes ); */
+        }
+        ++busy;
+    }
+    assert( 0 <= busy && busy <= 2 );
+    if( 2 == busy )     /* Both directions are unavailable to us */
+    {
+        result = paDeviceUnavailable;
+        goto error;
+    }
+
+    PA_UNLESS( *deviceInfo = PaUtil_GroupAllocateMemory( ossApi->allocations, sizeof (PaDeviceInfo) ), paInsufficientMemory );
+    PA_ENSURE( PaUtil_InitializeDeviceInfo( *deviceInfo, deviceName, ossApi->hostApiIndex, maxInputChannels, maxOutputChannels,
+                defaultLowInputLatency, defaultLowOutputLatency, defaultHighInputLatency, defaultHighOutputLatency, sampleRate,
+                ossApi->allocations ) );
+
+error:
+    return result;
+}
+
+/** Query host devices.
+ *
+ * Loop over host devices and query their capabilitiesu
+ *
+ * Aspect DeviceCapabilities: This function calls QueryDevice on each device entry and receives a filled in PaDeviceInfo object
+ * per device, these are placed in the host api representation's deviceInfos array.
+ */
+static PaError BuildDeviceList( PaOSSHostApiRepresentation *ossApi )
+{
+    PaError result = paNoError;
+    PaUtilHostApiRepresentation *commonApi = &ossApi->inheritedHostApiRep;
+    int i;
+    int numDevices = 0, maxDeviceInfos = 1;
+    PaDeviceInfo **deviceInfos = NULL;
+
+    /* These two will be set to the first working input and output device, respectively */
+    commonApi->info.defaultInputDevice = paNoDevice;
+    commonApi->info.defaultOutputDevice = paNoDevice;
+
+    /* Find devices by calling QueryDevice on each
+     * potential device names.  When we find a valid one,
+     * add it to a linked list.
+     * A: Can there only be 10 devices? */
+
+    for( i = 0; i < 10; i++ )
+    {
+       char deviceName[32];
+       PaDeviceInfo *deviceInfo;
+       int testResult;
+       struct stat stbuf;
+
+       if( i == 0 )
+          snprintf(deviceName, sizeof (deviceName), "%s", DEVICE_NAME_BASE);
+       else
+          snprintf(deviceName, sizeof (deviceName), "%s%d", DEVICE_NAME_BASE, i);
+
+       /* PA_DEBUG(("PaOSS BuildDeviceList: trying device %s\n", deviceName )); */
+       if( stat( deviceName, &stbuf ) < 0 )
+       {
+           if( ENOENT != errno )
+               PA_DEBUG(( "%s: Error stat'ing %s: %s\n", __FUNCTION__, deviceName, strerror( errno ) ));
+           continue;
+       }
+       if( (testResult = QueryDevice( deviceName, ossApi, &deviceInfo )) != paNoError )
+       {
+           if( testResult != paDeviceUnavailable )
+               PA_ENSURE( testResult );
+
+           continue;
+       }
+
+       ++numDevices;
+       if( !deviceInfos || numDevices > maxDeviceInfos )
+       {
+           maxDeviceInfos *= 2;
+           PA_UNLESS( deviceInfos = (PaDeviceInfo **) realloc( deviceInfos, maxDeviceInfos * sizeof (PaDeviceInfo *) ),
+                   paInsufficientMemory );
+       }
+       {
+           int devIdx = numDevices - 1;
+           deviceInfos[devIdx] = deviceInfo;
+
+           if( commonApi->info.defaultInputDevice == paNoDevice && deviceInfo->maxInputChannels > 0 )
+               commonApi->info.defaultInputDevice = devIdx;
+           if( commonApi->info.defaultOutputDevice == paNoDevice && deviceInfo->maxOutputChannels > 0 )
+               commonApi->info.defaultOutputDevice = devIdx;
+       }
+    }
+
+    /* Make an array of PaDeviceInfo pointers out of the linked list */
+
+    PA_DEBUG(("PaOSS %s: Total number of devices found: %d\n", __FUNCTION__, numDevices));
+
+    commonApi->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
+        ossApi->allocations, sizeof(PaDeviceInfo*) * numDevices );
+    memcpy( commonApi->deviceInfos, deviceInfos, numDevices * sizeof (PaDeviceInfo *) );
+
+    commonApi->info.deviceCount = numDevices;
+
+error:
+    free( deviceInfos );
+
+    return result;
+}
+
+static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
+{
+    PaOSSHostApiRepresentation *ossHostApi = (PaOSSHostApiRepresentation*)hostApi;
+
+    if( ossHostApi->allocations )
+    {
+        PaUtil_FreeAllAllocations( ossHostApi->allocations );
+        PaUtil_DestroyAllocationGroup( ossHostApi->allocations );
+    }
+
+    PaUtil_FreeMemory( ossHostApi );
+}
+
+static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
+                                  const PaStreamParameters *inputParameters,
+                                  const PaStreamParameters *outputParameters,
+                                  double sampleRate )
+{
+    PaError result = paNoError;
+    PaDeviceIndex device;
+    PaDeviceInfo *deviceInfo;
+    char *deviceName;
+    int inputChannelCount, outputChannelCount;
+    int tempDevHandle = -1;
+    int flags;
+    PaSampleFormat inputSampleFormat, outputSampleFormat;
+    
+    if( inputParameters )
+    {
+        inputChannelCount = inputParameters->channelCount;
+        inputSampleFormat = inputParameters->sampleFormat;
+
+        /* unless alternate device specification is supported, reject the use of
+            paUseHostApiSpecificDeviceSpecification */
+
+        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
+            return paInvalidDevice;
+
+        /* check that input device can support inputChannelCount */
+        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )
+            return paInvalidChannelCount;
+
+        /* validate inputStreamInfo */
+        if( inputParameters->hostApiSpecificStreamInfo )
+            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
+    }
+    else
+    {
+        inputChannelCount = 0;
+    }
+
+    if( outputParameters )
+    {
+        outputChannelCount = outputParameters->channelCount;
+        outputSampleFormat = outputParameters->sampleFormat;
+        
+        /* unless alternate device specification is supported, reject the use of
+            paUseHostApiSpecificDeviceSpecification */
+
+        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
+            return paInvalidDevice;
+
+        /* check that output device can support inputChannelCount */
+        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )
+            return paInvalidChannelCount;
+
+        /* validate outputStreamInfo */
+        if( outputParameters->hostApiSpecificStreamInfo )
+            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
+    }
+    else
+    {
+        outputChannelCount = 0;
+    }
+
+    if (inputChannelCount == 0 && outputChannelCount == 0)
+        return paInvalidChannelCount;
+
+    /* if full duplex, make sure that they're the same device */
+
+    if (inputChannelCount > 0 && outputChannelCount > 0 &&
+        inputParameters->device != outputParameters->device)
+        return paInvalidDevice;
+
+    /* if full duplex, also make sure that they're the same number of channels */
+
+    if (inputChannelCount > 0 && outputChannelCount > 0 &&
+        inputChannelCount != outputChannelCount)
+       return paInvalidChannelCount;
+
+    /* open the device so we can do more tests */
+    
+    if( inputChannelCount > 0 )
+    {
+        result = PaUtil_DeviceIndexToHostApiDeviceIndex(&device, inputParameters->device, hostApi);
+        if (result != paNoError)
+            return result;
+    }
+    else
+    {
+        result = PaUtil_DeviceIndexToHostApiDeviceIndex(&device, outputParameters->device, hostApi);
+        if (result != paNoError)
+            return result;
+    }
+
+    deviceInfo = hostApi->deviceInfos[device];
+    deviceName = (char *)deviceInfo->name;
+    
+    flags = O_NONBLOCK;
+    if (inputChannelCount > 0 && outputChannelCount > 0)
+       flags |= O_RDWR;
+    else if (inputChannelCount > 0)
+       flags |= O_RDONLY;
+    else
+       flags |= O_WRONLY;
+
+    ENSURE_( tempDevHandle = open( deviceInfo->name, flags ), paDeviceUnavailable );
+
+    /* PaOssStream_Configure will do the rest of the checking for us */
+    /* PA_ENSURE( PaOssStream_Configure( tempDevHandle, deviceName, outputChannelCount, &sampleRate ) ); */
+
+    /* everything succeeded! */
+
+ error:
+    if( tempDevHandle >= 0 )
+        close( tempDevHandle );         
+
+    return result;
+}
+
+/** Validate stream parameters.
+ *
+ * Aspect StreamChannels: We verify that the number of channels is within the allowed range for the device
+ */
+static PaError ValidateParameters( const PaStreamParameters *parameters, const PaDeviceInfo *deviceInfo, StreamMode mode )
+{
+    int maxChans;
+
+    assert( parameters );
+
+    if( parameters->device == paUseHostApiSpecificDeviceSpecification )
+    {
+        return paInvalidDevice;
+    }
+
+    maxChans = (mode == StreamMode_In ? deviceInfo->maxInputChannels :
+        deviceInfo->maxOutputChannels);
+    if( parameters->channelCount > maxChans )
+    {
+        return paInvalidChannelCount;
+    }
+
+    return paNoError;
+}
+
+static PaError PaOssStreamComponent_Initialize( PaOssStreamComponent *component, const PaStreamParameters *parameters,
+        int callbackMode, int fd, const char *deviceName )
+{
+    PaError result = paNoError;
+    assert( component );
+
+    memset( component, 0, sizeof (PaOssStreamComponent) );
+
+    component->fd = fd;
+    component->devName = deviceName;
+    component->userChannelCount = parameters->channelCount;
+    component->userFormat = parameters->sampleFormat;
+    component->latency = parameters->suggestedLatency;
+    component->userInterleaved = !(parameters->sampleFormat & paNonInterleaved);
+
+    if( !callbackMode && !component->userInterleaved )
+    {
+        /* Pre-allocate non-interleaved user provided buffers */
+        PA_UNLESS( component->userBuffers = PaUtil_AllocateMemory( sizeof (void *) * component->userChannelCount ),
+                paInsufficientMemory );
+    }
+
+error:
+    return result;
+}
+
+static void PaOssStreamComponent_Terminate( PaOssStreamComponent *component )
+{
+    assert( component );
+
+    if( component->fd >= 0 )
+        close( component->fd );
+    if( component->buffer )
+        PaUtil_FreeMemory( component->buffer );
+
+    if( component->userBuffers )
+        PaUtil_FreeMemory( component->userBuffers );
+
+    PaUtil_FreeMemory( component );
+}
+
+static PaError ModifyBlocking( int fd, int blocking )
+{
+    PaError result = paNoError;
+    int fflags;
+
+    ENSURE_( fflags = fcntl( fd, F_GETFL ), paUnanticipatedHostError );
+
+    if( blocking )
+        fflags &= ~O_NONBLOCK;
+    else
+        fflags |= O_NONBLOCK;
+
+    ENSURE_( fcntl( fd, F_SETFL, fflags ), paUnanticipatedHostError );
+
+error:
+    return result;
+}
+
+static PaError OpenDevices( const char *idevName, const char *odevName, int *idev, int *odev )
+{
+    PaError result = paNoError;
+    int flags = O_NONBLOCK, duplex = 0;
+    int enableBits = 0;
+    *idev = *odev = -1;
+
+    if( idevName && odevName )
+    {
+        duplex = 1;
+        flags |= O_RDWR;
+    }
+    else if( idevName )
+        flags |= O_RDONLY;
+    else
+        flags |= O_WRONLY;
+
+    /* open first in nonblocking mode, in case it's busy...
+     * A: then unset the non-blocking attribute */
+    assert( flags & O_NONBLOCK );
+    if( idevName )
+    {
+        ENSURE_( *idev = open( idevName, flags ), paDeviceUnavailable );
+        PA_ENSURE( ModifyBlocking( *idev, 1 ) ); /* Blocking */
+
+        /* Initially disable */
+        enableBits = ~PCM_ENABLE_INPUT;
+        ENSURE_( ioctl( *idev, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError );
+    }
+    if( odevName )
+    {
+        if( !idevName )
+        {
+            ENSURE_( *odev = open( odevName, flags ), paDeviceUnavailable );
+            PA_ENSURE( ModifyBlocking( *odev, 1 ) ); /* Blocking */
+
+            /* Initially disable */
+            enableBits = ~PCM_ENABLE_OUTPUT;
+            ENSURE_( ioctl( *odev, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError );
+        }
+        else
+        {
+            ENSURE_( *odev = dup( *idev ), paUnanticipatedHostError );
+        }
+    }
+
+error:
+    return result;
+}
+
+static PaError PaOssStream_Initialize( PaOssStream *stream, const PaStreamParameters *inputParameters, const PaStreamParameters *outputParameters,
+        PaStreamCallback callback, void *userData, PaStreamFlags streamFlags,
+        PaOSSHostApiRepresentation *ossApi )
+{
+    PaError result = paNoError;
+    int idev, odev;
+    PaUtilHostApiRepresentation *hostApi = &ossApi->inheritedHostApiRep;
+    const char *idevName = NULL, *odevName = NULL;
+
+    assert( stream );
+
+    memset( stream, 0, sizeof (PaOssStream) );
+    stream->isStopped = 1;
+
+    PA_ENSURE( PaUtil_InitializeThreading( &stream->threading ) );
+
+    if( inputParameters && outputParameters )
+    {
+        if( inputParameters->device == outputParameters->device )
+            stream->sharedDevice = 1;
+    }
+
+    if( inputParameters )
+        idevName = hostApi->deviceInfos[inputParameters->device]->name;
+    if( outputParameters )
+        odevName = hostApi->deviceInfos[outputParameters->device]->name;
+    PA_ENSURE( OpenDevices( idevName, odevName, &idev, &odev ) );
+    if( inputParameters )
+    {
+        PA_UNLESS( stream->capture = PaUtil_AllocateMemory( sizeof (PaOssStreamComponent) ), paInsufficientMemory );
+        PA_ENSURE( PaOssStreamComponent_Initialize( stream->capture, inputParameters, callback != NULL, idev, idevName ) );
+    }
+    if( outputParameters )
+    {
+        PA_UNLESS( stream->playback = PaUtil_AllocateMemory( sizeof (PaOssStreamComponent) ), paInsufficientMemory );
+        PA_ENSURE( PaOssStreamComponent_Initialize( stream->playback, outputParameters, callback != NULL, odev, odevName ) );
+    }
+
+    if( callback != NULL )
+    {
+        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
+                                               &ossApi->callbackStreamInterface, callback, userData );
+        stream->callbackMode = 1;
+    }
+    else
+    {
+        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
+                                               &ossApi->blockingStreamInterface, callback, userData );
+    }    
+
+    ENSURE_( sem_init( &stream->semaphore, 0, 0 ), paInternalError );
+
+error:
+    return result;
+}
+
+static void PaOssStream_Terminate( PaOssStream *stream )
+{
+    assert( stream );
+
+    PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
+    PaUtil_TerminateThreading( &stream->threading );
+
+    if( stream->capture )
+        PaOssStreamComponent_Terminate( stream->capture );
+    if( stream->playback )
+        PaOssStreamComponent_Terminate( stream->playback );
+
+    sem_destroy( &stream->semaphore );
+
+    PaUtil_FreeMemory( stream );
+}
+
+/** Translate from PA format to OSS native.
+ *
+ */
+static PaError Pa2OssFormat( PaSampleFormat paFormat, int *ossFormat )
+{
+    switch( paFormat )
+    {
+        case paUInt8:
+            *ossFormat = AFMT_U8;
+            break;
+        case paInt8:
+            *ossFormat = AFMT_S8;
+            break;
+        case paInt16:
+            *ossFormat = AFMT_S16_NE;
+            break;
+        default:
+            return paInternalError;     /* This shouldn't happen */
+    }
+
+    return paNoError;
+}
+
+/** Return the PA-compatible formats that this device can support.
+ *
+ */
+static PaError GetAvailableFormats( PaOssStreamComponent *component, PaSampleFormat *availableFormats )
+{
+    PaError result = paNoError;
+    int mask = 0;
+    PaSampleFormat frmts = 0;
+
+    ENSURE_( ioctl( component->fd, SNDCTL_DSP_GETFMTS, &mask ), paUnanticipatedHostError );
+    if( mask & AFMT_U8 )
+        frmts |= paUInt8;
+    if( mask & AFMT_S8 )
+        frmts |= paInt8;
+    if( mask & AFMT_S16_NE )
+        frmts |= paInt16;
+    else
+        result = paSampleFormatNotSupported;
+    
+    *availableFormats = frmts;
+
+error:
+    return result;
+}
+
+static unsigned int PaOssStreamComponent_FrameSize( PaOssStreamComponent *component )
+{
+    return Pa_GetSampleSize( component->hostFormat ) * component->hostChannelCount;
+}
+
+/** Buffer size in bytes.
+ *
+ */
+static unsigned long PaOssStreamComponent_BufferSize( PaOssStreamComponent *component )
+{
+    return PaOssStreamComponent_FrameSize( component ) * component->hostFrames * component->numBufs;
+}
+
+static int CalcHigherLogTwo( int n )
+{
+    int log2 = 0;
+    while( (1<<log2) < n ) log2++;
+    return log2;
+}
+
+static PaError PaOssStreamComponent_Configure( PaOssStreamComponent *component, double sampleRate, unsigned long framesPerBuffer,
+        StreamMode streamMode, PaOssStreamComponent *master )
+{
+    PaError result = paNoError;
+    int temp, nativeFormat;
+    int sr = (int)sampleRate;
+    PaSampleFormat availableFormats, hostFormat;
+    int chans = component->userChannelCount;
+    int frgmt;
+    int numBufs;
+    int bytesPerBuf;
+    double bufSz;
+    unsigned long fragSz;
+    audio_buf_info bufInfo;
+
+    /* We may have a situation where only one component (the master) is configured, if both point to the same device.
+     * In that case, the second component will copy settings from the other */
+    if( !master )
+    {
+        /* Aspect BufferSettings: If framesPerBuffer is unspecified we have to infer a suitable fragment size.
+         * The hardware need not respect the requested fragment size, so we may have to adapt.
+         */
+        if( framesPerBuffer == paFramesPerBufferUnspecified )
+        { 
+            bufSz = component->latency * sampleRate;
+            fragSz = bufSz / 4;
+        }
+        else
+        {
+            fragSz = framesPerBuffer;
+            bufSz = component->latency * sampleRate + fragSz; /* Latency + 1 buffer */
+        }
+
+        PA_ENSURE( GetAvailableFormats( component, &availableFormats ) );
+        hostFormat = PaUtil_SelectClosestAvailableFormat( availableFormats, component->userFormat );
+
+        /* OSS demands at least 2 buffers, and 16 bytes per buffer */
+        numBufs = PA_MAX( bufSz / fragSz, 2 );
+        bytesPerBuf = PA_MAX( fragSz * Pa_GetSampleSize( hostFormat ) * chans, 16 );
+
+        /* The fragment parameters are encoded like this:
+         * Most significant byte: number of fragments
+         * Least significant byte: exponent of fragment size (i.e., for 256, 8)
+         */
+        frgmt = (numBufs << 16) + (CalcHigherLogTwo( bytesPerBuf ) & 0xffff);
+        ENSURE_( ioctl( component->fd, SNDCTL_DSP_SETFRAGMENT, &frgmt ), paUnanticipatedHostError );
+
+        /* A: according to the OSS programmer's guide parameters should be set in this order:
+         * format, channels, rate */
+
+        /* This format should be deemed good before we get this far */
+        PA_ENSURE( Pa2OssFormat( hostFormat, &temp ) );
+        nativeFormat = temp;
+        ENSURE_( ioctl( component->fd, SNDCTL_DSP_SETFMT, &temp ), paUnanticipatedHostError );
+        PA_UNLESS( temp == nativeFormat, paInternalError );
+
+        /* try to set the number of channels */
+        ENSURE_( ioctl( component->fd, SNDCTL_DSP_CHANNELS, &chans ), paSampleFormatNotSupported );   /* XXX: Should be paInvalidChannelCount? */
+        /* It's possible that the minimum number of host channels is greater than what the user requested */
+        PA_UNLESS( chans >= component->userChannelCount, paInvalidChannelCount );
+
+        /* try to set the sample rate */
+        ENSURE_( ioctl( component->fd, SNDCTL_DSP_SPEED, &sr ), paInvalidSampleRate );
+
+        /* reject if there's no sample rate within 1% of the one requested */
+        if( (fabs( sampleRate - sr ) / sampleRate) > 0.01 )
+        {
+            PA_DEBUG(("%s: Wanted %f, closest sample rate was %d\n", __FUNCTION__, sampleRate, sr ));                 
+            PA_ENSURE( paInvalidSampleRate );
+        }
+
+        ENSURE_( ioctl( component->fd, streamMode == StreamMode_In ? SNDCTL_DSP_GETISPACE : SNDCTL_DSP_GETOSPACE, &bufInfo ),
+                paUnanticipatedHostError );
+        component->numBufs = bufInfo.fragstotal;
+
+        /* This needs to be the last ioctl call before the first read/write, according to the OSS programmer's guide */
+        ENSURE_( ioctl( component->fd, SNDCTL_DSP_GETBLKSIZE, &bytesPerBuf ), paUnanticipatedHostError );
+
+        component->hostFrames = bytesPerBuf / Pa_GetSampleSize( hostFormat ) / chans;
+        component->hostChannelCount = chans;
+        component->hostFormat = hostFormat;
+    }
+    else
+    {
+        component->hostFormat = master->hostFormat;
+        component->hostFrames = master->hostFrames;
+        component->hostChannelCount = master->hostChannelCount;
+        component->numBufs = master->numBufs;
+    }
+
+    PA_UNLESS( component->buffer = PaUtil_AllocateMemory( PaOssStreamComponent_BufferSize( component ) ),
+            paInsufficientMemory );
+
+error:
+    return result;
+}
+
+static PaError PaOssStreamComponent_Read( PaOssStreamComponent *component, unsigned long *frames )
+{
+    PaError result = paNoError;
+    size_t len = *frames * PaOssStreamComponent_FrameSize( component );
+    ssize_t bytesRead;
+
+    ENSURE_( bytesRead = read( component->fd, component->buffer, len ), paUnanticipatedHostError );
+    *frames = bytesRead / PaOssStreamComponent_FrameSize( component );
+    /* TODO: Handle condition where number of frames read doesn't equal number of frames requested */
+
+error:
+    return result;
+}
+
+static PaError PaOssStreamComponent_Write( PaOssStreamComponent *component, unsigned long *frames )
+{
+    PaError result = paNoError;
+    size_t len = *frames * PaOssStreamComponent_FrameSize( component );
+    ssize_t bytesWritten;
+
+    ENSURE_( bytesWritten = write( component->fd, component->buffer, len ), paUnanticipatedHostError );
+    *frames = bytesWritten / PaOssStreamComponent_FrameSize( component );
+    /* TODO: Handle condition where number of frames written doesn't equal number of frames requested */
+
+error:
+    return result;
+}
+
+/** Configure the stream according to input/output parameters.
+ *
+ * Aspect StreamChannels: The minimum number of channels supported by the device may exceed that requested by
+ * the user, if so we'll record the actual number of host channels and adapt later.
+ */
+static PaError PaOssStream_Configure( PaOssStream *stream, double sampleRate, unsigned long framesPerBuffer,
+        double *inputLatency, double *outputLatency )
+{
+    PaError result = paNoError;
+    int duplex = stream->capture && stream->playback;
+    unsigned long framesPerHostBuffer = 0;
+
+    /* We should request full duplex first thing after opening the device */
+    if( duplex && stream->sharedDevice )
+        ENSURE_( ioctl( stream->capture->fd, SNDCTL_DSP_SETDUPLEX, 0 ), paUnanticipatedHostError );
+
+    if( stream->capture )
+    {
+        PaOssStreamComponent *component = stream->capture;
+        PaOssStreamComponent_Configure( component, sampleRate, framesPerBuffer, StreamMode_In, NULL );
+
+        assert( component->hostChannelCount > 0 );
+        assert( component->hostFrames > 0 );
+
+        *inputLatency = component->hostFrames * (component->numBufs - 1) / sampleRate;
+    }
+    if( stream->playback )
+    {
+        PaOssStreamComponent *component = stream->playback, *master = stream->sharedDevice ? stream->capture : NULL;
+        PA_ENSURE( PaOssStreamComponent_Configure( component, sampleRate, framesPerBuffer, StreamMode_Out,
+                    master ) );
+
+        assert( component->hostChannelCount > 0 );
+        assert( component->hostFrames > 0 );
+
+        *outputLatency = component->hostFrames * (component->numBufs - 1) / sampleRate;
+    }
+
+    if( duplex )
+        framesPerHostBuffer = PA_MIN( stream->capture->hostFrames, stream->playback->hostFrames );
+    else if( stream->capture )
+        framesPerHostBuffer = stream->capture->hostFrames;
+    else if( stream->playback )
+        framesPerHostBuffer = stream->playback->hostFrames;
+
+    stream->framesPerHostBuffer = framesPerHostBuffer;
+    stream->pollTimeout = (int) ceil( 1e6 * framesPerHostBuffer / sampleRate );    /* Period in usecs, rounded up */
+
+    stream->sampleRate = stream->streamRepresentation.streamInfo.sampleRate = sampleRate;
+
+error:
+    return result;
+}
+
+/* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */
+
+/** Open a PA OSS stream.
+ *
+ * Aspect StreamChannels: The number of channels is specified per direction (in/out), and can differ between the
+ * two. However, OSS doesn't support separate configuration spaces for capture and playback so if both
+ * directions are the same device we will demand the same number of channels. The number of channels can range
+ * from 1 to the maximum supported by the device.
+ *
+ * Aspect BufferSettings: If framesPerBuffer != paFramesPerBufferUnspecified the number of frames per callback
+ * must reflect this, in addition the host latency per device should approximate the corresponding
+ * suggestedLatency. Based on these constraints we need to determine a number of frames per host buffer that
+ * both capture and playback can agree on (they can be different devices), the buffer processor can adapt
+ * between host and user buffer size, but the ratio should preferably be integral.
+ */
+static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
+                           PaStream** s,
+                           const PaStreamParameters *inputParameters,
+                           const PaStreamParameters *outputParameters,
+                           double sampleRate,
+                           unsigned long framesPerBuffer,
+                           PaStreamFlags streamFlags,
+                           PaStreamCallback *streamCallback,
+                           void *userData )
+{
+    PaError result = paNoError;
+    PaOSSHostApiRepresentation *ossHostApi = (PaOSSHostApiRepresentation*)hostApi;
+    PaOssStream *stream = NULL;
+    int inputChannelCount = 0, outputChannelCount = 0;
+    PaSampleFormat inputSampleFormat = 0, outputSampleFormat = 0, inputHostFormat = 0, outputHostFormat = 0;
+    const PaDeviceInfo *inputDeviceInfo = 0, *outputDeviceInfo = 0;
+    int bpInitialized = 0;
+    double inLatency, outLatency;
+
+    /* validate platform specific flags */
+    if( (streamFlags & paPlatformSpecificFlags) != 0 )
+        return paInvalidFlag; /* unexpected platform specific flag */
+
+    if( inputParameters )
+    {
+        /* unless alternate device specification is supported, reject the use of
+            paUseHostApiSpecificDeviceSpecification */
+        inputDeviceInfo = hostApi->deviceInfos[inputParameters->device];
+        PA_ENSURE( ValidateParameters( inputParameters, inputDeviceInfo, StreamMode_In ) );
+
+        inputChannelCount = inputParameters->channelCount;
+        inputSampleFormat = inputParameters->sampleFormat;
+    }
+    if( outputParameters )
+    {
+        outputDeviceInfo = hostApi->deviceInfos[outputParameters->device];
+        PA_ENSURE( ValidateParameters( outputParameters, outputDeviceInfo, StreamMode_Out ) );
+
+        outputChannelCount = outputParameters->channelCount;
+        outputSampleFormat = outputParameters->sampleFormat;
+    }
+
+    /* Aspect StreamChannels: We currently demand that number of input and output channels are the same, if the same
+     * device is opened for both directions
+     */
+    if( inputChannelCount > 0 && outputChannelCount > 0 )
+    {
+        if( inputParameters->device == outputParameters->device )
+        {
+            if( inputParameters->channelCount != outputParameters->channelCount )
+                return paInvalidChannelCount;
+        }
+    }
+    
+    /* allocate and do basic initialization of the stream structure */
+    PA_UNLESS( stream = (PaOssStream*)PaUtil_AllocateMemory( sizeof(PaOssStream) ), paInsufficientMemory );
+    PA_ENSURE( PaOssStream_Initialize( stream, inputParameters, outputParameters, streamCallback, userData, streamFlags, ossHostApi ) );
+
+    PA_ENSURE( PaOssStream_Configure( stream, sampleRate, framesPerBuffer, &inLatency, &outLatency ) );
+
+    PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );
+        
+    if( inputParameters )
+    {
+        inputHostFormat = stream->capture->hostFormat;
+        stream->streamRepresentation.streamInfo.inputLatency = inLatency +
+            PaUtil_GetBufferProcessorInputLatency( &stream->bufferProcessor ) / sampleRate;
+    }
+    if( outputParameters )
+    {
+        outputHostFormat = stream->playback->hostFormat;
+        stream->streamRepresentation.streamInfo.outputLatency = outLatency +
+            PaUtil_GetBufferProcessorOutputLatency( &stream->bufferProcessor ) / sampleRate;
+    }
+
+    /* Initialize buffer processor with fixed host buffer size.
+     * Aspect StreamSampleFormat: Here we commit the user and host sample formats, PA infrastructure will
+     * convert between the two.
+     */
+    PA_ENSURE( PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
+              inputChannelCount, inputSampleFormat, inputHostFormat, outputChannelCount, outputSampleFormat,
+              outputHostFormat, sampleRate, streamFlags, framesPerBuffer, stream->framesPerHostBuffer,
+              paUtilFixedHostBufferSize, streamCallback, userData ) );
+    bpInitialized = 1;
+
+    *s = (PaStream*)stream;
+
+    return result;
+
+error:
+    if( bpInitialized )
+        PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
+    if( stream )
+        PaOssStream_Terminate( stream );
+
+    return result;
+}
+
+/*! Poll on I/O filedescriptors.
+
+  Poll till we've determined there's data for read or write. In the full-duplex case,
+  we don't want to hang around forever waiting for either input or output frames, so
+  whenever we have a timed out filedescriptor we check if we're nearing under/overrun
+  for the other direction (critical limit set at one buffer). If so, we exit the waiting
+  state, and go on with what we got. We align the number of frames on a host buffer
+  boundary because it is possible that the buffer size differs for the two directions and
+  the host buffer size is a compromise between the two.
+  */
+static PaError PaOssStream_WaitForFrames( PaOssStream *stream, unsigned long *frames )
+{
+    PaError result = paNoError;
+    int pollPlayback = 0, pollCapture = 0;
+    int captureAvail = INT_MAX, playbackAvail = INT_MAX, commonAvail;
+    audio_buf_info bufInfo;
+    /* int ofs = 0, nfds = stream->nfds; */
+    fd_set readFds, writeFds;
+    int nfds = 0;
+    struct timeval selectTimeval = {0, 0};
+    unsigned long timeout = stream->pollTimeout;    /* In usecs */
+    int captureFd = -1, playbackFd = -1;
+
+    assert( stream );
+    assert( frames );
+
+    if( stream->capture )
+    {
+        pollCapture = 1;
+        captureFd = stream->capture->fd;
+        /* stream->capture->pfd->events = POLLIN; */
+    }
+    if( stream->playback )
+    {
+        pollPlayback = 1;
+        playbackFd = stream->playback->fd;
+        /* stream->playback->pfd->events = POLLOUT; */
+    }
+
+    FD_ZERO( &readFds );
+    FD_ZERO( &writeFds );
+
+    while( pollPlayback || pollCapture )
+    {
+        pthread_testcancel();
+
+        /* select may modify the timeout parameter */
+        selectTimeval.tv_usec = timeout;
+        nfds = 0;
+
+        if( pollCapture )
+        {
+            FD_SET( captureFd, &readFds );
+            nfds = captureFd + 1;
+        }
+        if( pollPlayback )
+        {
+            FD_SET( playbackFd, &writeFds );
+            nfds = PA_MAX( nfds, playbackFd + 1 );
+        }
+        ENSURE_( select( nfds, &readFds, &writeFds, NULL, &selectTimeval ), paUnanticipatedHostError );
+        /*
+        if( poll( stream->pfds + ofs, nfds, stream->pollTimeout ) < 0 )
+        {
+
+            ENSURE_( -1, paUnanticipatedHostError );
+        }
+        */
+        pthread_testcancel();
+
+        if( pollCapture )
+        {
+            if( FD_ISSET( captureFd, &readFds ) )
+            {
+                FD_CLR( captureFd, &readFds );
+                pollCapture = 0;
+            }
+            /*
+            if( stream->capture->pfd->revents & POLLIN )
+            {
+                --nfds;
+                ++ofs;
+                pollCapture = 0;
+            }
+            */
+            else if( stream->playback ) /* Timed out, go on with playback? */ 
+            {
+                /*PA_DEBUG(( "%s: Trying to poll again for capture frames, pollTimeout: %d\n",
+                            __FUNCTION__, stream->pollTimeout ));*/
+            }
+        }
+        if( pollPlayback )
+        {
+            if( FD_ISSET( playbackFd, &writeFds ) )
+            {
+                FD_CLR( playbackFd, &writeFds );
+                pollPlayback = 0;
+            }
+            /*
+            if( stream->playback->pfd->revents & POLLOUT )
+            {
+                --nfds;
+                pollPlayback = 0;
+            }
+            */
+            else if( stream->capture )  /* Timed out, go on with capture? */
+            {
+                /*PA_DEBUG(( "%s: Trying to poll again for playback frames, pollTimeout: %d\n\n",
+                            __FUNCTION__, stream->pollTimeout ));*/
+            }
+        }
+    }
+
+    if( stream->capture )
+    {
+        ENSURE_( ioctl( captureFd, SNDCTL_DSP_GETISPACE, &bufInfo ), paUnanticipatedHostError );
+        captureAvail = bufInfo.fragments * stream->capture->hostFrames;
+        if( !captureAvail )
+            PA_DEBUG(( "%s: captureAvail: 0\n", __FUNCTION__ ));
+
+        captureAvail = captureAvail == 0 ? INT_MAX : captureAvail;      /* Disregard if zero */
+    }
+    if( stream->playback )
+    {
+        ENSURE_( ioctl( playbackFd, SNDCTL_DSP_GETOSPACE, &bufInfo ), paUnanticipatedHostError );
+        playbackAvail = bufInfo.fragments * stream->playback->hostFrames;
+        if( !playbackAvail )
+        {
+            PA_DEBUG(( "%s: playbackAvail: 0\n", __FUNCTION__ ));
+        }
+
+        playbackAvail = playbackAvail == 0 ? INT_MAX : playbackAvail;      /* Disregard if zero */
+    }
+
+    commonAvail = PA_MIN( captureAvail, playbackAvail );
+    if( commonAvail == INT_MAX )
+        commonAvail = 0;
+    commonAvail -= commonAvail % stream->framesPerHostBuffer;
+
+    assert( commonAvail != INT_MAX );
+    assert( commonAvail >= 0 );
+    *frames = commonAvail;
+
+error:
+    return result;
+}
+
+/** Prepare stream for capture/playback.
+ *
+ * In order to synchronize capture and playback properly we use the SETTRIGGER command.
+ */
+static PaError PaOssStream_Prepare( PaOssStream *stream )
+{
+    PaError result = paNoError;
+    int enableBits = 0;
+
+    if( stream->triggered )
+        return result;
+
+    if( stream->playback )
+    {
+        size_t bufSz = PaOssStreamComponent_BufferSize( stream->playback );
+        memset( stream->playback->buffer, 0, bufSz );
+
+        /* Looks like we have to turn off blocking before we try this, but if we don't fill the buffer
+         * OSS will complain. */
+        PA_ENSURE( ModifyBlocking( stream->playback->fd, 0 ) );
+        while (1)
+        {
+            if( write( stream->playback->fd, stream->playback->buffer, bufSz ) < 0 )
+                break;
+        }
+        PA_ENSURE( ModifyBlocking( stream->playback->fd, 1 ) );
+    }
+
+    if( stream->sharedDevice )
+    {
+        enableBits = PCM_ENABLE_INPUT | PCM_ENABLE_OUTPUT;
+        ENSURE_( ioctl( stream->capture->fd, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError );
+    }
+    else
+    {
+        if( stream->capture )
+        {
+            enableBits = PCM_ENABLE_INPUT;
+            ENSURE_( ioctl( stream->capture->fd, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError );
+        }
+        if( stream->playback )
+        {
+            enableBits = PCM_ENABLE_OUTPUT;
+            ENSURE_( ioctl( stream->playback->fd, SNDCTL_DSP_SETTRIGGER, &enableBits ), paUnanticipatedHostError );
+        }
+    }
+
+    /* Ok, we have triggered the stream */
+    stream->triggered = 1;
+    
+error:
+    return result;
+}
+
+/** Stop audio processing
+ *
+ */
+static PaError PaOssStream_Stop( PaOssStream *stream, int abort )
+{
+    PaError result = paNoError;
+
+    /* Looks like the only safe way to stop audio without reopening the device is SNDCTL_DSP_POST.
+     * Also disable capture/playback till the stream is started again */
+    if( stream->capture )
+    {
+        ENSURE_( ioctl( stream->capture->fd, SNDCTL_DSP_POST, 0 ), paUnanticipatedHostError );
+    }
+    if( stream->playback && !stream->sharedDevice )
+    {
+        ENSURE_( ioctl( stream->playback->fd, SNDCTL_DSP_POST, 0 ), paUnanticipatedHostError );
+    }
+
+error:
+    return result;
+}
+
+/** Clean up after thread exit.
+ *
+ * Aspect StreamState: If the user has registered a streamFinishedCallback it will be called here
+ */
+static void OnExit( void *data )
+{
+    PaOssStream *stream = (PaOssStream *) data;
+    assert( data );
+
+    PaUtil_ResetCpuLoadMeasurer( &stream->cpuLoadMeasurer );
+
+    PaOssStream_Stop( stream, stream->callbackAbort );
+    
+    PA_DEBUG(( "OnExit: Stoppage\n" ));
+
+    /* Eventually notify user all buffers have played */
+    if( stream->streamRepresentation.streamFinishedCallback )
+        stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
+
+    stream->callbackAbort = 0;      /* Clear state */
+    stream->isActive = 0;
+}
+
+static PaError SetUpBuffers( PaOssStream *stream, unsigned long framesAvail )
+{
+    PaError result = paNoError;
+
+    if( stream->capture )
+    {
+        PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, 0, stream->capture->buffer,
+                stream->capture->hostChannelCount );
+        PaUtil_SetInputFrameCount( &stream->bufferProcessor, framesAvail );
+    }
+    if( stream->playback )
+    {
+        PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, 0, stream->playback->buffer,
+                stream->playback->hostChannelCount );
+        PaUtil_SetOutputFrameCount( &stream->bufferProcessor, framesAvail );
+    }
+
+    return result;
+}
+
+/** Thread procedure for callback processing.
+ *
+ * Aspect StreamState: StartStream will wait on this to initiate audio processing, useful in case the
+ * callback should be used for buffer priming. When the stream is cancelled a separate function will
+ * take care of the transition to the Callback Finished state (the stream isn't considered Stopped
+ * before StopStream() or AbortStream() are called).
+ */
+static void *PaOSS_AudioThreadProc( void *userData )
+{
+    PaError result = paNoError;
+    PaOssStream *stream = (PaOssStream*)userData;
+    unsigned long framesAvail, framesProcessed;
+    int callbackResult = paContinue;
+    int triggered = stream->triggered;  /* See if SNDCTL_DSP_TRIGGER has been issued already */
+    int initiateProcessing = triggered;    /* Already triggered? */
+    PaStreamCallbackFlags cbFlags = 0;  /* We might want to keep state across iterations */
+    PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /* TODO: IMPLEMENT ME */
+    
+    /*
+#if ( SOUND_VERSION > 0x030904 )
+        audio_errinfo errinfo;
+#endif
+*/
+    
+    assert( stream );
+
+    pthread_cleanup_push( &OnExit, stream );   /* Execute OnExit when exiting */
+
+    /* The first time the stream is started we use SNDCTL_DSP_TRIGGER to accurately start capture and
+     * playback in sync, when the stream is restarted after being stopped we simply start by reading/
+     * writing.
+     */
+    PA_ENSURE( PaOssStream_Prepare( stream ) );
+
+    /* If we are to initiate processing implicitly by reading/writing data, we start off in blocking mode */
+    if( initiateProcessing )
+    {
+        /* Make sure devices are in blocking mode */
+        if( stream->capture )
+            ModifyBlocking( stream->capture->fd, 1 );
+        if( stream->playback )
+            ModifyBlocking( stream->playback->fd, 1 );
+    }
+
+    while( 1 )
+    {
+        pthread_testcancel();
+
+        if( stream->callbackStop && callbackResult == paContinue )
+        {
+            PA_DEBUG(( "Setting callbackResult to paComplete\n" ));
+            callbackResult = paComplete;
+        }
+
+        /* Aspect StreamState: Because of the messy OSS scheme we can't explicitly trigger device start unless
+         * the stream has been recently started, we will have to go right ahead and read/write in blocking
+         * fashion to trigger operation. Therefore we begin with processing one host buffer before we switch
+         * to non-blocking mode.
+         */
+        if( !initiateProcessing )
+        {
+            PA_ENSURE( PaOssStream_WaitForFrames( stream, &framesAvail ) );  /* Wait on available frames */
+            assert( framesAvail % stream->framesPerHostBuffer == 0 );
+        }
+        else
+        {
+            framesAvail = stream->framesPerHostBuffer;
+        }
+
+        while( framesAvail > 0 )
+        {
+            unsigned long frames = framesAvail;
+
+            pthread_testcancel();
+
+            PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
+
+            /* Read data */
+            if ( stream->capture )
+            {
+                PA_ENSURE( PaOssStreamComponent_Read( stream->capture, &frames ) );
+                assert( frames == framesAvail );
+            }
+
+#if ( SOUND_VERSION >= 0x030904 )
+            /*
+               Check with OSS to see if there have been any under/overruns
+               since last time we checked.
+               */
+            /*
+            if( ioctl( stream->deviceHandle, SNDCTL_DSP_GETERROR, &errinfo ) >= 0 )
+            {
+                if( errinfo.play_underruns )
+                    cbFlags |= paOutputUnderflow ;
+                if( errinfo.record_underruns )
+                    cbFlags |= paInputUnderflow ;
+            }
+            else
+                PA_DEBUG(( "SNDCTL_DSP_GETERROR command failed: %s\n", strerror( errno ) ));
+                */
+#endif
+
+            PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo,
+                    cbFlags );
+            cbFlags = 0;
+            PA_ENSURE( SetUpBuffers( stream, framesAvail ) );
+
+            framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor,
+                    &callbackResult );
+            assert( framesProcessed == framesAvail );
+            PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed );
+
+            if ( stream->playback )
+            {
+                frames = framesAvail;
+
+                PA_ENSURE( PaOssStreamComponent_Write( stream->playback, &frames ) );
+                assert( frames == framesAvail );
+
+                /* TODO: handle bytesWritten != bytesRequested (slippage?) */
+            }
+
+            framesAvail -= framesProcessed;
+            stream->framesProcessed += framesProcessed;
+
+            if( callbackResult != paContinue )
+                break;
+        }
+
+        if( initiateProcessing || !triggered )
+        {
+            /* Non-blocking */
+            if( stream->capture )
+                PA_ENSURE( ModifyBlocking( stream->capture->fd, 0 ) );
+            if( stream->playback && !stream->sharedDevice )
+                PA_ENSURE( ModifyBlocking( stream->playback->fd, 0 ) );
+
+            initiateProcessing = 0;
+            sem_post( &stream->semaphore );
+        }
+
+        if( callbackResult != paContinue )
+        {
+            stream->callbackAbort = callbackResult == paAbort;
+            if( stream->callbackAbort || PaUtil_IsBufferProcessorOutputEmpty( &stream->bufferProcessor ) )
+                break;
+        }
+    }
+
+    pthread_cleanup_pop( 1 );
+
+error:
+    pthread_exit( NULL );
+}
+
+/** Close the stream.
+ *
+ */
+static PaError CloseStream( PaStream* s )
+{
+    PaError result = paNoError;
+    PaOssStream *stream = (PaOssStream*)s;
+
+    assert( stream );
+
+    PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
+    PaOssStream_Terminate( stream );
+
+    return result;
+}
+
+/** Start the stream.
+ *
+ * Aspect StreamState: After returning, the stream shall be in the Active state, implying that an eventual
+ * callback will be repeatedly called in a separate thread. If a separate thread is started this function
+ * will block untill it has started processing audio, otherwise audio processing is started directly.
+ */
+static PaError StartStream( PaStream *s )
+{
+    PaError result = paNoError;
+    PaOssStream *stream = (PaOssStream*)s;
+
+    stream->isActive = 1;
+    stream->isStopped = 0;
+    stream->lastPosPtr = 0;
+    stream->lastStreamBytes = 0;
+    stream->framesProcessed = 0;
+
+    /* only use the thread for callback streams */
+    if( stream->bufferProcessor.streamCallback )
+    {
+        PA_ENSURE( PaUtil_StartThreading( &stream->threading, &PaOSS_AudioThreadProc, stream ) );
+        sem_wait( &stream->semaphore );
+    }
+    else
+        PA_ENSURE( PaOssStream_Prepare( stream ) );
+
+error:
+    return result;
+}
+
+static PaError RealStop( PaOssStream *stream, int abort )
+{
+    PaError result = paNoError;
+
+    if( stream->callbackMode )
+    {
+        if( abort )
+            stream->callbackAbort = 1;
+        else
+            stream->callbackStop = 1;
+
+        PA_ENSURE( PaUtil_CancelThreading( &stream->threading, !abort, NULL ) );
+
+        stream->callbackStop = stream->callbackAbort = 0;
+    }
+    else
+        PA_ENSURE( PaOssStream_Stop( stream, abort ) );
+
+    stream->isStopped = 1;
+
+error:
+    return result;
+}
+
+/** Stop the stream.
+ *
+ * Aspect StreamState: This will cause the stream to transition to the Stopped state, playing all enqueued
+ * buffers.
+ */
+static PaError StopStream( PaStream *s )
+{
+    return RealStop( (PaOssStream *)s, 0 );
+}
+
+/** Abort the stream.
+ *
+ * Aspect StreamState: This will cause the stream to transition to the Stopped state, discarding all enqueued
+ * buffers. Note that the buffers are not currently correctly discarded, this is difficult without closing
+ * the OSS device.
+ */
+static PaError AbortStream( PaStream *s )
+{
+    return RealStop( (PaOssStream *)s, 1 );
+}
+
+/** Is the stream in the Stopped state.
+ *
+ */
+static PaError IsStreamStopped( PaStream *s )
+{
+    PaOssStream *stream = (PaOssStream*)s;
+
+    return (stream->isStopped);
+}
+
+/** Is the stream in the Active state.
+ *
+ */
+static PaError IsStreamActive( PaStream *s )
+{
+    PaOssStream *stream = (PaOssStream*)s;
+
+    return (stream->isActive);
+}
+
+static PaTime GetStreamTime( PaStream *s )
+{
+    PaOssStream *stream = (PaOssStream*)s;
+    count_info info;
+    int delta;
+
+    if( stream->playback ) {
+        if( ioctl( stream->playback->fd, SNDCTL_DSP_GETOPTR, &info) == 0 ) {
+            delta = ( info.bytes - stream->lastPosPtr ) /* & 0x000FFFFF*/;
+            return (float)(stream->lastStreamBytes + delta) / PaOssStreamComponent_FrameSize( stream->playback ) / stream->sampleRate;
+        }
+    }
+    else {
+        if (ioctl( stream->capture->fd, SNDCTL_DSP_GETIPTR, &info) == 0) {
+            delta = (info.bytes - stream->lastPosPtr) /*& 0x000FFFFF*/;
+            return (float)(stream->lastStreamBytes + delta) / PaOssStreamComponent_FrameSize( stream->capture ) / stream->sampleRate;
+        }
+    }
+
+    /* the ioctl failed, but we can still give a coarse estimate */
+
+    return stream->framesProcessed / stream->sampleRate;
+}
+
+
+static double GetStreamCpuLoad( PaStream* s )
+{
+    PaOssStream *stream = (PaOssStream*)s;
+
+    return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
+}
+
+
+/*
+    As separate stream interfaces are used for blocking and callback
+    streams, the following functions can be guaranteed to only be called
+    for blocking streams.
+*/
+
+
+static PaError ReadStream( PaStream* s,
+                           void *buffer,
+                           unsigned long frames )
+{
+    PaOssStream *stream = (PaOssStream*)s;
+    int bytesRequested, bytesRead;
+    unsigned long framesRequested;
+    void *userBuffer;
+
+    /* If user input is non-interleaved, PaUtil_CopyInput will manipulate the channel pointers,
+     * so we copy the user provided pointers */
+    if( stream->bufferProcessor.userInputIsInterleaved )
+        userBuffer = buffer;
+    else /* Copy channels into local array */
+    {
+        userBuffer = stream->capture->userBuffers;
+        memcpy( (void *)userBuffer, buffer, sizeof (void *) * stream->capture->userChannelCount );
+    }
+
+    while( frames )
+    {
+        framesRequested = PA_MIN( frames, stream->capture->hostFrames );
+
+       bytesRequested = framesRequested * PaOssStreamComponent_FrameSize( stream->capture );
+       bytesRead = read( stream->capture->fd, stream->capture->buffer, bytesRequested );
+       if ( bytesRequested != bytesRead )
+           return paUnanticipatedHostError;
+
+       PaUtil_SetInputFrameCount( &stream->bufferProcessor, stream->capture->hostFrames );
+       PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, 0, stream->capture->buffer, stream->capture->hostChannelCount );
+        PaUtil_CopyInput( &stream->bufferProcessor, &userBuffer, framesRequested );
+       frames -= framesRequested;
+    }
+    return paNoError;
+}
+
+
+static PaError WriteStream( PaStream *s, const void *buffer, unsigned long frames )
+{
+    PaOssStream *stream = (PaOssStream*)s;
+    int bytesRequested, bytesWritten;
+    unsigned long framesConverted;
+    const void *userBuffer;
+
+    /* If user output is non-interleaved, PaUtil_CopyOutput will manipulate the channel pointers,
+     * so we copy the user provided pointers */
+    if( stream->bufferProcessor.userOutputIsInterleaved )
+        userBuffer = buffer;
+    else
+    {
+        /* Copy channels into local array */
+        userBuffer = stream->playback->userBuffers;
+        memcpy( (void *)userBuffer, buffer, sizeof (void *) * stream->playback->userChannelCount );
+    }
+
+    while( frames )
+    {
+       PaUtil_SetOutputFrameCount( &stream->bufferProcessor, stream->playback->hostFrames );
+       PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, 0, stream->playback->buffer, stream->playback->hostChannelCount );
+
+       framesConverted = PaUtil_CopyOutput( &stream->bufferProcessor, &userBuffer, frames );
+       frames -= framesConverted;
+
+       bytesRequested = framesConverted * PaOssStreamComponent_FrameSize( stream->playback );
+       bytesWritten = write( stream->playback->fd, stream->playback->buffer, bytesRequested );
+
+       if ( bytesRequested != bytesWritten )
+           return paUnanticipatedHostError;
+    }
+    return paNoError;
+}
+
+
+static signed long GetStreamReadAvailable( PaStream* s )
+{
+    PaOssStream *stream = (PaOssStream*)s;
+    audio_buf_info info;
+
+    if( ioctl( stream->capture->fd, SNDCTL_DSP_GETISPACE, &info ) < 0 )
+        return paUnanticipatedHostError;
+    return info.fragments * stream->capture->hostFrames;
+}
+
+
+/* TODO: Compute number of allocated bytes somewhere else, can we use ODELAY with capture */
+static signed long GetStreamWriteAvailable( PaStream* s )
+{
+    PaOssStream *stream = (PaOssStream*)s;
+    int delay = 0;
+
+    if( ioctl( stream->playback->fd, SNDCTL_DSP_GETODELAY, &delay ) < 0 )
+        return paUnanticipatedHostError;
+    
+    return (PaOssStreamComponent_BufferSize( stream->playback ) - delay) / PaOssStreamComponent_FrameSize( stream->playback );
+}
+
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/oss/recplay.c b/utils/iaxclient/lib/portaudio/src/hostapi/oss/recplay.c
new file mode 100644 (file)
index 0000000..9d4c78c
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * recplay.c
+ * Phil Burk
+ * Minimal record and playback test.
+ * 
+ */
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#ifndef __STDC__
+/* #include <getopt.h> */
+#endif /* __STDC__ */
+#include <fcntl.h>
+#ifdef __STDC__
+#include <string.h>
+#else /* __STDC__ */
+#include <strings.h>
+#endif /* __STDC__ */
+#include <sys/soundcard.h>
+
+#define NUM_BYTES   (64*1024)
+#define BLOCK_SIZE   (4*1024)
+
+#define AUDIO "/dev/dsp"
+
+char buffer[NUM_BYTES];
+
+int audioDev = 0;
+
+main (int argc, char *argv[])
+{
+    int   numLeft;
+    char *ptr;
+    int   num;
+    int   samplesize;
+
+    /********** RECORD ********************/
+    /* Open audio device. */
+    audioDev = open (AUDIO, O_RDONLY, 0);
+    if (audioDev == -1)
+    {
+        perror (AUDIO);
+        exit (-1);
+    }
+
+    /* Set to 16 bit samples. */
+    samplesize = 16;
+    ioctl(audioDev, SNDCTL_DSP_SAMPLESIZE, &samplesize);
+    if (samplesize != 16)
+    {
+        perror("Unable to set the sample size.");
+        exit(-1);
+    }
+
+    /* Record in blocks */
+    printf("Begin recording.\n");
+    numLeft = NUM_BYTES;
+    ptr = buffer;
+    while( numLeft >= BLOCK_SIZE )
+    {
+        if ( (num = read (audioDev, ptr, BLOCK_SIZE)) < 0 )
+        {
+            perror (AUDIO);
+            exit (-1);
+        }
+        else
+        {
+            printf("Read %d bytes\n", num);
+            ptr += num;
+            numLeft -= num;
+        }
+    }
+
+    close( audioDev );
+
+    /********** PLAYBACK ********************/
+    /* Open audio device for writing. */
+    audioDev = open (AUDIO, O_WRONLY, 0);
+    if (audioDev == -1)
+    {
+        perror (AUDIO);
+        exit (-1);
+    }
+
+    /* Set to 16 bit samples. */
+    samplesize = 16;
+    ioctl(audioDev, SNDCTL_DSP_SAMPLESIZE, &samplesize);
+    if (samplesize != 16)
+    {
+        perror("Unable to set the sample size.");
+        exit(-1);
+    }
+
+    /* Play in blocks */
+    printf("Begin playing.\n");
+    numLeft = NUM_BYTES;
+    ptr = buffer;
+    while( numLeft >= BLOCK_SIZE )
+    {
+        if ( (num = write (audioDev, ptr, BLOCK_SIZE)) < 0 )
+        {
+            perror (AUDIO);
+            exit (-1);
+        }
+        else
+        {
+            printf("Wrote %d bytes\n", num);
+            ptr += num;
+            numLeft -= num;
+        }
+    }
+
+    close( audioDev );
+}
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/wasapi/pa_win_wasapi.cpp b/utils/iaxclient/lib/portaudio/src/hostapi/wasapi/pa_win_wasapi.cpp
new file mode 100644 (file)
index 0000000..34b8cfa
--- /dev/null
@@ -0,0 +1,1770 @@
+/*\r
+ * Portable Audio I/O Library WASAPI implementation\r
+ * Copyright (c) 2006 David Viens\r
+ *\r
+ * Based on the Open Source API proposed by Ross Bencina\r
+ * Copyright (c) 1999-2002 Ross Bencina, Phil Burk\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining\r
+ * a copy of this software and associated documentation files\r
+ * (the "Software"), to deal in the Software without restriction,\r
+ * including without limitation the rights to use, copy, modify, merge,\r
+ * publish, distribute, sublicense, and/or sell copies of the Software,\r
+ * and to permit persons to whom the Software is furnished to do so,\r
+ * subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be\r
+ * included in all copies or substantial portions of the Software.\r
+ *\r
+ * Any person wishing to distribute modifications to the Software is\r
+ * requested to send the modifications to the original developer so that\r
+ * they can be incorporated into the canonical version.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ */\r
+\r
+/** @file\r
+ @brief WASAPI implementation of support for a host API.\r
+\r
+ @note This file is provided as a starting point for implementing support for\r
+ a new host API. IMPLEMENT ME comments are used to indicate functionality\r
+ which much be customised for each implementation.\r
+*/\r
+\r
+\r
+\r
+//these headers are only in Windows SDK CTP Feb 2006 and only work in VC 2005!\r
+#if _MSC_VER >= 1400\r
+#include <windows.h>\r
+#include <MMReg.h>  //must be before other Wasapi headers\r
+#include <strsafe.h>\r
+#include <mmdeviceapi.h>\r
+#include <Avrt.h>\r
+#include <audioclient.h>\r
+#include <KsMedia.h>\r
+#include <propkey.h>  // PKEY_Device_FriendlyName\r
+#endif\r
+\r
+\r
+\r
+#include "pa_util.h"\r
+#include "pa_allocation.h"\r
+#include "pa_hostapi.h"\r
+#include "pa_stream.h"\r
+#include "pa_cpuload.h"\r
+#include "pa_process.h"\r
+\r
+\r
+\r
+/* prototypes for functions declared in this file */\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif /* __cplusplus */\r
+\r
+PaError PaWinWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif /* __cplusplus */\r
+\r
+\r
+\r
+\r
+static void Terminate( struct PaUtilHostApiRepresentation *hostApi );\r
+static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,\r
+                                  const PaStreamParameters *inputParameters,\r
+                                  const PaStreamParameters *outputParameters,\r
+                                  double sampleRate );\r
+static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,\r
+                           PaStream** s,\r
+                           const PaStreamParameters *inputParameters,\r
+                           const PaStreamParameters *outputParameters,\r
+                           double sampleRate,\r
+                           unsigned long framesPerBuffer,\r
+                           PaStreamFlags streamFlags,\r
+                           PaStreamCallback *streamCallback,\r
+                           void *userData );\r
+static PaError CloseStream( PaStream* stream );\r
+static PaError StartStream( PaStream *stream );\r
+static PaError StopStream( PaStream *stream );\r
+static PaError AbortStream( PaStream *stream );\r
+static PaError IsStreamStopped( PaStream *s );\r
+static PaError IsStreamActive( PaStream *stream );\r
+static PaTime GetStreamTime( PaStream *stream );\r
+static double GetStreamCpuLoad( PaStream* stream );\r
+static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames );\r
+static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames );\r
+static signed long GetStreamReadAvailable( PaStream* stream );\r
+static signed long GetStreamWriteAvailable( PaStream* stream );\r
+\r
+\r
+/* IMPLEMENT ME: a macro like the following one should be used for reporting\r
+ host errors */\r
+#define PA_SKELETON_SET_LAST_HOST_ERROR( errorCode, errorText ) \\r
+    PaUtil_SetLastHostErrorInfo( paInDevelopment, errorCode, errorText )\r
+\r
+/* PaWinWasapiHostApiRepresentation - host api datastructure specific to this implementation */\r
+\r
+\r
+\r
+//dummy entry point for other compilers and sdks\r
+//only in Windows SDK CTP Feb 2006 and only work in VC 2005!\r
+#if _MSC_VER < 1400\r
+\r
+PaError PaWinWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ){\r
+    return paNoError;\r
+}\r
+\r
+#else\r
+\r
+\r
+\r
+\r
+#define MAX_STR_LEN 512\r
+\r
+/*\r
+ These are fields that can be gathered from IDevice\r
+ and IAudioDevice PRIOR to Initialize, and done in first pass\r
+ i assume that neither of these will cause the Driver to "load",\r
+ but again, who knows how they implement their stuff\r
+ */\r
+typedef struct PaWinWasapiDeviceInfo\r
+{\r
+    //hmm is it wise to keep a reference until Terminate?\r
+    //TODO Check if that interface requires the driver to be loaded!\r
+    IMMDevice * device;\r
+\r
+    //Fields filled from IDevice\r
+    //from GetId\r
+    WCHAR szDeviceID[MAX_STR_LEN];\r
+    //from GetState\r
+    DWORD state;\r
+\r
+    //Fields filled from IMMEndpoint'sGetDataFlow\r
+    EDataFlow  flow;\r
+\r
+    //Fields filled from IAudioDevice (_prior_ to Initialize)\r
+    //from GetDevicePeriod(\r
+    REFERENCE_TIME  DefaultDevicePeriod;\r
+    REFERENCE_TIME  MinimumDevicePeriod;\r
+    //from GetMixFormat\r
+    WAVEFORMATEX   *MixFormat;//needs to be CoTaskMemFree'd after use!\r
+\r
+} PaWinWasapiDeviceInfo;\r
+\r
+\r
+typedef struct\r
+{\r
+    PaUtilHostApiRepresentation inheritedHostApiRep;\r
+    PaUtilStreamInterface callbackStreamInterface;\r
+    PaUtilStreamInterface blockingStreamInterface;\r
+\r
+    PaUtilAllocationGroup *allocations;\r
+\r
+    /* implementation specific data goes here */\r
+\r
+    //in case we later need the synch\r
+    IMMDeviceEnumerator * enumerator;\r
+\r
+    //this is the REAL number of devices, whether they are usefull to PA or not!\r
+    UINT deviceCount;\r
+\r
+    WCHAR defaultRenderer [MAX_STR_LEN];\r
+    WCHAR defaultCapturer [MAX_STR_LEN];\r
+\r
+    PaWinWasapiDeviceInfo   *devInfo;\r
+}PaWinWasapiHostApiRepresentation;\r
+\r
+\r
+/* PaWinWasapiStream - a stream data structure specifically for this implementation */\r
+\r
+typedef struct PaWinWasapiSubStream{\r
+    IAudioClient        *client;\r
+    WAVEFORMATEXTENSIBLE wavex;\r
+    UINT32               bufferSize;\r
+    REFERENCE_TIME       latency;\r
+    REFERENCE_TIME       period;\r
+    unsigned long framesPerHostCallback; /* just an example */\r
+}PaWinWasapiSubStream;\r
+\r
+typedef struct PaWinWasapiStream\r
+{ /* IMPLEMENT ME: rename this */\r
+    PaUtilStreamRepresentation streamRepresentation;\r
+    PaUtilCpuLoadMeasurer cpuLoadMeasurer;\r
+    PaUtilBufferProcessor bufferProcessor;\r
+\r
+    /* IMPLEMENT ME:\r
+            - implementation specific data goes here\r
+    */\r
+\r
+\r
+    //input\r
+       PaWinWasapiSubStream in;\r
+    IAudioCaptureClient *cclient;\r
+    \r
+       //output\r
+       PaWinWasapiSubStream out;\r
+    IAudioRenderClient  *rclient;\r
+\r
+\r
+    bool running;\r
+    bool closeRequest;\r
+\r
+    DWORD dwThreadId;\r
+    HANDLE hThread;\r
+\r
+    GUID  session;\r
+\r
+}PaWinWasapiStream;\r
+\r
+#define PRINT(x) PA_DEBUG(x);\r
+\r
+void\r
+logAUDCLNT_E(HRESULT res){\r
+\r
+    char *text = 0;\r
+    switch(res){\r
+        case S_OK: return; break;\r
+        case E_POINTER                              :text ="E_POINTER"; break;\r
+        case E_INVALIDARG                           :text ="E_INVALIDARG"; break;\r
+        case AUDCLNT_E_NOT_INITIALIZED              :text ="AUDCLNT_E_NOT_INITIALIZED"; break;\r
+        case AUDCLNT_E_ALREADY_INITIALIZED          :text ="AUDCLNT_E_ALREADY_INITIALIZED"; break;\r
+        case AUDCLNT_E_WRONG_ENDPOINT_TYPE          :text ="AUDCLNT_E_WRONG_ENDPOINT_TYPE"; break;\r
+        case AUDCLNT_E_DEVICE_INVALIDATED           :text ="AUDCLNT_E_DEVICE_INVALIDATED"; break;\r
+        case AUDCLNT_E_NOT_STOPPED                  :text ="AUDCLNT_E_NOT_STOPPED"; break;\r
+        case AUDCLNT_E_BUFFER_TOO_LARGE             :text ="AUDCLNT_E_BUFFER_TOO_LARGE"; break;\r
+        case AUDCLNT_E_OUT_OF_ORDER                 :text ="AUDCLNT_E_OUT_OF_ORDER"; break;\r
+        case AUDCLNT_E_UNSUPPORTED_FORMAT           :text ="AUDCLNT_E_UNSUPPORTED_FORMAT"; break;\r
+        case AUDCLNT_E_INVALID_SIZE                 :text ="AUDCLNT_E_INVALID_SIZE"; break;\r
+        case AUDCLNT_E_DEVICE_IN_USE                :text ="AUDCLNT_E_DEVICE_IN_USE"; break;\r
+        case AUDCLNT_E_BUFFER_OPERATION_PENDING     :text ="AUDCLNT_E_BUFFER_OPERATION_PENDING"; break;\r
+        case AUDCLNT_E_THREAD_NOT_REGISTERED        :text ="AUDCLNT_E_THREAD_NOT_REGISTERED"; break;\r
+        case AUDCLNT_E_NO_SINGLE_PROCESS            :text ="AUDCLNT_E_NO_SINGLE_PROCESS"; break;\r
+        case AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED   :text ="AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED"; break;\r
+        case AUDCLNT_E_ENDPOINT_CREATE_FAILED       :text ="AUDCLNT_E_ENDPOINT_CREATE_FAILED"; break;\r
+        default:\r
+            text =" dunno!";\r
+            return ;\r
+        break;\r
+\r
+    }\r
+    PRINT(("WASAPI ERROR HRESULT: 0x%X : %s\n",res,text));\r
+}\r
+\r
+inline double\r
+nano100ToMillis(const REFERENCE_TIME &ref){\r
+    //  1 nano = 0.000000001 seconds\r
+    //100 nano = 0.0000001   seconds\r
+    //100 nano = 0.0001   milliseconds\r
+    return ((double)ref)*0.0001;\r
+}\r
+\r
+inline double\r
+nano100ToSeconds(const REFERENCE_TIME &ref){\r
+    //  1 nano = 0.000000001 seconds\r
+    //100 nano = 0.0000001   seconds\r
+    //100 nano = 0.0001   milliseconds\r
+    return ((double)ref)*0.0000001;\r
+}\r
+\r
+#ifndef IF_FAILED_JUMP\r
+#define IF_FAILED_JUMP(hr, label) if(FAILED(hr)) goto label;\r
+#endif\r
+\r
+\r
+\r
+//AVRT is the new "multimedia schedulling stuff"\r
+\r
+typedef BOOL   (WINAPI *FAvRtCreateThreadOrderingGroup) (PHANDLE,PLARGE_INTEGER,GUID*,PLARGE_INTEGER);\r
+typedef BOOL   (WINAPI *FAvRtDeleteThreadOrderingGroup) (HANDLE);\r
+typedef BOOL   (WINAPI *FAvRtWaitOnThreadOrderingGroup) (HANDLE);\r
+typedef HANDLE (WINAPI *FAvSetMmThreadCharacteristics)  (LPCTSTR,LPDWORD);\r
+typedef BOOL   (WINAPI *FAvSetMmThreadPriority)         (HANDLE,AVRT_PRIORITY);\r
+\r
+HMODULE  hDInputDLL = 0;\r
+FAvRtCreateThreadOrderingGroup pAvRtCreateThreadOrderingGroup=0;\r
+FAvRtDeleteThreadOrderingGroup pAvRtDeleteThreadOrderingGroup=0;\r
+FAvRtWaitOnThreadOrderingGroup pAvRtWaitOnThreadOrderingGroup=0;\r
+FAvSetMmThreadCharacteristics  pAvSetMmThreadCharacteristics=0;\r
+FAvSetMmThreadPriority         pAvSetMmThreadPriority=0;\r
+\r
+#define setupPTR(fun, type, name)  {                                                        \\r
+                                        fun = (type) GetProcAddress(hDInputDLL,name);       \\r
+                                        if(fun == NULL) {                                   \\r
+                                            PRINT(("GetProcAddr failed for %s" ,name));     \\r
+                                            return false;                                   \\r
+                                        }                                                   \\r
+                                    }                                                       \\r
+\r
+bool\r
+setupAVRT(){\r
+\r
+    hDInputDLL = LoadLibraryA("avrt.dll");\r
+    if(hDInputDLL == NULL)\r
+        return false;\r
+\r
+    setupPTR(pAvRtCreateThreadOrderingGroup, FAvRtCreateThreadOrderingGroup, "AvRtCreateThreadOrderingGroup");\r
+    setupPTR(pAvRtDeleteThreadOrderingGroup, FAvRtDeleteThreadOrderingGroup, "AvRtDeleteThreadOrderingGroup");\r
+    setupPTR(pAvRtWaitOnThreadOrderingGroup, FAvRtWaitOnThreadOrderingGroup, "AvRtWaitOnThreadOrderingGroup");\r
+    setupPTR(pAvSetMmThreadCharacteristics,  FAvSetMmThreadCharacteristics,  "AvSetMmThreadCharacteristicsA");\r
+    setupPTR(pAvSetMmThreadPriority,         FAvSetMmThreadPriority,         "AvSetMmThreadPriority");\r
+\r
+    return true;\r
+}\r
+\r
+\r
+\r
+PaError PaWinWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )\r
+{\r
+    if (!setupAVRT()){\r
+        PRINT(("Windows WASAPI : No AVRT! (not VISTA?)"));\r
+        return paNoError;\r
+    }\r
+\r
+    CoInitialize(NULL);\r
+\r
+    PaError result = paNoError;\r
+    PaWinWasapiHostApiRepresentation *paWasapi;\r
+    PaDeviceInfo *deviceInfoArray;\r
+\r
+    paWasapi = (PaWinWasapiHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaWinWasapiHostApiRepresentation) );\r
+    if( !paWasapi ){\r
+        result = paInsufficientMemory;\r
+        goto error;\r
+    }\r
+\r
+    paWasapi->allocations = PaUtil_CreateAllocationGroup();\r
+    if( !paWasapi->allocations ){\r
+        result = paInsufficientMemory;\r
+        goto error;\r
+    }\r
+\r
+    *hostApi = &paWasapi->inheritedHostApiRep;\r
+    (*hostApi)->info.structVersion = 1;\r
+    (*hostApi)->info.type = paWASAPI;\r
+    (*hostApi)->info.name = "Windows WASAPI";\r
+    (*hostApi)->info.deviceCount = 0;   //so far, we must investigate each\r
+    (*hostApi)->info.defaultInputDevice  = paNoDevice;  /* IMPLEMENT ME */\r
+    (*hostApi)->info.defaultOutputDevice = paNoDevice; /* IMPLEMENT ME */\r
+\r
+\r
+    HRESULT hResult = S_OK;\r
+    IMMDeviceCollection* spEndpoints=0;\r
+    paWasapi->enumerator = 0;\r
+\r
+    if (!setupAVRT()){\r
+        PRINT(("Windows WASAPI : No AVRT! (not VISTA?)"));\r
+        goto error;\r
+    }\r
+\r
+    hResult = CoCreateInstance(\r
+             __uuidof(MMDeviceEnumerator), NULL,CLSCTX_INPROC_SERVER,\r
+             __uuidof(IMMDeviceEnumerator),\r
+             (void**)&paWasapi->enumerator);\r
+\r
+    IF_FAILED_JUMP(hResult, error);\r
+\r
+    //getting default device ids in the eMultimedia "role"\r
+    {\r
+        {\r
+            IMMDevice* defaultRenderer=0;\r
+            hResult = paWasapi->enumerator->GetDefaultAudioEndpoint(eRender, eMultimedia, &defaultRenderer);\r
+            IF_FAILED_JUMP(hResult, error);\r
+            WCHAR* pszDeviceId = NULL;\r
+            hResult = defaultRenderer->GetId(&pszDeviceId);\r
+            IF_FAILED_JUMP(hResult, error);\r
+            StringCchCopyW(paWasapi->defaultRenderer, MAX_STR_LEN-1, pszDeviceId);\r
+            CoTaskMemFree(pszDeviceId);\r
+            defaultRenderer->Release();\r
+        }\r
+\r
+        {\r
+            IMMDevice* defaultCapturer=0;\r
+            hResult = paWasapi->enumerator->GetDefaultAudioEndpoint(eCapture, eMultimedia, &defaultCapturer);\r
+            IF_FAILED_JUMP(hResult, error);\r
+            WCHAR* pszDeviceId = NULL;\r
+            hResult = defaultCapturer->GetId(&pszDeviceId);\r
+            IF_FAILED_JUMP(hResult, error);\r
+            StringCchCopyW(paWasapi->defaultCapturer, MAX_STR_LEN-1, pszDeviceId);\r
+            CoTaskMemFree(pszDeviceId);\r
+            defaultCapturer->Release();\r
+        }\r
+    }\r
+\r
+\r
+    hResult = paWasapi->enumerator->EnumAudioEndpoints(eAll, DEVICE_STATE_ACTIVE, &spEndpoints);\r
+    IF_FAILED_JUMP(hResult, error);\r
+\r
+    hResult = spEndpoints->GetCount(&paWasapi->deviceCount);\r
+    IF_FAILED_JUMP(hResult, error);\r
+\r
+    paWasapi->devInfo = new PaWinWasapiDeviceInfo[paWasapi->deviceCount];\r
+    {\r
+        for (size_t step=0;step<paWasapi->deviceCount;++step)\r
+            memset(&paWasapi->devInfo[step],0,sizeof(PaWinWasapiDeviceInfo));\r
+    }\r
+\r
+\r
+\r
+    if( paWasapi->deviceCount > 0 )\r
+    {\r
+        (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(\r
+                paWasapi->allocations, sizeof(PaDeviceInfo*) * paWasapi->deviceCount );\r
+        if( !(*hostApi)->deviceInfos ){\r
+            result = paInsufficientMemory;\r
+            goto error;\r
+        }\r
+\r
+        /* allocate all device info structs in a contiguous block */\r
+        deviceInfoArray = (PaDeviceInfo*)PaUtil_GroupAllocateMemory(\r
+                paWasapi->allocations, sizeof(PaDeviceInfo) * paWasapi->deviceCount );\r
+        if( !deviceInfoArray ){\r
+            result = paInsufficientMemory;\r
+            goto error;\r
+        }\r
+\r
+        for( UINT i=0; i < paWasapi->deviceCount; ++i ){\r
+\r
+            PaDeviceInfo *deviceInfo = &deviceInfoArray[i];\r
+            deviceInfo->structVersion = 2;\r
+            deviceInfo->hostApi = hostApiIndex;\r
+\r
+            hResult = spEndpoints->Item(i, &paWasapi->devInfo[i].device);\r
+            IF_FAILED_JUMP(hResult, error);\r
+\r
+            //getting ID\r
+            {\r
+                WCHAR* pszDeviceId = NULL;\r
+                hResult = paWasapi->devInfo[i].device->GetId(&pszDeviceId);\r
+                IF_FAILED_JUMP(hResult, error);\r
+                StringCchCopyW(paWasapi->devInfo[i].szDeviceID, MAX_STR_LEN-1, pszDeviceId);\r
+                CoTaskMemFree(pszDeviceId);\r
+\r
+                if (lstrcmpW(paWasapi->devInfo[i].szDeviceID, paWasapi->defaultCapturer)==0){\r
+                    //we found the default input!\r
+                    (*hostApi)->info.defaultInputDevice = (*hostApi)->info.deviceCount;\r
+                }\r
+                if (lstrcmpW(paWasapi->devInfo[i].szDeviceID, paWasapi->defaultRenderer)==0){\r
+                    //we found the default output!\r
+                    (*hostApi)->info.defaultOutputDevice = (*hostApi)->info.deviceCount;\r
+                }\r
+            }\r
+\r
+            DWORD state=0;\r
+            hResult = paWasapi->devInfo[i].device->GetState(&paWasapi->devInfo[i].state);\r
+            IF_FAILED_JUMP(hResult, error);\r
+\r
+            if (paWasapi->devInfo[i].state != DEVICE_STATE_ACTIVE){\r
+                PRINT(("WASAPI device:%d is not currently available (state:%d)\n",i,state));\r
+                //spDevice->Release();\r
+                //continue;\r
+            }\r
+\r
+            {\r
+                IPropertyStore* spProperties;\r
+                hResult = paWasapi->devInfo[i].device->OpenPropertyStore(STGM_READ, &spProperties);\r
+                IF_FAILED_JUMP(hResult, error);\r
+\r
+                //getting "Friendly" Name\r
+                {\r
+                    PROPVARIANT value;\r
+                    PropVariantInit(&value);\r
+                    hResult = spProperties->GetValue(PKEY_Device_FriendlyName, &value);\r
+                    IF_FAILED_JUMP(hResult, error);\r
+                    deviceInfo->name = 0;\r
+                    char* deviceName = (char*)PaUtil_GroupAllocateMemory( paWasapi->allocations, MAX_STR_LEN + 1 );\r
+                    if( !deviceName ){\r
+                        result = paInsufficientMemory;\r
+                        goto error;\r
+                    }\r
+\r
+                    wcstombs(deviceName,   value.pwszVal,MAX_STR_LEN-1); //todo proper size\r
+\r
+                    deviceInfo->name = deviceName;\r
+                    PropVariantClear(&value);\r
+                }\r
+\r
+#if 0\r
+                DWORD numProps = 0;\r
+                hResult = spProperties->GetCount(&numProps);\r
+                IF_FAILED_JUMP(hResult, error);\r
+                {\r
+                    for (DWORD i=0;i<numProps;++i){\r
+                        PROPERTYKEY pkey;\r
+                        hResult = spProperties->GetAt(i,&pkey);\r
+\r
+                        PROPVARIANT value;\r
+                        PropVariantInit(&value);\r
+                        hResult = spProperties->GetValue(pkey, &value);\r
+\r
+                        switch(value.vt){\r
+                            case 11:\r
+                                PRINT(("property*%u*\n",value.ulVal));\r
+                            break;\r
+                            case 19:\r
+                                PRINT(("property*%d*\n",value.boolVal));\r
+                            break;\r
+                            case 31:\r
+                            {\r
+                                char temp[512];\r
+                                wcstombs(temp,    value.pwszVal,MAX_STR_LEN-1);\r
+                                PRINT(("property*%s*\n",temp));\r
+                            }\r
+                            break;\r
+                            default:break;\r
+                        }\r
+\r
+                        PropVariantClear(&value);\r
+                    }\r
+                }\r
+#endif\r
+\r
+                /*  These look interresting... but they are undocumented\r
+                PKEY_AudioEndpoint_FormFactor\r
+                PKEY_AudioEndpoint_ControlPanelPageProvider\r
+                PKEY_AudioEndpoint_Association\r
+                PKEY_AudioEndpoint_PhysicalSpeakerConfig\r
+                PKEY_AudioEngine_DeviceFormat\r
+                */\r
+                spProperties->Release();\r
+            }\r
+\r
+\r
+            //getting the Endpoint data\r
+            {\r
+                IMMEndpoint *endpoint=0;\r
+                hResult = paWasapi->devInfo[i].device->QueryInterface(__uuidof(IMMEndpoint),(void **)&endpoint);\r
+                if (SUCCEEDED(hResult)){\r
+                    hResult = endpoint->GetDataFlow(&paWasapi->devInfo[i].flow);\r
+                    endpoint->Release();\r
+                }\r
+            }\r
+\r
+            //Getting a temporary IAudioDevice for more fields\r
+            //we make sure NOT to call Initialize yet!\r
+            {\r
+                IAudioClient *myClient=0;\r
+\r
+                hResult = paWasapi->devInfo[i].device->Activate(__uuidof(IAudioClient), CLSCTX_INPROC_SERVER, NULL, (void**)&myClient);\r
+                IF_FAILED_JUMP(hResult, error);\r
+\r
+                hResult = myClient->GetDevicePeriod(\r
+                    &paWasapi->devInfo[i].DefaultDevicePeriod,\r
+                    &paWasapi->devInfo[i].MinimumDevicePeriod);\r
+                IF_FAILED_JUMP(hResult, error);\r
+\r
+                hResult = myClient->GetMixFormat(&paWasapi->devInfo[i].MixFormat);\r
+\r
+                IF_FAILED_JUMP(hResult, error);\r
+                myClient->Release();\r
+            }\r
+\r
+            //we can now fill in portaudio device data\r
+            deviceInfo->maxInputChannels  = 0;  //for now\r
+            deviceInfo->maxOutputChannels = 0;  //for now\r
+\r
+            switch(paWasapi->devInfo[i].flow){\r
+                case eRender:\r
+                    //hum not exaclty maximum, more like "default"\r
+                    deviceInfo->maxOutputChannels = paWasapi->devInfo[i].MixFormat->nChannels;\r
+\r
+                    deviceInfo->defaultHighOutputLatency = nano100ToSeconds(paWasapi->devInfo[i].DefaultDevicePeriod);\r
+                    deviceInfo->defaultLowOutputLatency  = nano100ToSeconds(paWasapi->devInfo[i].MinimumDevicePeriod);\r
+                break;\r
+                case eCapture:\r
+                    //hum not exaclty maximum, more like "default"\r
+                    deviceInfo->maxInputChannels  = paWasapi->devInfo[i].MixFormat->nChannels;\r
+\r
+                    deviceInfo->defaultHighInputLatency = nano100ToSeconds(paWasapi->devInfo[i].DefaultDevicePeriod);\r
+                    deviceInfo->defaultLowInputLatency  = nano100ToSeconds(paWasapi->devInfo[i].MinimumDevicePeriod);\r
+                break;\r
+                default:\r
+                    PRINT(("WASAPI device:%d bad Data FLow! \n",i));\r
+                    goto error;\r
+                break;\r
+            }\r
+\r
+            deviceInfo->defaultSampleRate = (double)paWasapi->devInfo[i].MixFormat->nSamplesPerSec;\r
+\r
+            (*hostApi)->deviceInfos[i] = deviceInfo;\r
+            ++(*hostApi)->info.deviceCount;\r
+        }\r
+    }\r
+\r
+    spEndpoints->Release();\r
+\r
+    (*hostApi)->Terminate = Terminate;\r
+    (*hostApi)->OpenStream = OpenStream;\r
+    (*hostApi)->IsFormatSupported = IsFormatSupported;\r
+\r
+    PaUtil_InitializeStreamInterface( &paWasapi->callbackStreamInterface, CloseStream, StartStream,\r
+                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,\r
+                                      GetStreamTime, GetStreamCpuLoad,\r
+                                      PaUtil_DummyRead, PaUtil_DummyWrite,\r
+                                      PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable );\r
+\r
+    PaUtil_InitializeStreamInterface( &paWasapi->blockingStreamInterface, CloseStream, StartStream,\r
+                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,\r
+                                      GetStreamTime, PaUtil_DummyGetCpuLoad,\r
+                                      ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );\r
+\r
+    return result;\r
+\r
+error:\r
+\r
+    if (spEndpoints)\r
+        spEndpoints->Release();\r
+\r
+    if (paWasapi->enumerator)\r
+        paWasapi->enumerator->Release();\r
+\r
+    if( paWasapi )\r
+    {\r
+        if( paWasapi->allocations )\r
+        {\r
+            PaUtil_FreeAllAllocations( paWasapi->allocations );\r
+            PaUtil_DestroyAllocationGroup( paWasapi->allocations );\r
+        }\r
+\r
+        PaUtil_FreeMemory( paWasapi );\r
+    }\r
+    return result;\r
+}\r
+\r
+\r
+static void Terminate( struct PaUtilHostApiRepresentation *hostApi )\r
+{\r
+    PaWinWasapiHostApiRepresentation *paWasapi = (PaWinWasapiHostApiRepresentation*)hostApi;\r
+\r
+    paWasapi->enumerator->Release();\r
+\r
+    for (UINT i=0;i<paWasapi->deviceCount;++i){\r
+        PaWinWasapiDeviceInfo *info = &paWasapi->devInfo[i];\r
+\r
+        if (info->device)\r
+            info->device->Release();\r
+\r
+        if (info->MixFormat)\r
+            CoTaskMemFree(info->MixFormat);\r
+    }\r
+    delete [] paWasapi->devInfo;\r
+\r
+    CoUninitialize();\r
+\r
+    if( paWasapi->allocations ){\r
+        PaUtil_FreeAllAllocations( paWasapi->allocations );\r
+        PaUtil_DestroyAllocationGroup( paWasapi->allocations );\r
+    }\r
+\r
+    PaUtil_FreeMemory( paWasapi );\r
+}\r
+\r
+static void\r
+LogWAVEFORMATEXTENSIBLE(const WAVEFORMATEXTENSIBLE &in){\r
+\r
+    const WAVEFORMATEX *old = (WAVEFORMATEX *)&in;\r
+\r
+       switch (old->wFormatTag){\r
+               case WAVE_FORMAT_EXTENSIBLE:{\r
+\r
+                       PRINT(("wFormatTag=WAVE_FORMAT_EXTENSIBLE\n"));\r
+\r
+                       if (in.SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT){\r
+                               PRINT(("SubFormat=KSDATAFORMAT_SUBTYPE_IEEE_FLOAT\n"));\r
+                       }\r
+                       else if (in.SubFormat == KSDATAFORMAT_SUBTYPE_PCM){\r
+                               PRINT(("SubFormat=KSDATAFORMAT_SUBTYPE_PCM\n"));\r
+                       }\r
+                       else{\r
+                               PRINT(("SubFormat=CUSTOM GUID{%d:%d:%d:%d%d%d%d%d%d%d%d}\n",    \r
+                                                                                       in.SubFormat.Data1,\r
+                                                                                       in.SubFormat.Data2,\r
+                                                                                       in.SubFormat.Data3,\r
+                                                                                       (int)in.SubFormat.Data4[0],\r
+                                                                                       (int)in.SubFormat.Data4[1],\r
+                                                                                       (int)in.SubFormat.Data4[2],\r
+                                                                                       (int)in.SubFormat.Data4[3],\r
+                                                                                       (int)in.SubFormat.Data4[4],\r
+                                                                                       (int)in.SubFormat.Data4[5],\r
+                                                                                       (int)in.SubFormat.Data4[6],\r
+                                                                                       (int)in.SubFormat.Data4[7]));\r
+                       }\r
+                       PRINT(("Samples.wValidBitsPerSample=%d\n",  in.Samples.wValidBitsPerSample));\r
+                       PRINT(("dwChannelMask=0x%X\n",in.dwChannelMask));\r
+               }break;\r
+               \r
+               case WAVE_FORMAT_PCM:        PRINT(("wFormatTag=WAVE_FORMAT_PCM\n")); break;\r
+               case WAVE_FORMAT_IEEE_FLOAT: PRINT(("wFormatTag=WAVE_FORMAT_IEEE_FLOAT\n")); break;\r
+               default : PRINT(("wFormatTag=UNKNOWN(%d)\n",old->wFormatTag)); break;\r
+       }\r
+\r
+       PRINT(("nChannels      =%d\n",old->nChannels)); \r
+       PRINT(("nSamplesPerSec =%d\n",old->nSamplesPerSec));  \r
+       PRINT(("nAvgBytesPerSec=%d\n",old->nAvgBytesPerSec));  \r
+       PRINT(("nBlockAlign    =%d\n",old->nBlockAlign));  \r
+       PRINT(("wBitsPerSample =%d\n",old->wBitsPerSample));  \r
+       PRINT(("cbSize         =%d\n",old->cbSize));  \r
+}\r
+\r
+\r
+\r
+/*\r
+ WAVEFORMATXXX is always interleaved\r
+ */\r
+static PaSampleFormat\r
+waveformatToPaFormat(const WAVEFORMATEXTENSIBLE &in){\r
+\r
+    const WAVEFORMATEX *old = (WAVEFORMATEX *)&in;\r
+\r
+    switch (old->wFormatTag){\r
+\r
+        case WAVE_FORMAT_EXTENSIBLE:\r
+        {\r
+            if (in.SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT){\r
+                if (in.Samples.wValidBitsPerSample == 32)\r
+                    return paFloat32;\r
+                else\r
+                    return paCustomFormat;\r
+            }\r
+            else if (in.SubFormat == KSDATAFORMAT_SUBTYPE_PCM){\r
+                switch (old->wBitsPerSample){\r
+                    case 32: return paInt32; break;\r
+                    case 24: return paInt24;break;\r
+                    case  8: return paUInt8;break;\r
+                    case 16: return paInt16;break;\r
+                    default: return paCustomFormat;break;\r
+                }\r
+            }\r
+            else\r
+                return paCustomFormat;\r
+        }\r
+        break;\r
+\r
+        case WAVE_FORMAT_IEEE_FLOAT:\r
+            return paFloat32;\r
+        break;\r
+\r
+        case WAVE_FORMAT_PCM:\r
+        {\r
+            switch (old->wBitsPerSample){\r
+                case 32: return paInt32; break;\r
+                case 24: return paInt24;break;\r
+                case  8: return paUInt8;break;\r
+                case 16: return paInt16;break;\r
+                default: return paCustomFormat;break;\r
+            }\r
+        }\r
+        break;\r
+\r
+        default:\r
+            return paCustomFormat;\r
+        break;\r
+    }\r
+\r
+    return paCustomFormat;\r
+}\r
+\r
+\r
+\r
+static PaError\r
+waveformatFromParams(WAVEFORMATEXTENSIBLE &wav,\r
+                          const PaStreamParameters * params,\r
+                          double sampleRate){\r
+\r
+    size_t bytesPerSample = 0;\r
+    switch( params->sampleFormat & ~paNonInterleaved ){\r
+        case paFloat32:\r
+        case paInt32: bytesPerSample=4;break;\r
+        case paInt16: bytesPerSample=2;break;\r
+        case paInt24: bytesPerSample=3;break;\r
+        case paInt8:\r
+        case paUInt8: bytesPerSample=1;break;\r
+        case paCustomFormat:\r
+        default: return paSampleFormatNotSupported;break;\r
+    }\r
+\r
+    memset(&wav,0,sizeof(WAVEFORMATEXTENSIBLE));\r
+\r
+    WAVEFORMATEX *old    = (WAVEFORMATEX *)&wav;\r
+    old->nChannels       = (WORD)params->channelCount;\r
+    old->nSamplesPerSec  = (DWORD)sampleRate;\r
+    old->wBitsPerSample  = bytesPerSample*8;\r
+    old->nAvgBytesPerSec = old->nSamplesPerSec * old->nChannels * bytesPerSample;\r
+    old->nBlockAlign     = (WORD)(old->nChannels * bytesPerSample);\r
+\r
+    //WAVEFORMATEX\r
+    if (params->channelCount <=2 && (bytesPerSample == 2 || bytesPerSample == 1)){\r
+        old->cbSize          = 0;\r
+        old->wFormatTag      = WAVE_FORMAT_PCM;\r
+    }\r
+    //WAVEFORMATEXTENSIBLE\r
+    else{\r
+        old->wFormatTag = WAVE_FORMAT_EXTENSIBLE;\r
+\r
+        old->cbSize = sizeof (WAVEFORMATEXTENSIBLE) - sizeof (WAVEFORMATEX);\r
+\r
+        if ((params->sampleFormat & ~paNonInterleaved) == paFloat32)\r
+            wav.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;\r
+        else\r
+            wav.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;\r
+\r
+        wav.Samples.wValidBitsPerSample = old->wBitsPerSample; //no extra padding!\r
+\r
+        switch(params->channelCount){\r
+            case 1:  wav.dwChannelMask = SPEAKER_FRONT_CENTER; break;\r
+            case 2:  wav.dwChannelMask = 0x1 | 0x2; break;\r
+            case 4:  wav.dwChannelMask = 0x1 | 0x2 | 0x10 | 0x20; break;\r
+            case 6:  wav.dwChannelMask = 0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20; break;\r
+            case 8:  wav.dwChannelMask = 0x1 | 0x2 | 0x4 | 0x8 | 0x10 | 0x20 | 0x40 | 0x80; break;\r
+            default: wav.dwChannelMask = 0; break;\r
+        }\r
+    }\r
+\r
+    return paNoError;\r
+}\r
+\r
+\r
+enum PaWasapiFormatAnswer {PWFA_OK,PWFA_NO,PWFA_SUGGESTED};\r
+\r
+\r
+static PaWasapiFormatAnswer \r
+IsFormatSupportedInternal(IAudioClient * myClient, WAVEFORMATEXTENSIBLE &wavex){\r
+\r
+       PaWasapiFormatAnswer answer = PWFA_OK;\r
+\r
+    WAVEFORMATEX *closestMatch=0;\r
+    HRESULT hResult = myClient->IsFormatSupported(\r
+        //AUDCLNT_SHAREMODE_EXCLUSIVE,\r
+        AUDCLNT_SHAREMODE_SHARED,\r
+        (WAVEFORMATEX*)&wavex,&closestMatch);\r
+\r
+       if (hResult == S_OK)\r
+               answer = PWFA_OK;\r
+    else if (closestMatch){\r
+        WAVEFORMATEXTENSIBLE* ext = (WAVEFORMATEXTENSIBLE*)closestMatch;\r
+               \r
+               if (closestMatch->wFormatTag == WAVE_FORMAT_EXTENSIBLE)\r
+                       memcpy(&wavex,closestMatch,sizeof(WAVEFORMATEXTENSIBLE));\r
+               else\r
+                       memcpy(&wavex,closestMatch,sizeof(WAVEFORMATEX));\r
+\r
+        CoTaskMemFree(closestMatch);\r
+               answer = PWFA_SUGGESTED;\r
+       \r
+       }else if (hResult != S_OK){\r
+               logAUDCLNT_E(hResult);\r
+               answer = PWFA_NO;\r
+       }\r
+\r
+       return answer;\r
+}\r
+\r
+\r
+static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,\r
+                                  const PaStreamParameters *inputParameters,\r
+                                  const PaStreamParameters *outputParameters,\r
+                                  double sampleRate )\r
+{\r
+    int inputChannelCount, outputChannelCount;\r
+    PaSampleFormat inputSampleFormat, outputSampleFormat;\r
+\r
+    if( inputParameters )\r
+    {\r
+        inputChannelCount = inputParameters->channelCount;\r
+        inputSampleFormat = inputParameters->sampleFormat;\r
+\r
+        /* all standard sample formats are supported by the buffer adapter,\r
+            this implementation doesn't support any custom sample formats */\r
+        if( inputSampleFormat & paCustomFormat )\r
+            return paSampleFormatNotSupported;\r
+\r
+        /* unless alternate device specification is supported, reject the use of\r
+            paUseHostApiSpecificDeviceSpecification */\r
+\r
+        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )\r
+            return paInvalidDevice;\r
+\r
+        /* check that input device can support inputChannelCount */\r
+        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )\r
+            return paInvalidChannelCount;\r
+\r
+        /* validate inputStreamInfo */\r
+        if( inputParameters->hostApiSpecificStreamInfo )\r
+            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */\r
+\r
+\r
+        PaWinWasapiHostApiRepresentation *paWasapi = (PaWinWasapiHostApiRepresentation*)hostApi;\r
+\r
+        WAVEFORMATEXTENSIBLE wavex;\r
+        waveformatFromParams(wavex,inputParameters,sampleRate);\r
+       \r
+               IAudioClient *myClient=0;\r
+               HRESULT hResult = paWasapi->devInfo[inputParameters->device].device->Activate(\r
+                       __uuidof(IAudioClient), CLSCTX_INPROC_SERVER, NULL, (void**)&myClient);\r
+               if (hResult != S_OK){\r
+                       logAUDCLNT_E(hResult);\r
+                       return paInvalidDevice;\r
+               }\r
+\r
+               PaWasapiFormatAnswer answer = IsFormatSupportedInternal(myClient,wavex);\r
+               myClient->Release();\r
+\r
+               switch (answer){\r
+                       case PWFA_OK: break;\r
+                       case PWFA_NO: return paSampleFormatNotSupported;\r
+                       case PWFA_SUGGESTED:\r
+                       {\r
+                               PRINT(("Suggested format:"));\r
+                               LogWAVEFORMATEXTENSIBLE(wavex);\r
+                               if (wavex.Format.nSamplesPerSec == (DWORD)sampleRate){\r
+                                       //no problem its a format issue only\r
+                               }\r
+                               else{\r
+                                       return paInvalidSampleRate;\r
+                               }\r
+                       }\r
+               }\r
+\r
+\r
+    }\r
+    else\r
+    {\r
+        inputChannelCount = 0;\r
+    }\r
+\r
+    if( outputParameters )\r
+    {\r
+        outputChannelCount = outputParameters->channelCount;\r
+        outputSampleFormat = outputParameters->sampleFormat;\r
+\r
+        /* all standard sample formats are supported by the buffer adapter,\r
+            this implementation doesn't support any custom sample formats */\r
+        if( outputSampleFormat & paCustomFormat )\r
+            return paSampleFormatNotSupported;\r
+\r
+        /* unless alternate device specification is supported, reject the use of\r
+            paUseHostApiSpecificDeviceSpecification */\r
+\r
+        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )\r
+            return paInvalidDevice;\r
+\r
+        /* check that output device can support outputChannelCount */\r
+        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )\r
+            return paInvalidChannelCount;\r
+\r
+        /* validate outputStreamInfo */\r
+        if( outputParameters->hostApiSpecificStreamInfo )\r
+            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */\r
+\r
+\r
+        PaWinWasapiHostApiRepresentation *paWasapi = (PaWinWasapiHostApiRepresentation*)hostApi;\r
+\r
+        WAVEFORMATEXTENSIBLE wavex;\r
+        waveformatFromParams(wavex,outputParameters,sampleRate);\r
+       \r
+               IAudioClient *myClient=0;\r
+               HRESULT hResult = paWasapi->devInfo[outputParameters->device].device->Activate(\r
+                       __uuidof(IAudioClient), CLSCTX_INPROC_SERVER, NULL, (void**)&myClient);\r
+               if (hResult != S_OK){\r
+                       logAUDCLNT_E(hResult);\r
+                       return paInvalidDevice;\r
+               }\r
+\r
+               PaWasapiFormatAnswer answer = IsFormatSupportedInternal(myClient,wavex);\r
+               myClient->Release();\r
+\r
+               switch (answer){\r
+                       case PWFA_OK: break;\r
+                       case PWFA_NO: return paSampleFormatNotSupported;\r
+                       case PWFA_SUGGESTED:\r
+                       {\r
+                               PRINT(("Suggested format:"));\r
+                               LogWAVEFORMATEXTENSIBLE(wavex);\r
+                               if (wavex.Format.nSamplesPerSec == (DWORD)sampleRate){\r
+                                       //no problem its a format issue only\r
+                               }\r
+                               else{\r
+                                       return paInvalidSampleRate;\r
+                               }\r
+                       }\r
+               }\r
+\r
+\r
+    }\r
+    else\r
+    {\r
+        outputChannelCount = 0;\r
+    }\r
+\r
+\r
+    return paFormatIsSupported;\r
+}\r
+\r
+\r
+\r
+/* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */\r
+\r
+static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,\r
+                           PaStream** s,\r
+                           const PaStreamParameters *inputParameters,\r
+                           const PaStreamParameters *outputParameters,\r
+                           double sampleRate,\r
+                           unsigned long framesPerBuffer,\r
+                           PaStreamFlags streamFlags,\r
+                           PaStreamCallback *streamCallback,\r
+                           void *userData )\r
+{\r
+    PaError result = paNoError;\r
+    PaWinWasapiHostApiRepresentation *paWasapi = (PaWinWasapiHostApiRepresentation*)hostApi;\r
+    PaWinWasapiStream *stream = 0;\r
+    int inputChannelCount, outputChannelCount;\r
+    PaSampleFormat inputSampleFormat, outputSampleFormat;\r
+    PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat;\r
+\r
+\r
+    stream = (PaWinWasapiStream*)PaUtil_AllocateMemory( sizeof(PaWinWasapiStream) );\r
+    if( !stream ){\r
+        result = paInsufficientMemory;\r
+        goto error;\r
+    }\r
+\r
+    if( inputParameters )\r
+    {\r
+        inputChannelCount = inputParameters->channelCount;\r
+        inputSampleFormat = inputParameters->sampleFormat;\r
+\r
+        /* unless alternate device specification is supported, reject the use of\r
+            paUseHostApiSpecificDeviceSpecification */\r
+\r
+        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )\r
+            return paInvalidDevice;\r
+\r
+        /* check that input device can support inputChannelCount */\r
+        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )\r
+            return paInvalidChannelCount;\r
+\r
+        /* validate inputStreamInfo */\r
+        if( inputParameters->hostApiSpecificStreamInfo )\r
+            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */\r
+\r
+\r
+        PaWinWasapiDeviceInfo &info = paWasapi->devInfo[inputParameters->device];\r
+\r
+        HRESULT hResult = info.device->Activate(\r
+            __uuidof(IAudioClient), CLSCTX_INPROC_SERVER, NULL,\r
+            (void**)&stream->in.client);\r
+\r
+        if (hResult != S_OK)\r
+            return paInvalidDevice;\r
+\r
+        waveformatFromParams(stream->in.wavex,outputParameters,sampleRate);\r
+               \r
+               PaWasapiFormatAnswer answer = IsFormatSupportedInternal(stream->in.client,\r
+                                                                           stream->in.wavex);\r
+\r
+               switch (answer){\r
+                       case PWFA_OK: break;\r
+                       case PWFA_NO: return paSampleFormatNotSupported;\r
+                       case PWFA_SUGGESTED:\r
+                       {\r
+                               PRINT(("Suggested format:"));\r
+                               LogWAVEFORMATEXTENSIBLE(stream->in.wavex);\r
+                               if (stream->in.wavex.Format.nSamplesPerSec == (DWORD)sampleRate){\r
+                                       //no problem its a format issue only\r
+                               }\r
+                               else{\r
+                                       return paInvalidSampleRate;\r
+                               }\r
+                       }\r
+               }\r
+\r
+        //stream->out.period = info.DefaultDevicePeriod;\r
+        stream->in.period = info.MinimumDevicePeriod;\r
+\r
+        hResult = stream->in.client->Initialize(\r
+            AUDCLNT_SHAREMODE_SHARED,\r
+            //AUDCLNT_SHAREMODE_EXCLUSIVE,\r
+            0,  //no flags\r
+            stream->in.period*3, //tripple buffer\r
+            0,//stream->out.period,\r
+            (WAVEFORMATEX*)&stream->in.wavex,\r
+            &stream->session\r
+            );\r
+\r
+        if (hResult != S_OK){\r
+            logAUDCLNT_E(hResult);\r
+            return paInvalidDevice;\r
+        }\r
+\r
+        hResult = stream->in.client->GetBufferSize(&stream->in.bufferSize);\r
+        if (hResult != S_OK)\r
+            return paInvalidDevice;\r
+\r
+        hResult = stream->in.client->GetStreamLatency(&stream->in.latency);\r
+        if (hResult != S_OK)\r
+            return paInvalidDevice;\r
+\r
+        double periodsPerSecond = 1.0/nano100ToSeconds(stream->in.period);\r
+        double samplesPerPeriod = (double)(stream->in.wavex.Format.nSamplesPerSec)/periodsPerSecond;\r
+\r
+        //this is the number of samples that are required at each period\r
+        stream->in.framesPerHostCallback = (unsigned long)samplesPerPeriod;//unrelated to channels\r
+\r
+        /* IMPLEMENT ME - establish which  host formats are available */\r
+        hostInputSampleFormat =\r
+            PaUtil_SelectClosestAvailableFormat( waveformatToPaFormat(stream->in.wavex), inputSampleFormat );\r
+       }\r
+    else\r
+    {\r
+        inputChannelCount = 0;\r
+        inputSampleFormat = hostInputSampleFormat = paInt16; /* Surpress 'uninitialised var' warnings. */\r
+    }\r
+\r
+    if( outputParameters )\r
+    {\r
+        outputChannelCount = outputParameters->channelCount;\r
+        outputSampleFormat = outputParameters->sampleFormat;\r
+\r
+        /* unless alternate device specification is supported, reject the use of\r
+            paUseHostApiSpecificDeviceSpecification */\r
+\r
+        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )\r
+            return paInvalidDevice;\r
+\r
+        /* check that output device can support inputChannelCount */\r
+        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )\r
+            return paInvalidChannelCount;\r
+\r
+        /* validate outputStreamInfo */\r
+        if( outputParameters->hostApiSpecificStreamInfo )\r
+            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */\r
+\r
+\r
+        PaWinWasapiDeviceInfo &info = paWasapi->devInfo[outputParameters->device];\r
+\r
+        HRESULT hResult = info.device->Activate(\r
+            __uuidof(IAudioClient), CLSCTX_INPROC_SERVER, NULL,\r
+            (void**)&stream->out.client);\r
+\r
+        if (hResult != S_OK)\r
+            return paInvalidDevice;\r
+\r
+        waveformatFromParams(stream->out.wavex,outputParameters,sampleRate);\r
+               \r
+               PaWasapiFormatAnswer answer = IsFormatSupportedInternal(stream->out.client,\r
+                                                                           stream->out.wavex);\r
+\r
+               switch (answer){\r
+                       case PWFA_OK: break;\r
+                       case PWFA_NO: return paSampleFormatNotSupported;\r
+                       case PWFA_SUGGESTED:\r
+                       {\r
+                               PRINT(("Suggested format:"));\r
+                               LogWAVEFORMATEXTENSIBLE(stream->out.wavex);\r
+                               if (stream->out.wavex.Format.nSamplesPerSec == (DWORD)sampleRate){\r
+                                       //no problem its a format issue only\r
+                               }\r
+                               else{\r
+                                       return paInvalidSampleRate;\r
+                               }\r
+                       }\r
+               }\r
+\r
+        //stream->out.period = info.DefaultDevicePeriod;\r
+        stream->out.period = info.MinimumDevicePeriod;\r
+\r
+        hResult = stream->out.client->Initialize(\r
+            AUDCLNT_SHAREMODE_SHARED,\r
+            //AUDCLNT_SHAREMODE_EXCLUSIVE,\r
+            0,  //no flags\r
+            stream->out.period*3, //tripple buffer\r
+            0,//stream->out.period,\r
+            (WAVEFORMATEX*)&stream->out.wavex,\r
+            &stream->session\r
+            );\r
+\r
+        if (hResult != S_OK){\r
+            logAUDCLNT_E(hResult);\r
+            return paInvalidDevice;\r
+        }\r
+\r
+        hResult = stream->out.client->GetBufferSize(&stream->out.bufferSize);\r
+        if (hResult != S_OK)\r
+            return paInvalidDevice;\r
+\r
+        hResult = stream->out.client->GetStreamLatency(&stream->out.latency);\r
+        if (hResult != S_OK)\r
+            return paInvalidDevice;\r
+\r
+        double periodsPerSecond = 1.0/nano100ToSeconds(stream->out.period);\r
+        double samplesPerPeriod = (double)(stream->out.wavex.Format.nSamplesPerSec)/periodsPerSecond;\r
+\r
+        //this is the number of samples that are required at each period\r
+        stream->out.framesPerHostCallback = (unsigned long)samplesPerPeriod;//unrelated to channels\r
+\r
+        /* IMPLEMENT ME - establish which  host formats are available */\r
+        hostOutputSampleFormat =\r
+            PaUtil_SelectClosestAvailableFormat( waveformatToPaFormat(stream->out.wavex), outputSampleFormat );\r
+    }\r
+    else\r
+    {\r
+        outputChannelCount = 0;\r
+        outputSampleFormat = hostOutputSampleFormat = paInt16; /* Surpress 'uninitialized var' warnings. */\r
+    }\r
+\r
+\r
+\r
+    /*\r
+        IMPLEMENT ME:\r
+\r
+        ( the following two checks are taken care of by PaUtil_InitializeBufferProcessor() FIXME - checks needed? )\r
+\r
+            - check that input device can support inputSampleFormat, or that\r
+                we have the capability to convert from outputSampleFormat to\r
+                a native format\r
+\r
+            - check that output device can support outputSampleFormat, or that\r
+                we have the capability to convert from outputSampleFormat to\r
+                a native format\r
+\r
+            - if a full duplex stream is requested, check that the combination\r
+                of input and output parameters is supported\r
+\r
+            - check that the device supports sampleRate\r
+\r
+            - alter sampleRate to a close allowable rate if possible / necessary\r
+\r
+            - validate suggestedInputLatency and suggestedOutputLatency parameters,\r
+                use default values where necessary\r
+    */\r
+\r
+\r
+\r
+    /* validate platform specific flags */\r
+    if( (streamFlags & paPlatformSpecificFlags) != 0 )\r
+        return paInvalidFlag; /* unexpected platform specific flag */\r
+\r
+\r
+\r
+    if( streamCallback )\r
+    {\r
+        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,\r
+                                               &paWasapi->callbackStreamInterface, streamCallback, userData );\r
+    }\r
+    else\r
+    {\r
+        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,\r
+                                               &paWasapi->blockingStreamInterface, streamCallback, userData );\r
+    }\r
+\r
+    PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );\r
+\r
+\r
+       if (outputParameters && inputParameters){\r
+\r
+               //serious problem #1\r
+               if (stream->in.period != stream->out.period){\r
+                       PRINT(("OpenStream: period discrepancy\n"));\r
+                       goto error;\r
+               }\r
+\r
+               //serious problem #2\r
+               if (stream->out.framesPerHostCallback != stream->in.framesPerHostCallback){\r
+                       PRINT(("OpenStream: framesPerHostCallback discrepancy\n"));\r
+                       goto error;\r
+               }\r
+       }\r
+\r
+       unsigned long framesPerHostCallback = (outputParameters)?\r
+               stream->out.framesPerHostCallback: \r
+               stream->in.framesPerHostCallback;\r
+\r
+    /* we assume a fixed host buffer size in this example, but the buffer processor\r
+        can also support bounded and unknown host buffer sizes by passing\r
+        paUtilBoundedHostBufferSize or paUtilUnknownHostBufferSize instead of\r
+        paUtilFixedHostBufferSize below. */\r
+\r
+    result =  PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,\r
+              inputChannelCount, inputSampleFormat, hostInputSampleFormat,\r
+              outputChannelCount, outputSampleFormat, hostOutputSampleFormat,\r
+              sampleRate, streamFlags, framesPerBuffer,\r
+              framesPerHostCallback, paUtilFixedHostBufferSize,\r
+              streamCallback, userData );\r
+    if( result != paNoError )\r
+        goto error;\r
+\r
+\r
+    /*\r
+        IMPLEMENT ME: initialise the following fields with estimated or actual\r
+        values.\r
+    */\r
+    stream->streamRepresentation.streamInfo.inputLatency =\r
+            PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor)\r
+                       + ((inputParameters)?nano100ToSeconds(stream->in.latency) :0);\r
+\r
+    stream->streamRepresentation.streamInfo.outputLatency =\r
+            PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor)\r
+                       + ((outputParameters)?nano100ToSeconds(stream->out.latency) :0);\r
+\r
+    stream->streamRepresentation.streamInfo.sampleRate = sampleRate;\r
+\r
+\r
+    *s = (PaStream*)stream;\r
+\r
+\r
+    return result;\r
+\r
+error:\r
+    if( stream )\r
+        PaUtil_FreeMemory( stream );\r
+\r
+    return result;\r
+}\r
+\r
+\r
+\r
+/*\r
+    When CloseStream() is called, the multi-api layer ensures that\r
+    the stream has already been stopped or aborted.\r
+*/\r
+\r
+#define SAFE_RELEASE(punk)  \\r
+              if ((punk) != NULL)  \\r
+                { (punk)->Release(); (punk) = NULL; }\r
+\r
+static PaError CloseStream( PaStream* s )\r
+{\r
+    PaError result = paNoError;\r
+    PaWinWasapiStream *stream = (PaWinWasapiStream*)s;\r
+\r
+    /*\r
+        IMPLEMENT ME:\r
+            - additional stream closing + cleanup\r
+    */\r
+\r
+    SAFE_RELEASE(stream->out.client);\r
+    SAFE_RELEASE(stream->in.client);\r
+    SAFE_RELEASE(stream->cclient);\r
+    SAFE_RELEASE(stream->rclient);\r
+    CloseHandle(stream->hThread);\r
+\r
+    PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );\r
+    PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );\r
+    PaUtil_FreeMemory( stream );\r
+\r
+    return result;\r
+}\r
+\r
+VOID ProcThread(void *client);\r
+\r
+static PaError StartStream( PaStream *s )\r
+{\r
+    PaError result = paNoError;\r
+    PaWinWasapiStream *stream = (PaWinWasapiStream*)s;\r
+\r
+    PaUtil_ResetBufferProcessor( &stream->bufferProcessor );\r
+       \r
+       HRESULT hResult=S_OK;\r
+\r
+       if (stream->out.client){\r
+               hResult = stream->out.client->GetService(__uuidof(IAudioRenderClient),(void**)&stream->rclient);\r
+               logAUDCLNT_E(hResult);\r
+               if (hResult!=S_OK)\r
+                       return paUnanticipatedHostError;\r
+       }\r
+       \r
+       if (stream->in.client){\r
+        hResult = stream->in.client->GetService(__uuidof(IAudioCaptureClient),(void**)&stream->cclient);\r
+               logAUDCLNT_E(hResult);\r
+               if (hResult!=S_OK)\r
+                       return paUnanticipatedHostError;\r
+       }\r
+\r
+    // Create a thread for this client.\r
+    stream->hThread = CreateThread(\r
+        NULL,              // no security attribute\r
+        0,                 // default stack size\r
+        (LPTHREAD_START_ROUTINE) ProcThread,\r
+        (LPVOID) stream,    // thread parameter\r
+        0,                 // not suspended\r
+        &stream->dwThreadId);      // returns thread ID\r
+\r
+    if (stream->hThread == NULL)\r
+        return paUnanticipatedHostError;\r
+\r
+    return paNoError;\r
+}\r
+\r
+\r
+static PaError StopStream( PaStream *s )\r
+{\r
+    PaError result = paNoError;\r
+    PaWinWasapiStream *stream = (PaWinWasapiStream*)s;\r
+\r
+    /* suppress unused variable warnings */\r
+    stream->closeRequest = true;\r
+    //todo something MUCH better than this\r
+    while(stream->closeRequest)\r
+        Sleep(100);\r
+\r
+    /* IMPLEMENT ME, see portaudio.h for required behavior */\r
+\r
+    stream->running = false;\r
+\r
+    return result;\r
+}\r
+\r
+\r
+static PaError AbortStream( PaStream *s )\r
+{\r
+    PaError result = paNoError;\r
+    PaWinWasapiStream *stream = (PaWinWasapiStream*)s;\r
+\r
+    /* suppress unused variable warnings */\r
+    stream->closeRequest = true;\r
+    //todo something MUCH better than this\r
+    while(stream->closeRequest)\r
+        Sleep(100);\r
+\r
+    /* IMPLEMENT ME, see portaudio.h for required behavior */\r
+\r
+    return result;\r
+}\r
+\r
+\r
+static PaError IsStreamStopped( PaStream *s )\r
+{\r
+    PaWinWasapiStream *stream = (PaWinWasapiStream*)s;\r
+\r
+    return !stream->running;\r
+}\r
+\r
+\r
+static PaError IsStreamActive( PaStream *s )\r
+{\r
+    PaWinWasapiStream *stream = (PaWinWasapiStream*)s;\r
+    return stream->running;\r
+}\r
+\r
+\r
+static PaTime GetStreamTime( PaStream *s )\r
+{\r
+    PaWinWasapiStream *stream = (PaWinWasapiStream*)s;\r
+\r
+    /* suppress unused variable warnings */\r
+    (void) stream;\r
+\r
+    /* IMPLEMENT ME, see portaudio.h for required behavior*/\r
+\r
+       //this is lame ds and mme does the same thing, quite useless method imho\r
+       //why dont we fetch the time in the pa callbacks?\r
+       //at least its doing to be clocked to something\r
+    return PaUtil_GetTime();\r
+}\r
+\r
+\r
+static double GetStreamCpuLoad( PaStream* s )\r
+{\r
+    PaWinWasapiStream *stream = (PaWinWasapiStream*)s;\r
+\r
+    return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );\r
+}\r
+\r
+\r
+/*\r
+    As separate stream interfaces are used for blocking and callback\r
+    streams, the following functions can be guaranteed to only be called\r
+    for blocking streams.\r
+*/\r
+\r
+static PaError ReadStream( PaStream* s,\r
+                           void *buffer,\r
+                           unsigned long frames )\r
+{\r
+    PaWinWasapiStream *stream = (PaWinWasapiStream*)s;\r
+\r
+    /* suppress unused variable warnings */\r
+    (void) buffer;\r
+    (void) frames;\r
+    (void) stream;\r
+\r
+    /* IMPLEMENT ME, see portaudio.h for required behavior*/\r
+\r
+    return paNoError;\r
+}\r
+\r
+\r
+static PaError WriteStream( PaStream* s,\r
+                            const void *buffer,\r
+                            unsigned long frames )\r
+{\r
+    PaWinWasapiStream *stream = (PaWinWasapiStream*)s;\r
+\r
+    /* suppress unused variable warnings */\r
+    (void) buffer;\r
+    (void) frames;\r
+    (void) stream;\r
+\r
+    /* IMPLEMENT ME, see portaudio.h for required behavior*/\r
+\r
+    return paNoError;\r
+}\r
+\r
+\r
+static signed long GetStreamReadAvailable( PaStream* s )\r
+{\r
+    PaWinWasapiStream *stream = (PaWinWasapiStream*)s;\r
+\r
+    /* suppress unused variable warnings */\r
+    (void) stream;\r
+\r
+    /* IMPLEMENT ME, see portaudio.h for required behavior*/\r
+\r
+    return 0;\r
+}\r
+\r
+\r
+static signed long GetStreamWriteAvailable( PaStream* s )\r
+{\r
+    PaWinWasapiStream *stream = (PaWinWasapiStream*)s;\r
+\r
+    /* suppress unused variable warnings */\r
+    (void) stream;\r
+\r
+    /* IMPLEMENT ME, see portaudio.h for required behavior*/\r
+\r
+    return 0;\r
+}\r
+\r
+\r
+\r
+/*\r
+    ExampleHostProcessingLoop() illustrates the kind of processing which may\r
+    occur in a host implementation.\r
+\r
+*/\r
+static void WaspiHostProcessingLoop( void *inputBuffer,  long inputFrames,\r
+                                     void *outputBuffer, long outputFrames,\r
+                                     void *userData )\r
+{\r
+    PaWinWasapiStream *stream = (PaWinWasapiStream*)userData;\r
+    PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /* IMPLEMENT ME */\r
+    int callbackResult;\r
+    unsigned long framesProcessed;\r
+\r
+    PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );\r
+\r
+\r
+    /*\r
+        IMPLEMENT ME:\r
+            - generate timing information\r
+            - handle buffer slips\r
+    */\r
+\r
+    /*\r
+        If you need to byte swap or shift inputBuffer to convert it into a\r
+        portaudio format, do it here.\r
+    */\r
+\r
+\r
+\r
+    PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, 0 /* IMPLEMENT ME: pass underflow/overflow flags when necessary */ );\r
+\r
+    /*\r
+        depending on whether the host buffers are interleaved, non-interleaved\r
+        or a mixture, you will want to call PaUtil_SetInterleaved*Channels(),\r
+        PaUtil_SetNonInterleaved*Channel() or PaUtil_Set*Channel() here.\r
+    */\r
+\r
+    if( stream->bufferProcessor.inputChannelCount > 0 )\r
+    {\r
+        PaUtil_SetInputFrameCount( &stream->bufferProcessor, inputFrames );\r
+        PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor,\r
+            0, /* first channel of inputBuffer is channel 0 */\r
+            inputBuffer,\r
+            0 ); /* 0 - use inputChannelCount passed to init buffer processor */\r
+    }\r
+\r
+    if( stream->bufferProcessor.outputChannelCount > 0 )\r
+    {\r
+        PaUtil_SetOutputFrameCount( &stream->bufferProcessor, outputFrames);\r
+        PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor,\r
+            0, /* first channel of outputBuffer is channel 0 */\r
+            outputBuffer,\r
+            0 ); /* 0 - use outputChannelCount passed to init buffer processor */\r
+    }\r
+\r
+    /* you must pass a valid value of callback result to PaUtil_EndBufferProcessing()\r
+        in general you would pass paContinue for normal operation, and\r
+        paComplete to drain the buffer processor's internal output buffer.\r
+        You can check whether the buffer processor's output buffer is empty\r
+        using PaUtil_IsBufferProcessorOuputEmpty( bufferProcessor )\r
+    */\r
+    callbackResult = paContinue;\r
+    framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult );\r
+\r
+\r
+    /*\r
+        If you need to byte swap or shift outputBuffer to convert it to\r
+        host format, do it here.\r
+    */\r
+\r
+    PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed );\r
+\r
+\r
+    if( callbackResult == paContinue )\r
+    {\r
+        /* nothing special to do */\r
+    }\r
+    else if( callbackResult == paAbort )\r
+    {\r
+        /* IMPLEMENT ME - finish playback immediately  */\r
+\r
+        /* once finished, call the finished callback */\r
+        if( stream->streamRepresentation.streamFinishedCallback != 0 )\r
+            stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );\r
+    }\r
+    else\r
+    {\r
+        /* User callback has asked us to stop with paComplete or other non-zero value */\r
+\r
+        /* IMPLEMENT ME - finish playback once currently queued audio has completed  */\r
+\r
+        /* once finished, call the finished callback */\r
+        if( stream->streamRepresentation.streamFinishedCallback != 0 )\r
+            stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );\r
+    }\r
+}\r
+\r
+\r
+\r
+VOID\r
+ProcThread(void *param){\r
+\r
+       HRESULT hResult;\r
+\r
+    DWORD stuff=0;\r
+    HANDLE thCarac = pAvSetMmThreadCharacteristics("Pro Audio",&stuff);\r
+    if (!thCarac){\r
+        PRINT(("AvSetMmThreadCharacteristics failed!\n"));\r
+    }\r
+\r
+    BOOL prio = pAvSetMmThreadPriority(thCarac,AVRT_PRIORITY_NORMAL);\r
+    if (!prio){\r
+        PRINT(("AvSetMmThreadPriority failed!\n"));\r
+    }\r
+\r
+\r
+    PaWinWasapiStream *stream = (PaWinWasapiStream*)param;\r
+\r
+    HANDLE context;\r
+    GUID threadOrderGUID;\r
+    memset(&threadOrderGUID,0,sizeof(GUID));\r
+    LARGE_INTEGER large;\r
+\r
+    large.QuadPart = stream->out.period;\r
+\r
+    BOOL ok = pAvRtCreateThreadOrderingGroup(&context,\r
+        &large,\r
+        &threadOrderGUID,\r
+#ifdef _DEBUG\r
+        0 //THREAD_ORDER_GROUP_INFINITE_TIMEOUT\r
+#else\r
+        0 //default is 5 times the 2nd param\r
+#endif\r
+        //TEXT("Audio")\r
+        );\r
+\r
+    if (!ok){\r
+        PRINT(("AvRtCreateThreadOrderingGroup failed!\n"));\r
+    }\r
+\r
+       //debug\r
+    {\r
+        HANDLE hh       = GetCurrentThread();\r
+        int  currprio   = GetThreadPriority(hh);\r
+        DWORD currclass = GetPriorityClass(GetCurrentProcess());\r
+        PRINT(("currprio 0x%X currclass 0x%X\n",currprio,currclass));\r
+    }\r
+\r
+\r
+    //fill up initial buffer latency??\r
+\r
+       if (stream->out.client){\r
+               hResult = stream->out.client->Start();\r
+               if (hResult != S_OK)\r
+                       logAUDCLNT_E(hResult);\r
+       }\r
+\r
+    stream->running = true;\r
+\r
+    while(!stream->closeRequest){\r
+        BOOL answer = pAvRtWaitOnThreadOrderingGroup(context);\r
+        if (!answer){\r
+            PRINT(("AvRtWaitOnThreadOrderingGroup failed\n"));\r
+        }\r
+\r
+        unsigned long usingBS = stream->out.framesPerHostCallback;\r
+\r
+        UINT32 padding=0;\r
+        hResult = stream->out.client->GetCurrentPadding(&padding);\r
+        logAUDCLNT_E(hResult);\r
+\r
+        //buffer full dont pursue\r
+        if (padding == stream->out.bufferSize)\r
+            continue;\r
+\r
+        //if something is already inside\r
+        if (padding > 0){\r
+            usingBS = stream->out.bufferSize-padding;\r
+            if (usingBS > stream->out.framesPerHostCallback){\r
+                //PRINT(("underflow! %d\n",usingBS));\r
+            }\r
+            else if (usingBS < stream->out.framesPerHostCallback){\r
+                //PRINT(("overflow! %d\n",usingBS));\r
+            }\r
+        }\r
+        else\r
+            usingBS = stream->out.framesPerHostCallback;\r
+\r
+\r
+        BYTE*indata =0;\r
+        BYTE*outdata=0;\r
+\r
+        hResult = stream->rclient->GetBuffer(usingBS,&outdata);\r
+\r
+        if (hResult != S_OK || !outdata) {\r
+            logAUDCLNT_E(hResult);\r
+                       continue;\r
+        }\r
+\r
+        WaspiHostProcessingLoop(indata, usingBS\r
+                                          ,outdata,usingBS,stream);\r
+\r
+        hResult = stream->rclient->ReleaseBuffer(usingBS,0);\r
+        if (hResult != S_OK)\r
+            logAUDCLNT_E(hResult);\r
+\r
+    }\r
+\r
+\r
+    BOOL bRes = pAvRtDeleteThreadOrderingGroup(context);\r
+    if (!bRes){\r
+        PRINT(("AvRtDeleteThreadOrderingGroup failure\n"));\r
+    }\r
+\r
+    stream->closeRequest = false;\r
+}\r
+\r
+\r
+\r
+\r
+#endif //VC 2005
\ No newline at end of file
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/wdmks/pa_win_wdmks.c b/utils/iaxclient/lib/portaudio/src/hostapi/wdmks/pa_win_wdmks.c
new file mode 100644 (file)
index 0000000..2f5308e
--- /dev/null
@@ -0,0 +1,3269 @@
+/*
+ * $Id: pa_win_wdmks.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * PortAudio Windows WDM-KS interface
+ *
+ * Author: Andrew Baldwin
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2004 Andrew Baldwin, Ross Bencina, Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file
+ @brief Portaudio WDM-KS host API.
+
+ @note This is the implementation of the Portaudio host API using the
+ Windows WDM/Kernel Streaming API in order to enable very low latency
+ playback and recording on all modern Windows platforms (e.g. 2K, XP)
+ Note: This API accesses the device drivers below the usual KMIXER
+ component which is normally used to enable multi-client mixing and
+ format conversion. That means that it will lock out all other users
+ of a device for the duration of active stream using those devices
+*/
+
+#include <stdio.h>
+
+/* Debugging/tracing support */
+
+#define PA_LOGE_
+#define PA_LOGL_
+
+#ifdef __GNUC__
+    #include <initguid.h>
+    #define _WIN32_WINNT 0x0501
+    #define WINVER 0x0501
+#endif
+
+#include <string.h> /* strlen() */
+#include <assert.h>
+
+#include "pa_util.h"
+#include "pa_allocation.h"
+#include "pa_hostapi.h"
+#include "pa_stream.h"
+#include "pa_cpuload.h"
+#include "pa_process.h"
+#include "portaudio.h"
+
+#include <windows.h>
+#include <winioctl.h>
+
+
+#ifdef __GNUC__
+    #undef PA_LOGE_
+    #define PA_LOGE_ PA_DEBUG(("%s {\n",__FUNCTION__))
+    #undef PA_LOGL_
+    #define PA_LOGL_ PA_DEBUG(("} %s\n",__FUNCTION__))
+    /* These defines are set in order to allow the WIndows DirectX
+     * headers to compile with a GCC compiler such as MinGW
+     * NOTE: The headers may generate a few warning in GCC, but
+     * they should compile */
+    #define _INC_MMSYSTEM
+    #define _INC_MMREG
+    #define _NTRTL_ /* Turn off default definition of DEFINE_GUIDEX */
+    #define DEFINE_GUID_THUNK(name,guid) DEFINE_GUID(name,guid)
+    #define DEFINE_GUIDEX(n) DEFINE_GUID_THUNK( n, STATIC_##n )
+    #if !defined( DEFINE_WAVEFORMATEX_GUID )
+        #define DEFINE_WAVEFORMATEX_GUID(x) (USHORT)(x), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
+    #endif
+    #define  WAVE_FORMAT_ADPCM      0x0002
+    #define  WAVE_FORMAT_IEEE_FLOAT 0x0003
+    #define  WAVE_FORMAT_ALAW       0x0006
+    #define  WAVE_FORMAT_MULAW      0x0007
+    #define  WAVE_FORMAT_MPEG       0x0050
+    #define  WAVE_FORMAT_DRM        0x0009
+    #define DYNAMIC_GUID_THUNK(l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
+    #define DYNAMIC_GUID(data) DYNAMIC_GUID_THUNK(data)
+#endif
+
+#ifdef _MSC_VER
+    #define DYNAMIC_GUID(data) {data}
+    #define _INC_MMREG
+    #define _NTRTL_ /* Turn off default definition of DEFINE_GUIDEX */
+    #undef DEFINE_GUID
+    #define DEFINE_GUID(n,data) EXTERN_C const GUID n = {data}
+    #define DEFINE_GUID_THUNK(n,data) DEFINE_GUID(n,data)
+    #define DEFINE_GUIDEX(n) DEFINE_GUID_THUNK(n, STATIC_##n)
+    #if !defined( DEFINE_WAVEFORMATEX_GUID )
+        #define DEFINE_WAVEFORMATEX_GUID(x) (USHORT)(x), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
+    #endif
+    #define  WAVE_FORMAT_ADPCM      0x0002
+    #define  WAVE_FORMAT_IEEE_FLOAT 0x0003
+    #define  WAVE_FORMAT_ALAW       0x0006
+    #define  WAVE_FORMAT_MULAW      0x0007
+    #define  WAVE_FORMAT_MPEG       0x0050
+    #define  WAVE_FORMAT_DRM        0x0009
+#endif
+
+#include <ks.h>
+#include <ksmedia.h>
+#include <tchar.h>
+#include <assert.h>
+#include <stdio.h>
+
+/* These next definitions allow the use of the KSUSER DLL */
+typedef KSDDKAPI DWORD WINAPI KSCREATEPIN(HANDLE, PKSPIN_CONNECT, ACCESS_MASK, PHANDLE);
+extern HMODULE      DllKsUser;
+extern KSCREATEPIN* FunctionKsCreatePin;
+
+/* Forward definition to break circular type reference between pin and filter */
+struct __PaWinWdmFilter;
+typedef struct __PaWinWdmFilter PaWinWdmFilter;
+
+/* The Pin structure
+ * A pin is an input or output node, e.g. for audio flow */
+typedef struct __PaWinWdmPin
+{
+    HANDLE                      handle;
+    PaWinWdmFilter*             parentFilter;
+    unsigned long               pinId;
+    KSPIN_CONNECT*              pinConnect;
+    unsigned long               pinConnectSize;
+    KSDATAFORMAT_WAVEFORMATEX*  ksDataFormatWfx;
+    KSPIN_COMMUNICATION         communication;
+    KSDATARANGE*                dataRanges;
+    KSMULTIPLE_ITEM*            dataRangesItem;
+    KSPIN_DATAFLOW              dataFlow;
+    KSPIN_CINSTANCES            instances;
+    unsigned long               frameSize;
+    int                         maxChannels;
+    unsigned long               formats;
+    int                         bestSampleRate;
+}
+PaWinWdmPin;
+
+/* The Filter structure
+ * A filter has a number of pins and a "friendly name" */
+struct __PaWinWdmFilter
+{
+    HANDLE         handle;
+    int            pinCount;
+    PaWinWdmPin**  pins;
+    TCHAR          filterName[MAX_PATH];
+    TCHAR          friendlyName[MAX_PATH];
+    int            maxInputChannels;
+    int            maxOutputChannels;
+    unsigned long  formats;
+    int            usageCount;
+    int            bestSampleRate;
+};
+
+/* PaWinWdmHostApiRepresentation - host api datastructure specific to this implementation */
+typedef struct __PaWinWdmHostApiRepresentation
+{
+    PaUtilHostApiRepresentation  inheritedHostApiRep;
+    PaUtilStreamInterface        callbackStreamInterface;
+    PaUtilStreamInterface        blockingStreamInterface;
+
+    PaUtilAllocationGroup*       allocations;
+    PaWinWdmFilter**             filters;
+    int                          filterCount;
+}
+PaWinWdmHostApiRepresentation;
+
+typedef struct __PaWinWdmDeviceInfo
+{
+    PaDeviceInfo     inheritedDeviceInfo;
+    PaWinWdmFilter*  filter;
+}
+PaWinWdmDeviceInfo;
+
+typedef struct __DATAPACKET
+{
+    KSSTREAM_HEADER  Header;
+    OVERLAPPED       Signal;
+} DATAPACKET;
+
+/* PaWinWdmStream - a stream data structure specifically for this implementation */
+typedef struct __PaWinWdmStream
+{
+    PaUtilStreamRepresentation  streamRepresentation;
+    PaUtilCpuLoadMeasurer       cpuLoadMeasurer;
+    PaUtilBufferProcessor       bufferProcessor;
+
+    PaWinWdmPin*                recordingPin;
+    PaWinWdmPin*                playbackPin;
+    char*                       hostBuffer;
+    unsigned long               framesPerHostIBuffer;
+    unsigned long               framesPerHostOBuffer;
+    int                         bytesPerInputFrame;
+    int                         bytesPerOutputFrame;
+    int                         streamStarted;
+    int                         streamActive;
+    int                         streamStop;
+    int                         streamAbort;
+    int                         oldProcessPriority;
+    HANDLE                      streamThread;
+    HANDLE                      events[5];  /* 2 play + 2 record packets + abort events */
+    DATAPACKET                  packets[4]; /* 2 play + 2 record */
+    PaStreamFlags               streamFlags;
+    /* These values handle the case where the user wants to use fewer
+     * channels than the device has */
+    int                         userInputChannels;
+    int                         deviceInputChannels;
+    int                         userOutputChannels;
+    int                         deviceOutputChannels;
+    int                         inputSampleSize;
+    int                         outputSampleSize;
+}
+PaWinWdmStream;
+
+#include <setupapi.h>
+
+HMODULE      DllKsUser = NULL;
+KSCREATEPIN* FunctionKsCreatePin = NULL;
+
+/* prototypes for functions declared in this file */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+PaError PaWinWdm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+/* Low level I/O functions */
+static PaError WdmSyncIoctl(HANDLE handle,
+    unsigned long ioctlNumber,
+    void* inBuffer,
+    unsigned long inBufferCount,
+    void* outBuffer,
+    unsigned long outBufferCount,
+    unsigned long* bytesReturned);
+static PaError WdmGetPropertySimple(HANDLE handle,
+    const GUID* const guidPropertySet,
+    unsigned long property,
+    void* value,
+    unsigned long valueCount,
+    void* instance,
+    unsigned long instanceCount);
+static PaError WdmSetPropertySimple(HANDLE handle,
+    const GUID* const guidPropertySet,
+    unsigned long property,
+    void* value,
+    unsigned long valueCount,
+    void* instance,
+    unsigned long instanceCount);
+static PaError WdmGetPinPropertySimple(HANDLE  handle,
+    unsigned long pinId,
+    const GUID* const guidPropertySet,
+    unsigned long property,
+    void* value,
+    unsigned long valueCount);
+static PaError WdmGetPinPropertyMulti(HANDLE  handle,
+    unsigned long pinId,
+    const GUID* const guidPropertySet,
+    unsigned long property,
+    KSMULTIPLE_ITEM** ksMultipleItem);
+
+/** Pin management functions */
+static PaWinWdmPin* PinNew(PaWinWdmFilter* parentFilter, unsigned long pinId, PaError* error);
+static void PinFree(PaWinWdmPin* pin);
+static void PinClose(PaWinWdmPin* pin);
+static PaError PinInstantiate(PaWinWdmPin* pin);
+/*static PaError PinGetState(PaWinWdmPin* pin, KSSTATE* state); NOT USED */
+static PaError PinSetState(PaWinWdmPin* pin, KSSTATE state);
+static PaError PinSetFormat(PaWinWdmPin* pin, const WAVEFORMATEX* format);
+static PaError PinIsFormatSupported(PaWinWdmPin* pin, const WAVEFORMATEX* format);
+
+/* Filter management functions */
+static PaWinWdmFilter* FilterNew(
+    TCHAR* filterName,
+    TCHAR* friendlyName,
+    PaError* error);
+static void FilterFree(PaWinWdmFilter* filter);
+static PaWinWdmPin* FilterCreateRenderPin(
+    PaWinWdmFilter* filter,
+    const WAVEFORMATEX* wfex,
+    PaError* error);
+static PaWinWdmPin* FilterFindViableRenderPin(
+    PaWinWdmFilter* filter,
+    const WAVEFORMATEX* wfex,
+    PaError* error);
+static PaError FilterCanCreateRenderPin(
+    PaWinWdmFilter* filter,
+    const WAVEFORMATEX* wfex);
+static PaWinWdmPin* FilterCreateCapturePin(
+    PaWinWdmFilter* filter,
+    const WAVEFORMATEX* wfex,
+    PaError* error);
+static PaWinWdmPin* FilterFindViableCapturePin(
+    PaWinWdmFilter* filter,
+    const WAVEFORMATEX* wfex,
+    PaError* error);
+static PaError FilterCanCreateCapturePin(
+    PaWinWdmFilter* filter,
+    const WAVEFORMATEX* pwfx);
+static PaError FilterUse(
+    PaWinWdmFilter* filter);
+static void FilterRelease(
+    PaWinWdmFilter* filter);
+
+/* Interface functions */
+static void Terminate( struct PaUtilHostApiRepresentation *hostApi );
+static PaError IsFormatSupported(
+    struct PaUtilHostApiRepresentation *hostApi,
+    const PaStreamParameters *inputParameters,
+    const PaStreamParameters *outputParameters,
+    double sampleRate );
+static PaError OpenStream(
+    struct PaUtilHostApiRepresentation *hostApi,
+    PaStream** s,
+    const PaStreamParameters *inputParameters,
+    const PaStreamParameters *outputParameters,
+    double sampleRate,
+    unsigned long framesPerBuffer,
+    PaStreamFlags streamFlags,
+    PaStreamCallback *streamCallback,
+    void *userData );
+static PaError CloseStream( PaStream* stream );
+static PaError StartStream( PaStream *stream );
+static PaError StopStream( PaStream *stream );
+static PaError AbortStream( PaStream *stream );
+static PaError IsStreamStopped( PaStream *s );
+static PaError IsStreamActive( PaStream *stream );
+static PaTime GetStreamTime( PaStream *stream );
+static double GetStreamCpuLoad( PaStream* stream );
+static PaError ReadStream(
+    PaStream* stream,
+    void *buffer,
+    unsigned long frames );
+static PaError WriteStream(
+    PaStream* stream,
+    const void *buffer,
+    unsigned long frames );
+static signed long GetStreamReadAvailable( PaStream* stream );
+static signed long GetStreamWriteAvailable( PaStream* stream );
+
+/* Utility functions */
+static unsigned long GetWfexSize(const WAVEFORMATEX* wfex);
+static PaError BuildFilterList(PaWinWdmHostApiRepresentation* wdmHostApi);
+static BOOL PinWrite(HANDLE h, DATAPACKET* p);
+static BOOL PinRead(HANDLE h, DATAPACKET* p);
+static void DuplicateFirstChannelInt16(void* buffer, int channels, int samples);
+static void DuplicateFirstChannelInt24(void* buffer, int channels, int samples);
+static DWORD WINAPI ProcessingThread(LPVOID pParam);
+
+/* Function bodies */
+
+static unsigned long GetWfexSize(const WAVEFORMATEX* wfex)
+{
+    if( wfex->wFormatTag == WAVE_FORMAT_PCM )
+    {
+        return sizeof( WAVEFORMATEX );
+    }
+    else
+    {
+        return (sizeof( WAVEFORMATEX ) + wfex->cbSize);
+    }
+}
+
+/*
+Low level pin/filter access functions
+*/
+static PaError WdmSyncIoctl(
+    HANDLE handle,
+    unsigned long ioctlNumber,
+    void* inBuffer,
+    unsigned long inBufferCount,
+    void* outBuffer,
+    unsigned long outBufferCount,
+    unsigned long* bytesReturned)
+{
+    PaError result = paNoError;
+    OVERLAPPED overlapped;
+    int boolResult;
+    unsigned long dummyBytesReturned;
+    unsigned long error;
+
+    if( !bytesReturned )
+    {
+        /* User a dummy as the caller hasn't supplied one */
+        bytesReturned = &dummyBytesReturned;
+    }
+
+    FillMemory((void *)&overlapped,sizeof(overlapped),0);
+    overlapped.hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
+    if( !overlapped.hEvent )
+    {
+          result = paInsufficientMemory;
+        goto error;
+    }
+    overlapped.hEvent = (HANDLE)((DWORD_PTR)overlapped.hEvent | 0x1);
+
+    boolResult = DeviceIoControl(handle, ioctlNumber, inBuffer, inBufferCount,
+        outBuffer, outBufferCount, bytesReturned, &overlapped);
+    if( !boolResult )
+    {
+        error = GetLastError();
+        if( error == ERROR_IO_PENDING )
+        {
+            error = WaitForSingleObject(overlapped.hEvent,INFINITE);
+            if( error != WAIT_OBJECT_0 )
+            {
+                result = paUnanticipatedHostError;
+                goto error;
+            }
+        }
+        else if((( error == ERROR_INSUFFICIENT_BUFFER ) ||
+                  ( error == ERROR_MORE_DATA )) &&
+                  ( ioctlNumber == IOCTL_KS_PROPERTY ) &&
+                  ( outBufferCount == 0 ))
+        {
+            boolResult = TRUE;
+        }
+        else
+        {
+            result = paUnanticipatedHostError;
+        }
+    }
+    if( !boolResult )
+        *bytesReturned = 0;
+
+error:
+    if( overlapped.hEvent )
+    {
+            CloseHandle( overlapped.hEvent );
+    }
+    return result;
+}
+
+static PaError WdmGetPropertySimple(HANDLE handle,
+    const GUID* const guidPropertySet,
+    unsigned long property,
+    void* value,
+    unsigned long valueCount,
+    void* instance,
+    unsigned long instanceCount)
+{
+    PaError result;
+    KSPROPERTY* ksProperty;
+    unsigned long propertyCount;
+
+    propertyCount = sizeof(KSPROPERTY) + instanceCount;
+    ksProperty = (KSPROPERTY*)PaUtil_AllocateMemory( propertyCount );
+    if( !ksProperty )
+    {
+        return paInsufficientMemory;
+    }
+
+    FillMemory((void*)ksProperty,sizeof(ksProperty),0);
+    ksProperty->Set = *guidPropertySet;
+    ksProperty->Id = property;
+    ksProperty->Flags = KSPROPERTY_TYPE_GET;
+
+    if( instance )
+    {
+        memcpy( (void*)(((char*)ksProperty)+sizeof(KSPROPERTY)), instance, instanceCount );
+    }
+
+    result = WdmSyncIoctl(
+                handle,
+                IOCTL_KS_PROPERTY,
+                ksProperty,
+                propertyCount,
+                value,
+                valueCount,
+                NULL);
+
+    PaUtil_FreeMemory( ksProperty );
+    return result;
+}
+
+static PaError WdmSetPropertySimple(
+    HANDLE handle,
+    const GUID* const guidPropertySet,
+    unsigned long property,
+    void* value,
+    unsigned long valueCount,
+    void* instance,
+    unsigned long instanceCount)
+{
+    PaError result;
+    KSPROPERTY* ksProperty;
+    unsigned long propertyCount  = 0;
+
+    propertyCount = sizeof(KSPROPERTY) + instanceCount;
+    ksProperty = (KSPROPERTY*)PaUtil_AllocateMemory( propertyCount );
+    if( !ksProperty )
+    {
+        return paInsufficientMemory;
+    }
+
+    ksProperty->Set = *guidPropertySet;
+    ksProperty->Id = property;
+    ksProperty->Flags = KSPROPERTY_TYPE_SET;
+
+    if( instance )
+    {
+        memcpy((void*)((char*)ksProperty + sizeof(KSPROPERTY)), instance, instanceCount);
+    }
+
+    result = WdmSyncIoctl(
+                handle,
+                IOCTL_KS_PROPERTY,
+                ksProperty,
+                propertyCount,
+                value,
+                valueCount,
+                NULL);
+
+    PaUtil_FreeMemory( ksProperty );
+    return result;
+}
+
+static PaError WdmGetPinPropertySimple(
+    HANDLE  handle,
+    unsigned long pinId,
+    const GUID* const guidPropertySet,
+    unsigned long property,
+    void* value,
+    unsigned long valueCount)
+{
+    PaError result;
+
+    KSP_PIN ksPProp;
+    ksPProp.Property.Set = *guidPropertySet;
+    ksPProp.Property.Id = property;
+    ksPProp.Property.Flags = KSPROPERTY_TYPE_GET;
+    ksPProp.PinId = pinId;
+    ksPProp.Reserved = 0;
+
+    result = WdmSyncIoctl(
+                handle,
+                IOCTL_KS_PROPERTY,
+                &ksPProp,
+                sizeof(KSP_PIN),
+                value,
+                valueCount,
+                NULL);
+
+    return result;
+}
+
+static PaError WdmGetPinPropertyMulti(
+    HANDLE handle,
+    unsigned long pinId,
+    const GUID* const guidPropertySet,
+    unsigned long property,
+    KSMULTIPLE_ITEM** ksMultipleItem)
+{
+    PaError result;
+    unsigned long multipleItemSize = 0;
+    KSP_PIN ksPProp;
+
+    ksPProp.Property.Set = *guidPropertySet;
+    ksPProp.Property.Id = property;
+    ksPProp.Property.Flags = KSPROPERTY_TYPE_GET;
+    ksPProp.PinId = pinId;
+    ksPProp.Reserved = 0;
+
+    result = WdmSyncIoctl(
+                handle,
+                IOCTL_KS_PROPERTY,
+                &ksPProp.Property,
+                sizeof(KSP_PIN),
+                NULL,
+                0,
+                &multipleItemSize);
+    if( result != paNoError )
+    {
+        return result;
+    }
+
+    *ksMultipleItem = (KSMULTIPLE_ITEM*)PaUtil_AllocateMemory( multipleItemSize );
+    if( !*ksMultipleItem )
+    {
+        return paInsufficientMemory;
+    }
+
+    result = WdmSyncIoctl(
+                handle,
+                IOCTL_KS_PROPERTY,
+                &ksPProp,
+                sizeof(KSP_PIN),
+                (void*)*ksMultipleItem,
+                multipleItemSize,
+                NULL);
+
+    if( result != paNoError )
+    {
+        PaUtil_FreeMemory( ksMultipleItem );
+    }
+
+    return result;
+}
+
+
+/*
+Create a new pin object belonging to a filter
+The pin object holds all the configuration information about the pin
+before it is opened, and then the handle of the pin after is opened
+*/
+static PaWinWdmPin* PinNew(PaWinWdmFilter* parentFilter, unsigned long pinId, PaError* error)
+{
+    PaWinWdmPin* pin;
+    PaError result;
+    unsigned long i;
+    KSMULTIPLE_ITEM* item = NULL;
+    KSIDENTIFIER* identifier;
+    KSDATARANGE* dataRange;
+
+    PA_LOGE_;
+    PA_DEBUG(("Creating pin %d:\n",pinId));
+
+    /* Allocate the new PIN object */
+    pin = (PaWinWdmPin*)PaUtil_AllocateMemory( sizeof(PaWinWdmPin) );
+    if( !pin )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+
+    /* Zero the pin object */
+    /* memset( (void*)pin, 0, sizeof(PaWinWdmPin) ); */
+
+    pin->parentFilter = parentFilter;
+    pin->pinId = pinId;
+
+    /* Allocate a connect structure */
+    pin->pinConnectSize = sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX);
+    pin->pinConnect = (KSPIN_CONNECT*)PaUtil_AllocateMemory( pin->pinConnectSize );
+    if( !pin->pinConnect )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+
+    /* Configure the connect structure with default values */
+    pin->pinConnect->Interface.Set               = KSINTERFACESETID_Standard;
+    pin->pinConnect->Interface.Id                = KSINTERFACE_STANDARD_STREAMING;
+    pin->pinConnect->Interface.Flags             = 0;
+    pin->pinConnect->Medium.Set                  = KSMEDIUMSETID_Standard;
+    pin->pinConnect->Medium.Id                   = KSMEDIUM_TYPE_ANYINSTANCE;
+    pin->pinConnect->Medium.Flags                = 0;
+    pin->pinConnect->PinId                       = pinId;
+    pin->pinConnect->PinToHandle                 = NULL;
+    pin->pinConnect->Priority.PriorityClass      = KSPRIORITY_NORMAL;
+    pin->pinConnect->Priority.PrioritySubClass   = 1;
+    pin->ksDataFormatWfx = (KSDATAFORMAT_WAVEFORMATEX*)(pin->pinConnect + 1);
+    pin->ksDataFormatWfx->DataFormat.FormatSize  = sizeof(KSDATAFORMAT_WAVEFORMATEX);
+    pin->ksDataFormatWfx->DataFormat.Flags       = 0;
+    pin->ksDataFormatWfx->DataFormat.Reserved    = 0;
+    pin->ksDataFormatWfx->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO;
+    pin->ksDataFormatWfx->DataFormat.SubFormat   = KSDATAFORMAT_SUBTYPE_PCM;
+    pin->ksDataFormatWfx->DataFormat.Specifier   = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;
+
+    pin->frameSize = 0; /* Unknown until we instantiate pin */
+
+    /* Get the COMMUNICATION property */
+    result = WdmGetPinPropertySimple(
+        parentFilter->handle,
+        pinId,
+        &KSPROPSETID_Pin,
+        KSPROPERTY_PIN_COMMUNICATION,
+        &pin->communication,
+        sizeof(KSPIN_COMMUNICATION));
+    if( result != paNoError )
+        goto error;
+
+    if( /*(pin->communication != KSPIN_COMMUNICATION_SOURCE) &&*/
+         (pin->communication != KSPIN_COMMUNICATION_SINK) &&
+         (pin->communication != KSPIN_COMMUNICATION_BOTH) )
+    {
+        PA_DEBUG(("Not source/sink\n"));
+        result = paInvalidDevice;
+        goto error;
+    }
+
+    /* Get dataflow information */
+    result = WdmGetPinPropertySimple(
+        parentFilter->handle,
+        pinId,
+        &KSPROPSETID_Pin,
+        KSPROPERTY_PIN_DATAFLOW,
+        &pin->dataFlow,
+        sizeof(KSPIN_DATAFLOW));
+
+    if( result != paNoError )
+        goto error;
+
+    /* Get the INTERFACE property list */
+    result = WdmGetPinPropertyMulti(
+        parentFilter->handle,
+        pinId,
+        &KSPROPSETID_Pin,
+        KSPROPERTY_PIN_INTERFACES,
+        &item);
+
+    if( result != paNoError )
+        goto error;
+
+    identifier = (KSIDENTIFIER*)(item+1);
+
+    /* Check that at least one interface is STANDARD_STREAMING */
+    result = paUnanticipatedHostError;
+    for( i = 0; i < item->Count; i++ )
+    {
+        if( !memcmp( (void*)&identifier[i].Set, (void*)&KSINTERFACESETID_Standard, sizeof( GUID ) ) &&
+            ( identifier[i].Id == KSINTERFACE_STANDARD_STREAMING ) )
+        {
+            result = paNoError;
+            break;
+        }
+    }
+
+    if( result != paNoError )
+    {
+        PA_DEBUG(("No standard streaming\n"));
+        goto error;
+    }
+
+    /* Don't need interfaces any more */
+    PaUtil_FreeMemory( item );
+    item = NULL;
+
+    /* Get the MEDIUM properties list */
+    result = WdmGetPinPropertyMulti(
+        parentFilter->handle,
+        pinId,
+        &KSPROPSETID_Pin,
+        KSPROPERTY_PIN_MEDIUMS,
+        &item);
+
+    if( result != paNoError )
+        goto error;
+
+    identifier = (KSIDENTIFIER*)(item+1); /* Not actually necessary... */
+
+    /* Check that at least one medium is STANDARD_DEVIO */
+    result = paUnanticipatedHostError;
+    for( i = 0; i < item->Count; i++ )
+    {
+        if( !memcmp( (void*)&identifier[i].Set, (void*)&KSMEDIUMSETID_Standard, sizeof( GUID ) ) &&
+           ( identifier[i].Id == KSMEDIUM_STANDARD_DEVIO ) )
+        {
+            result = paNoError;
+            break;
+        }
+    }
+
+    if( result != paNoError )
+    {
+        PA_DEBUG(("No standard devio\n"));
+        goto error;
+    }
+    /* Don't need mediums any more */
+    PaUtil_FreeMemory( item );
+    item = NULL;
+
+    /* Get DATARANGES */
+    result = WdmGetPinPropertyMulti(
+        parentFilter->handle,
+        pinId,
+        &KSPROPSETID_Pin,
+        KSPROPERTY_PIN_DATARANGES,
+        &pin->dataRangesItem);
+
+    if( result != paNoError )
+        goto error;
+
+    pin->dataRanges = (KSDATARANGE*)(pin->dataRangesItem +1);
+
+    /* Check that at least one datarange supports audio */
+    result = paUnanticipatedHostError;
+    dataRange = pin->dataRanges;
+    pin->maxChannels = 0;
+    pin->bestSampleRate = 0;
+    pin->formats = 0;
+    for( i = 0; i <pin->dataRangesItem->Count; i++)
+    {
+        PA_DEBUG(("DR major format %x\n",*(unsigned long*)(&(dataRange->MajorFormat))));
+        /* Check that subformat is WAVEFORMATEX, PCM or WILDCARD */
+        if( IS_VALID_WAVEFORMATEX_GUID(&dataRange->SubFormat) ||
+            !memcmp((void*)&dataRange->SubFormat, (void*)&KSDATAFORMAT_SUBTYPE_PCM, sizeof ( GUID ) ) ||
+            ( !memcmp((void*)&dataRange->SubFormat, (void*)&KSDATAFORMAT_SUBTYPE_WILDCARD, sizeof ( GUID ) ) &&
+            ( !memcmp((void*)&dataRange->MajorFormat, (void*)&KSDATAFORMAT_TYPE_AUDIO, sizeof ( GUID ) ) ) ) )
+        {
+            result = paNoError;
+            /* Record the maximum possible channels with this pin */
+            PA_DEBUG(("MaxChannel: %d\n",pin->maxChannels));
+            if( (int)((KSDATARANGE_AUDIO*)dataRange)->MaximumChannels > pin->maxChannels )
+            {
+                pin->maxChannels = ((KSDATARANGE_AUDIO*)dataRange)->MaximumChannels;
+                /*PA_DEBUG(("MaxChannel: %d\n",pin->maxChannels));*/
+            }
+            /* Record the formats (bit depths) that are supported */
+            if( ((KSDATARANGE_AUDIO*)dataRange)->MinimumBitsPerSample <= 16 )
+            {
+                pin->formats |= paInt16;
+                PA_DEBUG(("Format 16 bit supported\n"));
+            }
+            if( ((KSDATARANGE_AUDIO*)dataRange)->MaximumBitsPerSample >= 24 )
+            {
+                pin->formats |= paInt24;
+                PA_DEBUG(("Format 24 bit supported\n"));
+            }
+            if( ( pin->bestSampleRate != 48000) &&
+                (((KSDATARANGE_AUDIO*)dataRange)->MaximumSampleFrequency >= 48000) &&
+                (((KSDATARANGE_AUDIO*)dataRange)->MinimumSampleFrequency <= 48000) )
+            {
+                pin->bestSampleRate = 48000;
+                PA_DEBUG(("48kHz supported\n"));
+            }
+            else if(( pin->bestSampleRate != 48000) && ( pin->bestSampleRate != 44100 ) &&
+                (((KSDATARANGE_AUDIO*)dataRange)->MaximumSampleFrequency >= 44100) &&
+                (((KSDATARANGE_AUDIO*)dataRange)->MinimumSampleFrequency <= 44100) )
+            {
+                pin->bestSampleRate = 44100;
+                PA_DEBUG(("44.1kHz supported\n"));
+            }
+            else
+            {
+                pin->bestSampleRate = ((KSDATARANGE_AUDIO*)dataRange)->MaximumSampleFrequency;
+            }
+        }
+        dataRange = (KSDATARANGE*)( ((char*)dataRange) + dataRange->FormatSize);
+    }
+
+    if( result != paNoError )
+        goto error;
+
+    /* Get instance information */
+    result = WdmGetPinPropertySimple(
+        parentFilter->handle,
+        pinId,
+        &KSPROPSETID_Pin,
+        KSPROPERTY_PIN_CINSTANCES,
+        &pin->instances,
+        sizeof(KSPIN_CINSTANCES));
+
+    if( result != paNoError )
+        goto error;
+
+    /* Success */
+    *error = paNoError;
+    PA_DEBUG(("Pin created successfully\n"));
+    PA_LOGL_;
+    return pin;
+
+error:
+    /*
+    Error cleanup
+    */
+    PaUtil_FreeMemory( item );
+    if( pin )
+    {
+        PaUtil_FreeMemory( pin->pinConnect );
+        PaUtil_FreeMemory( pin->dataRangesItem );
+        PaUtil_FreeMemory( pin );
+    }
+    *error = result;
+    PA_LOGL_;
+    return NULL;
+}
+
+/*
+Safely free all resources associated with the pin
+*/
+static void PinFree(PaWinWdmPin* pin)
+{
+    PA_LOGE_;
+    if( pin )
+    {
+        PinClose(pin);
+        if( pin->pinConnect )
+        {
+            PaUtil_FreeMemory( pin->pinConnect );
+        }
+        if( pin->dataRangesItem )
+        {
+            PaUtil_FreeMemory( pin->dataRangesItem );
+        }
+        PaUtil_FreeMemory( pin );
+    }
+    PA_LOGL_;
+}
+
+/*
+If the pin handle is open, close it
+*/
+static void PinClose(PaWinWdmPin* pin)
+{
+    PA_LOGE_;
+    if( pin == NULL )
+    {
+        PA_DEBUG(("Closing NULL pin!"));
+        PA_LOGL_;
+        return;
+    }
+    if( pin->handle != NULL )
+    {
+        PinSetState( pin, KSSTATE_PAUSE );
+        PinSetState( pin, KSSTATE_STOP );
+        CloseHandle( pin->handle );
+        pin->handle = NULL;
+        FilterRelease(pin->parentFilter);
+    }
+    PA_LOGL_;
+}
+
+/*
+Set the state of this (instantiated) pin
+*/
+static PaError PinSetState(PaWinWdmPin* pin, KSSTATE state)
+{
+    PaError result;
+
+    PA_LOGE_;
+    if( pin == NULL )
+        return paInternalError;
+    if( pin->handle == NULL )
+        return paInternalError;
+
+    result = WdmSetPropertySimple(
+        pin->handle,
+        &KSPROPSETID_Connection,
+        KSPROPERTY_CONNECTION_STATE,
+        &state,
+        sizeof(state),
+        NULL,
+        0);
+    PA_LOGL_;
+    return result;
+}
+
+static PaError PinInstantiate(PaWinWdmPin* pin)
+{
+    PaError result;
+    unsigned long createResult;
+    KSALLOCATOR_FRAMING ksaf;
+    KSALLOCATOR_FRAMING_EX ksafex;
+
+    PA_LOGE_;
+
+    if( pin == NULL )
+        return paInternalError;
+    if(!pin->pinConnect)
+        return paInternalError;
+
+    FilterUse(pin->parentFilter);
+
+    createResult = FunctionKsCreatePin(
+        pin->parentFilter->handle,
+        pin->pinConnect,
+        GENERIC_WRITE | GENERIC_READ,
+        &pin->handle
+        );
+
+    PA_DEBUG(("Pin create result = %x\n",createResult));
+    if( createResult != ERROR_SUCCESS )
+    {
+        FilterRelease(pin->parentFilter);
+        pin->handle = NULL;
+        return paInvalidDevice;
+    }
+
+    result = WdmGetPropertySimple(
+        pin->handle,
+        &KSPROPSETID_Connection,
+        KSPROPERTY_CONNECTION_ALLOCATORFRAMING,
+        &ksaf,
+        sizeof(ksaf),
+        NULL,
+        0);
+
+    if( result != paNoError )
+    {
+        result = WdmGetPropertySimple(
+            pin->handle,
+            &KSPROPSETID_Connection,
+            KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX,
+            &ksafex,
+            sizeof(ksafex),
+            NULL,
+            0);
+        if( result == paNoError )
+        {
+            pin->frameSize = ksafex.FramingItem[0].FramingRange.Range.MinFrameSize;
+        }
+    }
+    else
+    {
+        pin->frameSize = ksaf.FrameSize;
+    }
+
+    PA_LOGL_;
+
+    return paNoError;
+}
+
+/* NOT USED
+static PaError PinGetState(PaWinWdmPin* pin, KSSTATE* state)
+{
+    PaError result;
+
+    if( state == NULL )
+        return paInternalError;
+    if( pin == NULL )
+        return paInternalError;
+    if( pin->handle == NULL )
+        return paInternalError;
+
+    result = WdmGetPropertySimple(
+        pin->handle,
+        KSPROPSETID_Connection,
+        KSPROPERTY_CONNECTION_STATE,
+        state,
+        sizeof(KSSTATE),
+        NULL,
+        0);
+
+    return result;
+}
+*/
+static PaError PinSetFormat(PaWinWdmPin* pin, const WAVEFORMATEX* format)
+{
+    unsigned long size;
+    void* newConnect;
+
+    PA_LOGE_;
+
+    if( pin == NULL )
+        return paInternalError;
+    if( format == NULL )
+        return paInternalError;
+
+    size = GetWfexSize(format) + sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX) - sizeof(WAVEFORMATEX);
+
+    if( pin->pinConnectSize != size )
+    {
+        newConnect = PaUtil_AllocateMemory( size );
+        if( newConnect == NULL )
+            return paInsufficientMemory;
+        memcpy( newConnect, (void*)pin->pinConnect, min(pin->pinConnectSize,size) );
+        PaUtil_FreeMemory( pin->pinConnect );
+        pin->pinConnect = (KSPIN_CONNECT*)newConnect;
+        pin->pinConnectSize = size;
+        pin->ksDataFormatWfx = (KSDATAFORMAT_WAVEFORMATEX*)((KSPIN_CONNECT*)newConnect + 1);
+        pin->ksDataFormatWfx->DataFormat.FormatSize = size - sizeof(KSPIN_CONNECT);
+    }
+
+    memcpy( (void*)&(pin->ksDataFormatWfx->WaveFormatEx), format, GetWfexSize(format) );
+    pin->ksDataFormatWfx->DataFormat.SampleSize = (unsigned short)(format->nChannels * (format->wBitsPerSample / 8));
+
+    PA_LOGL_;
+
+    return paNoError;
+}
+
+static PaError PinIsFormatSupported(PaWinWdmPin* pin, const WAVEFORMATEX* format)
+{
+    KSDATARANGE_AUDIO* dataRange;
+    unsigned long count;
+    GUID guid = DYNAMIC_GUID( DEFINE_WAVEFORMATEX_GUID(format->wFormatTag) );
+    PaError result = paInvalidDevice;
+
+    PA_LOGE_;
+
+    if( format->wFormatTag == WAVE_FORMAT_EXTENSIBLE )
+    {
+        guid = ((WAVEFORMATEXTENSIBLE*)format)->SubFormat;
+    }
+    dataRange = (KSDATARANGE_AUDIO*)pin->dataRanges;
+    for(count = 0; count<pin->dataRangesItem->Count; count++)
+    {
+        if(( !memcmp(&(dataRange->DataRange.MajorFormat),&KSDATAFORMAT_TYPE_AUDIO,sizeof(GUID)) ) ||
+           ( !memcmp(&(dataRange->DataRange.MajorFormat),&KSDATAFORMAT_TYPE_WILDCARD,sizeof(GUID)) ))
+        {
+            /* This is an audio or wildcard datarange... */
+            if(( !memcmp(&(dataRange->DataRange.SubFormat),&KSDATAFORMAT_SUBTYPE_WILDCARD,sizeof(GUID)) ) ||
+                ( !memcmp(&(dataRange->DataRange.SubFormat),&guid,sizeof(GUID)) ))
+            {
+                if(( !memcmp(&(dataRange->DataRange.Specifier),&KSDATAFORMAT_SPECIFIER_WILDCARD,sizeof(GUID)) ) ||
+                  ( !memcmp(&(dataRange->DataRange.Specifier),&KSDATAFORMAT_SPECIFIER_WAVEFORMATEX,sizeof(GUID) )))
+                {
+
+                    PA_DEBUG(("Pin:%x, DataRange:%d\n",(void*)pin,count));
+                    PA_DEBUG(("\tFormatSize:%d, SampleSize:%d\n",dataRange->DataRange.FormatSize,dataRange->DataRange.SampleSize));
+                    PA_DEBUG(("\tMaxChannels:%d\n",dataRange->MaximumChannels));
+                    PA_DEBUG(("\tBits:%d-%d\n",dataRange->MinimumBitsPerSample,dataRange->MaximumBitsPerSample));
+                    PA_DEBUG(("\tSampleRate:%d-%d\n",dataRange->MinimumSampleFrequency,dataRange->MaximumSampleFrequency));
+
+                    if( dataRange->MaximumChannels < format->nChannels )
+                    {
+                        result = paInvalidChannelCount;
+                        continue;
+                    }
+                    if( dataRange->MinimumBitsPerSample > format->wBitsPerSample )
+                    {
+                        result = paSampleFormatNotSupported;
+                        continue;
+                    }
+                    if( dataRange->MaximumBitsPerSample < format->wBitsPerSample )
+                    {
+                        result = paSampleFormatNotSupported;
+                        continue;
+                    }
+                    if( dataRange->MinimumSampleFrequency > format->nSamplesPerSec )
+                    {
+                        result = paInvalidSampleRate;
+                        continue;
+                    }
+                    if( dataRange->MaximumSampleFrequency < format->nSamplesPerSec )
+                    {
+                        result = paInvalidSampleRate;
+                        continue;
+                    }
+                    /* Success! */
+                    PA_LOGL_;
+                    return paNoError;
+                }
+            }
+        }
+        dataRange = (KSDATARANGE_AUDIO*)( ((char*)dataRange) + dataRange->DataRange.FormatSize);
+    }
+
+    PA_LOGL_;
+
+    return result;
+}
+
+/**
+ * Create a new filter object
+ */
+static PaWinWdmFilter* FilterNew(TCHAR* filterName, TCHAR* friendlyName, PaError* error)
+{
+    PaWinWdmFilter* filter;
+    PaError result;
+    int pinId;
+    int valid;
+
+
+    /* Allocate the new filter object */
+    filter = (PaWinWdmFilter*)PaUtil_AllocateMemory( sizeof(PaWinWdmFilter) );
+    if( !filter )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+
+    /* Zero the filter object - done by AllocateMemory */
+    /* memset( (void*)filter, 0, sizeof(PaWinWdmFilter) ); */
+
+    /* Copy the filter name */
+    _tcsncpy(filter->filterName, filterName, MAX_PATH);
+
+    /* Copy the friendly name */
+    _tcsncpy(filter->friendlyName, friendlyName, MAX_PATH);
+
+    /* Open the filter handle */
+    result = FilterUse(filter);
+    if( result != paNoError )
+    {
+        goto error;
+    }
+
+    /* Get pin count */
+    result = WdmGetPinPropertySimple
+        (
+        filter->handle,
+        0,
+        &KSPROPSETID_Pin,
+        KSPROPERTY_PIN_CTYPES,
+        &filter->pinCount,
+        sizeof(filter->pinCount)
+        );
+
+    if( result != paNoError)
+    {
+        goto error;
+    }
+
+    /* Allocate pointer array to hold the pins */
+    filter->pins = (PaWinWdmPin**)PaUtil_AllocateMemory( sizeof(PaWinWdmPin*) * filter->pinCount );
+    if( !filter->pins )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+
+    /* Create all the pins we can */
+    filter->maxInputChannels = 0;
+    filter->maxOutputChannels = 0;
+    filter->bestSampleRate = 0;
+
+    valid = 0;
+    for(pinId = 0; pinId < filter->pinCount; pinId++)
+    {
+        /* Create the pin with this Id */
+        PaWinWdmPin* newPin;
+        newPin = PinNew(filter, pinId, &result);
+        if( result == paInsufficientMemory )
+            goto error;
+        if( newPin != NULL )
+        {
+            filter->pins[pinId] = newPin;
+            valid = 1;
+
+            /* Get the max output channel count */
+            if(( newPin->dataFlow == KSPIN_DATAFLOW_IN ) &&
+                (( newPin->communication == KSPIN_COMMUNICATION_SINK) ||
+                 ( newPin->communication == KSPIN_COMMUNICATION_BOTH)))
+            {
+                if(newPin->maxChannels > filter->maxOutputChannels)
+                    filter->maxOutputChannels = newPin->maxChannels;
+                filter->formats |= newPin->formats;
+            }
+            /* Get the max input channel count */
+            if(( newPin->dataFlow == KSPIN_DATAFLOW_OUT ) &&
+                (( newPin->communication == KSPIN_COMMUNICATION_SINK) ||
+                 ( newPin->communication == KSPIN_COMMUNICATION_BOTH)))
+            {
+                if(newPin->maxChannels > filter->maxInputChannels)
+                    filter->maxInputChannels = newPin->maxChannels;
+                filter->formats |= newPin->formats;
+            }
+
+            if(newPin->bestSampleRate > filter->bestSampleRate)
+            {
+                filter->bestSampleRate = newPin->bestSampleRate;
+            }
+        }
+    }
+
+    if(( filter->maxInputChannels == 0) && ( filter->maxOutputChannels == 0))
+    {
+        /* No input or output... not valid */
+        valid = 0;
+    }
+
+    if( !valid )
+    {
+        /* No valid pin was found on this filter so we destroy it */
+        result = paDeviceUnavailable;
+        goto error;
+    }
+
+    /* Close the filter handle for now
+     * It will be opened later when needed */
+    FilterRelease(filter);
+
+    *error = paNoError;
+    return filter;
+
+error:
+    /*
+    Error cleanup
+    */
+    if( filter )
+    {
+        for( pinId = 0; pinId < filter->pinCount; pinId++ )
+            PinFree(filter->pins[pinId]);
+        PaUtil_FreeMemory( filter->pins );
+        if( filter->handle )
+            CloseHandle( filter->handle );
+        PaUtil_FreeMemory( filter );
+    }
+    *error = result;
+    return NULL;
+}
+
+/**
+ * Free a previously created filter
+ */
+static void FilterFree(PaWinWdmFilter* filter)
+{
+    int pinId;
+    PA_LOGL_;
+    if( filter )
+    {
+        for( pinId = 0; pinId < filter->pinCount; pinId++ )
+            PinFree(filter->pins[pinId]);
+        PaUtil_FreeMemory( filter->pins );
+        if( filter->handle )
+            CloseHandle( filter->handle );
+        PaUtil_FreeMemory( filter );
+    }
+    PA_LOGE_;
+}
+
+/**
+ * Reopen the filter handle if necessary so it can be used
+ **/
+static PaError FilterUse(PaWinWdmFilter* filter)
+{
+    assert( filter );
+
+    PA_LOGE_;
+    if( filter->handle == NULL )
+    {
+        /* Open the filter */
+        filter->handle = CreateFile(
+            filter->filterName,
+            GENERIC_READ | GENERIC_WRITE,
+            0,
+            NULL,
+            OPEN_EXISTING,
+            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
+            NULL);
+
+        if( filter->handle == NULL )
+        {
+            return paDeviceUnavailable;
+        }
+    }
+    filter->usageCount++;
+    PA_LOGL_;
+    return paNoError;
+}
+
+/**
+ * Release the filter handle if nobody is using it
+ **/
+static void FilterRelease(PaWinWdmFilter* filter)
+{
+    assert( filter );
+    assert( filter->usageCount > 0 );
+
+    PA_LOGE_;
+    filter->usageCount--;
+    if( filter->usageCount == 0 )
+    {
+        if( filter->handle != NULL )
+        {
+            CloseHandle( filter->handle );
+            filter->handle = NULL;
+        }
+    }
+    PA_LOGL_;
+}
+
+/**
+ * Create a render (playback) Pin using the supplied format
+ **/
+static PaWinWdmPin* FilterCreateRenderPin(PaWinWdmFilter* filter,
+    const WAVEFORMATEX* wfex,
+    PaError* error)
+{
+    PaError result;
+    PaWinWdmPin* pin;
+
+    assert( filter );
+
+    pin = FilterFindViableRenderPin(filter,wfex,&result);
+    if(!pin)
+    {
+        goto error;
+    }
+    result = PinSetFormat(pin,wfex);
+    if( result != paNoError )
+    {
+        goto error;
+    }
+    result = PinInstantiate(pin);
+    if( result != paNoError )
+    {
+        goto error;
+    }
+
+    *error = paNoError;
+    return pin;
+
+error:
+    *error = result;
+    return NULL;
+}
+
+/**
+ * Find a pin that supports the given format
+ **/
+static PaWinWdmPin* FilterFindViableRenderPin(PaWinWdmFilter* filter,
+    const WAVEFORMATEX* wfex,
+    PaError* error)
+{
+    int pinId;
+    PaWinWdmPin*  pin;
+    PaError result = paDeviceUnavailable;
+    *error = paNoError;
+
+    assert( filter );
+
+    for( pinId = 0; pinId<filter->pinCount; pinId++ )
+    {
+        pin = filter->pins[pinId];
+        if( pin != NULL )
+        {
+            if(( pin->dataFlow == KSPIN_DATAFLOW_IN ) &&
+                (( pin->communication == KSPIN_COMMUNICATION_SINK) ||
+                 ( pin->communication == KSPIN_COMMUNICATION_BOTH)))
+            {
+                result = PinIsFormatSupported( pin, wfex );
+                if( result == paNoError )
+                {
+                    return pin;
+                }
+            }
+        }
+    }
+
+    *error = result;
+    return NULL;
+}
+
+/**
+ * Check if there is a pin that should playback
+ * with the supplied format
+ **/
+static PaError FilterCanCreateRenderPin(PaWinWdmFilter* filter,
+    const WAVEFORMATEX* wfex)
+{
+    PaWinWdmPin* pin;
+    PaError result;
+
+    assert ( filter );
+
+    pin = FilterFindViableRenderPin(filter,wfex,&result);
+    /* result will be paNoError if pin found
+     * or else an error code indicating what is wrong with the format
+     **/
+    return result;
+}
+
+/**
+ * Create a capture (record) Pin using the supplied format
+ **/
+static PaWinWdmPin* FilterCreateCapturePin(PaWinWdmFilter* filter,
+    const WAVEFORMATEX* wfex,
+    PaError* error)
+{
+    PaError result;
+    PaWinWdmPin* pin;
+
+    assert( filter );
+
+    pin = FilterFindViableCapturePin(filter,wfex,&result);
+    if(!pin)
+    {
+        goto error;
+    }
+
+    result = PinSetFormat(pin,wfex);
+    if( result != paNoError )
+    {
+        goto error;
+    }
+
+    result = PinInstantiate(pin);
+    if( result != paNoError )
+    {
+        goto error;
+    }
+
+    *error = paNoError;
+    return pin;
+
+error:
+    *error = result;
+    return NULL;
+}
+
+/**
+ * Find a capture pin that supports the given format
+ **/
+static PaWinWdmPin* FilterFindViableCapturePin(PaWinWdmFilter* filter,
+    const WAVEFORMATEX* wfex,
+    PaError* error)
+{
+    int pinId;
+    PaWinWdmPin*  pin;
+    PaError result = paDeviceUnavailable;
+    *error = paNoError;
+
+    assert( filter );
+
+    for( pinId = 0; pinId<filter->pinCount; pinId++ )
+    {
+        pin = filter->pins[pinId];
+        if( pin != NULL )
+        {
+            if(( pin->dataFlow == KSPIN_DATAFLOW_OUT ) &&
+                (( pin->communication == KSPIN_COMMUNICATION_SINK) ||
+                 ( pin->communication == KSPIN_COMMUNICATION_BOTH)))
+            {
+                result = PinIsFormatSupported( pin, wfex );
+                if( result == paNoError )
+                {
+                    return pin;
+                }
+            }
+        }
+    }
+
+    *error = result;
+    return NULL;
+}
+
+/**
+ * Check if there is a pin that should playback
+ * with the supplied format
+ **/
+static PaError FilterCanCreateCapturePin(PaWinWdmFilter* filter,
+    const WAVEFORMATEX* wfex)
+{
+    PaWinWdmPin* pin;
+    PaError result;
+
+    assert ( filter );
+
+    pin = FilterFindViableCapturePin(filter,wfex,&result);
+    /* result will be paNoError if pin found
+     * or else an error code indicating what is wrong with the format
+     **/
+    return result;
+}
+
+/**
+ * Build the list of available filters
+ */
+static PaError BuildFilterList(PaWinWdmHostApiRepresentation* wdmHostApi)
+{
+    PaError result = paNoError;
+    HDEVINFO handle = NULL;
+    int device;
+    int invalidDevices;
+    int slot;
+    SP_DEVICE_INTERFACE_DATA interfaceData;
+    SP_DEVICE_INTERFACE_DATA aliasData;
+    SP_DEVINFO_DATA devInfoData;
+    int noError;
+    const int sizeInterface = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + (MAX_PATH * sizeof(WCHAR));
+    unsigned char interfaceDetailsArray[sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + (MAX_PATH * sizeof(WCHAR))];
+    SP_DEVICE_INTERFACE_DETAIL_DATA* devInterfaceDetails = (SP_DEVICE_INTERFACE_DETAIL_DATA*)interfaceDetailsArray;
+    TCHAR friendlyName[MAX_PATH];
+    HKEY hkey;
+    DWORD sizeFriendlyName;
+    DWORD type;
+    PaWinWdmFilter* newFilter;
+    GUID* category = (GUID*)&KSCATEGORY_AUDIO;
+    GUID* alias_render = (GUID*)&KSCATEGORY_RENDER;
+    GUID* alias_capture = (GUID*)&KSCATEGORY_CAPTURE;
+    DWORD hasAlias;
+
+    PA_LOGE_;
+
+    devInterfaceDetails->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
+
+    /* Open a handle to search for devices (filters) */
+    handle = SetupDiGetClassDevs(category,NULL,NULL,DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
+    if( handle == NULL )
+    {
+        return paUnanticipatedHostError;
+    }
+    PA_DEBUG(("Setup called\n"));
+
+    /* First let's count the number of devices so we can allocate a list */
+    invalidDevices = 0;
+    for( device = 0;;device++ )
+    {
+        interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
+        interfaceData.Reserved = 0;
+        aliasData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
+        aliasData.Reserved = 0;
+        noError = SetupDiEnumDeviceInterfaces(handle,NULL,category,device,&interfaceData);
+        PA_DEBUG(("Enum called\n"));
+        if( !noError )
+            break; /* No more devices */
+
+        /* Check this one has the render or capture alias */
+        hasAlias = 0;
+        noError = SetupDiGetDeviceInterfaceAlias(handle,&interfaceData,alias_render,&aliasData);
+        PA_DEBUG(("noError = %d\n",noError));
+        if(noError)
+        {
+            if(aliasData.Flags && (!(aliasData.Flags & SPINT_REMOVED)))
+            {
+                PA_DEBUG(("Device %d has render alias\n",device));
+                hasAlias |= 1; /* Has render alias */
+            }
+            else
+            {
+                PA_DEBUG(("Device %d has no render alias\n",device));
+            }
+        }
+        noError = SetupDiGetDeviceInterfaceAlias(handle,&interfaceData,alias_capture,&aliasData);
+        if(noError)
+        {
+            if(aliasData.Flags && (!(aliasData.Flags & SPINT_REMOVED)))
+            {
+                PA_DEBUG(("Device %d has capture alias\n",device));
+                hasAlias |= 2; /* Has capture alias */
+            }
+            else
+            {
+                PA_DEBUG(("Device %d has no capture alias\n",device));
+            }
+        }
+        if(!hasAlias)
+            invalidDevices++; /* This was not a valid capture or render audio device */
+
+    }
+    /* Remember how many there are */
+    wdmHostApi->filterCount = device-invalidDevices;
+
+    PA_DEBUG(("Interfaces found: %d\n",device-invalidDevices));
+
+    /* Now allocate the list of pointers to devices */
+    wdmHostApi->filters  = (PaWinWdmFilter**)PaUtil_AllocateMemory( sizeof(PaWinWdmFilter*) * device );
+    if( !wdmHostApi->filters )
+    {
+        if(handle != NULL)
+            SetupDiDestroyDeviceInfoList(handle);
+        return paInsufficientMemory;
+    }
+
+    /* Now create filter objects for each interface found */
+    slot = 0;
+    for( device = 0;;device++ )
+    {
+        interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
+        interfaceData.Reserved = 0;
+        aliasData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
+        aliasData.Reserved = 0;
+        devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
+        devInfoData.Reserved = 0;
+
+        noError = SetupDiEnumDeviceInterfaces(handle,NULL,category,device,&interfaceData);
+        if( !noError )
+            break; /* No more devices */
+
+        /* Check this one has the render or capture alias */
+        hasAlias = 0;
+        noError = SetupDiGetDeviceInterfaceAlias(handle,&interfaceData,alias_render,&aliasData);
+        if(noError)
+        {
+            if(aliasData.Flags && (!(aliasData.Flags & SPINT_REMOVED)))
+            {
+                PA_DEBUG(("Device %d has render alias\n",device));
+                hasAlias |= 1; /* Has render alias */
+            }
+        }
+        noError = SetupDiGetDeviceInterfaceAlias(handle,&interfaceData,alias_capture,&aliasData);
+        if(noError)
+        {
+            if(aliasData.Flags && (!(aliasData.Flags & SPINT_REMOVED)))
+            {
+                PA_DEBUG(("Device %d has capture alias\n",device));
+                hasAlias |= 2; /* Has capture alias */
+            }
+        }
+        if(!hasAlias)
+            continue; /* This was not a valid capture or render audio device */
+
+        noError = SetupDiGetDeviceInterfaceDetail(handle,&interfaceData,devInterfaceDetails,sizeInterface,NULL,&devInfoData);
+        if( noError )
+        {
+            /* Try to get the "friendly name" for this interface */
+            sizeFriendlyName = sizeof(friendlyName);
+            /* Fix contributed by Ben Allison
+             * Removed KEY_SET_VALUE from flags on following call
+             * as its causes failure when running without admin rights
+             * and it was not required */
+            hkey=SetupDiOpenDeviceInterfaceRegKey(handle,&interfaceData,0,KEY_QUERY_VALUE);
+            if(hkey!=INVALID_HANDLE_VALUE)
+            {
+                noError = RegQueryValueEx(hkey,TEXT("FriendlyName"),0,&type,(BYTE*)friendlyName,&sizeFriendlyName);
+                if( noError == ERROR_SUCCESS )
+                {
+                    PA_DEBUG(("Interface %d, Name: %s\n",device,friendlyName));
+                    RegCloseKey(hkey);
+                }
+                else
+                {
+                    friendlyName[0] = 0;
+                }
+            }
+            newFilter = FilterNew(devInterfaceDetails->DevicePath,friendlyName,&result);
+            if( result == paNoError )
+            {
+                PA_DEBUG(("Filter created\n"));
+                wdmHostApi->filters[slot] = newFilter;
+                slot++;
+            }
+            else
+            {
+                PA_DEBUG(("Filter NOT created\n"));
+                /* As there are now less filters than we initially thought
+                 * we must reduce the count by one */
+                wdmHostApi->filterCount--;
+            }
+        }
+    }
+
+    /* Clean up */
+    if(handle != NULL)
+        SetupDiDestroyDeviceInfoList(handle);
+
+    return paNoError;
+}
+
+PaError PaWinWdm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
+{
+    PaError result = paNoError;
+    int i, deviceCount;
+    PaWinWdmHostApiRepresentation *wdmHostApi;
+    PaWinWdmDeviceInfo *deviceInfoArray;
+    PaWinWdmFilter* pFilter;
+    PaWinWdmDeviceInfo *wdmDeviceInfo;
+    PaDeviceInfo *deviceInfo;
+
+    PA_LOGE_;
+
+    /*
+    Attempt to load the KSUSER.DLL without which we cannot create pins
+    We will unload this on termination
+    */
+    if(DllKsUser == NULL)
+    {
+        DllKsUser = LoadLibrary(TEXT("ksuser.dll"));
+        if(DllKsUser == NULL)
+            goto error;
+    }
+
+    FunctionKsCreatePin = (KSCREATEPIN*)GetProcAddress(DllKsUser, "KsCreatePin");
+    if(FunctionKsCreatePin == NULL)
+        goto error;
+
+    wdmHostApi = (PaWinWdmHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaWinWdmHostApiRepresentation) );
+    if( !wdmHostApi )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+
+    wdmHostApi->allocations = PaUtil_CreateAllocationGroup();
+    if( !wdmHostApi->allocations )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+
+    result = BuildFilterList( wdmHostApi );
+    if( result != paNoError )
+    {
+        goto error;
+    }
+    deviceCount = wdmHostApi->filterCount;
+
+    *hostApi = &wdmHostApi->inheritedHostApiRep;
+    (*hostApi)->info.structVersion = 1;
+    (*hostApi)->info.type = paWDMKS;
+    (*hostApi)->info.name = "Windows WDM-KS";
+    (*hostApi)->info.defaultInputDevice = paNoDevice;
+    (*hostApi)->info.defaultOutputDevice = paNoDevice;
+
+    if( deviceCount > 0 )
+    {
+        (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
+               wdmHostApi->allocations, sizeof(PaWinWdmDeviceInfo*) * deviceCount );
+        if( !(*hostApi)->deviceInfos )
+        {
+            result = paInsufficientMemory;
+            goto error;
+        }
+
+        /* allocate all device info structs in a contiguous block */
+        deviceInfoArray = (PaWinWdmDeviceInfo*)PaUtil_GroupAllocateMemory(
+                wdmHostApi->allocations, sizeof(PaWinWdmDeviceInfo) * deviceCount );
+        if( !deviceInfoArray )
+        {
+            result = paInsufficientMemory;
+            goto error;
+        }
+
+        for( i=0; i < deviceCount; ++i )
+        {
+            wdmDeviceInfo = &deviceInfoArray[i];
+            deviceInfo = &wdmDeviceInfo->inheritedDeviceInfo;
+            pFilter = wdmHostApi->filters[i];
+            if( pFilter == NULL )
+                continue;
+            wdmDeviceInfo->filter = pFilter;
+            deviceInfo->structVersion = 2;
+            deviceInfo->hostApi = hostApiIndex;
+            deviceInfo->name = (char*)pFilter->friendlyName;
+            PA_DEBUG(("Device found name: %s\n",(char*)pFilter->friendlyName));
+            deviceInfo->maxInputChannels = pFilter->maxInputChannels;
+            if(deviceInfo->maxInputChannels > 0)
+            {
+                /* Set the default input device to the first device we find with
+                 * more than zero input channels
+                 **/
+                if((*hostApi)->info.defaultInputDevice == paNoDevice)
+                {
+                    (*hostApi)->info.defaultInputDevice = i;
+                }
+            }
+
+            deviceInfo->maxOutputChannels = pFilter->maxOutputChannels;
+            if(deviceInfo->maxOutputChannels > 0)
+            {
+                /* Set the default output device to the first device we find with
+                 * more than zero output channels
+                 **/
+                if((*hostApi)->info.defaultOutputDevice == paNoDevice)
+                {
+                    (*hostApi)->info.defaultOutputDevice = i;
+                }
+            }
+
+            /* These low values are not very useful because
+             * a) The lowest latency we end up with can depend on many factors such
+             *    as the device buffer sizes/granularities, sample rate, channels and format
+             * b) We cannot know the device buffer sizes until we try to open/use it at
+             *    a particular setting
+             * So: we give 512x48000Hz frames as the default low input latency
+             **/
+            deviceInfo->defaultLowInputLatency = (512.0/48000.0);
+            deviceInfo->defaultLowOutputLatency = (512.0/48000.0);
+            deviceInfo->defaultHighInputLatency = (4096.0/48000.0);
+            deviceInfo->defaultHighOutputLatency = (4096.0/48000.0);
+            deviceInfo->defaultSampleRate = (double)(pFilter->bestSampleRate);
+
+            (*hostApi)->deviceInfos[i] = deviceInfo;
+        }
+    }
+
+    (*hostApi)->info.deviceCount = deviceCount;
+
+    (*hostApi)->Terminate = Terminate;
+    (*hostApi)->OpenStream = OpenStream;
+    (*hostApi)->IsFormatSupported = IsFormatSupported;
+
+    PaUtil_InitializeStreamInterface( &wdmHostApi->callbackStreamInterface, CloseStream, StartStream,
+                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
+                                      GetStreamTime, GetStreamCpuLoad,
+                                      PaUtil_DummyRead, PaUtil_DummyWrite,
+                                      PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable );
+
+    PaUtil_InitializeStreamInterface( &wdmHostApi->blockingStreamInterface, CloseStream, StartStream,
+                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
+                                      GetStreamTime, PaUtil_DummyGetCpuLoad,
+                                      ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );
+
+    PA_LOGL_;
+    return result;
+
+error:
+    if( DllKsUser != NULL )
+    {
+        FreeLibrary( DllKsUser );
+        DllKsUser = NULL;
+    }
+
+    if( wdmHostApi )
+    {
+        PaUtil_FreeMemory( wdmHostApi->filters );
+        if( wdmHostApi->allocations )
+        {
+            PaUtil_FreeAllAllocations( wdmHostApi->allocations );
+            PaUtil_DestroyAllocationGroup( wdmHostApi->allocations );
+        }
+        PaUtil_FreeMemory( wdmHostApi );
+    }
+    PA_LOGL_;
+    return result;
+}
+
+
+static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
+{
+    PaWinWdmHostApiRepresentation *wdmHostApi = (PaWinWdmHostApiRepresentation*)hostApi;
+    int i;
+    PA_LOGE_;
+
+    if( wdmHostApi->filters )
+    {
+        for( i=0; i<wdmHostApi->filterCount; i++)
+        {
+            if( wdmHostApi->filters[i] != NULL )
+            {
+                FilterFree( wdmHostApi->filters[i] );
+                wdmHostApi->filters[i] = NULL;
+            }
+        }
+    }
+    PaUtil_FreeMemory( wdmHostApi->filters );
+    if( wdmHostApi->allocations )
+    {
+        PaUtil_FreeAllAllocations( wdmHostApi->allocations );
+        PaUtil_DestroyAllocationGroup( wdmHostApi->allocations );
+    }
+    PaUtil_FreeMemory( wdmHostApi );
+    PA_LOGL_;
+}
+
+static void FillWFEXT( WAVEFORMATEXTENSIBLE* pwfext, PaSampleFormat sampleFormat, double sampleRate, int channelCount)
+{
+    PA_LOGE_;
+    PA_DEBUG(( "sampleFormat = %lx\n" , sampleFormat ));
+    PA_DEBUG(( "sampleRate = %f\n" , sampleRate ));
+    PA_DEBUG(( "chanelCount = %d\n", channelCount ));
+
+    pwfext->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
+    pwfext->Format.nChannels = channelCount;
+    pwfext->Format.nSamplesPerSec = (int)sampleRate;
+    if(channelCount == 1)
+        pwfext->dwChannelMask = KSAUDIO_SPEAKER_DIRECTOUT;
+    else
+        pwfext->dwChannelMask = KSAUDIO_SPEAKER_STEREO;
+    if(sampleFormat == paFloat32)
+    {
+        pwfext->Format.nBlockAlign = channelCount * 4;
+        pwfext->Format.wBitsPerSample = 32;
+        pwfext->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);
+        pwfext->Samples.wValidBitsPerSample = 32;
+        pwfext->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
+    }
+    else if(sampleFormat == paInt32)
+    {
+        pwfext->Format.nBlockAlign = channelCount * 4;
+        pwfext->Format.wBitsPerSample = 32;
+        pwfext->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);
+        pwfext->Samples.wValidBitsPerSample = 32;
+        pwfext->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
+    }
+    else if(sampleFormat == paInt24)
+    {
+        pwfext->Format.nBlockAlign = channelCount * 3;
+        pwfext->Format.wBitsPerSample = 24;
+        pwfext->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);
+        pwfext->Samples.wValidBitsPerSample = 24;
+        pwfext->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
+    }
+    else if(sampleFormat == paInt16)
+    {
+        pwfext->Format.nBlockAlign = channelCount * 2;
+        pwfext->Format.wBitsPerSample = 16;
+        pwfext->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);
+        pwfext->Samples.wValidBitsPerSample = 16;
+        pwfext->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
+    }
+    pwfext->Format.nAvgBytesPerSec = pwfext->Format.nSamplesPerSec * pwfext->Format.nBlockAlign;
+
+    PA_LOGL_;
+}
+
+static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
+                                  const PaStreamParameters *inputParameters,
+                                  const PaStreamParameters *outputParameters,
+                                  double sampleRate )
+{
+    int inputChannelCount, outputChannelCount;
+    PaSampleFormat inputSampleFormat, outputSampleFormat;
+    PaWinWdmHostApiRepresentation *wdmHostApi = (PaWinWdmHostApiRepresentation*)hostApi;
+    PaWinWdmFilter* pFilter;
+    int result = paFormatIsSupported;
+    WAVEFORMATEXTENSIBLE wfx;
+
+    PA_LOGE_;
+
+    if( inputParameters )
+    {
+        inputChannelCount = inputParameters->channelCount;
+        inputSampleFormat = inputParameters->sampleFormat;
+
+        /* all standard sample formats are supported by the buffer adapter,
+            this implementation doesn't support any custom sample formats */
+        if( inputSampleFormat & paCustomFormat )
+            return paSampleFormatNotSupported;
+
+        /* unless alternate device specification is supported, reject the use of
+            paUseHostApiSpecificDeviceSpecification */
+
+        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
+            return paInvalidDevice;
+
+        /* check that input device can support inputChannelCount */
+        if( inputChannelCount > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )
+            return paInvalidChannelCount;
+
+        /* validate inputStreamInfo */
+        if( inputParameters->hostApiSpecificStreamInfo )
+            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
+
+        /* Check that the input format is supported */
+        FillWFEXT(&wfx,paInt16,sampleRate,inputChannelCount);
+
+        pFilter = wdmHostApi->filters[inputParameters->device];
+        result = FilterCanCreateCapturePin(pFilter,(const WAVEFORMATEX*)&wfx);
+        if( result != paNoError )
+        {
+            /* Try a WAVE_FORMAT_PCM instead */
+            wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
+            wfx.Format.cbSize = 0;
+            wfx.Samples.wValidBitsPerSample = 0;
+            wfx.dwChannelMask = 0;
+            wfx.SubFormat = GUID_NULL;
+            result = FilterCanCreateCapturePin(pFilter,(const WAVEFORMATEX*)&wfx);
+            if( result != paNoError )
+                 return result;
+        }
+    }
+    else
+    {
+        inputChannelCount = 0;
+    }
+
+    if( outputParameters )
+    {
+        outputChannelCount = outputParameters->channelCount;
+        outputSampleFormat = outputParameters->sampleFormat;
+
+        /* all standard sample formats are supported by the buffer adapter,
+            this implementation doesn't support any custom sample formats */
+        if( outputSampleFormat & paCustomFormat )
+            return paSampleFormatNotSupported;
+
+        /* unless alternate device specification is supported, reject the use of
+            paUseHostApiSpecificDeviceSpecification */
+
+        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
+            return paInvalidDevice;
+
+        /* check that output device can support outputChannelCount */
+        if( outputChannelCount > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )
+            return paInvalidChannelCount;
+
+        /* validate outputStreamInfo */
+        if( outputParameters->hostApiSpecificStreamInfo )
+            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
+
+        /* Check that the output format is supported */
+        FillWFEXT(&wfx,paInt16,sampleRate,outputChannelCount);
+
+        pFilter = wdmHostApi->filters[outputParameters->device];
+        result = FilterCanCreateRenderPin(pFilter,(const WAVEFORMATEX*)&wfx);
+        if( result != paNoError )
+        {
+            /* Try a WAVE_FORMAT_PCM instead */
+            wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
+            wfx.Format.cbSize = 0;
+            wfx.Samples.wValidBitsPerSample = 0;
+            wfx.dwChannelMask = 0;
+            wfx.SubFormat = GUID_NULL;
+            result = FilterCanCreateRenderPin(pFilter,(const WAVEFORMATEX*)&wfx);
+            if( result != paNoError )
+                 return result;
+        }
+
+    }
+    else
+    {
+        outputChannelCount = 0;
+    }
+
+    /*
+        IMPLEMENT ME:
+
+            - if a full duplex stream is requested, check that the combination
+                of input and output parameters is supported if necessary
+
+            - check that the device supports sampleRate
+
+        Because the buffer adapter handles conversion between all standard
+        sample formats, the following checks are only required if paCustomFormat
+        is implemented, or under some other unusual conditions.
+
+            - check that input device can support inputSampleFormat, or that
+                we have the capability to convert from inputSampleFormat to
+                a native format
+
+            - check that output device can support outputSampleFormat, or that
+                we have the capability to convert from outputSampleFormat to
+                a native format
+    */
+    if((inputChannelCount == 0)&&(outputChannelCount == 0))
+            result = paSampleFormatNotSupported; /* Not right error */
+
+    PA_LOGL_;
+    return result;
+}
+
+/* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */
+
+static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
+                           PaStream** s,
+                           const PaStreamParameters *inputParameters,
+                           const PaStreamParameters *outputParameters,
+                           double sampleRate,
+                           unsigned long framesPerBuffer,
+                           PaStreamFlags streamFlags,
+                           PaStreamCallback *streamCallback,
+                           void *userData )
+{
+    PaError result = paNoError;
+    PaWinWdmHostApiRepresentation *wdmHostApi = (PaWinWdmHostApiRepresentation*)hostApi;
+    PaWinWdmStream *stream = 0;
+    /* unsigned long framesPerHostBuffer; these may not be equivalent for all implementations */
+    PaSampleFormat inputSampleFormat, outputSampleFormat;
+    PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat;
+    int userInputChannels,userOutputChannels;
+    int size;
+    PaWinWdmFilter* pFilter;
+    WAVEFORMATEXTENSIBLE wfx;
+
+    PA_LOGE_;
+    PA_DEBUG(("OpenStream:sampleRate = %f\n",sampleRate));
+    PA_DEBUG(("OpenStream:framesPerBuffer = %lu\n",framesPerBuffer));
+
+    if( inputParameters )
+    {
+        userInputChannels = inputParameters->channelCount;
+        inputSampleFormat = inputParameters->sampleFormat;
+
+        /* unless alternate device specification is supported, reject the use of
+            paUseHostApiSpecificDeviceSpecification */
+
+        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification )
+            return paInvalidDevice;
+
+        /* check that input device can support stream->userInputChannels */
+        if( userInputChannels > hostApi->deviceInfos[ inputParameters->device ]->maxInputChannels )
+            return paInvalidChannelCount;
+
+        /* validate inputStreamInfo */
+        if( inputParameters->hostApiSpecificStreamInfo )
+            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
+
+    }
+    else
+    {
+        userInputChannels = 0;
+        inputSampleFormat = hostInputSampleFormat = paInt16; /* Surpress 'uninitialised var' warnings. */
+    }
+
+    if( outputParameters )
+    {
+        userOutputChannels = outputParameters->channelCount;
+        outputSampleFormat = outputParameters->sampleFormat;
+
+        /* unless alternate device specification is supported, reject the use of
+            paUseHostApiSpecificDeviceSpecification */
+
+        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification )
+            return paInvalidDevice;
+
+        /* check that output device can support stream->userInputChannels */
+        if( userOutputChannels > hostApi->deviceInfos[ outputParameters->device ]->maxOutputChannels )
+            return paInvalidChannelCount;
+
+        /* validate outputStreamInfo */
+        if( outputParameters->hostApiSpecificStreamInfo )
+            return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */
+
+    }
+    else
+    {
+        userOutputChannels = 0;
+        outputSampleFormat = hostOutputSampleFormat = paInt16; /* Surpress 'uninitialized var' warnings. */
+    }
+
+    /* validate platform specific flags */
+    if( (streamFlags & paPlatformSpecificFlags) != 0 )
+        return paInvalidFlag; /* unexpected platform specific flag */
+
+    stream = (PaWinWdmStream*)PaUtil_AllocateMemory( sizeof(PaWinWdmStream) );
+    if( !stream )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+    /* Zero the stream object */
+    /* memset((void*)stream,0,sizeof(PaWinWdmStream)); */
+
+    if( streamCallback )
+    {
+        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
+                                               &wdmHostApi->callbackStreamInterface, streamCallback, userData );
+    }
+    else
+    {
+        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
+                                               &wdmHostApi->blockingStreamInterface, streamCallback, userData );
+    }
+
+    PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );
+
+    /* Instantiate the input pin if necessary */
+    if(userInputChannels > 0)
+    {
+        result = paSampleFormatNotSupported;
+        pFilter = wdmHostApi->filters[inputParameters->device];
+        stream->userInputChannels = userInputChannels;
+
+        if(((inputSampleFormat & ~paNonInterleaved) & pFilter->formats) != 0)
+        {   /* inputSampleFormat is supported, so try to use it */
+            hostInputSampleFormat = inputSampleFormat;
+            FillWFEXT(&wfx, hostInputSampleFormat, sampleRate, stream->userInputChannels);
+            stream->bytesPerInputFrame = wfx.Format.nBlockAlign;
+            stream->recordingPin = FilterCreateCapturePin(pFilter, (const WAVEFORMATEX*)&wfx, &result);
+            stream->deviceInputChannels = stream->userInputChannels;
+        }
+        
+        if(result != paNoError)
+        {   /* Search through all PaSampleFormats to find one that works */
+            hostInputSampleFormat = paFloat32;
+
+            do {
+                FillWFEXT(&wfx, hostInputSampleFormat, sampleRate, stream->userInputChannels);
+                stream->bytesPerInputFrame = wfx.Format.nBlockAlign;
+                stream->recordingPin = FilterCreateCapturePin(pFilter, (const WAVEFORMATEX*)&wfx, &result);
+                stream->deviceInputChannels = stream->userInputChannels;
+                
+                if(stream->recordingPin == NULL) result = paSampleFormatNotSupported;
+                if(result != paNoError)    hostInputSampleFormat <<= 1;
+            }
+            while(result != paNoError && hostInputSampleFormat <= paUInt8);
+        }
+
+        if(result != paNoError)
+        {    /* None of the PaSampleFormats worked.  Set the hostInputSampleFormat to the best fit
+             * and try a PCM format.
+             **/
+            hostInputSampleFormat =
+                PaUtil_SelectClosestAvailableFormat( pFilter->formats, inputSampleFormat );
+
+            /* Try a WAVE_FORMAT_PCM instead */
+            wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
+            wfx.Format.cbSize = 0;
+            wfx.Samples.wValidBitsPerSample = 0;
+            wfx.dwChannelMask = 0;
+            wfx.SubFormat = GUID_NULL;
+            stream->recordingPin = FilterCreateCapturePin(pFilter,(const WAVEFORMATEX*)&wfx,&result);
+            if(stream->recordingPin == NULL) result = paSampleFormatNotSupported;
+        }
+
+        if( result != paNoError )
+        {
+            /* Some or all KS devices can only handle the exact number of channels
+             * they specify. But PortAudio clients expect to be able to
+             * at least specify mono I/O on a multi-channel device
+             * If this is the case, then we will do the channel mapping internally
+             **/
+            if( stream->userInputChannels < pFilter->maxInputChannels )
+            {
+                FillWFEXT(&wfx,hostInputSampleFormat,sampleRate,pFilter->maxInputChannels);
+                stream->bytesPerInputFrame = wfx.Format.nBlockAlign;
+                stream->recordingPin = FilterCreateCapturePin(pFilter,(const WAVEFORMATEX*)&wfx,&result);
+                stream->deviceInputChannels = pFilter->maxInputChannels;
+
+                if( result != paNoError )
+                {
+                    /* Try a WAVE_FORMAT_PCM instead */
+                    wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
+                    wfx.Format.cbSize = 0;
+                    wfx.Samples.wValidBitsPerSample = 0;
+                    wfx.dwChannelMask = 0;
+                    wfx.SubFormat = GUID_NULL;
+                    stream->recordingPin = FilterCreateCapturePin(pFilter,(const WAVEFORMATEX*)&wfx,&result);
+                }
+            }
+        }
+
+        if(stream->recordingPin == NULL)
+        {
+            goto error;
+        }
+
+        switch(hostInputSampleFormat)
+        {
+            case paInt16: stream->inputSampleSize = 2; break;
+            case paInt24: stream->inputSampleSize = 3; break;
+            case paInt32:
+            case paFloat32:    stream->inputSampleSize = 4; break;
+        }
+
+        stream->recordingPin->frameSize /= stream->bytesPerInputFrame;
+        PA_DEBUG(("Pin output frames: %d\n",stream->recordingPin->frameSize));
+    }
+    else
+    {
+        stream->recordingPin = NULL;
+        stream->bytesPerInputFrame = 0;
+    }
+
+    /* Instantiate the output pin if necessary */
+    if(userOutputChannels > 0)
+    {
+        result = paSampleFormatNotSupported;
+        pFilter = wdmHostApi->filters[outputParameters->device];
+        stream->userOutputChannels = userOutputChannels;
+
+        if(((outputSampleFormat & ~paNonInterleaved) & pFilter->formats) != 0)
+        {
+            hostOutputSampleFormat = outputSampleFormat;
+            FillWFEXT(&wfx,hostOutputSampleFormat,sampleRate,stream->userOutputChannels);
+            stream->bytesPerOutputFrame = wfx.Format.nBlockAlign;
+            stream->playbackPin = FilterCreateRenderPin(pFilter,(WAVEFORMATEX*)&wfx,&result);
+            stream->deviceOutputChannels = stream->userOutputChannels;
+        }
+
+        if(result != paNoError)
+        {
+            hostOutputSampleFormat = paFloat32;
+
+            do {
+                FillWFEXT(&wfx,hostOutputSampleFormat,sampleRate,stream->userOutputChannels);
+                stream->bytesPerOutputFrame = wfx.Format.nBlockAlign;
+                stream->playbackPin = FilterCreateRenderPin(pFilter,(WAVEFORMATEX*)&wfx,&result);
+                stream->deviceOutputChannels = stream->userOutputChannels;
+
+                if(stream->playbackPin == NULL) result = paSampleFormatNotSupported;
+                if(result != paNoError)    hostOutputSampleFormat <<= 1;
+            }
+            while(result != paNoError && hostOutputSampleFormat <= paUInt8);
+        }
+
+        if(result != paNoError)
+        {
+            hostOutputSampleFormat =
+                PaUtil_SelectClosestAvailableFormat( pFilter->formats, outputSampleFormat );
+       
+            /* Try a WAVE_FORMAT_PCM instead */
+            wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
+            wfx.Format.cbSize = 0;
+            wfx.Samples.wValidBitsPerSample = 0;
+            wfx.dwChannelMask = 0;
+            wfx.SubFormat = GUID_NULL;
+            stream->playbackPin = FilterCreateRenderPin(pFilter,(WAVEFORMATEX*)&wfx,&result);
+            if(stream->playbackPin == NULL) result = paSampleFormatNotSupported;
+        }
+            
+        if( result != paNoError )
+        {
+            /* Some or all KS devices can only handle the exact number of channels
+             * they specify. But PortAudio clients expect to be able to
+             * at least specify mono I/O on a multi-channel device
+             * If this is the case, then we will do the channel mapping internally
+             **/
+            if( stream->userOutputChannels < pFilter->maxOutputChannels )
+            {
+                FillWFEXT(&wfx,hostOutputSampleFormat,sampleRate,pFilter->maxOutputChannels);
+                stream->bytesPerOutputFrame = wfx.Format.nBlockAlign;
+                stream->playbackPin = FilterCreateRenderPin(pFilter,(const WAVEFORMATEX*)&wfx,&result);
+                stream->deviceOutputChannels = pFilter->maxOutputChannels;
+                if( result != paNoError )
+                {
+                    /* Try a WAVE_FORMAT_PCM instead */
+                    wfx.Format.wFormatTag = WAVE_FORMAT_PCM;
+                    wfx.Format.cbSize = 0;
+                    wfx.Samples.wValidBitsPerSample = 0;
+                    wfx.dwChannelMask = 0;
+                    wfx.SubFormat = GUID_NULL;
+                    stream->playbackPin = FilterCreateRenderPin(pFilter,(const WAVEFORMATEX*)&wfx,&result);
+                }
+            }
+        }
+
+        if(stream->playbackPin == NULL)
+        {
+            goto error;
+        }
+
+        switch(hostOutputSampleFormat)
+        {
+            case paInt16: stream->outputSampleSize = 2; break;
+            case paInt24: stream->outputSampleSize = 3; break;
+            case paInt32:
+            case paFloat32: stream->outputSampleSize = 4; break;
+        }
+
+        stream->playbackPin->frameSize /= stream->bytesPerOutputFrame;
+        PA_DEBUG(("Pin output frames: %d\n",stream->playbackPin->frameSize));
+    }
+    else
+    {
+        stream->playbackPin = NULL;
+        stream->bytesPerOutputFrame = 0;
+    }
+
+    /* Calculate the framesPerHostXxxxBuffer size based upon the suggested latency values */
+
+    /* Record the buffer length */
+    if(inputParameters)
+    {
+        /* Calculate the frames from the user's value - add a bit to round up */
+            stream->framesPerHostIBuffer = (unsigned long)((inputParameters->suggestedLatency*sampleRate)+0.0001);
+        if(stream->framesPerHostIBuffer > (unsigned long)sampleRate)
+        { /* Upper limit is 1 second */
+              stream->framesPerHostIBuffer = (unsigned long)sampleRate;
+        }
+        else if(stream->framesPerHostIBuffer < stream->recordingPin->frameSize)
+        {
+              stream->framesPerHostIBuffer = stream->recordingPin->frameSize;
+        }
+        PA_DEBUG(("Input frames chosen:%ld\n",stream->framesPerHostIBuffer));
+    }
+
+    if(outputParameters)
+    {
+        /* Calculate the frames from the user's value - add a bit to round up */
+        stream->framesPerHostOBuffer = (unsigned long)((outputParameters->suggestedLatency*sampleRate)+0.0001);
+        if(stream->framesPerHostOBuffer > (unsigned long)sampleRate)
+        { /* Upper limit is 1 second */
+                  stream->framesPerHostOBuffer = (unsigned long)sampleRate;
+        }
+        else if(stream->framesPerHostOBuffer < stream->playbackPin->frameSize)
+        {
+              stream->framesPerHostOBuffer = stream->playbackPin->frameSize;
+        }
+        PA_DEBUG(("Output frames chosen:%ld\n",stream->framesPerHostOBuffer));
+    }
+
+    /* Host buffer size is bounded to the largest of the input and output
+    frame sizes */
+
+    result =  PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
+              stream->userInputChannels, inputSampleFormat, hostInputSampleFormat,
+              stream->userOutputChannels, outputSampleFormat, hostOutputSampleFormat,
+              sampleRate, streamFlags, framesPerBuffer,
+              max(stream->framesPerHostOBuffer,stream->framesPerHostIBuffer),
+              paUtilBoundedHostBufferSize,
+              streamCallback, userData );
+    if( result != paNoError )
+        goto error;
+
+    stream->streamRepresentation.streamInfo.inputLatency =
+            ((double)stream->framesPerHostIBuffer) / sampleRate;
+    stream->streamRepresentation.streamInfo.outputLatency =
+            ((double)stream->framesPerHostOBuffer) / sampleRate;
+    stream->streamRepresentation.streamInfo.sampleRate = sampleRate;
+
+      PA_DEBUG(("BytesPerInputFrame = %d\n",stream->bytesPerInputFrame));
+      PA_DEBUG(("BytesPerOutputFrame = %d\n",stream->bytesPerOutputFrame));
+
+    /* Allocate all the buffers for host I/O */
+    size = 2 * (stream->framesPerHostIBuffer*stream->bytesPerInputFrame +  stream->framesPerHostOBuffer*stream->bytesPerOutputFrame);
+    PA_DEBUG(("Buffer size = %d\n",size));
+    stream->hostBuffer = (char*)PaUtil_AllocateMemory(size);
+    PA_DEBUG(("Buffer allocated\n"));
+    if( !stream->hostBuffer )
+    {
+        PA_DEBUG(("Cannot allocate host buffer!\n"));
+        result = paInsufficientMemory;
+        goto error;
+    }
+    PA_DEBUG(("Buffer start = %p\n",stream->hostBuffer));
+    /* memset(stream->hostBuffer,0,size); */
+
+    /* Set up the packets */
+    stream->events[0] = CreateEvent(NULL, FALSE, FALSE, NULL);
+    ResetEvent(stream->events[0]); /* Record buffer 1 */
+    stream->events[1] = CreateEvent(NULL, FALSE, FALSE, NULL);
+    ResetEvent(stream->events[1]); /* Record buffer 2 */
+    stream->events[2] = CreateEvent(NULL, FALSE, FALSE, NULL);
+    ResetEvent(stream->events[2]); /* Play buffer 1 */
+    stream->events[3] = CreateEvent(NULL, FALSE, FALSE, NULL);
+    ResetEvent(stream->events[3]); /* Play buffer 2 */
+    stream->events[4] = CreateEvent(NULL, FALSE, FALSE, NULL);
+    ResetEvent(stream->events[4]); /* Abort event */
+    if(stream->userInputChannels > 0)
+    {
+        DATAPACKET *p = &(stream->packets[0]);
+        p->Signal.hEvent = stream->events[0];
+        p->Header.Data = stream->hostBuffer;
+        p->Header.FrameExtent = stream->framesPerHostIBuffer*stream->bytesPerInputFrame;
+        p->Header.DataUsed = 0;
+        p->Header.Size = sizeof(p->Header);
+        p->Header.PresentationTime.Numerator = 1;
+        p->Header.PresentationTime.Denominator = 1;
+
+        p = &(stream->packets[1]);
+        p->Signal.hEvent = stream->events[1];
+        p->Header.Data = stream->hostBuffer + stream->framesPerHostIBuffer*stream->bytesPerInputFrame;
+        p->Header.FrameExtent = stream->framesPerHostIBuffer*stream->bytesPerInputFrame;
+        p->Header.DataUsed = 0;
+        p->Header.Size = sizeof(p->Header);
+        p->Header.PresentationTime.Numerator = 1;
+        p->Header.PresentationTime.Denominator = 1;
+    }
+    if(stream->userOutputChannels > 0)
+    {
+        DATAPACKET *p = &(stream->packets[2]);
+        p->Signal.hEvent = stream->events[2];
+        p->Header.Data = stream->hostBuffer + 2*stream->framesPerHostIBuffer*stream->bytesPerInputFrame;
+        p->Header.FrameExtent = stream->framesPerHostOBuffer*stream->bytesPerOutputFrame;
+        p->Header.DataUsed = stream->framesPerHostOBuffer*stream->bytesPerOutputFrame;
+        p->Header.Size = sizeof(p->Header);
+        p->Header.PresentationTime.Numerator = 1;
+        p->Header.PresentationTime.Denominator = 1;
+    
+        p = &(stream->packets[3]);
+        p->Signal.hEvent = stream->events[3];
+        p->Header.Data = stream->hostBuffer + 2*stream->framesPerHostIBuffer*stream->bytesPerInputFrame + stream->framesPerHostOBuffer*stream->bytesPerOutputFrame;
+        p->Header.FrameExtent = stream->framesPerHostOBuffer*stream->bytesPerOutputFrame;
+        p->Header.DataUsed = stream->framesPerHostOBuffer*stream->bytesPerOutputFrame;
+        p->Header.Size = sizeof(p->Header);
+        p->Header.PresentationTime.Numerator = 1;
+        p->Header.PresentationTime.Denominator = 1;
+    }
+
+    stream->streamStarted = 0;
+    stream->streamActive = 0;
+    stream->streamStop = 0;
+    stream->streamAbort = 0;
+    stream->streamFlags = streamFlags;
+    stream->oldProcessPriority = REALTIME_PRIORITY_CLASS;
+
+    *s = (PaStream*)stream;
+
+    PA_LOGL_;
+    return result;
+
+error:
+    size = 5;
+    while(size--)
+    {
+        if(stream->events[size] != NULL)
+        {
+            CloseHandle(stream->events[size]);
+            stream->events[size] = NULL;
+        }
+    }
+    if(stream->hostBuffer)
+        PaUtil_FreeMemory( stream->hostBuffer );
+
+    if(stream->playbackPin)
+        PinClose(stream->playbackPin);
+    if(stream->recordingPin)
+        PinClose(stream->recordingPin);
+
+    if( stream )
+        PaUtil_FreeMemory( stream );
+
+    PA_LOGL_;
+    return result;
+}
+
+/*
+    When CloseStream() is called, the multi-api layer ensures that
+    the stream has already been stopped or aborted.
+*/
+static PaError CloseStream( PaStream* s )
+{
+    PaError result = paNoError;
+    PaWinWdmStream *stream = (PaWinWdmStream*)s;
+    int size;
+
+    PA_LOGE_;
+
+    assert(!stream->streamStarted);
+    assert(!stream->streamActive);
+
+    PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
+    PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
+    size = 5;
+    while(size--)
+    {
+        if(stream->events[size] != NULL)
+        {
+            CloseHandle(stream->events[size]);
+            stream->events[size] = NULL;
+        }
+    }
+    if(stream->hostBuffer)
+        PaUtil_FreeMemory( stream->hostBuffer );
+
+    if(stream->playbackPin)
+        PinClose(stream->playbackPin);
+    if(stream->recordingPin)
+        PinClose(stream->recordingPin);
+
+    PaUtil_FreeMemory( stream );
+
+    PA_LOGL_;
+    return result;
+}
+
+/*
+Write the supplied packet to the pin
+Asynchronous
+Should return false on success
+*/
+static BOOL PinWrite(HANDLE h, DATAPACKET* p)
+{
+    unsigned long cbReturned = 0;
+    return DeviceIoControl(h,IOCTL_KS_WRITE_STREAM,NULL,0,
+                            &p->Header,p->Header.Size,&cbReturned,&p->Signal);
+}
+
+/*
+Read to the supplied packet from the pin
+Asynchronous
+Should return false on success
+*/
+static BOOL PinRead(HANDLE h, DATAPACKET* p)
+{
+    unsigned long cbReturned = 0;
+    return DeviceIoControl(h,IOCTL_KS_READ_STREAM,NULL,0,
+                            &p->Header,p->Header.Size,&cbReturned,&p->Signal);
+}
+
+/*
+Copy the first interleaved channel of 16 bit data to the other channels
+*/
+static void DuplicateFirstChannelInt16(void* buffer, int channels, int samples)
+{
+    unsigned short* data = (unsigned short*)buffer;
+    int channel;
+    unsigned short sourceSample;
+    while( samples-- )
+    {
+        sourceSample = *data++;
+        channel = channels-1;
+        while( channel-- )
+        {
+            *data++ = sourceSample;
+        }
+    }
+}
+
+/*
+Copy the first interleaved channel of 24 bit data to the other channels
+*/
+static void DuplicateFirstChannelInt24(void* buffer, int channels, int samples)
+{
+    unsigned char* data = (unsigned char*)buffer;
+    int channel;
+    unsigned char sourceSample[3];
+    while( samples-- )
+    {
+        sourceSample[0] = data[0];
+        sourceSample[1] = data[1];
+        sourceSample[2] = data[2];
+        data += 3;
+        channel = channels-1;
+        while( channel-- )
+        {
+            data[0] = sourceSample[0];
+            data[1] = sourceSample[1];
+            data[2] = sourceSample[2];
+            data += 3;
+        }
+    }
+}
+
+/*
+Copy the first interleaved channel of 32 bit data to the other channels
+*/
+static void DuplicateFirstChannelInt32(void* buffer, int channels, int samples)
+{
+    unsigned long* data = (unsigned long*)buffer;
+    int channel;
+    unsigned long sourceSample;
+    while( samples-- )
+    {
+        sourceSample = *data++;
+        channel = channels-1;
+        while( channel-- )
+        {
+            *data++ = sourceSample;
+        }
+    }
+}
+
+static DWORD WINAPI ProcessingThread(LPVOID pParam)
+{
+    PaWinWdmStream *stream = (PaWinWdmStream*)pParam;
+    PaStreamCallbackTimeInfo ti;
+    int cbResult = paContinue;
+    int inbuf = 0;
+    int outbuf = 0;
+    int pending = 0;
+    PaError result;
+    unsigned long wait;
+    unsigned long eventSignaled;
+    int fillPlaybuf = 0;
+    int emptyRecordbuf = 0;
+    int framesProcessed;
+    unsigned long timeout;
+    int i;
+    int doChannelCopy;
+    int priming = 0;
+    PaStreamCallbackFlags underover = 0;
+
+    PA_LOGE_;
+
+    ti.inputBufferAdcTime = 0.0;
+    ti.currentTime = 0.0;
+    ti.outputBufferDacTime = 0.0;
+
+    /* Get double buffering going */
+
+    /* Submit buffers */
+    if(stream->playbackPin)
+    {
+        result = PinSetState(stream->playbackPin, KSSTATE_RUN);
+
+        PA_DEBUG(("play state run = %d;",(int)result));
+        SetEvent(stream->events[outbuf+2]);
+        outbuf = (outbuf+1)&1;
+        SetEvent(stream->events[outbuf+2]);
+        outbuf = (outbuf+1)&1;
+        pending += 2;
+        priming += 4;
+    }
+    if(stream->recordingPin)
+    {
+        result = PinSetState(stream->recordingPin, KSSTATE_RUN);
+
+        PA_DEBUG(("recording state run = %d;",(int)result));
+        PinRead(stream->recordingPin->handle,&stream->packets[inbuf]);
+        inbuf = (inbuf+1)&1; /* Increment and wrap */
+        PinRead(stream->recordingPin->handle,&stream->packets[inbuf]);
+        inbuf = (inbuf+1)&1; /* Increment and wrap */
+        /* FIXME - do error checking */
+        pending += 2;
+    }
+    PA_DEBUG(("Out buffer len:%f\n",(2000*stream->framesPerHostOBuffer) / stream->streamRepresentation.streamInfo.sampleRate));
+    PA_DEBUG(("In buffer len:%f\n",(2000*stream->framesPerHostIBuffer) / stream->streamRepresentation.streamInfo.sampleRate));
+    timeout = max(
+       ((2000*(DWORD)stream->framesPerHostOBuffer) / (DWORD)stream->streamRepresentation.streamInfo.sampleRate),
+       ((2000*(DWORD)stream->framesPerHostIBuffer) / (DWORD)stream->streamRepresentation.streamInfo.sampleRate));
+    timeout = max(timeout,1);
+    PA_DEBUG(("Timeout = %ld\n",timeout));
+
+    while(!stream->streamAbort)
+    {
+        fillPlaybuf = 0;
+        emptyRecordbuf = 0;
+
+        /* Wait for next input or output buffer to be finished with*/
+        assert(pending>0);
+
+        if(stream->streamStop)
+        {
+            PA_DEBUG(("ss1:pending=%d ",pending));
+        }
+        wait = WaitForMultipleObjects(5, stream->events, FALSE, 0);
+        if( wait == WAIT_TIMEOUT )
+        {
+            /* No (under|over)flow has ocurred */
+            wait = WaitForMultipleObjects(5, stream->events, FALSE, timeout);
+            eventSignaled = wait - WAIT_OBJECT_0;
+        }
+        else
+        {
+            eventSignaled = wait - WAIT_OBJECT_0;
+            if( eventSignaled < 2 )
+            {
+                underover |= paInputOverflow;
+                PA_DEBUG(("Input overflow\n"));
+            }
+            else if(( eventSignaled < 4 )&&(!priming))
+            {
+                underover |= paOutputUnderflow;
+                PA_DEBUG(("Output underflow\n"));
+            }
+        }
+
+        if(stream->streamStop)
+        {
+            PA_DEBUG(("ss2:wait=%ld",wait));
+        }
+        if(wait == WAIT_FAILED)
+        {
+            PA_DEBUG(("Wait fail = %ld! ",wait));
+            break;
+        }
+        if(wait == WAIT_TIMEOUT)
+        {
+            continue;
+        }
+
+        if(eventSignaled < 2)
+        { /* Recording input buffer has been filled */
+            if(stream->playbackPin)
+            {
+                /* First check if also the next playback buffer has been signaled */
+                wait = WaitForSingleObject(stream->events[outbuf+2],0);
+                if(wait == WAIT_OBJECT_0)
+                {
+                    /* Yes, so do both buffers at same time */
+                    fillPlaybuf = 1;
+                    pending--;
+                    /* Was this an underflow situation? */
+                    if( underover )
+                        underover |= paOutputUnderflow; /* Yes! */
+                }
+            }
+            emptyRecordbuf = 1;
+            pending--;
+        }
+        else if(eventSignaled < 4)
+        { /* Playback output buffer has been emptied */
+            if(stream->recordingPin)
+            {
+                /* First check if also the next recording buffer has been signaled */
+                wait = WaitForSingleObject(stream->events[inbuf],0);
+                if(wait == WAIT_OBJECT_0)
+                { /* Yes, so do both buffers at same time */
+                    emptyRecordbuf = 1;
+                    pending--;
+                    /* Was this an overflow situation? */
+                    if( underover )
+                        underover |= paInputOverflow; /* Yes! */
+                }
+            }
+            fillPlaybuf = 1;
+            pending--;
+        }
+        else
+        {
+            /* Abort event! */
+            assert(stream->streamAbort); /* Should have been set */
+            PA_DEBUG(("ABORTING "));
+            break;
+        }
+        ResetEvent(stream->events[eventSignaled]);
+
+        if(stream->streamStop)
+        {
+            PA_DEBUG(("Stream stop! pending=%d",pending));
+            cbResult = paComplete; /* Stop, but play remaining buffers */
+        }
+
+        /* Do necessary buffer processing (which will invoke user callback if necessary */
+        doChannelCopy = 0;
+        if(cbResult==paContinue)
+        {
+            PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
+            if((stream->bufferProcessor.hostInputFrameCount[0] + stream->bufferProcessor.hostInputFrameCount[1]) ==
+                (stream->bufferProcessor.hostOutputFrameCount[0] + stream->bufferProcessor.hostOutputFrameCount[1]) )
+                PaUtil_BeginBufferProcessing(&stream->bufferProcessor,&ti,underover);
+            underover = 0; /* Reset the (under|over)flow status */
+            if(fillPlaybuf)
+            {
+                PaUtil_SetOutputFrameCount(&stream->bufferProcessor,0);
+                if( stream->userOutputChannels == 1 )
+                {
+                    /* Write the single user channel to the first interleaved block */
+                    PaUtil_SetOutputChannel(&stream->bufferProcessor,0,stream->packets[outbuf+2].Header.Data,stream->deviceOutputChannels);
+                    /* We will do a copy to the other channels after the data has been written */
+                    doChannelCopy = 1;
+                }
+                else
+                {
+                    for(i=0;i<stream->userOutputChannels;i++)
+                    {
+                        /* Only write the user output channels. Leave the rest blank */
+                        PaUtil_SetOutputChannel(&stream->bufferProcessor,i,((unsigned char*)(stream->packets[outbuf+2].Header.Data))+(i*stream->outputSampleSize),stream->deviceOutputChannels);
+                    }
+                }
+            }
+            if(emptyRecordbuf)
+            {
+                PaUtil_SetInputFrameCount(&stream->bufferProcessor,stream->packets[inbuf].Header.DataUsed/stream->bytesPerInputFrame);
+                for(i=0;i<stream->userInputChannels;i++)
+                {
+                    /* Only read as many channels as the user wants */
+                    PaUtil_SetInputChannel(&stream->bufferProcessor,i,((unsigned char*)(stream->packets[inbuf].Header.Data))+(i*stream->inputSampleSize),stream->deviceInputChannels);
+                }
+            }
+            /* Only call the EndBufferProcessing function is the total input frames == total output frames */
+            if((stream->bufferProcessor.hostInputFrameCount[0] + stream->bufferProcessor.hostInputFrameCount[1]) ==
+                (stream->bufferProcessor.hostOutputFrameCount[0] + stream->bufferProcessor.hostOutputFrameCount[1]) )
+                framesProcessed = PaUtil_EndBufferProcessing(&stream->bufferProcessor,&cbResult);
+            else framesProcessed = 0;
+            if( doChannelCopy )
+            {
+                /* Copy the first output channel to the other channels */
+                switch(stream->outputSampleSize)
+                {
+                    case 2:
+                        DuplicateFirstChannelInt16(stream->packets[outbuf+2].Header.Data,stream->deviceOutputChannels,stream->framesPerHostOBuffer);
+                        break;
+                    case 3:
+                        DuplicateFirstChannelInt24(stream->packets[outbuf+2].Header.Data,stream->deviceOutputChannels,stream->framesPerHostOBuffer);
+                        break;
+                    case 4:
+                        DuplicateFirstChannelInt32(stream->packets[outbuf+2].Header.Data,stream->deviceOutputChannels,stream->framesPerHostOBuffer);
+                        break;
+                    default:
+                        assert(0); /* Unsupported format! */
+                        break;
+                }
+            }
+            PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed );
+        }
+        else
+        {
+            fillPlaybuf = 0;
+            emptyRecordbuf = 0;
+        }
+            
+        /*
+        if(cbResult != paContinue)
+        {
+            PA_DEBUG(("cbResult=%d, pending=%d:",cbResult,pending));
+        }
+        */
+        /* Submit buffers */
+        if((fillPlaybuf)&&(cbResult!=paAbort))
+        {
+            if(!PinWrite(stream->playbackPin->handle,&stream->packets[outbuf+2]))
+                outbuf = (outbuf+1)&1; /* Increment and wrap */
+            pending++;
+            if( priming )
+                priming--; /* Have to prime twice */
+        }
+        if((emptyRecordbuf)&&(cbResult==paContinue))
+        {
+            stream->packets[inbuf].Header.DataUsed = 0; /* Reset for reuse */
+            PinRead(stream->recordingPin->handle,&stream->packets[inbuf]);
+            inbuf = (inbuf+1)&1; /* Increment and wrap */
+            pending++;
+        }
+        if(pending==0)
+        {
+            PA_DEBUG(("pending==0 finished...;"));
+            break;
+        }
+        if((!stream->playbackPin)&&(cbResult!=paContinue))
+        {
+            PA_DEBUG(("record only cbResult=%d...;",cbResult));
+            break;
+        }
+    }
+
+    PA_DEBUG(("Finished thread"));
+
+    /* Finished, either normally or aborted */
+    if(stream->playbackPin)
+    {
+        result = PinSetState(stream->playbackPin, KSSTATE_PAUSE);
+        result = PinSetState(stream->playbackPin, KSSTATE_STOP);
+    }
+    if(stream->recordingPin)
+    {
+        result = PinSetState(stream->recordingPin, KSSTATE_PAUSE);
+        result = PinSetState(stream->recordingPin, KSSTATE_STOP);
+    }
+
+    stream->streamActive = 0;
+
+    if((!stream->streamStop)&&(!stream->streamAbort))
+    {
+          /* Invoke the user stream finished callback */
+          /* Only do it from here if not being stopped/aborted by user */
+          if( stream->streamRepresentation.streamFinishedCallback != 0 )
+              stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
+    }
+    stream->streamStop = 0;
+    stream->streamAbort = 0;
+
+    /* Reset process priority if necessary */
+    if(stream->oldProcessPriority != REALTIME_PRIORITY_CLASS)
+    {
+        SetPriorityClass(GetCurrentProcess(),stream->oldProcessPriority);
+        stream->oldProcessPriority = REALTIME_PRIORITY_CLASS;
+    }
+
+    PA_LOGL_;
+    ExitThread(0);
+    return 0;
+}
+
+static PaError StartStream( PaStream *s )
+{
+    PaError result = paNoError;
+    PaWinWdmStream *stream = (PaWinWdmStream*)s;
+    DWORD dwID;
+    BOOL ret;
+    int size;
+
+    PA_LOGE_;
+
+    stream->streamStop = 0;
+    stream->streamAbort = 0;
+    size = 5;
+    while(size--)
+    {
+        if(stream->events[size] != NULL)
+        {
+            ResetEvent(stream->events[size]);
+        }
+    }
+
+    PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
+
+    stream->oldProcessPriority = GetPriorityClass(GetCurrentProcess());
+    /* Uncomment the following line to enable dynamic boosting of the process
+     * priority to real time for best low latency support
+     * Disabled by default because RT processes can easily block the OS */
+    /*ret = SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS);
+      PA_DEBUG(("Class ret = %d;",ret));*/
+
+    stream->streamStarted = 1;
+    stream->streamThread = CreateThread(NULL, 0, ProcessingThread, stream, 0, &dwID);
+    if(stream->streamThread == NULL)
+    {
+        stream->streamStarted = 0;
+        result = paInsufficientMemory;
+        goto end;
+    }
+    ret = SetThreadPriority(stream->streamThread,THREAD_PRIORITY_TIME_CRITICAL);
+    PA_DEBUG(("Priority ret = %d;",ret));
+    /* Make the stream active */
+    stream->streamActive = 1;
+
+end:
+    PA_LOGL_;
+    return result;
+}
+
+
+static PaError StopStream( PaStream *s )
+{
+    PaError result = paNoError;
+    PaWinWdmStream *stream = (PaWinWdmStream*)s;
+    int doCb = 0;
+
+    PA_LOGE_;
+
+    if(stream->streamActive)
+    {
+        doCb = 1;
+        stream->streamStop = 1;
+        while(stream->streamActive)
+        {
+            PA_DEBUG(("W."));
+            Sleep(10); /* Let thread sleep for 10 msec */
+        }
+    }
+
+    PA_DEBUG(("Terminating thread"));
+    if(stream->streamStarted && stream->streamThread)
+    {
+        TerminateThread(stream->streamThread,0);
+        stream->streamThread = NULL;
+    }
+
+    stream->streamStarted = 0;
+
+    if(stream->oldProcessPriority != REALTIME_PRIORITY_CLASS)
+    {
+        SetPriorityClass(GetCurrentProcess(),stream->oldProcessPriority);
+        stream->oldProcessPriority = REALTIME_PRIORITY_CLASS;
+    }
+
+    if(doCb)
+    {
+        /* Do user callback now after all state has been reset */
+        /* This means it should be safe for the called function */
+        /* to invoke e.g. StartStream */
+        if( stream->streamRepresentation.streamFinishedCallback != 0 )
+             stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
+    }
+
+    PA_LOGL_;
+    return result;
+}
+
+static PaError AbortStream( PaStream *s )
+{
+    PaError result = paNoError;
+    PaWinWdmStream *stream = (PaWinWdmStream*)s;
+    int doCb = 0;
+
+    PA_LOGE_;
+
+    if(stream->streamActive)
+    {
+        doCb = 1;
+        stream->streamAbort = 1;
+        SetEvent(stream->events[4]); /* Signal immediately */
+        while(stream->streamActive)
+        {
+            Sleep(10);
+        }
+    }
+
+    if(stream->streamStarted && stream->streamThread)
+    {
+        TerminateThread(stream->streamThread,0);
+        stream->streamThread = NULL;
+    }
+
+    stream->streamStarted = 0;
+
+    if(stream->oldProcessPriority != REALTIME_PRIORITY_CLASS)
+    {
+        SetPriorityClass(GetCurrentProcess(),stream->oldProcessPriority);
+        stream->oldProcessPriority = REALTIME_PRIORITY_CLASS;
+    }
+
+    if(doCb)
+    {
+        /* Do user callback now after all state has been reset */
+        /* This means it should be safe for the called function */
+        /* to invoke e.g. StartStream */
+        if( stream->streamRepresentation.streamFinishedCallback != 0 )
+            stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
+    }
+
+    stream->streamActive = 0;
+    stream->streamStarted = 0;
+
+    PA_LOGL_;
+    return result;
+}
+
+
+static PaError IsStreamStopped( PaStream *s )
+{
+    PaWinWdmStream *stream = (PaWinWdmStream*)s;
+    int result = 0;
+
+    PA_LOGE_;
+
+    if(!stream->streamStarted)
+        result = 1;
+
+    PA_LOGL_;
+    return result;
+}
+
+
+static PaError IsStreamActive( PaStream *s )
+{
+    PaWinWdmStream *stream = (PaWinWdmStream*)s;
+    int result = 0;
+
+    PA_LOGE_;
+
+    if(stream->streamActive)
+        result = 1;
+
+    PA_LOGL_;
+    return result;
+}
+
+
+static PaTime GetStreamTime( PaStream* s )
+{
+    PA_LOGE_;
+    PA_LOGL_;
+    (void)s;
+    return PaUtil_GetTime();
+}
+
+
+static double GetStreamCpuLoad( PaStream* s )
+{
+    PaWinWdmStream *stream = (PaWinWdmStream*)s;
+    double result;
+    PA_LOGE_;
+    result = PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
+    PA_LOGL_;
+    return result;
+}
+
+
+/*
+    As separate stream interfaces are used for blocking and callback
+    streams, the following functions can be guaranteed to only be called
+    for blocking streams.
+*/
+
+static PaError ReadStream( PaStream* s,
+                           void *buffer,
+                           unsigned long frames )
+{
+    PaWinWdmStream *stream = (PaWinWdmStream*)s;
+
+    PA_LOGE_;
+
+    /* suppress unused variable warnings */
+    (void) buffer;
+    (void) frames;
+    (void) stream;
+
+    /* IMPLEMENT ME, see portaudio.h for required behavior*/
+    PA_LOGL_;
+    return paNoError;
+}
+
+
+static PaError WriteStream( PaStream* s,
+                            const void *buffer,
+                            unsigned long frames )
+{
+    PaWinWdmStream *stream = (PaWinWdmStream*)s;
+
+    PA_LOGE_;
+
+    /* suppress unused variable warnings */
+    (void) buffer;
+    (void) frames;
+    (void) stream;
+
+    /* IMPLEMENT ME, see portaudio.h for required behavior*/
+    PA_LOGL_;
+    return paNoError;
+}
+
+
+static signed long GetStreamReadAvailable( PaStream* s )
+{
+    PaWinWdmStream *stream = (PaWinWdmStream*)s;
+
+    PA_LOGE_;
+
+    /* suppress unused variable warnings */
+    (void) stream;
+
+    /* IMPLEMENT ME, see portaudio.h for required behavior*/
+    PA_LOGL_;
+    return 0;
+}
+
+
+static signed long GetStreamWriteAvailable( PaStream* s )
+{
+    PaWinWdmStream *stream = (PaWinWdmStream*)s;
+
+    PA_LOGE_;
+    /* suppress unused variable warnings */
+    (void) stream;
+
+    /* IMPLEMENT ME, see portaudio.h for required behavior*/
+    PA_LOGL_;
+    return 0;
+}
\ No newline at end of file
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/wdmks/readme.txt b/utils/iaxclient/lib/portaudio/src/hostapi/wdmks/readme.txt
new file mode 100644 (file)
index 0000000..1a381fe
--- /dev/null
@@ -0,0 +1,82 @@
+Notes about WDM-KS host API
+---------------------------
+
+Status history
+--------------
+10th November 2005:
+Made following changes:
+ * OpenStream: Try all PaSampleFormats internally if the the chosen
+     format is not supported natively.  This fixed several problems
+     with soundcards that soundcards that did not take kindly to
+     using 24-bit 3-byte formats.
+ * OpenStream: Make the minimum framesPerHostIBuffer (and framesPerHostOBuffer)
+     the default frameSize for the playback/recording pin.
+ * ProcessingThread: Added a switch to only call PaUtil_EndBufferProcessing
+     if the total input frames equals the total output frames
+
+5th September 2004:
+This is the first public version of the code. It should be considered
+an alpha release with zero guarantee not to crash on any particular 
+system. So far it has only been tested in the author's development
+environment, which means a Win2k/SP2 PIII laptop with integrated 
+SoundMAX driver and USB Tascam US-428 compiled with both MinGW
+(GCC 3.3) and MSVC++6 using the MS DirectX 9 SDK.
+It has been most widely tested with the MinGW build, with most of the
+test programs (particularly paqa_devs and paqa_errs) passing.
+There are some notable failures: patest_out_underflow and both of the
+blocking I/O tests (as blocking I/O is not implemented).
+At this point the code needs to be tested with a much wider variety 
+of configurations and feedback provided from testers regarding
+both working and failing cases.
+
+What is the WDM-KS host API?
+----------------------------
+PortAudio for Windows currently has 3 functional host implementations.
+MME uses the oldest Windows audio API which does not offer good
+play/record latency. 
+DirectX improves this, but still imposes a penalty
+of 10s of milliseconds due to the system mixing of streams from
+multiple applications. 
+ASIO offers very good latency, but requires special drivers which are
+not always available for cheaper audio hardware. Also, when ASIO 
+drivers are available, they are not always so robust because they 
+bypass all of the standardised Windows device driver architecture 
+and hit the hardware their own way.
+Alternatively there are a couple of free (but closed source) ASIO 
+implementations which connect to the lower level Windows 
+"Kernel Streaming" API, but again these require special installation 
+by the user, and can be limited in functionality or difficult to use. 
+
+This is where the PortAudio "WDM-KS" host implementation comes in.
+It directly connects PortAudio to the same Kernel Streaming API which
+those ASIO bridges use. This avoids the mixing penatly of DirectX, 
+giving at least as good latency as any ASIO driver, but it has the
+advantage of working with ANY Windows audio hardware which is available
+through the normal MME/DirectX routes without the user requiring 
+any additional device drivers to be installed, and allowing all 
+device selection to be done through the normal PortAudio API.
+
+Note that in general you should only be using this host API if your 
+application has a real requirement for very low latency audio (<20ms), 
+either because you are generating sounds in real-time based upon 
+user input, or you a processing recorded audio in real time.
+
+The only thing to be aware of is that using the KS interface will
+block that device from being used by the rest of system through
+the higher level APIs, or conversely, if the system is using
+a device, the KS API will not be able to use it. MS recommend that
+you should keep the device open only when your application has focus.
+In PortAudio terms, this means having a stream Open on a WDMKS device.
+
+Usage
+-----
+To add the WDMKS backend to your program which is already using 
+PortAudio, you must undefine PA_NO_WDMKS from your build file,
+and include the pa_win_wdmks\pa_win_wdmks.c into your build.
+The file should compile in both C and C++.
+You will need a DirectX SDK installed on your system for the
+ks.h and ksmedia.h header files.
+You will need to link to the system "setupapi" library.
+Note that if you use MinGW, you will get more warnings from 
+the DX header files when using GCC(C), and still a few warnings
+with G++(CPP).
\ No newline at end of file
diff --git a/utils/iaxclient/lib/portaudio/src/hostapi/wmme/pa_win_wmme.c b/utils/iaxclient/lib/portaudio/src/hostapi/wmme/pa_win_wmme.c
new file mode 100644 (file)
index 0000000..4ffca4f
--- /dev/null
@@ -0,0 +1,3634 @@
+/*
+ * $Id: pa_win_wmme.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * pa_win_wmme.c
+ * Implementation of PortAudio for Windows MultiMedia Extensions (WMME)       
+ *                                                                                         
+ * PortAudio Portable Real-Time Audio Library
+ * Latest Version at: http://www.portaudio.com
+ *
+ * Authors: Ross Bencina and Phil Burk
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/* Modification History:
+ PLB = Phil Burk
+ JM = Julien Maillard
+ RDB = Ross Bencina
+ PLB20010402 - sDevicePtrs now allocates based on sizeof(pointer)
+ PLB20010413 - check for excessive numbers of channels
+ PLB20010422 - apply Mike Berry's changes for CodeWarrior on PC
+               including conditional inclusion of memory.h,
+               and explicit typecasting on memory allocation
+ PLB20010802 - use GlobalAlloc for sDevicesPtr instead of PaHost_AllocFastMemory
+ PLB20010816 - pass process instead of thread to SetPriorityClass()
+ PLB20010927 - use number of frames instead of real-time for CPULoad calculation.
+ JM20020118 - prevent hung thread when buffers underflow.
+ PLB20020321 - detect Win XP versus NT, 9x; fix DBUG typo; removed init of CurrentCount
+ RDB20020411 - various renaming cleanups, factored streamData alloc and cpu usage init
+ RDB20020417 - stopped counting WAVE_MAPPER when there were no real devices
+               refactoring, renaming and fixed a few edge case bugs
+ RDB20020531 - converted to V19 framework
+ ** NOTE  maintanance history is now stored in CVS **
+*/
+
+/** @file
+       
+       @todo Fix buffer catch up code, can sometimes get stuck (perhaps fixed now,
+            needs to be reviewed and tested.)
+
+    @todo implement paInputUnderflow, paOutputOverflow streamCallback statusFlags, paNeverDropInput.
+
+    @todo BUG: PA_MME_SET_LAST_WAVEIN/OUT_ERROR is used in functions which may
+                be called asynchronously from the callback thread. this is bad.
+
+    @todo implement inputBufferAdcTime in callback thread
+
+    @todo review/fix error recovery and cleanup in marked functions
+
+    @todo implement timeInfo for stream priming
+
+    @todo handle the case where the callback returns paAbort or paComplete during stream priming.
+
+    @todo review input overflow and output underflow handling in ReadStream and WriteStream
+
+Non-critical stuff for the future:
+
+    @todo Investigate supporting host buffer formats > 16 bits
+    
+    @todo define UNICODE and _UNICODE in the project settings and see what breaks
+
+*/
+
+/*
+    How it works:
+
+    For both callback and blocking read/write streams we open the MME devices
+    in CALLBACK_EVENT mode. In this mode, MME signals an Event object whenever
+    it has finished with a buffer (either filled it for input, or played it
+    for output). Where necessary we block waiting for Event objects using
+    WaitMultipleObjects().
+
+    When implementing a PA callback stream, we set up a high priority thread
+    which waits on the MME buffer Events and drains/fills the buffers when
+    they are ready.
+
+    When implementing a PA blocking read/write stream, we simply wait on these
+    Events (when necessary) inside the ReadStream() and WriteStream() functions.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <windows.h>
+#include <mmsystem.h>
+#include <process.h>
+#include <assert.h>
+/* PLB20010422 - "memory.h" doesn't work on CodeWarrior for PC. Thanks Mike Berry for the mod. */
+#ifndef __MWERKS__
+#include <malloc.h>
+#include <memory.h>
+#endif /* __MWERKS__ */
+
+#include "portaudio.h"
+#include "pa_trace.h"
+#include "pa_util.h"
+#include "pa_allocation.h"
+#include "pa_hostapi.h"
+#include "pa_stream.h"
+#include "pa_cpuload.h"
+#include "pa_process.h"
+
+#include "pa_win_wmme.h"
+
+#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) /* MSC version 6 and above */
+#pragma comment(lib, "winmm.lib")
+#endif
+
+/*
+ provided in newer platform sdks
+ */
+#ifndef DWORD_PTR
+#define DWORD_PTR DWORD
+#endif
+
+/************************************************* Constants ********/
+
+#define PA_MME_USE_HIGH_DEFAULT_LATENCY_    (0)  /* For debugging glitches. */
+
+#if PA_MME_USE_HIGH_DEFAULT_LATENCY_
+ #define PA_MME_WIN_9X_DEFAULT_LATENCY_                     (0.4)
+ #define PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_               (4)
+ #define PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_       (4)
+ #define PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_HALF_DUPLEX_       (4)
+ #define PA_MME_MIN_HOST_BUFFER_FRAMES_WHEN_UNSPECIFIED_       (16)
+ #define PA_MME_MAX_HOST_BUFFER_SECS_                                  (0.3)       /* Do not exceed unless user buffer exceeds */
+ #define PA_MME_MAX_HOST_BUFFER_BYTES_                                 (32 * 1024) /* Has precedence over PA_MME_MAX_HOST_BUFFER_SECS_, some drivers are known to crash with buffer sizes > 32k */
+#else
+ #define PA_MME_WIN_9X_DEFAULT_LATENCY_                     (0.2)
+ #define PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_               (2)
+ #define PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_       (3)
+ #define PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_HALF_DUPLEX_       (2)
+ #define PA_MME_MIN_HOST_BUFFER_FRAMES_WHEN_UNSPECIFIED_       (16)
+ #define PA_MME_MAX_HOST_BUFFER_SECS_                                  (0.1)       /* Do not exceed unless user buffer exceeds */
+ #define PA_MME_MAX_HOST_BUFFER_BYTES_                                 (32 * 1024) /* Has precedence over PA_MME_MAX_HOST_BUFFER_SECS_, some drivers are known to crash with buffer sizes > 32k */
+#endif
+
+/* Use higher latency for NT because it is even worse at real-time
+   operation than Win9x.
+*/
+#define PA_MME_WIN_NT_DEFAULT_LATENCY_      (PA_MME_WIN_9X_DEFAULT_LATENCY_ * 2)
+#define PA_MME_WIN_WDM_DEFAULT_LATENCY_     (PA_MME_WIN_9X_DEFAULT_LATENCY_)
+
+
+#define PA_MME_MIN_TIMEOUT_MSEC_        (1000)
+
+static const char constInputMapperSuffix_[] = " - Input";
+static const char constOutputMapperSuffix_[] = " - Output";
+
+/********************************************************************/
+
+typedef struct PaWinMmeStream PaWinMmeStream;     /* forward declaration */
+
+/* prototypes for functions declared in this file */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+static void Terminate( struct PaUtilHostApiRepresentation *hostApi );
+static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
+                           PaStream** stream,
+                           const PaStreamParameters *inputParameters,
+                           const PaStreamParameters *outputParameters,
+                           double sampleRate,
+                           unsigned long framesPerBuffer,
+                           PaStreamFlags streamFlags,
+                           PaStreamCallback *streamCallback,
+                           void *userData );
+static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
+                                  const PaStreamParameters *inputParameters,
+                                  const PaStreamParameters *outputParameters,
+                                  double sampleRate );
+static PaError CloseStream( PaStream* stream );
+static PaError StartStream( PaStream *stream );
+static PaError StopStream( PaStream *stream );
+static PaError AbortStream( PaStream *stream );
+static PaError IsStreamStopped( PaStream *s );
+static PaError IsStreamActive( PaStream *stream );
+static PaTime GetStreamTime( PaStream *stream );
+static double GetStreamCpuLoad( PaStream* stream );
+static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames );
+static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames );
+static signed long GetStreamReadAvailable( PaStream* stream );
+static signed long GetStreamWriteAvailable( PaStream* stream );
+
+
+/* macros for setting last host error information */
+
+#ifdef UNICODE
+
+#define PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ) \
+    {                                                                   \
+        wchar_t mmeErrorTextWide[ MAXERRORLENGTH ];                     \
+        char mmeErrorText[ MAXERRORLENGTH ];                            \
+        waveInGetErrorText( mmresult, mmeErrorTextWide, MAXERRORLENGTH );   \
+        WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR,\
+            mmeErrorTextWide, -1, mmeErrorText, MAXERRORLENGTH, NULL, NULL );  \
+        PaUtil_SetLastHostErrorInfo( paMME, mmresult, mmeErrorText );   \
+    }
+
+#define PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ) \
+    {                                                                   \
+        wchar_t mmeErrorTextWide[ MAXERRORLENGTH ];                     \
+        char mmeErrorText[ MAXERRORLENGTH ];                            \
+        waveOutGetErrorText( mmresult, mmeErrorTextWide, MAXERRORLENGTH );  \
+        WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK | WC_DEFAULTCHAR,\
+            mmeErrorTextWide, -1, mmeErrorText, MAXERRORLENGTH, NULL, NULL );  \
+        PaUtil_SetLastHostErrorInfo( paMME, mmresult, mmeErrorText );   \
+    }
+    
+#else /* !UNICODE */
+
+#define PA_MME_SET_LAST_WAVEIN_ERROR( mmresult ) \
+    {                                                                   \
+        char mmeErrorText[ MAXERRORLENGTH ];                            \
+        waveInGetErrorText( mmresult, mmeErrorText, MAXERRORLENGTH );   \
+        PaUtil_SetLastHostErrorInfo( paMME, mmresult, mmeErrorText );   \
+    }
+
+#define PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult ) \
+    {                                                                   \
+        char mmeErrorText[ MAXERRORLENGTH ];                            \
+        waveOutGetErrorText( mmresult, mmeErrorText, MAXERRORLENGTH );  \
+        PaUtil_SetLastHostErrorInfo( paMME, mmresult, mmeErrorText );   \
+    }
+
+#endif /* UNICODE */
+
+
+static void PaMme_SetLastSystemError( DWORD errorCode )
+{
+    char *lpMsgBuf;
+    FormatMessage(
+        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+        NULL,
+        errorCode,
+        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+        (LPTSTR) &lpMsgBuf,
+        0,
+        NULL
+    );
+    PaUtil_SetLastHostErrorInfo( paMME, errorCode, lpMsgBuf );
+    LocalFree( lpMsgBuf );
+}
+
+#define PA_MME_SET_LAST_SYSTEM_ERROR( errorCode ) \
+    PaMme_SetLastSystemError( errorCode )
+
+
+/* PaError returning wrappers for some commonly used win32 functions
+    note that we allow passing a null ptr to have no effect.
+*/
+
+static PaError CreateEventWithPaError( HANDLE *handle,
+        LPSECURITY_ATTRIBUTES lpEventAttributes,
+        BOOL bManualReset,
+        BOOL bInitialState,
+        LPCTSTR lpName )
+{
+    PaError result = paNoError;
+
+    *handle = NULL;
+    
+    *handle = CreateEvent( lpEventAttributes, bManualReset, bInitialState, lpName );
+    if( *handle == NULL )
+    {
+        result = paUnanticipatedHostError;
+        PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() );
+    }
+
+    return result;
+}
+
+
+static PaError ResetEventWithPaError( HANDLE handle )
+{
+    PaError result = paNoError;
+
+    if( handle )
+    {
+        if( ResetEvent( handle ) == 0 )
+        {
+            result = paUnanticipatedHostError;
+            PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() );
+        }
+    }
+
+    return result;
+}
+
+
+static PaError CloseHandleWithPaError( HANDLE handle )
+{
+    PaError result = paNoError;
+    
+    if( handle )
+    {
+        if( CloseHandle( handle ) == 0 )
+        {
+            result = paUnanticipatedHostError;
+            PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() );
+        }
+    }
+    
+    return result;
+}
+
+
+/* PaWinMmeHostApiRepresentation - host api datastructure specific to this implementation */
+
+typedef struct
+{
+    PaUtilHostApiRepresentation inheritedHostApiRep;
+    PaUtilStreamInterface callbackStreamInterface;
+    PaUtilStreamInterface blockingStreamInterface;
+
+    PaUtilAllocationGroup *allocations;
+    
+    int inputDeviceCount, outputDeviceCount;
+
+    /** winMmeDeviceIds is an array of WinMme device ids.
+        fields in the range [0, inputDeviceCount) are input device ids,
+        and [inputDeviceCount, inputDeviceCount + outputDeviceCount) are output
+        device ids.
+     */ 
+    UINT *winMmeDeviceIds;
+}
+PaWinMmeHostApiRepresentation;
+
+
+typedef struct
+{
+    PaDeviceInfo inheritedDeviceInfo;
+    DWORD dwFormats; /**<< standard formats bitmask from the WAVEINCAPS and WAVEOUTCAPS structures */
+}
+PaWinMmeDeviceInfo;
+
+
+/*************************************************************************
+ * Returns recommended device ID.
+ * On the PC, the recommended device can be specified by the user by
+ * setting an environment variable. For example, to use device #1.
+ *
+ *    set PA_RECOMMENDED_OUTPUT_DEVICE=1
+ *
+ * The user should first determine the available device ID by using
+ * the supplied application "pa_devs".
+ */
+#define PA_ENV_BUF_SIZE_  (32)
+#define PA_REC_IN_DEV_ENV_NAME_  ("PA_RECOMMENDED_INPUT_DEVICE")
+#define PA_REC_OUT_DEV_ENV_NAME_  ("PA_RECOMMENDED_OUTPUT_DEVICE")
+static PaDeviceIndex GetEnvDefaultDeviceID( char *envName )
+{
+    PaDeviceIndex recommendedIndex = paNoDevice;
+    DWORD   hresult;
+    char    envbuf[PA_ENV_BUF_SIZE_];
+
+#ifndef WIN32_PLATFORM_PSPC /* no GetEnvironmentVariable on PocketPC */
+
+    /* Let user determine default device by setting environment variable. */
+    hresult = GetEnvironmentVariable( envName, envbuf, PA_ENV_BUF_SIZE_ );
+    if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE_) )
+    {
+        recommendedIndex = atoi( envbuf );
+    }
+#endif
+
+    return recommendedIndex;
+}
+
+
+static void InitializeDefaultDeviceIdsFromEnv( PaWinMmeHostApiRepresentation *hostApi )
+{
+    PaDeviceIndex device;
+
+    /* input */
+    device = GetEnvDefaultDeviceID( PA_REC_IN_DEV_ENV_NAME_ );
+    if( device != paNoDevice &&
+            ( device >= 0 && device < hostApi->inheritedHostApiRep.info.deviceCount ) &&
+            hostApi->inheritedHostApiRep.deviceInfos[ device ]->maxInputChannels > 0 )
+    {
+        hostApi->inheritedHostApiRep.info.defaultInputDevice = device;
+    }
+
+    /* output */
+    device = GetEnvDefaultDeviceID( PA_REC_OUT_DEV_ENV_NAME_ );
+    if( device != paNoDevice &&
+            ( device >= 0 && device < hostApi->inheritedHostApiRep.info.deviceCount ) &&
+            hostApi->inheritedHostApiRep.deviceInfos[ device ]->maxOutputChannels > 0 )
+    {
+        hostApi->inheritedHostApiRep.info.defaultOutputDevice = device;
+    }
+}
+
+
+/** Convert external PA ID to a windows multimedia device ID
+*/
+static UINT LocalDeviceIndexToWinMmeDeviceId( PaWinMmeHostApiRepresentation *hostApi, PaDeviceIndex device )
+{
+    assert( device >= 0 && device < hostApi->inputDeviceCount + hostApi->outputDeviceCount );
+
+       return hostApi->winMmeDeviceIds[ device ];
+}
+
+
+static PaError QueryInputWaveFormatEx( int deviceId, WAVEFORMATEX *waveFormatEx )
+{
+    MMRESULT mmresult;
+    
+    switch( mmresult = waveInOpen( NULL, deviceId, waveFormatEx, 0, 0, WAVE_FORMAT_QUERY ) )
+    {
+        case MMSYSERR_NOERROR:
+            return paNoError;
+        case MMSYSERR_ALLOCATED:    /* Specified resource is already allocated. */
+            return paDeviceUnavailable;
+        case MMSYSERR_NODRIVER:            /* No device driver is present. */
+            return paDeviceUnavailable;
+        case MMSYSERR_NOMEM:       /* Unable to allocate or lock memory. */
+            return paInsufficientMemory;
+        case WAVERR_BADFORMAT:      /* Attempted to open with an unsupported waveform-audio format. */
+            return paSampleFormatNotSupported;
+                    
+        case MMSYSERR_BADDEVICEID:     /* Specified device identifier is out of range. */
+            /* falls through */
+        default:
+            PA_MME_SET_LAST_WAVEIN_ERROR( mmresult );
+            return paUnanticipatedHostError;
+    }
+}
+
+
+static PaError QueryOutputWaveFormatEx( int deviceId, WAVEFORMATEX *waveFormatEx )
+{
+    MMRESULT mmresult;
+    
+    switch( mmresult = waveOutOpen( NULL, deviceId, waveFormatEx, 0, 0, WAVE_FORMAT_QUERY ) )
+    {
+        case MMSYSERR_NOERROR:
+            return paNoError;
+        case MMSYSERR_ALLOCATED:    /* Specified resource is already allocated. */
+            return paDeviceUnavailable;
+        case MMSYSERR_NODRIVER:            /* No device driver is present. */
+            return paDeviceUnavailable;
+        case MMSYSERR_NOMEM:       /* Unable to allocate or lock memory. */
+            return paInsufficientMemory;
+        case WAVERR_BADFORMAT:      /* Attempted to open with an unsupported waveform-audio format. */
+            return paSampleFormatNotSupported;
+                    
+        case MMSYSERR_BADDEVICEID:     /* Specified device identifier is out of range. */
+            /* falls through */
+        default:
+            PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult );
+            return paUnanticipatedHostError;
+    }
+}
+
+
+static PaError QueryFormatSupported( PaDeviceInfo *deviceInfo,
+        PaError (*waveFormatExQueryFunction)(int, WAVEFORMATEX*),
+        int winMmeDeviceId, int channels, double sampleRate )
+{
+    PaWinMmeDeviceInfo *winMmeDeviceInfo = (PaWinMmeDeviceInfo*)deviceInfo;
+    WAVEFORMATEX waveFormatEx;
+    
+    if( sampleRate == 11025.0
+        && ( (channels == 1 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_1M16))
+            || (channels == 2 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_1S16)) ) ){
+
+        return paNoError;
+    }
+
+    if( sampleRate == 22050.0
+        && ( (channels == 1 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_2M16))
+            || (channels == 2 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_2S16)) ) ){
+
+        return paNoError;
+    }
+
+    if( sampleRate == 44100.0
+        && ( (channels == 1 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_4M16))
+            || (channels == 2 && (winMmeDeviceInfo->dwFormats & WAVE_FORMAT_4S16)) ) ){
+
+        return paNoError;
+    }
+
+    waveFormatEx.wFormatTag = WAVE_FORMAT_PCM;
+    waveFormatEx.nChannels = (WORD)channels;
+    waveFormatEx.nSamplesPerSec = (DWORD)sampleRate;
+    waveFormatEx.nAvgBytesPerSec = waveFormatEx.nSamplesPerSec * channels * sizeof(short);
+    waveFormatEx.nBlockAlign = (WORD)(channels * sizeof(short));
+    waveFormatEx.wBitsPerSample = 16;
+    waveFormatEx.cbSize = 0;
+
+    return waveFormatExQueryFunction( winMmeDeviceId, &waveFormatEx );
+}
+
+
+#define PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_  (13) /* must match array length below */
+static double defaultSampleRateSearchOrder_[] =
+    { 44100.0, 48000.0, 32000.0, 24000.0, 22050.0, 88200.0, 96000.0, 192000.0,
+        16000.0, 12000.0, 11025.0, 9600.0, 8000.0 };
+
+static void DetectDefaultSampleRate( PaWinMmeDeviceInfo *winMmeDeviceInfo, int winMmeDeviceId,
+        PaError (*waveFormatExQueryFunction)(int, WAVEFORMATEX*), int maxChannels )
+{
+    PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo;
+    int i;
+    
+    deviceInfo->defaultSampleRate = 0.;
+
+    for( i=0; i < PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_; ++i )
+    {
+        double sampleRate = defaultSampleRateSearchOrder_[ i ]; 
+        PaError paerror = QueryFormatSupported( deviceInfo, waveFormatExQueryFunction, winMmeDeviceId, maxChannels, sampleRate );
+        if( paerror == paNoError )
+        {
+            deviceInfo->defaultSampleRate = sampleRate;
+            break;
+        }
+    }
+}
+
+
+static PaError InitializeInputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeHostApi,
+        PaWinMmeDeviceInfo *winMmeDeviceInfo, UINT winMmeInputDeviceId, int *success )
+{
+    PaError result = paNoError;
+    char *deviceName; /* non-const ptr */
+    MMRESULT mmresult;
+    WAVEINCAPS wic;
+    PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo;
+    
+    *success = 0;
+
+    mmresult = waveInGetDevCaps( winMmeInputDeviceId, &wic, sizeof( WAVEINCAPS ) );
+    if( mmresult == MMSYSERR_NOMEM )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+    else if( mmresult != MMSYSERR_NOERROR )
+    {
+        /* instead of returning paUnanticipatedHostError we return
+            paNoError, but leave success set as 0. This allows
+            Pa_Initialize to just ignore this device, without failing
+            the entire initialisation process.
+        */
+        return paNoError;
+    }           
+
+    if( winMmeInputDeviceId == WAVE_MAPPER )
+    {
+        /* Append I/O suffix to WAVE_MAPPER device. */
+        deviceName = (char *)PaUtil_GroupAllocateMemory(
+                    winMmeHostApi->allocations, strlen( wic.szPname ) + 1 + sizeof(constInputMapperSuffix_) );
+        if( !deviceName )
+        {
+            result = paInsufficientMemory;
+            goto error;
+        }
+        strcpy( deviceName, wic.szPname );
+        strcat( deviceName, constInputMapperSuffix_ );
+    }
+    else
+    {
+        deviceName = (char*)PaUtil_GroupAllocateMemory(
+                    winMmeHostApi->allocations, strlen( wic.szPname ) + 1 );
+        if( !deviceName )
+        {
+            result = paInsufficientMemory;
+            goto error;
+        }
+        strcpy( deviceName, wic.szPname  );
+    }
+    deviceInfo->name = deviceName;
+
+    deviceInfo->maxInputChannels = wic.wChannels;
+    /* Sometimes a device can return a rediculously large number of channels.
+     * This happened with an SBLive card on a Windows ME box.
+     * If that happens, then force it to 2 channels.  PLB20010413
+     */
+    if( (deviceInfo->maxInputChannels < 1) || (deviceInfo->maxInputChannels > 256) )
+    {
+        PA_DEBUG(("Pa_GetDeviceInfo: Num input channels reported as %d! Changed to 2.\n", deviceInfo->maxInputChannels ));
+        deviceInfo->maxInputChannels = 2;
+    }
+
+    winMmeDeviceInfo->dwFormats = wic.dwFormats;
+
+    DetectDefaultSampleRate( winMmeDeviceInfo, winMmeInputDeviceId,
+            QueryInputWaveFormatEx, deviceInfo->maxInputChannels );
+
+    *success = 1;
+    
+error:
+    return result;
+}
+
+
+static PaError InitializeOutputDeviceInfo( PaWinMmeHostApiRepresentation *winMmeHostApi,
+        PaWinMmeDeviceInfo *winMmeDeviceInfo, UINT winMmeOutputDeviceId, int *success )
+{
+    PaError result = paNoError;
+    char *deviceName; /* non-const ptr */
+    MMRESULT mmresult;
+    WAVEOUTCAPS woc;
+    PaDeviceInfo *deviceInfo = &winMmeDeviceInfo->inheritedDeviceInfo;
+    
+    *success = 0;
+
+    mmresult = waveOutGetDevCaps( winMmeOutputDeviceId, &woc, sizeof( WAVEOUTCAPS ) );
+    if( mmresult == MMSYSERR_NOMEM )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+    else if( mmresult != MMSYSERR_NOERROR )
+    {
+        /* instead of returning paUnanticipatedHostError we return
+            paNoError, but leave success set as 0. This allows
+            Pa_Initialize to just ignore this device, without failing
+            the entire initialisation process.
+        */
+        return paNoError;
+    }
+
+    if( winMmeOutputDeviceId == WAVE_MAPPER )
+    {
+        /* Append I/O suffix to WAVE_MAPPER device. */
+        deviceName = (char *)PaUtil_GroupAllocateMemory(
+                    winMmeHostApi->allocations, strlen( woc.szPname ) + 1 + sizeof(constOutputMapperSuffix_) );
+        if( !deviceName )
+        {
+            result = paInsufficientMemory;
+            goto error;
+        }
+        strcpy( deviceName, woc.szPname );
+        strcat( deviceName, constOutputMapperSuffix_ );
+    }
+    else
+    {
+        deviceName = (char*)PaUtil_GroupAllocateMemory(
+                    winMmeHostApi->allocations, strlen( woc.szPname ) + 1 );
+        if( !deviceName )
+        {
+            result = paInsufficientMemory;
+            goto error;
+        }
+        strcpy( deviceName, woc.szPname  );
+    }
+    deviceInfo->name = deviceName;
+
+    deviceInfo->maxOutputChannels = woc.wChannels;
+    /* Sometimes a device can return a rediculously large number of channels.
+     * This happened with an SBLive card on a Windows ME box.
+     * It also happens on Win XP!
+     */
+    if( (deviceInfo->maxOutputChannels < 1) || (deviceInfo->maxOutputChannels > 256) )
+    {
+        PA_DEBUG(("Pa_GetDeviceInfo: Num output channels reported as %d! Changed to 2.\n", deviceInfo->maxOutputChannels ));
+        deviceInfo->maxOutputChannels = 2;
+    }
+
+    winMmeDeviceInfo->dwFormats = woc.dwFormats;
+
+    DetectDefaultSampleRate( winMmeDeviceInfo, winMmeOutputDeviceId,
+            QueryOutputWaveFormatEx, deviceInfo->maxOutputChannels );
+
+    *success = 1;
+    
+error:
+    return result;
+}
+
+
+static void GetDefaultLatencies( PaTime *defaultLowLatency, PaTime *defaultHighLatency )
+{
+    OSVERSIONINFO osvi;
+    osvi.dwOSVersionInfoSize = sizeof( osvi );
+       GetVersionEx( &osvi );
+
+    /* Check for NT */
+    if( (osvi.dwMajorVersion == 4) && (osvi.dwPlatformId == 2) )
+    {
+        *defaultLowLatency = PA_MME_WIN_NT_DEFAULT_LATENCY_;
+    }
+    else if(osvi.dwMajorVersion >= 5)
+    {
+        *defaultLowLatency  = PA_MME_WIN_WDM_DEFAULT_LATENCY_;
+    }
+    else
+    {
+        *defaultLowLatency  = PA_MME_WIN_9X_DEFAULT_LATENCY_;
+    }     
+
+    *defaultHighLatency = *defaultLowLatency * 2;
+}
+
+
+PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
+{
+    PaError result = paNoError;
+    int i;
+    PaWinMmeHostApiRepresentation *winMmeHostApi;
+    int inputDeviceCount, outputDeviceCount, maximumPossibleDeviceCount;
+    PaWinMmeDeviceInfo *deviceInfoArray;
+    int deviceInfoInitializationSucceeded;
+    PaTime defaultLowLatency, defaultHighLatency;
+
+    winMmeHostApi = (PaWinMmeHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaWinMmeHostApiRepresentation) );
+    if( !winMmeHostApi )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+
+    winMmeHostApi->allocations = PaUtil_CreateAllocationGroup();
+    if( !winMmeHostApi->allocations )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+
+    *hostApi = &winMmeHostApi->inheritedHostApiRep;
+    (*hostApi)->info.structVersion = 1;
+    (*hostApi)->info.type = paMME;
+    (*hostApi)->info.name = "MME";
+
+    
+    /* initialise device counts and default devices under the assumption that
+        there are no devices. These values are incremented below if and when
+        devices are successfully initialized.
+    */
+    (*hostApi)->info.deviceCount = 0;
+    (*hostApi)->info.defaultInputDevice = paNoDevice;
+    (*hostApi)->info.defaultOutputDevice = paNoDevice;
+    winMmeHostApi->inputDeviceCount = 0;
+    winMmeHostApi->outputDeviceCount = 0;
+
+
+    maximumPossibleDeviceCount = 0;
+
+    inputDeviceCount = waveInGetNumDevs();
+    if( inputDeviceCount > 0 )
+       maximumPossibleDeviceCount += inputDeviceCount + 1;     /* assume there is a WAVE_MAPPER */
+
+    outputDeviceCount = waveOutGetNumDevs();
+    if( outputDeviceCount > 0 )
+           maximumPossibleDeviceCount += outputDeviceCount + 1;        /* assume there is a WAVE_MAPPER */
+
+
+    if( maximumPossibleDeviceCount > 0 ){
+
+        (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory(
+                winMmeHostApi->allocations, sizeof(PaDeviceInfo*) * maximumPossibleDeviceCount );
+        if( !(*hostApi)->deviceInfos )
+        {
+            result = paInsufficientMemory;
+            goto error;
+        }
+
+        /* allocate all device info structs in a contiguous block */
+        deviceInfoArray = (PaWinMmeDeviceInfo*)PaUtil_GroupAllocateMemory(
+                winMmeHostApi->allocations, sizeof(PaWinMmeDeviceInfo) * maximumPossibleDeviceCount );
+        if( !deviceInfoArray )
+        {
+            result = paInsufficientMemory;
+            goto error;
+        }
+
+        winMmeHostApi->winMmeDeviceIds = (UINT*)PaUtil_GroupAllocateMemory(
+                winMmeHostApi->allocations, sizeof(int) * maximumPossibleDeviceCount );
+        if( !winMmeHostApi->winMmeDeviceIds )
+        {
+            result = paInsufficientMemory;
+            goto error;
+        }
+
+        GetDefaultLatencies( &defaultLowLatency, &defaultHighLatency );
+
+        if( inputDeviceCount > 0 ){
+            /* -1 is the WAVE_MAPPER */
+            for( i = -1; i < inputDeviceCount; ++i ){
+                UINT winMmeDeviceId = (UINT)((i==-1) ? WAVE_MAPPER : i);
+                PaWinMmeDeviceInfo *wmmeDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ];
+                PaDeviceInfo *deviceInfo = &wmmeDeviceInfo->inheritedDeviceInfo;
+                deviceInfo->structVersion = 2;
+                deviceInfo->hostApi = hostApiIndex;
+
+                deviceInfo->maxInputChannels = 0;
+                deviceInfo->maxOutputChannels = 0;
+
+                deviceInfo->defaultLowInputLatency = defaultLowLatency;
+                deviceInfo->defaultLowOutputLatency = defaultLowLatency;
+                deviceInfo->defaultHighInputLatency = defaultHighLatency;
+                deviceInfo->defaultHighOutputLatency = defaultHighLatency;
+
+                result = InitializeInputDeviceInfo( winMmeHostApi, wmmeDeviceInfo,
+                        winMmeDeviceId, &deviceInfoInitializationSucceeded );
+                if( result != paNoError )
+                    goto error;
+
+                if( deviceInfoInitializationSucceeded ){
+                    if( (*hostApi)->info.defaultInputDevice == paNoDevice )
+                        (*hostApi)->info.defaultInputDevice = (*hostApi)->info.deviceCount;
+
+                    winMmeHostApi->winMmeDeviceIds[ (*hostApi)->info.deviceCount ] = winMmeDeviceId;
+                    (*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo;
+
+                    winMmeHostApi->inputDeviceCount++;
+                    (*hostApi)->info.deviceCount++;
+                }
+            }
+        }
+
+        if( outputDeviceCount > 0 ){
+            /* -1 is the WAVE_MAPPER */
+            for( i = -1; i < outputDeviceCount; ++i ){
+                UINT winMmeDeviceId = (UINT)((i==-1) ? WAVE_MAPPER : i);
+                PaWinMmeDeviceInfo *wmmeDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ];
+                PaDeviceInfo *deviceInfo = &wmmeDeviceInfo->inheritedDeviceInfo;
+                deviceInfo->structVersion = 2;
+                deviceInfo->hostApi = hostApiIndex;
+
+                deviceInfo->maxInputChannels = 0;
+                deviceInfo->maxOutputChannels = 0;
+
+                deviceInfo->defaultLowInputLatency = defaultLowLatency;
+                deviceInfo->defaultLowOutputLatency = defaultLowLatency;
+                deviceInfo->defaultHighInputLatency = defaultHighLatency;
+                deviceInfo->defaultHighOutputLatency = defaultHighLatency; 
+
+                result = InitializeOutputDeviceInfo( winMmeHostApi, wmmeDeviceInfo,
+                        winMmeDeviceId, &deviceInfoInitializationSucceeded );
+                if( result != paNoError )
+                    goto error;
+
+                if( deviceInfoInitializationSucceeded ){
+                    if( (*hostApi)->info.defaultOutputDevice == paNoDevice )
+                        (*hostApi)->info.defaultOutputDevice = (*hostApi)->info.deviceCount;
+
+                    winMmeHostApi->winMmeDeviceIds[ (*hostApi)->info.deviceCount ] = winMmeDeviceId;
+                    (*hostApi)->deviceInfos[ (*hostApi)->info.deviceCount ] = deviceInfo;
+
+                    winMmeHostApi->outputDeviceCount++;
+                    (*hostApi)->info.deviceCount++;
+                }
+            }
+        }
+    }
+    
+
+    InitializeDefaultDeviceIdsFromEnv( winMmeHostApi );
+
+    (*hostApi)->Terminate = Terminate;
+    (*hostApi)->OpenStream = OpenStream;
+    (*hostApi)->IsFormatSupported = IsFormatSupported;
+
+    PaUtil_InitializeStreamInterface( &winMmeHostApi->callbackStreamInterface, CloseStream, StartStream,
+                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
+                                      GetStreamTime, GetStreamCpuLoad,
+                                      PaUtil_DummyRead, PaUtil_DummyWrite,
+                                      PaUtil_DummyGetReadAvailable, PaUtil_DummyGetWriteAvailable );
+
+    PaUtil_InitializeStreamInterface( &winMmeHostApi->blockingStreamInterface, CloseStream, StartStream,
+                                      StopStream, AbortStream, IsStreamStopped, IsStreamActive,
+                                      GetStreamTime, PaUtil_DummyGetCpuLoad,
+                                      ReadStream, WriteStream, GetStreamReadAvailable, GetStreamWriteAvailable );
+
+    return result;
+
+error:
+    if( winMmeHostApi )
+    {
+        if( winMmeHostApi->allocations )
+        {
+            PaUtil_FreeAllAllocations( winMmeHostApi->allocations );
+            PaUtil_DestroyAllocationGroup( winMmeHostApi->allocations );
+        }
+        
+        PaUtil_FreeMemory( winMmeHostApi );
+    }
+
+    return result;
+}
+
+
+static void Terminate( struct PaUtilHostApiRepresentation *hostApi )
+{
+    PaWinMmeHostApiRepresentation *winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi;
+
+    if( winMmeHostApi->allocations )
+    {
+        PaUtil_FreeAllAllocations( winMmeHostApi->allocations );
+        PaUtil_DestroyAllocationGroup( winMmeHostApi->allocations );
+    }
+
+    PaUtil_FreeMemory( winMmeHostApi );
+}
+
+
+static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
+                                  const PaStreamParameters *inputParameters,
+                                  const PaStreamParameters *outputParameters,
+                                  double sampleRate )
+{
+    PaWinMmeHostApiRepresentation *winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi;
+    PaDeviceInfo *inputDeviceInfo, *outputDeviceInfo;
+    int inputChannelCount, outputChannelCount;
+    int inputMultipleDeviceChannelCount, outputMultipleDeviceChannelCount;
+    PaSampleFormat inputSampleFormat, outputSampleFormat;
+    PaWinMmeStreamInfo *inputStreamInfo, *outputStreamInfo;
+    UINT winMmeInputDeviceId, winMmeOutputDeviceId;
+    unsigned int i;
+    PaError paerror;
+
+    /* The calls to QueryFormatSupported below are intended to detect invalid
+        sample rates. If we assume that the channel count and format are OK,
+        then the only thing that could fail is the sample rate. This isn't
+        strictly true, but I can't think of a better way to test that the
+        sample rate is valid.
+    */  
+    
+    if( inputParameters )
+    {
+        inputChannelCount = inputParameters->channelCount;
+        inputSampleFormat = inputParameters->sampleFormat;
+        inputStreamInfo = inputParameters->hostApiSpecificStreamInfo;
+        
+        /* all standard sample formats are supported by the buffer adapter,
+             this implementation doesn't support any custom sample formats */
+        if( inputSampleFormat & paCustomFormat )
+            return paSampleFormatNotSupported;
+
+        if( inputParameters->device == paUseHostApiSpecificDeviceSpecification
+                && inputStreamInfo && (inputStreamInfo->flags & paWinMmeUseMultipleDevices) )
+        {
+            inputMultipleDeviceChannelCount = 0;
+            for( i=0; i< inputStreamInfo->deviceCount; ++i )
+            {
+                inputMultipleDeviceChannelCount += inputStreamInfo->devices[i].channelCount;
+                    
+                inputDeviceInfo = hostApi->deviceInfos[ inputStreamInfo->devices[i].device ];
+
+                /* check that input device can support inputChannelCount */
+                if( inputStreamInfo->devices[i].channelCount <= 0
+                        || inputStreamInfo->devices[i].channelCount > inputDeviceInfo->maxInputChannels )
+                    return paInvalidChannelCount;
+
+                /* test for valid sample rate, see comment above */
+                winMmeInputDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, inputStreamInfo->devices[i].device );
+                paerror = QueryFormatSupported( inputDeviceInfo, QueryInputWaveFormatEx, winMmeInputDeviceId, inputStreamInfo->devices[i].channelCount, sampleRate );
+                if( paerror != paNoError )
+                    return paInvalidSampleRate;
+            }
+                
+            if( inputMultipleDeviceChannelCount != inputChannelCount )
+                return paIncompatibleHostApiSpecificStreamInfo;                  
+        }
+        else
+        {
+            if( inputStreamInfo && (inputStreamInfo->flags & paWinMmeUseMultipleDevices) )
+                return paIncompatibleHostApiSpecificStreamInfo; /* paUseHostApiSpecificDeviceSpecification was not supplied as the input device */
+
+            inputDeviceInfo = hostApi->deviceInfos[ inputParameters->device ];
+
+            /* check that input device can support inputChannelCount */
+            if( inputChannelCount > inputDeviceInfo->maxInputChannels )
+                return paInvalidChannelCount;
+
+            /* test for valid sample rate, see comment above */
+            winMmeInputDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, inputParameters->device );
+            paerror = QueryFormatSupported( inputDeviceInfo, QueryInputWaveFormatEx, winMmeInputDeviceId, inputChannelCount, sampleRate );
+            if( paerror != paNoError )
+                return paInvalidSampleRate;
+        }
+    }
+
+    if( outputParameters )
+    {
+        outputChannelCount = outputParameters->channelCount;
+        outputSampleFormat = outputParameters->sampleFormat;
+        outputStreamInfo = outputParameters->hostApiSpecificStreamInfo;
+
+        /* all standard sample formats are supported by the buffer adapter,
+            this implementation doesn't support any custom sample formats */
+        if( outputSampleFormat & paCustomFormat )
+            return paSampleFormatNotSupported;
+
+        if( outputParameters->device == paUseHostApiSpecificDeviceSpecification
+                && outputStreamInfo && (outputStreamInfo->flags & paWinMmeUseMultipleDevices) )
+        {
+            outputMultipleDeviceChannelCount = 0;
+            for( i=0; i< outputStreamInfo->deviceCount; ++i )
+            {
+                outputMultipleDeviceChannelCount += outputStreamInfo->devices[i].channelCount;
+                    
+                outputDeviceInfo = hostApi->deviceInfos[ outputStreamInfo->devices[i].device ];
+
+                /* check that output device can support outputChannelCount */
+                if( outputStreamInfo->devices[i].channelCount <= 0
+                        || outputStreamInfo->devices[i].channelCount > outputDeviceInfo->maxOutputChannels )
+                    return paInvalidChannelCount;
+
+                /* test for valid sample rate, see comment above */
+                winMmeOutputDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, outputStreamInfo->devices[i].device );
+                paerror = QueryFormatSupported( outputDeviceInfo, QueryOutputWaveFormatEx, winMmeOutputDeviceId, outputStreamInfo->devices[i].channelCount, sampleRate );
+                if( paerror != paNoError )
+                    return paInvalidSampleRate;
+            }
+                
+            if( outputMultipleDeviceChannelCount != outputChannelCount )
+                return paIncompatibleHostApiSpecificStreamInfo;            
+        }
+        else
+        {
+            if( outputStreamInfo && (outputStreamInfo->flags & paWinMmeUseMultipleDevices) )
+                return paIncompatibleHostApiSpecificStreamInfo; /* paUseHostApiSpecificDeviceSpecification was not supplied as the output device */
+
+            outputDeviceInfo = hostApi->deviceInfos[ outputParameters->device ];
+
+            /* check that output device can support outputChannelCount */
+            if( outputChannelCount > outputDeviceInfo->maxOutputChannels )
+                return paInvalidChannelCount;
+
+            /* test for valid sample rate, see comment above */
+            winMmeOutputDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, outputParameters->device );
+            paerror = QueryFormatSupported( outputDeviceInfo, QueryOutputWaveFormatEx, winMmeOutputDeviceId, outputChannelCount, sampleRate );
+            if( paerror != paNoError )
+                return paInvalidSampleRate;
+        }
+    }
+    
+    /*
+            - if a full duplex stream is requested, check that the combination
+                of input and output parameters is supported
+
+            - check that the device supports sampleRate
+
+            for mme all we can do is test that the input and output devices
+            support the requested sample rate and number of channels. we
+            cannot test for full duplex compatibility.
+    */                                             
+
+    return paFormatIsSupported;
+}
+
+
+
+static void SelectBufferSizeAndCount( unsigned long baseBufferSize,
+    unsigned long requestedLatency,
+    unsigned long baseBufferCount, unsigned long minimumBufferCount,
+    unsigned long maximumBufferSize, unsigned long *hostBufferSize,
+    unsigned long *hostBufferCount )
+{
+    unsigned long sizeMultiplier, bufferCount, latency;
+    unsigned long nextLatency, nextBufferSize;
+    int baseBufferSizeIsPowerOfTwo;
+    
+    sizeMultiplier = 1;
+    bufferCount = baseBufferCount;
+
+    /* count-1 below because latency is always determined by one less
+        than the total number of buffers.
+    */
+    latency = (baseBufferSize * sizeMultiplier) * (bufferCount-1);
+
+    if( latency > requestedLatency )
+    {
+
+        /* reduce number of buffers without falling below suggested latency */
+
+        nextLatency = (baseBufferSize * sizeMultiplier) * (bufferCount-2);
+        while( bufferCount > minimumBufferCount && nextLatency >= requestedLatency )
+        {
+            --bufferCount;
+            nextLatency = (baseBufferSize * sizeMultiplier) * (bufferCount-2);
+        }
+
+    }else if( latency < requestedLatency ){
+
+        baseBufferSizeIsPowerOfTwo = (! (baseBufferSize & (baseBufferSize - 1)));
+        if( baseBufferSizeIsPowerOfTwo ){
+
+            /* double size of buffers without exceeding requestedLatency */
+
+            nextBufferSize = (baseBufferSize * (sizeMultiplier*2));
+            nextLatency = nextBufferSize * (bufferCount-1);
+            while( nextBufferSize <= maximumBufferSize
+                    && nextLatency < requestedLatency )
+            {
+                sizeMultiplier *= 2;
+                nextBufferSize = (baseBufferSize * (sizeMultiplier*2));
+                nextLatency = nextBufferSize * (bufferCount-1);
+            }   
+
+        }else{
+
+            /* increase size of buffers upto first excess of requestedLatency */
+
+            nextBufferSize = (baseBufferSize * (sizeMultiplier+1));
+            nextLatency = nextBufferSize * (bufferCount-1);
+            while( nextBufferSize <= maximumBufferSize
+                    && nextLatency < requestedLatency )
+            {
+                ++sizeMultiplier;
+                nextBufferSize = (baseBufferSize * (sizeMultiplier+1));
+                nextLatency = nextBufferSize * (bufferCount-1);
+            }
+
+            if( nextLatency < requestedLatency )
+                ++sizeMultiplier;            
+        }
+
+        /* increase number of buffers until requestedLatency is reached */
+
+        latency = (baseBufferSize * sizeMultiplier) * (bufferCount-1);
+        while( latency < requestedLatency )
+        {
+            ++bufferCount;
+            latency = (baseBufferSize * sizeMultiplier) * (bufferCount-1);
+        }
+    }
+
+    *hostBufferSize = baseBufferSize * sizeMultiplier;
+    *hostBufferCount = bufferCount;
+}
+
+
+static void ReselectBufferCount( unsigned long bufferSize,
+    unsigned long requestedLatency,
+    unsigned long baseBufferCount, unsigned long minimumBufferCount,
+    unsigned long *hostBufferCount )
+{
+    unsigned long bufferCount, latency;
+    unsigned long nextLatency;
+
+    bufferCount = baseBufferCount;
+
+    /* count-1 below because latency is always determined by one less
+        than the total number of buffers.
+    */
+    latency = bufferSize * (bufferCount-1);
+
+    if( latency > requestedLatency )
+    {
+        /* reduce number of buffers without falling below suggested latency */
+
+        nextLatency = bufferSize * (bufferCount-2);
+        while( bufferCount > minimumBufferCount && nextLatency >= requestedLatency )
+        {
+            --bufferCount;
+            nextLatency = bufferSize * (bufferCount-2);
+        }
+
+    }else if( latency < requestedLatency ){
+
+        /* increase number of buffers until requestedLatency is reached */
+
+        latency = bufferSize * (bufferCount-1);
+        while( latency < requestedLatency )
+        {
+            ++bufferCount;
+            latency = bufferSize * (bufferCount-1);
+        }                                                         
+    }
+
+    *hostBufferCount = bufferCount;
+}
+
+
+/* CalculateBufferSettings() fills the framesPerHostInputBuffer, hostInputBufferCount,
+   framesPerHostOutputBuffer and hostOutputBufferCount parameters based on the values
+   of the other parameters.
+*/
+
+static PaError CalculateBufferSettings(
+        unsigned long *framesPerHostInputBuffer, unsigned long *hostInputBufferCount,
+        unsigned long *framesPerHostOutputBuffer, unsigned long *hostOutputBufferCount,
+        int inputChannelCount, PaSampleFormat hostInputSampleFormat,
+        PaTime suggestedInputLatency, PaWinMmeStreamInfo *inputStreamInfo,
+        int outputChannelCount, PaSampleFormat hostOutputSampleFormat,
+        PaTime suggestedOutputLatency, PaWinMmeStreamInfo *outputStreamInfo,
+        double sampleRate, unsigned long framesPerBuffer )
+{
+    PaError result = paNoError;
+    int effectiveInputChannelCount, effectiveOutputChannelCount;
+    int hostInputFrameSize = 0;
+    unsigned int i;
+    
+    if( inputChannelCount > 0 )
+    {
+        int hostInputSampleSize = Pa_GetSampleSize( hostInputSampleFormat );
+        if( hostInputSampleSize < 0 )
+        {
+            result = hostInputSampleSize;
+            goto error;
+        }
+
+        if( inputStreamInfo
+                && ( inputStreamInfo->flags & paWinMmeUseMultipleDevices ) )
+        {
+            /* set effectiveInputChannelCount to the largest number of
+                channels on any one device.
+            */
+            effectiveInputChannelCount = 0;
+            for( i=0; i< inputStreamInfo->deviceCount; ++i )
+            {
+                if( inputStreamInfo->devices[i].channelCount > effectiveInputChannelCount )
+                    effectiveInputChannelCount = inputStreamInfo->devices[i].channelCount;
+            }
+        }
+        else
+        {
+            effectiveInputChannelCount = inputChannelCount;
+        }
+
+        hostInputFrameSize = hostInputSampleSize * effectiveInputChannelCount;
+
+        if( inputStreamInfo
+                && ( inputStreamInfo->flags & paWinMmeUseLowLevelLatencyParameters ) )
+        {
+            if( inputStreamInfo->bufferCount <= 0
+                    || inputStreamInfo->framesPerBuffer <= 0 )
+            {
+                result = paIncompatibleHostApiSpecificStreamInfo;
+                goto error;
+            }
+
+            *framesPerHostInputBuffer = inputStreamInfo->framesPerBuffer;
+            *hostInputBufferCount = inputStreamInfo->bufferCount;
+        }
+        else
+        {
+            unsigned long hostBufferSizeBytes, hostBufferCount;
+            unsigned long minimumBufferCount = (outputChannelCount > 0)
+                    ? PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_
+                    : PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_HALF_DUPLEX_;
+
+            unsigned long maximumBufferSize = (long) ((PA_MME_MAX_HOST_BUFFER_SECS_ * sampleRate) * hostInputFrameSize);
+            if( maximumBufferSize > PA_MME_MAX_HOST_BUFFER_BYTES_ )
+                maximumBufferSize = PA_MME_MAX_HOST_BUFFER_BYTES_;
+
+            /* compute the following in bytes, then convert back to frames */
+
+            SelectBufferSizeAndCount(
+                ((framesPerBuffer == paFramesPerBufferUnspecified)
+                    ? PA_MME_MIN_HOST_BUFFER_FRAMES_WHEN_UNSPECIFIED_
+                    : framesPerBuffer ) * hostInputFrameSize, /* baseBufferSize */
+                ((unsigned long)(suggestedInputLatency * sampleRate)) * hostInputFrameSize, /* suggestedLatency */
+                4, /* baseBufferCount */
+                minimumBufferCount, maximumBufferSize,
+                &hostBufferSizeBytes, &hostBufferCount );
+
+            *framesPerHostInputBuffer = hostBufferSizeBytes / hostInputFrameSize;
+            *hostInputBufferCount = hostBufferCount;
+        }
+    }
+    else
+    {
+        *framesPerHostInputBuffer = 0;
+        *hostInputBufferCount = 0;
+    }
+
+    if( outputChannelCount > 0 )
+    {
+        if( outputStreamInfo
+                && ( outputStreamInfo->flags & paWinMmeUseLowLevelLatencyParameters ) )
+        {
+            if( outputStreamInfo->bufferCount <= 0
+                    || outputStreamInfo->framesPerBuffer <= 0 )
+            {
+                result = paIncompatibleHostApiSpecificStreamInfo;
+                goto error;
+            }
+
+            *framesPerHostOutputBuffer = outputStreamInfo->framesPerBuffer;
+            *hostOutputBufferCount = outputStreamInfo->bufferCount;
+
+            
+            if( inputChannelCount > 0 ) /* full duplex */
+            {
+                if( *framesPerHostInputBuffer != *framesPerHostOutputBuffer )
+                {
+                    if( inputStreamInfo
+                            && ( inputStreamInfo->flags & paWinMmeUseLowLevelLatencyParameters ) )
+                    { 
+                        /* a custom StreamInfo was used for specifying both input
+                            and output buffer sizes, the larger buffer size
+                            must be a multiple of the smaller buffer size */
+
+                        if( *framesPerHostInputBuffer < *framesPerHostOutputBuffer )
+                        {
+                            if( *framesPerHostOutputBuffer % *framesPerHostInputBuffer != 0 )
+                            {
+                                result = paIncompatibleHostApiSpecificStreamInfo;
+                                goto error;
+                            }
+                        }
+                        else
+                        {
+                            assert( *framesPerHostInputBuffer > *framesPerHostOutputBuffer );
+                            if( *framesPerHostInputBuffer % *framesPerHostOutputBuffer != 0 )
+                            {
+                                result = paIncompatibleHostApiSpecificStreamInfo;
+                                goto error;
+                            }
+                        }                        
+                    }
+                    else
+                    {
+                        /* a custom StreamInfo was not used for specifying the input buffer size,
+                            so use the output buffer size, and approximately the same latency. */
+
+                        *framesPerHostInputBuffer = *framesPerHostOutputBuffer;
+                        *hostInputBufferCount = (((unsigned long)(suggestedInputLatency * sampleRate)) / *framesPerHostInputBuffer) + 1;
+
+                        if( *hostInputBufferCount < PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_ )
+                            *hostInputBufferCount = PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_;
+                    }
+                }
+            }
+        }
+        else
+        {
+            unsigned long hostBufferSizeBytes, hostBufferCount;
+            unsigned long minimumBufferCount = PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_;
+            unsigned long maximumBufferSize;
+            int hostOutputFrameSize;
+            int hostOutputSampleSize;
+
+            hostOutputSampleSize = Pa_GetSampleSize( hostOutputSampleFormat );
+            if( hostOutputSampleSize < 0 )
+            {
+                result = hostOutputSampleSize;
+                goto error;
+            }
+
+            if( outputStreamInfo
+                && ( outputStreamInfo->flags & paWinMmeUseMultipleDevices ) )
+            {
+                /* set effectiveOutputChannelCount to the largest number of
+                    channels on any one device.
+                */
+                effectiveOutputChannelCount = 0;
+                for( i=0; i< outputStreamInfo->deviceCount; ++i )
+                {
+                    if( outputStreamInfo->devices[i].channelCount > effectiveOutputChannelCount )
+                        effectiveOutputChannelCount = outputStreamInfo->devices[i].channelCount;
+                }
+            }
+            else
+            {
+                effectiveOutputChannelCount = outputChannelCount;
+            }
+
+            hostOutputFrameSize = hostOutputSampleSize * effectiveOutputChannelCount;
+            
+            maximumBufferSize = (long) ((PA_MME_MAX_HOST_BUFFER_SECS_ * sampleRate) * hostOutputFrameSize);
+            if( maximumBufferSize > PA_MME_MAX_HOST_BUFFER_BYTES_ )
+                maximumBufferSize = PA_MME_MAX_HOST_BUFFER_BYTES_;
+
+
+            /* compute the following in bytes, then convert back to frames */
+
+            SelectBufferSizeAndCount(
+                ((framesPerBuffer == paFramesPerBufferUnspecified)
+                    ? PA_MME_MIN_HOST_BUFFER_FRAMES_WHEN_UNSPECIFIED_
+                    : framesPerBuffer ) * hostOutputFrameSize, /* baseBufferSize */
+                ((unsigned long)(suggestedOutputLatency * sampleRate)) * hostOutputFrameSize, /* suggestedLatency */
+                4, /* baseBufferCount */
+                minimumBufferCount,
+                maximumBufferSize,
+                &hostBufferSizeBytes, &hostBufferCount );
+
+            *framesPerHostOutputBuffer = hostBufferSizeBytes / hostOutputFrameSize;
+            *hostOutputBufferCount = hostBufferCount;
+
+
+            if( inputChannelCount > 0 )
+            {
+                /* ensure that both input and output buffer sizes are the same.
+                    if they don't match at this stage, choose the smallest one
+                    and use that for input and output
+                */
+
+                if( *framesPerHostOutputBuffer != *framesPerHostInputBuffer )
+                {
+                    if( framesPerHostInputBuffer < framesPerHostOutputBuffer )
+                    {
+                        unsigned long framesPerHostBuffer = *framesPerHostInputBuffer;
+                        
+                        minimumBufferCount = PA_MME_MIN_HOST_OUTPUT_BUFFER_COUNT_;
+                        ReselectBufferCount(
+                            framesPerHostBuffer * hostOutputFrameSize, /* bufferSize */
+                            ((unsigned long)(suggestedOutputLatency * sampleRate)) * hostOutputFrameSize, /* suggestedLatency */
+                            4, /* baseBufferCount */
+                            minimumBufferCount,
+                            &hostBufferCount );
+
+                        *framesPerHostOutputBuffer = framesPerHostBuffer;
+                        *hostOutputBufferCount = hostBufferCount;
+                    }
+                    else
+                    {
+                        unsigned long framesPerHostBuffer = *framesPerHostOutputBuffer;
+                        
+                        minimumBufferCount = PA_MME_MIN_HOST_INPUT_BUFFER_COUNT_FULL_DUPLEX_;
+                        ReselectBufferCount(
+                            framesPerHostBuffer * hostInputFrameSize, /* bufferSize */
+                            ((unsigned long)(suggestedInputLatency * sampleRate)) * hostInputFrameSize, /* suggestedLatency */
+                            4, /* baseBufferCount */
+                            minimumBufferCount,
+                            &hostBufferCount );
+
+                        *framesPerHostInputBuffer = framesPerHostBuffer;
+                        *hostInputBufferCount = hostBufferCount;
+                    }
+                }   
+            }
+        }
+    }
+    else
+    {
+        *framesPerHostOutputBuffer = 0;
+        *hostOutputBufferCount = 0;
+    }
+
+error:
+    return result;
+}
+
+
+typedef struct
+{
+    HANDLE bufferEvent;
+    void *waveHandles;
+    unsigned int deviceCount;
+    /* unsigned int channelCount; */
+    WAVEHDR **waveHeaders;                  /* waveHeaders[device][buffer] */
+    unsigned int bufferCount;
+    unsigned int currentBufferIndex;
+    unsigned int framesPerBuffer;
+    unsigned int framesUsedInCurrentBuffer;
+}PaWinMmeSingleDirectionHandlesAndBuffers;
+
+/* prototypes for functions operating on PaWinMmeSingleDirectionHandlesAndBuffers */
+
+static void InitializeSingleDirectionHandlesAndBuffers( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers );
+static PaError InitializeWaveHandles( PaWinMmeHostApiRepresentation *winMmeHostApi,
+        PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers,
+        unsigned long bytesPerHostSample,
+        double sampleRate, PaWinMmeDeviceAndChannelCount *devices,
+        unsigned int deviceCount, int isInput );
+static PaError TerminateWaveHandles( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, int isInput, int currentlyProcessingAnError );
+static PaError InitializeWaveHeaders( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers,
+        unsigned long hostBufferCount,
+        PaSampleFormat hostSampleFormat,
+        unsigned long framesPerHostBuffer,
+        PaWinMmeDeviceAndChannelCount *devices,
+        int isInput );
+static void TerminateWaveHeaders( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, int isInput );
+
+
+static void InitializeSingleDirectionHandlesAndBuffers( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers )
+{
+    handlesAndBuffers->bufferEvent = 0;
+    handlesAndBuffers->waveHandles = 0;
+    handlesAndBuffers->deviceCount = 0;
+    handlesAndBuffers->waveHeaders = 0;
+    handlesAndBuffers->bufferCount = 0;
+}    
+
+static PaError InitializeWaveHandles( PaWinMmeHostApiRepresentation *winMmeHostApi,
+        PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers,
+        unsigned long bytesPerHostSample,
+        double sampleRate, PaWinMmeDeviceAndChannelCount *devices,
+        unsigned int deviceCount, int isInput )
+{
+    PaError result;
+    MMRESULT mmresult;
+    unsigned long bytesPerFrame;
+    WAVEFORMATEX wfx;
+    signed int i;
+
+    /* for error cleanup we expect that InitializeSingleDirectionHandlesAndBuffers()
+        has already been called to zero some fields */       
+
+    result = CreateEventWithPaError( &handlesAndBuffers->bufferEvent, NULL, FALSE, FALSE, NULL );
+    if( result != paNoError ) goto error;
+
+    if( isInput )
+        handlesAndBuffers->waveHandles = (void*)PaUtil_AllocateMemory( sizeof(HWAVEIN) * deviceCount );
+    else
+        handlesAndBuffers->waveHandles = (void*)PaUtil_AllocateMemory( sizeof(HWAVEOUT) * deviceCount );
+    if( !handlesAndBuffers->waveHandles )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+
+    handlesAndBuffers->deviceCount = deviceCount;
+
+    for( i = 0; i < (signed int)deviceCount; ++i )
+    {
+        if( isInput )
+            ((HWAVEIN*)handlesAndBuffers->waveHandles)[i] = 0;
+        else
+            ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i] = 0;
+    }
+
+    wfx.wFormatTag = WAVE_FORMAT_PCM;
+    wfx.nSamplesPerSec = (DWORD) sampleRate;
+    wfx.cbSize = 0;
+    
+    for( i = 0; i < (signed int)deviceCount; ++i )
+    {
+        UINT winMmeDeviceId;
+
+        winMmeDeviceId = LocalDeviceIndexToWinMmeDeviceId( winMmeHostApi, devices[i].device );
+        wfx.nChannels = (WORD)devices[i].channelCount;
+
+        bytesPerFrame = wfx.nChannels * bytesPerHostSample;
+
+        wfx.nAvgBytesPerSec = (DWORD)(bytesPerFrame * sampleRate);
+        wfx.nBlockAlign = (WORD)bytesPerFrame;
+        wfx.wBitsPerSample = (WORD)((bytesPerFrame/wfx.nChannels) * 8);
+
+        /* REVIEW: consider not firing an event for input when a full duplex
+            stream is being used. this would probably depend on the
+            neverDropInput flag. */
+
+        if( isInput )
+            mmresult = waveInOpen( &((HWAVEIN*)handlesAndBuffers->waveHandles)[i], winMmeDeviceId, &wfx,
+                               (DWORD_PTR)handlesAndBuffers->bufferEvent, (DWORD_PTR)0, CALLBACK_EVENT );
+        else
+            mmresult = waveOutOpen( &((HWAVEOUT*)handlesAndBuffers->waveHandles)[i], winMmeDeviceId, &wfx,
+                                (DWORD_PTR)handlesAndBuffers->bufferEvent, (DWORD_PTR)0, CALLBACK_EVENT );
+
+        if( mmresult != MMSYSERR_NOERROR )
+        {
+            switch( mmresult )
+            {
+                case MMSYSERR_ALLOCATED:    /* Specified resource is already allocated. */
+                    result = paDeviceUnavailable;
+                    break;
+                case MMSYSERR_NODRIVER:            /* No device driver is present. */
+                    result = paDeviceUnavailable;
+                    break;
+                case MMSYSERR_NOMEM:       /* Unable to allocate or lock memory. */
+                    result = paInsufficientMemory;
+                    break;
+
+                case MMSYSERR_BADDEVICEID:     /* Specified device identifier is out of range. */
+                    /* falls through */
+                case WAVERR_BADFORMAT:      /* Attempted to open with an unsupported waveform-audio format. */
+                    /* falls through */
+                default:
+                    result = paUnanticipatedHostError;
+                    if( isInput )
+                    {
+                        PA_MME_SET_LAST_WAVEIN_ERROR( mmresult );
+                    }
+                    else
+                    {
+                        PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult );
+                    }
+            }
+            goto error;
+        }
+    }
+
+    return result;
+
+error:
+    TerminateWaveHandles( handlesAndBuffers, isInput, 1 /* currentlyProcessingAnError */ );
+
+    return result;
+}
+
+
+static PaError TerminateWaveHandles( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, int isInput, int currentlyProcessingAnError )
+{
+    PaError result = paNoError;
+    MMRESULT mmresult;
+    signed int i;
+    
+    if( handlesAndBuffers->waveHandles )
+    {
+        for( i = handlesAndBuffers->deviceCount-1; i >= 0; --i )
+        {
+            if( isInput )
+            {
+                if( ((HWAVEIN*)handlesAndBuffers->waveHandles)[i] )
+                    mmresult = waveInClose( ((HWAVEIN*)handlesAndBuffers->waveHandles)[i] );
+                else
+                    mmresult = MMSYSERR_NOERROR;
+            }
+            else
+            {
+                if( ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i] )
+                    mmresult = waveOutClose( ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i] );
+                else
+                    mmresult = MMSYSERR_NOERROR;
+            }
+
+            if( mmresult != MMSYSERR_NOERROR &&
+                !currentlyProcessingAnError ) /* don't update the error state if we're already processing an error */
+            {
+                result = paUnanticipatedHostError;
+                if( isInput )
+                {
+                    PA_MME_SET_LAST_WAVEIN_ERROR( mmresult );
+                }
+                else
+                {
+                    PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult );
+                }
+                /* note that we don't break here, we try to continue closing devices */
+            }
+        }
+
+        PaUtil_FreeMemory( handlesAndBuffers->waveHandles );
+        handlesAndBuffers->waveHandles = 0;
+    }
+
+    if( handlesAndBuffers->bufferEvent )
+    {
+        result = CloseHandleWithPaError( handlesAndBuffers->bufferEvent );
+        handlesAndBuffers->bufferEvent = 0;
+    }
+    
+    return result;
+}
+
+
+static PaError InitializeWaveHeaders( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers,
+        unsigned long hostBufferCount,
+        PaSampleFormat hostSampleFormat,
+        unsigned long framesPerHostBuffer,
+        PaWinMmeDeviceAndChannelCount *devices,
+        int isInput )
+{
+    PaError result = paNoError;
+    MMRESULT mmresult;
+    WAVEHDR *deviceWaveHeaders;
+    signed int i, j;
+
+    /* for error cleanup we expect that InitializeSingleDirectionHandlesAndBuffers()
+        has already been called to zero some fields */
+        
+
+    /* allocate an array of pointers to arrays of wave headers, one array of
+        wave headers per device */
+    handlesAndBuffers->waveHeaders = (WAVEHDR**)PaUtil_AllocateMemory( sizeof(WAVEHDR*) * handlesAndBuffers->deviceCount );
+    if( !handlesAndBuffers->waveHeaders )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+    
+    for( i = 0; i < (signed int)handlesAndBuffers->deviceCount; ++i )
+        handlesAndBuffers->waveHeaders[i] = 0;
+
+    handlesAndBuffers->bufferCount = hostBufferCount;
+
+    for( i = 0; i < (signed int)handlesAndBuffers->deviceCount; ++i )
+    {
+        int bufferBytes = Pa_GetSampleSize( hostSampleFormat ) *
+                framesPerHostBuffer * devices[i].channelCount;
+        if( bufferBytes < 0 )
+        {
+            result = paInternalError;
+            goto error;
+        }
+
+        /* Allocate an array of wave headers for device i */
+        deviceWaveHeaders = (WAVEHDR *) PaUtil_AllocateMemory( sizeof(WAVEHDR)*hostBufferCount );
+        if( !deviceWaveHeaders )
+        {
+            result = paInsufficientMemory;
+            goto error;
+        }
+
+        for( j=0; j < (signed int)hostBufferCount; ++j )
+            deviceWaveHeaders[j].lpData = 0;
+
+        handlesAndBuffers->waveHeaders[i] = deviceWaveHeaders;
+
+        /* Allocate a buffer for each wave header */
+        for( j=0; j < (signed int)hostBufferCount; ++j )
+        {
+            deviceWaveHeaders[j].lpData = (char *)PaUtil_AllocateMemory( bufferBytes );
+            if( !deviceWaveHeaders[j].lpData )
+            {
+                result = paInsufficientMemory;
+                goto error;
+            }
+            deviceWaveHeaders[j].dwBufferLength = bufferBytes;
+            deviceWaveHeaders[j].dwUser = 0xFFFFFFFF; /* indicates that *PrepareHeader() has not yet been called, for error clean up code */
+
+            if( isInput )
+            {
+                mmresult = waveInPrepareHeader( ((HWAVEIN*)handlesAndBuffers->waveHandles)[i], &deviceWaveHeaders[j], sizeof(WAVEHDR) );
+                if( mmresult != MMSYSERR_NOERROR )
+                {
+                    result = paUnanticipatedHostError;
+                    PA_MME_SET_LAST_WAVEIN_ERROR( mmresult );
+                    goto error;
+                }
+            }
+            else /* output */
+            {
+                mmresult = waveOutPrepareHeader( ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i], &deviceWaveHeaders[j], sizeof(WAVEHDR) );
+                if( mmresult != MMSYSERR_NOERROR )
+                {
+                    result = paUnanticipatedHostError;
+                    PA_MME_SET_LAST_WAVEIN_ERROR( mmresult );
+                    goto error;
+                }
+            }
+            deviceWaveHeaders[j].dwUser = devices[i].channelCount;
+        }
+    }
+
+    return result;
+
+error:
+    TerminateWaveHeaders( handlesAndBuffers, isInput );
+    
+    return result;
+}
+
+
+static void TerminateWaveHeaders( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers, int isInput )
+{
+    signed int i, j;
+    WAVEHDR *deviceWaveHeaders;
+    
+    if( handlesAndBuffers->waveHeaders )
+    {
+        for( i = handlesAndBuffers->deviceCount-1; i >= 0 ; --i )
+        {
+            deviceWaveHeaders = handlesAndBuffers->waveHeaders[i];  /* wave headers for device i */
+            if( deviceWaveHeaders )
+            {
+                for( j = handlesAndBuffers->bufferCount-1; j >= 0; --j )
+                {
+                    if( deviceWaveHeaders[j].lpData )
+                    {
+                        if( deviceWaveHeaders[j].dwUser != 0xFFFFFFFF )
+                        {
+                            if( isInput )
+                                waveInUnprepareHeader( ((HWAVEIN*)handlesAndBuffers->waveHandles)[i], &deviceWaveHeaders[j], sizeof(WAVEHDR) );
+                            else
+                                waveOutUnprepareHeader( ((HWAVEOUT*)handlesAndBuffers->waveHandles)[i], &deviceWaveHeaders[j], sizeof(WAVEHDR) );
+                        }
+
+                        PaUtil_FreeMemory( deviceWaveHeaders[j].lpData );
+                    }
+                }
+
+                PaUtil_FreeMemory( deviceWaveHeaders );
+            }
+        }
+
+        PaUtil_FreeMemory( handlesAndBuffers->waveHeaders );
+        handlesAndBuffers->waveHeaders = 0;
+    }
+}
+
+
+
+/* PaWinMmeStream - a stream data structure specifically for this implementation */
+/* note that struct PaWinMmeStream is typedeffed to PaWinMmeStream above. */
+struct PaWinMmeStream
+{
+    PaUtilStreamRepresentation streamRepresentation;
+    PaUtilCpuLoadMeasurer cpuLoadMeasurer;
+    PaUtilBufferProcessor bufferProcessor;
+
+    int primeStreamUsingCallback;
+
+    PaWinMmeSingleDirectionHandlesAndBuffers input;
+    PaWinMmeSingleDirectionHandlesAndBuffers output;
+
+    /* Processing thread management -------------- */
+    HANDLE abortEvent;
+    HANDLE processingThread;
+    DWORD processingThreadId;
+
+    char throttleProcessingThreadOnOverload; /* 0 -> don't throtte, non-0 -> throttle */
+    int processingThreadPriority;
+    int highThreadPriority;
+    int throttledThreadPriority;
+    unsigned long throttledSleepMsecs;
+
+    int isStopped;
+    volatile int isActive;
+    volatile int stopProcessing; /* stop thread once existing buffers have been returned */
+    volatile int abortProcessing; /* stop thread immediately */
+
+    DWORD allBuffersDurationMs; /* used to calculate timeouts */
+};
+
+/* updates deviceCount if PaWinMmeUseMultipleDevices is used */
+
+static PaError ValidateWinMmeSpecificStreamInfo(
+        const PaStreamParameters *streamParameters,
+        const PaWinMmeStreamInfo *streamInfo,
+        char *throttleProcessingThreadOnOverload,
+        unsigned long *deviceCount )
+{
+       if( streamInfo )
+       {
+           if( streamInfo->size != sizeof( PaWinMmeStreamInfo )
+                   || streamInfo->version != 1 )
+           {
+               return paIncompatibleHostApiSpecificStreamInfo;
+           }
+
+           if( streamInfo->flags & paWinMmeDontThrottleOverloadedProcessingThread )
+               *throttleProcessingThreadOnOverload = 0;
+            
+           if( streamInfo->flags & paWinMmeUseMultipleDevices )
+           {
+               if( streamParameters->device != paUseHostApiSpecificDeviceSpecification )
+                   return paInvalidDevice;
+       
+                       *deviceCount = streamInfo->deviceCount;
+               }       
+       }
+
+       return paNoError;
+}
+
+static PaError RetrieveDevicesFromStreamParameters(
+        struct PaUtilHostApiRepresentation *hostApi,
+        const PaStreamParameters *streamParameters,
+        const PaWinMmeStreamInfo *streamInfo,
+        PaWinMmeDeviceAndChannelCount *devices,
+        unsigned long deviceCount )
+{
+    PaError result = paNoError;
+    unsigned int i;
+    int totalChannelCount;
+    PaDeviceIndex hostApiDevice;
+    
+       if( streamInfo && streamInfo->flags & paWinMmeUseMultipleDevices )
+       {
+               totalChannelCount = 0;
+           for( i=0; i < deviceCount; ++i )
+           {
+               /* validate that the device number is within range */
+               result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice,
+                               streamInfo->devices[i].device, hostApi );
+               if( result != paNoError )
+                   return result;
+               
+               devices[i].device = hostApiDevice;
+               devices[i].channelCount = streamInfo->devices[i].channelCount;
+       
+               totalChannelCount += devices[i].channelCount;
+           }
+       
+           if( totalChannelCount != streamParameters->channelCount )
+           {
+               /* channelCount must match total channels specified by multiple devices */
+               return paInvalidChannelCount; /* REVIEW use of this error code */
+           }
+       }       
+       else
+       {               
+           devices[0].device = streamParameters->device;
+           devices[0].channelCount = streamParameters->channelCount;
+       }
+
+    return result;
+}
+
+static PaError ValidateInputChannelCounts(
+        struct PaUtilHostApiRepresentation *hostApi,
+        PaWinMmeDeviceAndChannelCount *devices,
+        unsigned long deviceCount )
+{
+    unsigned int i;
+
+       for( i=0; i < deviceCount; ++i )
+       {
+               if( devices[i].channelCount < 1 || devices[i].channelCount
+                                       > hostApi->deviceInfos[ devices[i].device ]->maxInputChannels )
+               return paInvalidChannelCount;
+       }
+
+    return paNoError;
+}
+
+static PaError ValidateOutputChannelCounts(
+        struct PaUtilHostApiRepresentation *hostApi,
+        PaWinMmeDeviceAndChannelCount *devices,
+        unsigned long deviceCount )
+{
+    unsigned int i;
+
+       for( i=0; i < deviceCount; ++i )
+       {
+               if( devices[i].channelCount < 1 || devices[i].channelCount
+                                       > hostApi->deviceInfos[ devices[i].device ]->maxOutputChannels )
+               return paInvalidChannelCount;
+       }
+
+    return paNoError;
+}
+
+
+/* the following macros are intended to improve the readability of the following code */
+#define PA_IS_INPUT_STREAM_( stream ) ( stream ->input.waveHandles )
+#define PA_IS_OUTPUT_STREAM_( stream ) ( stream ->output.waveHandles )
+#define PA_IS_FULL_DUPLEX_STREAM_( stream ) ( stream ->input.waveHandles && stream ->output.waveHandles )
+#define PA_IS_HALF_DUPLEX_STREAM_( stream ) ( !(stream ->input.waveHandles && stream ->output.waveHandles) )
+
+static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,
+                           PaStream** s,
+                           const PaStreamParameters *inputParameters,
+                           const PaStreamParameters *outputParameters,
+                           double sampleRate,
+                           unsigned long framesPerBuffer,
+                           PaStreamFlags streamFlags,
+                           PaStreamCallback *streamCallback,
+                           void *userData )
+{
+    PaError result;
+    PaWinMmeHostApiRepresentation *winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi;
+    PaWinMmeStream *stream = 0;
+    int bufferProcessorIsInitialized = 0;
+    int streamRepresentationIsInitialized = 0;
+    PaSampleFormat hostInputSampleFormat, hostOutputSampleFormat;
+    int inputChannelCount, outputChannelCount;
+    PaSampleFormat inputSampleFormat, outputSampleFormat;
+    double suggestedInputLatency, suggestedOutputLatency;
+    PaWinMmeStreamInfo *inputStreamInfo, *outputStreamInfo;
+    unsigned long framesPerHostInputBuffer;
+    unsigned long hostInputBufferCount;
+    unsigned long framesPerHostOutputBuffer;
+    unsigned long hostOutputBufferCount;
+    unsigned long framesPerBufferProcessorCall;
+    PaWinMmeDeviceAndChannelCount *inputDevices = 0;  /* contains all devices and channel counts as local host api ids, even when PaWinMmeUseMultipleDevices is not used */
+    unsigned long inputDeviceCount = 0;            
+    PaWinMmeDeviceAndChannelCount *outputDevices = 0;
+    unsigned long outputDeviceCount = 0;                /* contains all devices and channel counts as local host api ids, even when PaWinMmeUseMultipleDevices is not used */
+    char throttleProcessingThreadOnOverload = 1;
+
+    
+    if( inputParameters )
+    {
+               inputChannelCount = inputParameters->channelCount;
+        inputSampleFormat = inputParameters->sampleFormat;
+        suggestedInputLatency = inputParameters->suggestedLatency;
+
+       inputDeviceCount = 1;
+
+               /* validate input hostApiSpecificStreamInfo */
+        inputStreamInfo = (PaWinMmeStreamInfo*)inputParameters->hostApiSpecificStreamInfo;
+               result = ValidateWinMmeSpecificStreamInfo( inputParameters, inputStreamInfo,
+                               &throttleProcessingThreadOnOverload,
+                               &inputDeviceCount );
+               if( result != paNoError ) return result;
+
+               inputDevices = (PaWinMmeDeviceAndChannelCount*)alloca( sizeof(PaWinMmeDeviceAndChannelCount) * inputDeviceCount );
+        if( !inputDevices ) return paInsufficientMemory;
+
+               result = RetrieveDevicesFromStreamParameters( hostApi, inputParameters, inputStreamInfo, inputDevices, inputDeviceCount );
+               if( result != paNoError ) return result;
+
+               result = ValidateInputChannelCounts( hostApi, inputDevices, inputDeviceCount );
+               if( result != paNoError ) return result;
+
+        hostInputSampleFormat =
+            PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, inputSampleFormat );
+       }
+    else
+    {
+        inputChannelCount = 0;
+        inputSampleFormat = 0;
+        suggestedInputLatency = 0.;
+        inputStreamInfo = 0;
+        hostInputSampleFormat = 0;
+    }
+
+
+    if( outputParameters )
+    {
+        outputChannelCount = outputParameters->channelCount;
+        outputSampleFormat = outputParameters->sampleFormat;
+        suggestedOutputLatency = outputParameters->suggestedLatency;
+
+        outputDeviceCount = 1;
+
+               /* validate output hostApiSpecificStreamInfo */
+        outputStreamInfo = (PaWinMmeStreamInfo*)outputParameters->hostApiSpecificStreamInfo;
+               result = ValidateWinMmeSpecificStreamInfo( outputParameters, outputStreamInfo,
+                               &throttleProcessingThreadOnOverload,
+                               &outputDeviceCount );
+               if( result != paNoError ) return result;
+
+               outputDevices = (PaWinMmeDeviceAndChannelCount*)alloca( sizeof(PaWinMmeDeviceAndChannelCount) * outputDeviceCount );
+        if( !outputDevices ) return paInsufficientMemory;
+
+               result = RetrieveDevicesFromStreamParameters( hostApi, outputParameters, outputStreamInfo, outputDevices, outputDeviceCount );
+               if( result != paNoError ) return result;
+
+               result = ValidateOutputChannelCounts( hostApi, outputDevices, outputDeviceCount );
+               if( result != paNoError ) return result;
+
+        hostOutputSampleFormat =
+            PaUtil_SelectClosestAvailableFormat( paInt16 /* native formats */, outputSampleFormat );
+    }
+    else
+    {
+        outputChannelCount = 0;
+        outputSampleFormat = 0;
+        outputStreamInfo = 0;
+        hostOutputSampleFormat = 0;
+        suggestedOutputLatency = 0.;
+    }
+
+
+    /*
+        IMPLEMENT ME:
+            - alter sampleRate to a close allowable rate if possible / necessary
+    */
+
+
+    /* validate platform specific flags */
+    if( (streamFlags & paPlatformSpecificFlags) != 0 )
+        return paInvalidFlag; /* unexpected platform specific flag */
+
+
+    result = CalculateBufferSettings( &framesPerHostInputBuffer, &hostInputBufferCount,
+                &framesPerHostOutputBuffer, &hostOutputBufferCount,
+                inputChannelCount, hostInputSampleFormat, suggestedInputLatency, inputStreamInfo,
+                outputChannelCount, hostOutputSampleFormat, suggestedOutputLatency, outputStreamInfo,
+                sampleRate, framesPerBuffer );
+    if( result != paNoError ) goto error;
+
+
+    stream = (PaWinMmeStream*)PaUtil_AllocateMemory( sizeof(PaWinMmeStream) );
+    if( !stream )
+    {
+        result = paInsufficientMemory;
+        goto error;
+    }
+
+    InitializeSingleDirectionHandlesAndBuffers( &stream->input );
+    InitializeSingleDirectionHandlesAndBuffers( &stream->output );
+
+    stream->abortEvent = 0;
+    stream->processingThread = 0;
+
+    stream->throttleProcessingThreadOnOverload = throttleProcessingThreadOnOverload;
+
+    PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,
+                                           ( (streamCallback)
+                                            ? &winMmeHostApi->callbackStreamInterface
+                                            : &winMmeHostApi->blockingStreamInterface ),
+                                           streamCallback, userData );
+    streamRepresentationIsInitialized = 1;
+
+    PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );
+
+
+    if( inputParameters && outputParameters ) /* full duplex */
+    {
+        if( framesPerHostInputBuffer < framesPerHostOutputBuffer )
+        {
+            assert( (framesPerHostOutputBuffer % framesPerHostInputBuffer) == 0 ); /* CalculateBufferSettings() should guarantee this condition */
+
+            framesPerBufferProcessorCall = framesPerHostInputBuffer;
+        }
+        else
+        {
+            assert( (framesPerHostInputBuffer % framesPerHostOutputBuffer) == 0 ); /* CalculateBufferSettings() should guarantee this condition */
+            
+            framesPerBufferProcessorCall = framesPerHostOutputBuffer;
+        }
+    }
+    else if( inputParameters )
+    {
+        framesPerBufferProcessorCall = framesPerHostInputBuffer;
+    }
+    else if( outputParameters )
+    {
+        framesPerBufferProcessorCall = framesPerHostOutputBuffer;
+    }
+
+    stream->input.framesPerBuffer = framesPerHostInputBuffer;
+    stream->output.framesPerBuffer = framesPerHostOutputBuffer;
+
+    result =  PaUtil_InitializeBufferProcessor( &stream->bufferProcessor,
+                    inputChannelCount, inputSampleFormat, hostInputSampleFormat,
+                    outputChannelCount, outputSampleFormat, hostOutputSampleFormat,
+                    sampleRate, streamFlags, framesPerBuffer,
+                    framesPerBufferProcessorCall, paUtilFixedHostBufferSize,
+                    streamCallback, userData );
+    if( result != paNoError ) goto error;
+    
+    bufferProcessorIsInitialized = 1;
+
+    stream->streamRepresentation.streamInfo.inputLatency =
+            (double)(PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor)
+                +(framesPerHostInputBuffer * (hostInputBufferCount-1))) / sampleRate;
+    stream->streamRepresentation.streamInfo.outputLatency =
+            (double)(PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor)
+                +(framesPerHostOutputBuffer * (hostOutputBufferCount-1))) / sampleRate;
+    stream->streamRepresentation.streamInfo.sampleRate = sampleRate;
+
+    stream->primeStreamUsingCallback = ( (streamFlags&paPrimeOutputBuffersUsingStreamCallback) && streamCallback ) ? 1 : 0;
+
+    /* time to sleep when throttling due to >100% cpu usage.
+        -a quater of a buffer's duration */
+    stream->throttledSleepMsecs =
+            (unsigned long)(stream->bufferProcessor.framesPerHostBuffer *
+             stream->bufferProcessor.samplePeriod * .25 * 1000);
+
+    stream->isStopped = 1;
+    stream->isActive = 0;
+
+
+    /* for maximum compatibility with multi-device multichannel drivers,
+        we first open all devices, then we prepare all buffers, finally
+        we start all devices ( in StartStream() ). teardown in reverse order.
+    */
+
+    if( inputParameters )
+    {
+        result = InitializeWaveHandles( winMmeHostApi, &stream->input,
+                stream->bufferProcessor.bytesPerHostInputSample, sampleRate,
+                inputDevices, inputDeviceCount, 1 /* isInput */ );
+        if( result != paNoError ) goto error;
+    }
+    
+    if( outputParameters )
+    {
+        result = InitializeWaveHandles( winMmeHostApi, &stream->output,
+                stream->bufferProcessor.bytesPerHostOutputSample, sampleRate,
+                outputDevices, outputDeviceCount, 0 /* isInput */ );
+        if( result != paNoError ) goto error;
+    }
+
+    if( inputParameters )
+    {
+        result = InitializeWaveHeaders( &stream->input, hostInputBufferCount,
+                hostInputSampleFormat, framesPerHostInputBuffer, inputDevices, 1 /* isInput */ );
+        if( result != paNoError ) goto error;
+    }
+
+    if( outputParameters )
+    {
+        result = InitializeWaveHeaders( &stream->output, hostOutputBufferCount,
+                hostOutputSampleFormat, framesPerHostOutputBuffer, outputDevices, 0 /* not isInput */ );
+        if( result != paNoError ) goto error;
+
+        stream->allBuffersDurationMs = (DWORD) (1000.0 * (framesPerHostOutputBuffer * stream->output.bufferCount) / sampleRate);
+    }
+    else
+    {
+        stream->allBuffersDurationMs = (DWORD) (1000.0 * (framesPerHostInputBuffer * stream->input.bufferCount) / sampleRate);
+    }
+
+    
+    if( streamCallback )
+    {
+        /* abort event is only needed for callback streams */
+        result = CreateEventWithPaError( &stream->abortEvent, NULL, TRUE, FALSE, NULL );
+        if( result != paNoError ) goto error;
+    }
+
+    *s = (PaStream*)stream;
+
+    return result;
+
+error:
+
+    if( stream )
+    {
+        if( stream->abortEvent )
+            CloseHandle( stream->abortEvent );
+            
+        TerminateWaveHeaders( &stream->output, 0 /* not isInput */ );
+        TerminateWaveHeaders( &stream->input, 1 /* isInput */ );
+
+        TerminateWaveHandles( &stream->output, 0 /* not isInput */, 1 /* currentlyProcessingAnError */ );
+        TerminateWaveHandles( &stream->input, 1 /* isInput */, 1 /* currentlyProcessingAnError */ );
+
+        if( bufferProcessorIsInitialized )
+            PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
+
+        if( streamRepresentationIsInitialized )
+            PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
+
+        PaUtil_FreeMemory( stream );
+    }
+
+    return result;
+}
+
+
+/* return non-zero if all current buffers are done */
+static int BuffersAreDone( WAVEHDR **waveHeaders, unsigned int deviceCount, int bufferIndex )
+{
+    unsigned int i;
+    
+    for( i=0; i < deviceCount; ++i )
+    {
+        if( !(waveHeaders[i][ bufferIndex ].dwFlags & WHDR_DONE) )
+        {
+            return 0;
+        }         
+    }
+
+    return 1;
+}
+
+static int CurrentInputBuffersAreDone( PaWinMmeStream *stream )
+{
+    return BuffersAreDone( stream->input.waveHeaders, stream->input.deviceCount, stream->input.currentBufferIndex );
+}
+
+static int CurrentOutputBuffersAreDone( PaWinMmeStream *stream )
+{
+    return BuffersAreDone( stream->output.waveHeaders, stream->output.deviceCount, stream->output.currentBufferIndex );
+}
+
+
+/* return non-zero if any buffers are queued */
+static int NoBuffersAreQueued( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers )
+{
+    unsigned int i, j;
+
+    if( handlesAndBuffers->waveHandles )
+    {
+        for( i=0; i < handlesAndBuffers->bufferCount; ++i )
+        {
+            for( j=0; j < handlesAndBuffers->deviceCount; ++j )
+            {
+                if( !( handlesAndBuffers->waveHeaders[ j ][ i ].dwFlags & WHDR_DONE) )
+                {
+                    return 0;
+                }
+            }
+        }
+    }
+
+    return 1;
+}
+
+
+#define PA_CIRCULAR_INCREMENT_( current, max )\
+    ( (((current) + 1) >= (max)) ? (0) : (current+1) )
+
+#define PA_CIRCULAR_DECREMENT_( current, max )\
+    ( ((current) == 0) ? ((max)-1) : (current-1) )
+    
+
+static signed long GetAvailableFrames( PaWinMmeSingleDirectionHandlesAndBuffers *handlesAndBuffers )
+{
+    signed long result = 0;
+    unsigned int i;
+    
+    if( BuffersAreDone( handlesAndBuffers->waveHeaders, handlesAndBuffers->deviceCount, handlesAndBuffers->currentBufferIndex ) )
+    {
+        /* we could calculate the following in O(1) if we kept track of the
+            last done buffer */
+        result = handlesAndBuffers->framesPerBuffer - handlesAndBuffers->framesUsedInCurrentBuffer;
+
+        i = PA_CIRCULAR_INCREMENT_( handlesAndBuffers->currentBufferIndex, handlesAndBuffers->bufferCount );
+        while( i != handlesAndBuffers->currentBufferIndex )
+        {
+            if( BuffersAreDone( handlesAndBuffers->waveHeaders, handlesAndBuffers->deviceCount, i ) )
+            {
+                result += handlesAndBuffers->framesPerBuffer;
+                i = PA_CIRCULAR_INCREMENT_( i, handlesAndBuffers->bufferCount );
+            }
+            else
+                break;
+        }
+    }
+
+    return result;
+}
+
+
+static PaError AdvanceToNextInputBuffer( PaWinMmeStream *stream )
+{
+    PaError result = paNoError;
+    MMRESULT mmresult;
+    unsigned int i;
+
+    for( i=0; i < stream->input.deviceCount; ++i )
+    {
+        mmresult = waveInAddBuffer( ((HWAVEIN*)stream->input.waveHandles)[i],
+                                    &stream->input.waveHeaders[i][ stream->input.currentBufferIndex ],
+                                    sizeof(WAVEHDR) );
+        if( mmresult != MMSYSERR_NOERROR )
+        {
+            result = paUnanticipatedHostError;
+            PA_MME_SET_LAST_WAVEIN_ERROR( mmresult );
+        }
+    }
+
+    stream->input.currentBufferIndex =
+            PA_CIRCULAR_INCREMENT_( stream->input.currentBufferIndex, stream->input.bufferCount );
+
+    stream->input.framesUsedInCurrentBuffer = 0;
+
+    return result;
+}
+
+
+static PaError AdvanceToNextOutputBuffer( PaWinMmeStream *stream )
+{
+    PaError result = paNoError;
+    MMRESULT mmresult;
+    unsigned int i;
+
+    for( i=0; i < stream->output.deviceCount; ++i )
+    {
+        mmresult = waveOutWrite( ((HWAVEOUT*)stream->output.waveHandles)[i],
+                                 &stream->output.waveHeaders[i][ stream->output.currentBufferIndex ],
+                                 sizeof(WAVEHDR) );
+        if( mmresult != MMSYSERR_NOERROR )
+        {
+            result = paUnanticipatedHostError;
+            PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult );
+        }
+    }
+
+    stream->output.currentBufferIndex =
+            PA_CIRCULAR_INCREMENT_( stream->output.currentBufferIndex, stream->output.bufferCount );
+
+    stream->output.framesUsedInCurrentBuffer = 0;
+    
+    return result;
+}
+
+
+/* requeue all but the most recent input with the driver. Used for catching
+    up after a total input buffer underrun */
+static PaError CatchUpInputBuffers( PaWinMmeStream *stream )
+{
+    PaError result = paNoError;
+    unsigned int i;
+    
+    for( i=0; i < stream->input.bufferCount - 1; ++i )
+    {
+        result = AdvanceToNextInputBuffer( stream );
+        if( result != paNoError )
+            break;
+    }
+
+    return result;
+}
+
+
+/* take the most recent output and duplicate it to all other output buffers
+    and requeue them. Used for catching up after a total output buffer underrun.
+*/
+static PaError CatchUpOutputBuffers( PaWinMmeStream *stream )
+{
+    PaError result = paNoError;
+    unsigned int i, j;
+    unsigned int previousBufferIndex =
+            PA_CIRCULAR_DECREMENT_( stream->output.currentBufferIndex, stream->output.bufferCount );
+
+    for( i=0; i < stream->output.bufferCount - 1; ++i )
+    {
+        for( j=0; j < stream->output.deviceCount; ++j )
+        {
+            if( stream->output.waveHeaders[j][ stream->output.currentBufferIndex ].lpData
+                    != stream->output.waveHeaders[j][ previousBufferIndex ].lpData )
+            {
+                CopyMemory( stream->output.waveHeaders[j][ stream->output.currentBufferIndex ].lpData,
+                            stream->output.waveHeaders[j][ previousBufferIndex ].lpData,
+                            stream->output.waveHeaders[j][ stream->output.currentBufferIndex ].dwBufferLength );
+            }
+        }
+
+        result = AdvanceToNextOutputBuffer( stream );
+        if( result != paNoError )
+            break;
+    }
+
+    return result;
+}
+
+
+static DWORD WINAPI ProcessingThreadProc( void *pArg )
+{
+    PaWinMmeStream *stream = (PaWinMmeStream *)pArg;
+    HANDLE events[3];
+    int eventCount = 0;
+    DWORD result = paNoError;
+    DWORD waitResult;
+    DWORD timeout = (unsigned long)(stream->allBuffersDurationMs * 0.5);
+    int hostBuffersAvailable;
+    signed int hostInputBufferIndex, hostOutputBufferIndex;
+    PaStreamCallbackFlags statusFlags;
+    int callbackResult;
+    int done = 0;
+    unsigned int channel, i;
+    unsigned long framesProcessed;
+    
+    /* prepare event array for call to WaitForMultipleObjects() */
+    if( stream->input.bufferEvent )
+        events[eventCount++] = stream->input.bufferEvent;
+    if( stream->output.bufferEvent )
+        events[eventCount++] = stream->output.bufferEvent;
+    events[eventCount++] = stream->abortEvent;
+
+    statusFlags = 0; /** @todo support paInputUnderflow, paOutputOverflow and paNeverDropInput */
+    
+    /* loop until something causes us to stop */
+    do{
+        /* wait for MME to signal that a buffer is available, or for
+            the PA abort event to be signaled.
+
+          When this indicates that one or more buffers are available
+          NoBuffersAreQueued() and Current*BuffersAreDone are used below to
+          poll for additional done buffers. NoBuffersAreQueued() will fail
+          to identify an underrun/overflow if the driver doesn't mark all done
+          buffers prior to signalling the event. Some drivers do this
+          (eg RME Digi96, and others don't eg VIA PC 97 input). This isn't a
+          huge problem, it just means that we won't always be able to detect
+          underflow/overflow.
+        */
+        waitResult = WaitForMultipleObjects( eventCount, events, FALSE /* wait all = FALSE */, timeout );
+        if( waitResult == WAIT_FAILED )
+        {
+            result = paUnanticipatedHostError;
+            /** @todo FIXME/REVIEW: can't return host error info from an asyncronous thread */
+            done = 1;
+        }
+        else if( waitResult == WAIT_TIMEOUT )
+        {
+            /* if a timeout is encountered, continue */
+        }
+
+        if( stream->abortProcessing )
+        {
+            /* Pa_AbortStream() has been called, stop processing immediately */
+            done = 1;
+        }
+        else if( stream->stopProcessing )
+        {
+            /* Pa_StopStream() has been called or the user callback returned
+                non-zero, processing will continue until all output buffers
+                are marked as done. The stream will stop immediately if it
+                is input-only.
+            */
+
+            if( PA_IS_OUTPUT_STREAM_(stream) )
+            {
+                if( NoBuffersAreQueued( &stream->output ) )
+                    done = 1; /* Will cause thread to return. */
+            }
+            else
+            {
+                /* input only stream */
+                done = 1; /* Will cause thread to return. */
+            }
+        }
+        else
+        {
+            hostBuffersAvailable = 1;
+
+            /* process all available host buffers */
+            do
+            {
+                hostInputBufferIndex = -1;
+                hostOutputBufferIndex = -1;
+                
+                if( PA_IS_INPUT_STREAM_(stream) )
+                {
+                    if( CurrentInputBuffersAreDone( stream ) )
+                    {
+                        if( NoBuffersAreQueued( &stream->input ) )
+                        {
+                            /** @todo
+                               if all of the other buffers are also ready then
+                               we discard all but the most recent. This is an
+                               input buffer overflow. FIXME: these buffers should
+                               be passed to the callback in a paNeverDropInput
+                               stream.
+
+                               note that it is also possible for an input overflow
+                               to happen while the callback is processing a buffer.
+                               that is handled further down.
+                            */
+                            result = CatchUpInputBuffers( stream );
+                            if( result != paNoError )
+                                done = 1;
+
+                            statusFlags |= paInputOverflow;
+                        }
+
+                        hostInputBufferIndex = stream->input.currentBufferIndex;
+                    }
+                }
+
+                if( PA_IS_OUTPUT_STREAM_(stream) )
+                {
+                    if( CurrentOutputBuffersAreDone( stream ) )
+                    {
+                        /* ok, we have an output buffer */
+                        
+                        if( NoBuffersAreQueued( &stream->output ) )
+                        {
+                            /*
+                            if all of the other buffers are also ready, catch up by copying
+                            the most recently generated buffer into all but one of the output
+                            buffers.
+
+                            note that this catch up code only handles the case where all
+                            buffers have been played out due to this thread not having
+                            woken up at all. a more common case occurs when this thread
+                            is woken up, processes one buffer, but takes too long, and as
+                            a result all the other buffers have become un-queued. that
+                            case is handled further down.
+                            */
+
+                            result = CatchUpOutputBuffers( stream );
+                            if( result != paNoError )
+                                done = 1;
+
+                            statusFlags |= paOutputUnderflow;
+                        }
+
+                        hostOutputBufferIndex = stream->output.currentBufferIndex;
+                    }
+                }
+
+               
+                if( (PA_IS_FULL_DUPLEX_STREAM_(stream) && hostInputBufferIndex != -1 && hostOutputBufferIndex != -1) ||
+                        (PA_IS_HALF_DUPLEX_STREAM_(stream) && ( hostInputBufferIndex != -1 || hostOutputBufferIndex != -1 ) ) )
+                {
+                    PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /** @todo implement inputBufferAdcTime */
+
+
+                    if( PA_IS_OUTPUT_STREAM_(stream) )
+                    {
+                        /* set timeInfo.currentTime and calculate timeInfo.outputBufferDacTime
+                            from the current wave out position */
+                        MMTIME mmtime;
+                        double timeBeforeGetPosition, timeAfterGetPosition;
+                        double time;
+                        long framesInBufferRing;               
+                        long writePosition;
+                        long playbackPosition;
+                        HWAVEOUT firstWaveOutDevice = ((HWAVEOUT*)stream->output.waveHandles)[0];
+                        
+                        mmtime.wType = TIME_SAMPLES;
+                        timeBeforeGetPosition = PaUtil_GetTime();
+                        waveOutGetPosition( firstWaveOutDevice, &mmtime, sizeof(MMTIME) );
+                        timeAfterGetPosition = PaUtil_GetTime();
+
+                        timeInfo.currentTime = timeAfterGetPosition;
+
+                        /* approximate time at which wave out position was measured
+                            as half way between timeBeforeGetPosition and timeAfterGetPosition */
+                        time = timeBeforeGetPosition + (timeAfterGetPosition - timeBeforeGetPosition) * .5;
+                        
+                        framesInBufferRing = stream->output.bufferCount * stream->bufferProcessor.framesPerHostBuffer;
+                        playbackPosition = mmtime.u.sample % framesInBufferRing;
+
+                        writePosition = stream->output.currentBufferIndex * stream->bufferProcessor.framesPerHostBuffer
+                                + stream->output.framesUsedInCurrentBuffer;
+                       
+                        if( playbackPosition >= writePosition ){
+                            timeInfo.outputBufferDacTime =
+                                    time + ((double)( writePosition + (framesInBufferRing - playbackPosition) ) * stream->bufferProcessor.samplePeriod );
+                        }else{
+                            timeInfo.outputBufferDacTime =
+                                    time + ((double)( writePosition - playbackPosition ) * stream->bufferProcessor.samplePeriod );
+                        }
+                    }
+
+
+                    PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );
+
+                    PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo, statusFlags  );
+
+                    /* reset status flags once they have been passed to the buffer processor */
+                    statusFlags = 0;
+
+                    if( PA_IS_INPUT_STREAM_(stream) )
+                    {
+                        PaUtil_SetInputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ );
+
+                        channel = 0;
+                        for( i=0; i<stream->input.deviceCount; ++i )
+                        {
+                             /* we have stored the number of channels in the buffer in dwUser */
+                            int channelCount = stream->input.waveHeaders[i][ hostInputBufferIndex ].dwUser;
+                            
+                            PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, channel,
+                                    stream->input.waveHeaders[i][ hostInputBufferIndex ].lpData +
+                                        stream->input.framesUsedInCurrentBuffer * channelCount *
+                                        stream->bufferProcessor.bytesPerHostInputSample,
+                                    channelCount );
+                                    
+
+                            channel += channelCount;
+                        }
+                    }
+
+                    if( PA_IS_OUTPUT_STREAM_(stream) )
+                    {
+                        PaUtil_SetOutputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ );
+                        
+                        channel = 0;
+                        for( i=0; i<stream->output.deviceCount; ++i )
+                        {
+                            /* we have stored the number of channels in the buffer in dwUser */
+                            int channelCount = stream->output.waveHeaders[i][ hostOutputBufferIndex ].dwUser;
+
+                            PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, channel,
+                                    stream->output.waveHeaders[i][ hostOutputBufferIndex ].lpData +
+                                        stream->output.framesUsedInCurrentBuffer * channelCount *
+                                        stream->bufferProcessor.bytesPerHostOutputSample,
+                                    channelCount );
+
+                            channel += channelCount;
+                        }
+                    }
+
+                    callbackResult = paContinue;
+                    framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult );
+
+                    stream->input.framesUsedInCurrentBuffer += framesProcessed;
+                    stream->output.framesUsedInCurrentBuffer += framesProcessed;
+
+                    PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed );
+
+                    if( callbackResult == paContinue )
+                    {
+                        /* nothing special to do */
+                    }
+                    else if( callbackResult == paAbort )
+                    {
+                        stream->abortProcessing = 1;
+                        done = 1;
+                        /** @todo FIXME: should probably reset the output device immediately once the callback returns paAbort */
+                        result = paNoError;
+                    }
+                    else
+                    {
+                        /* User callback has asked us to stop with paComplete or other non-zero value */
+                        stream->stopProcessing = 1; /* stop once currently queued audio has finished */
+                        result = paNoError;
+                    }
+
+
+                    if( PA_IS_INPUT_STREAM_(stream)
+                            && stream->stopProcessing == 0 && stream->abortProcessing == 0
+                            && stream->input.framesUsedInCurrentBuffer == stream->input.framesPerBuffer )
+                    {
+                        if( NoBuffersAreQueued( &stream->input ) )
+                        {
+                            /** @todo need to handle PaNeverDropInput here where necessary */
+                            result = CatchUpInputBuffers( stream );
+                            if( result != paNoError )
+                                done = 1;
+
+                            statusFlags |= paInputOverflow;
+                        }
+
+                        result = AdvanceToNextInputBuffer( stream );
+                        if( result != paNoError )
+                            done = 1;
+                    }
+
+                    
+                    if( PA_IS_OUTPUT_STREAM_(stream) && !stream->abortProcessing )
+                    {
+                        if( stream->stopProcessing &&
+                                stream->output.framesUsedInCurrentBuffer < stream->output.framesPerBuffer )
+                        {
+                            /* zero remaining samples in output output buffer and flush */
+
+                            stream->output.framesUsedInCurrentBuffer += PaUtil_ZeroOutput( &stream->bufferProcessor,
+                                    stream->output.framesPerBuffer - stream->output.framesUsedInCurrentBuffer );
+
+                            /* we send the entire buffer to the output devices, but we could
+                                just send a partial buffer, rather than zeroing the unused
+                                samples.
+                            */
+                        }
+
+                        if( stream->output.framesUsedInCurrentBuffer == stream->output.framesPerBuffer )
+                        {
+                            /* check for underflow before enquing the just-generated buffer,
+                                but recover from underflow after enquing it. This ensures
+                                that the most recent audio segment is repeated */
+                            int outputUnderflow = NoBuffersAreQueued( &stream->output );
+
+                            result = AdvanceToNextOutputBuffer( stream );
+                            if( result != paNoError )
+                                done = 1;
+
+                            if( outputUnderflow && !done && !stream->stopProcessing )
+                            {
+                                /* Recover from underflow in the case where the
+                                    underflow occured while processing the buffer
+                                    we just finished */
+
+                                result = CatchUpOutputBuffers( stream );
+                                if( result != paNoError )
+                                    done = 1;
+
+                                statusFlags |= paOutputUnderflow;
+                            }
+                        }
+                    }
+                    
+                    if( stream->throttleProcessingThreadOnOverload != 0 )
+                    {
+                        if( stream->stopProcessing || stream->abortProcessing )
+                        {
+                            if( stream->processingThreadPriority != stream->highThreadPriority )
+                            {
+                                SetThreadPriority( stream->processingThread, stream->highThreadPriority );
+                                stream->processingThreadPriority = stream->highThreadPriority;
+                            }
+                        }
+                        else if( PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer ) > 1. )
+                        {
+                            if( stream->processingThreadPriority != stream->throttledThreadPriority )
+                            {
+                                SetThreadPriority( stream->processingThread, stream->throttledThreadPriority );
+                                stream->processingThreadPriority = stream->throttledThreadPriority;
+                            }
+
+                            /* sleep to give other processes a go */
+                            Sleep( stream->throttledSleepMsecs );
+                        }
+                        else
+                        {
+                            if( stream->processingThreadPriority != stream->highThreadPriority )
+                            {
+                                SetThreadPriority( stream->processingThread, stream->highThreadPriority );
+                                stream->processingThreadPriority = stream->highThreadPriority;
+                            }
+                        }
+                    }
+                }
+                else
+                {
+                    hostBuffersAvailable = 0;
+                }
+            }
+            while( hostBuffersAvailable &&
+                    stream->stopProcessing == 0 &&
+                    stream->abortProcessing == 0 &&
+                    !done );
+        }
+    }
+    while( !done );
+
+    stream->isActive = 0;
+
+    if( stream->streamRepresentation.streamFinishedCallback != 0 )
+        stream->streamRepresentation.streamFinishedCallback( stream->streamRepresentation.userData );
+
+    PaUtil_ResetCpuLoadMeasurer( &stream->cpuLoadMeasurer );
+    
+    return result;
+}
+
+
+/*
+    When CloseStream() is called, the multi-api layer ensures that
+    the stream has already been stopped or aborted.
+*/
+static PaError CloseStream( PaStream* s )
+{
+    PaError result;
+    PaWinMmeStream *stream = (PaWinMmeStream*)s;
+
+    result = CloseHandleWithPaError( stream->abortEvent );
+    if( result != paNoError ) goto error;
+    
+    TerminateWaveHeaders( &stream->output, 0 /* not isInput */ );
+    TerminateWaveHeaders( &stream->input, 1 /* isInput */ );
+
+    TerminateWaveHandles( &stream->output, 0 /* not isInput */, 0 /* not currentlyProcessingAnError */ );
+    TerminateWaveHandles( &stream->input, 1 /* isInput */, 0 /* not currentlyProcessingAnError */ );
+    
+    PaUtil_TerminateBufferProcessor( &stream->bufferProcessor );
+    PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );
+    PaUtil_FreeMemory( stream );
+
+error:
+    /** @todo REVIEW: what is the best way to clean up a stream if an error is detected? */
+    return result;
+}
+
+
+static PaError StartStream( PaStream *s )
+{
+    PaError result;
+    PaWinMmeStream *stream = (PaWinMmeStream*)s;
+    MMRESULT mmresult;
+    unsigned int i, j;
+    int callbackResult;
+       unsigned int channel;
+       unsigned long framesProcessed;
+       PaStreamCallbackTimeInfo timeInfo = {0,0,0}; /** @todo implement this for stream priming */
+    
+    PaUtil_ResetBufferProcessor( &stream->bufferProcessor );
+    
+    if( PA_IS_INPUT_STREAM_(stream) )
+    {
+        for( i=0; i<stream->input.bufferCount; ++i )
+        {
+            for( j=0; j<stream->input.deviceCount; ++j )
+            {
+                mmresult = waveInAddBuffer( ((HWAVEIN*)stream->input.waveHandles)[j], &stream->input.waveHeaders[j][i], sizeof(WAVEHDR) );
+                if( mmresult != MMSYSERR_NOERROR )
+                {
+                    result = paUnanticipatedHostError;
+                    PA_MME_SET_LAST_WAVEIN_ERROR( mmresult );
+                    goto error;
+                }
+            }
+        }
+        stream->input.currentBufferIndex = 0;
+        stream->input.framesUsedInCurrentBuffer = 0;
+    }
+
+    if( PA_IS_OUTPUT_STREAM_(stream) )
+    {
+        for( i=0; i<stream->output.deviceCount; ++i )
+        {
+            if( (mmresult = waveOutPause( ((HWAVEOUT*)stream->output.waveHandles)[i] )) != MMSYSERR_NOERROR )
+            {
+                result = paUnanticipatedHostError;
+                PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult );
+                goto error;
+            }
+        }
+
+        for( i=0; i<stream->output.bufferCount; ++i )
+        {
+            if( stream->primeStreamUsingCallback )
+            {
+
+                stream->output.framesUsedInCurrentBuffer = 0;
+                do{
+
+                    PaUtil_BeginBufferProcessing( &stream->bufferProcessor,
+                            &timeInfo,
+                            paPrimingOutput | ((stream->input.bufferCount > 0 ) ? paInputUnderflow : 0));
+
+                    if( stream->input.bufferCount > 0 )
+                        PaUtil_SetNoInput( &stream->bufferProcessor );
+
+                    PaUtil_SetOutputFrameCount( &stream->bufferProcessor, 0 /* default to host buffer size */ );
+
+                    channel = 0;
+                    for( j=0; j<stream->output.deviceCount; ++j )
+                    {
+                        /* we have stored the number of channels in the buffer in dwUser */
+                        int channelCount = stream->output.waveHeaders[j][i].dwUser;
+
+                        PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, channel,
+                                stream->output.waveHeaders[j][i].lpData +
+                                stream->output.framesUsedInCurrentBuffer * channelCount *
+                                stream->bufferProcessor.bytesPerHostOutputSample,
+                                channelCount );
+
+                        /* we have stored the number of channels in the buffer in dwUser */
+                        channel += channelCount;
+                    }
+
+                    callbackResult = paContinue;
+                    framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor, &callbackResult );
+                    stream->output.framesUsedInCurrentBuffer += framesProcessed;
+
+                    if( callbackResult != paContinue )
+                    {
+                        /** @todo fix this, what do we do if callback result is non-zero during stream
+                            priming?
+
+                            for complete: play out primed waveHeaders as usual
+                            for abort: clean up immediately.
+                       */
+                    }
+
+                }while( stream->output.framesUsedInCurrentBuffer != stream->output.framesPerBuffer );
+
+            }
+            else
+            {
+                for( j=0; j<stream->output.deviceCount; ++j )
+                {
+                    ZeroMemory( stream->output.waveHeaders[j][i].lpData, stream->output.waveHeaders[j][i].dwBufferLength );
+                }
+            }   
+
+            /* we queue all channels of a single buffer frame (accross all
+                devices, because some multidevice multichannel drivers work
+                better this way */
+            for( j=0; j<stream->output.deviceCount; ++j )
+            {
+                mmresult = waveOutWrite( ((HWAVEOUT*)stream->output.waveHandles)[j], &stream->output.waveHeaders[j][i], sizeof(WAVEHDR) );
+                if( mmresult != MMSYSERR_NOERROR )
+                {
+                    result = paUnanticipatedHostError;
+                    PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult );
+                    goto error;
+                }
+            }
+        }
+        stream->output.currentBufferIndex = 0;
+        stream->output.framesUsedInCurrentBuffer = 0;
+    }
+
+
+    stream->isStopped = 0;
+    stream->isActive = 1;
+    stream->stopProcessing = 0;
+    stream->abortProcessing = 0;
+
+    result = ResetEventWithPaError( stream->input.bufferEvent );
+    if( result != paNoError ) goto error;
+
+    result = ResetEventWithPaError( stream->output.bufferEvent );
+    if( result != paNoError ) goto error;
+    
+    
+    if( stream->streamRepresentation.streamCallback )
+    {
+        /* callback stream */
+
+        result = ResetEventWithPaError( stream->abortEvent );
+        if( result != paNoError ) goto error;
+
+        /* Create thread that waits for audio buffers to be ready for processing. */
+        stream->processingThread = CreateThread( 0, 0, ProcessingThreadProc, stream, 0, &stream->processingThreadId );
+        if( !stream->processingThread )
+        {
+            result = paUnanticipatedHostError;
+            PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() );
+            goto error;
+        }
+
+        /** @todo could have mme specific stream parameters to allow the user
+            to set the callback thread priorities */
+        stream->highThreadPriority = THREAD_PRIORITY_TIME_CRITICAL;
+        stream->throttledThreadPriority = THREAD_PRIORITY_NORMAL;
+
+        if( !SetThreadPriority( stream->processingThread, stream->highThreadPriority ) )
+        {
+            result = paUnanticipatedHostError;
+            PA_MME_SET_LAST_SYSTEM_ERROR( GetLastError() );
+            goto error;
+        }
+        stream->processingThreadPriority = stream->highThreadPriority;
+    }
+    else
+    {
+        /* blocking read/write stream */
+
+    }
+
+    if( PA_IS_INPUT_STREAM_(stream) )
+    {
+        for( i=0; i < stream->input.deviceCount; ++i )
+        {
+            mmresult = waveInStart( ((HWAVEIN*)stream->input.waveHandles)[i] );
+            PA_DEBUG(("Pa_StartStream: waveInStart returned = 0x%X.\n", mmresult));
+            if( mmresult != MMSYSERR_NOERROR )
+            {
+                result = paUnanticipatedHostError;
+                PA_MME_SET_LAST_WAVEIN_ERROR( mmresult );
+                goto error;
+            }
+        }
+    }
+
+    if( PA_IS_OUTPUT_STREAM_(stream) )
+    {
+        for( i=0; i < stream->output.deviceCount; ++i )
+        {
+            if( (mmresult = waveOutRestart( ((HWAVEOUT*)stream->output.waveHandles)[i] )) != MMSYSERR_NOERROR )
+            {
+                result = paUnanticipatedHostError;
+                PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult );
+                goto error;
+            }
+        }
+    }
+
+    return result;
+
+error:
+    /** @todo FIXME: implement recovery as best we can
+    This should involve rolling back to a state as-if this function had never been called
+    */
+    return result;
+}
+
+
+static PaError StopStream( PaStream *s )
+{
+    PaError result = paNoError;
+    PaWinMmeStream *stream = (PaWinMmeStream*)s;
+    int timeout;
+    DWORD waitResult;
+    MMRESULT mmresult;
+    signed int hostOutputBufferIndex;
+    unsigned int channel, waitCount, i;                  
+    
+    /** @todo
+        REVIEW: the error checking in this function needs review. the basic
+        idea is to return from this function in a known state - for example
+        there is no point avoiding calling waveInReset just because
+        the thread times out.
+    */
+
+    if( stream->processingThread )
+    {
+        /* callback stream */
+
+        /* Tell processing thread to stop generating more data and to let current data play out. */
+        stream->stopProcessing = 1;
+
+        /* Calculate timeOut longer than longest time it could take to return all buffers. */
+        timeout = (int)(stream->allBuffersDurationMs * 1.5);
+        if( timeout < PA_MME_MIN_TIMEOUT_MSEC_ )
+            timeout = PA_MME_MIN_TIMEOUT_MSEC_;
+
+        PA_DEBUG(("WinMME StopStream: waiting for background thread.\n"));
+
+        waitResult = WaitForSingleObject( stream->processingThread, timeout );
+        if( waitResult == WAIT_TIMEOUT )
+        {
+            /* try to abort */
+            stream->abortProcessing = 1;
+            SetEvent( stream->abortEvent );
+            waitResult = WaitForSingleObject( stream->processingThread, timeout );
+            if( waitResult == WAIT_TIMEOUT )
+            {
+                PA_DEBUG(("WinMME StopStream: timed out while waiting for background thread to finish.\n"));
+                result = paTimedOut;
+            }
+        }
+
+        CloseHandle( stream->processingThread );
+        stream->processingThread = NULL;
+    }
+    else
+    {
+        /* blocking read / write stream */
+
+        if( PA_IS_OUTPUT_STREAM_(stream) )
+        {
+            if( stream->output.framesUsedInCurrentBuffer > 0 )
+            {
+                /* there are still unqueued frames in the current buffer, so flush them */
+
+                hostOutputBufferIndex = stream->output.currentBufferIndex;
+
+                PaUtil_SetOutputFrameCount( &stream->bufferProcessor,
+                        stream->output.framesPerBuffer - stream->output.framesUsedInCurrentBuffer );
+                
+                channel = 0;
+                for( i=0; i<stream->output.deviceCount; ++i )
+                {
+                    /* we have stored the number of channels in the buffer in dwUser */
+                    int channelCount = stream->output.waveHeaders[i][ hostOutputBufferIndex ].dwUser;
+
+                    PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, channel,
+                            stream->output.waveHeaders[i][ hostOutputBufferIndex ].lpData +
+                                stream->output.framesUsedInCurrentBuffer * channelCount *
+                                stream->bufferProcessor.bytesPerHostOutputSample,
+                            channelCount );
+
+                    channel += channelCount;
+                }
+
+                PaUtil_ZeroOutput( &stream->bufferProcessor,
+                        stream->output.framesPerBuffer - stream->output.framesUsedInCurrentBuffer );
+
+                /* we send the entire buffer to the output devices, but we could
+                    just send a partial buffer, rather than zeroing the unused
+                    samples.
+                */
+                AdvanceToNextOutputBuffer( stream );
+            }
+            
+
+            timeout = (stream->allBuffersDurationMs / stream->output.bufferCount) + 1;
+            if( timeout < PA_MME_MIN_TIMEOUT_MSEC_ )
+                timeout = PA_MME_MIN_TIMEOUT_MSEC_;
+
+            waitCount = 0;
+            while( !NoBuffersAreQueued( &stream->output ) && waitCount <= stream->output.bufferCount )
+            {
+                /* wait for MME to signal that a buffer is available */
+                waitResult = WaitForSingleObject( stream->output.bufferEvent, timeout );
+                if( waitResult == WAIT_FAILED )
+                {
+                    break;
+                }
+                else if( waitResult == WAIT_TIMEOUT )
+                {
+                    /* keep waiting */
+                }
+
+                ++waitCount;
+            }
+        }
+    }
+
+    if( PA_IS_OUTPUT_STREAM_(stream) )
+    {
+        for( i =0; i < stream->output.deviceCount; ++i )
+        {
+            mmresult = waveOutReset( ((HWAVEOUT*)stream->output.waveHandles)[i] );
+            if( mmresult != MMSYSERR_NOERROR )
+            {
+                result = paUnanticipatedHostError;
+                PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult );
+            }
+        }
+    }
+
+    if( PA_IS_INPUT_STREAM_(stream) )
+    {
+        for( i=0; i < stream->input.deviceCount; ++i )
+        {
+            mmresult = waveInReset( ((HWAVEIN*)stream->input.waveHandles)[i] );
+            if( mmresult != MMSYSERR_NOERROR )
+            {
+                result = paUnanticipatedHostError;
+                PA_MME_SET_LAST_WAVEIN_ERROR( mmresult );
+            }
+        }
+    }
+
+    stream->isStopped = 1;
+    stream->isActive = 0;
+
+    return result;
+}
+
+
+static PaError AbortStream( PaStream *s )
+{
+    PaError result = paNoError;
+    PaWinMmeStream *stream = (PaWinMmeStream*)s;
+    int timeout;
+    DWORD waitResult;
+    MMRESULT mmresult;
+    unsigned int i;
+    
+    /** @todo
+        REVIEW: the error checking in this function needs review. the basic
+        idea is to return from this function in a known state - for example
+        there is no point avoiding calling waveInReset just because
+        the thread times out.
+    */
+
+    if( stream->processingThread )
+    {
+        /* callback stream */
+        
+        /* Tell processing thread to abort immediately */
+        stream->abortProcessing = 1;
+        SetEvent( stream->abortEvent );
+    }
+
+
+    if( PA_IS_OUTPUT_STREAM_(stream) )
+    {
+        for( i =0; i < stream->output.deviceCount; ++i )
+        {
+            mmresult = waveOutReset( ((HWAVEOUT*)stream->output.waveHandles)[i] );
+            if( mmresult != MMSYSERR_NOERROR )
+            {
+                PA_MME_SET_LAST_WAVEOUT_ERROR( mmresult );
+                return paUnanticipatedHostError;
+            }
+        }
+    }
+
+    if( PA_IS_INPUT_STREAM_(stream) )
+    {
+        for( i=0; i < stream->input.deviceCount; ++i )
+        {
+            mmresult = waveInReset( ((HWAVEIN*)stream->input.waveHandles)[i] );
+            if( mmresult != MMSYSERR_NOERROR )
+            {
+                PA_MME_SET_LAST_WAVEIN_ERROR( mmresult );
+                return paUnanticipatedHostError;
+            }
+        }
+    }
+
+
+    if( stream->processingThread )
+    {
+        /* callback stream */
+        
+        PA_DEBUG(("WinMME AbortStream: waiting for background thread.\n"));
+
+        /* Calculate timeOut longer than longest time it could take to return all buffers. */
+        timeout = (int)(stream->allBuffersDurationMs * 1.5);
+        if( timeout < PA_MME_MIN_TIMEOUT_MSEC_ )
+            timeout = PA_MME_MIN_TIMEOUT_MSEC_;
+            
+        waitResult = WaitForSingleObject( stream->processingThread, timeout );
+        if( waitResult == WAIT_TIMEOUT )
+        {
+            PA_DEBUG(("WinMME AbortStream: timed out while waiting for background thread to finish.\n"));
+            return paTimedOut;
+        }
+
+        CloseHandle( stream->processingThread );
+        stream->processingThread = NULL;
+    }
+
+    stream->isStopped = 1;
+    stream->isActive = 0;
+
+    return result;
+}
+
+
+static PaError IsStreamStopped( PaStream *s )
+{
+    PaWinMmeStream *stream = (PaWinMmeStream*)s;
+
+    return stream->isStopped;
+}
+
+
+static PaError IsStreamActive( PaStream *s )
+{
+    PaWinMmeStream *stream = (PaWinMmeStream*)s;
+
+    return stream->isActive;
+}
+
+
+static PaTime GetStreamTime( PaStream *s )
+{
+    (void) s; /* unused parameter */
+    
+    return PaUtil_GetTime();
+}
+
+
+static double GetStreamCpuLoad( PaStream* s )
+{
+    PaWinMmeStream *stream = (PaWinMmeStream*)s;
+
+    return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );
+}
+
+
+/*
+    As separate stream interfaces are used for blocking and callback
+    streams, the following functions can be guaranteed to only be called
+    for blocking streams.
+*/
+
+static PaError ReadStream( PaStream* s,
+                           void *buffer,
+                           unsigned long frames )
+{
+    PaError result = paNoError;
+    PaWinMmeStream *stream = (PaWinMmeStream*)s;
+    void *userBuffer;
+    unsigned long framesRead = 0;
+    unsigned long framesProcessed;
+    signed int hostInputBufferIndex;
+    DWORD waitResult;
+    DWORD timeout = (unsigned long)(stream->allBuffersDurationMs * 0.5);
+    unsigned int channel, i;
+    
+    if( PA_IS_INPUT_STREAM_(stream) )
+    {
+        /* make a local copy of the user buffer pointer(s). this is necessary
+            because PaUtil_CopyInput() advances these pointers every time
+            it is called.
+        */
+        if( stream->bufferProcessor.userInputIsInterleaved )
+        {
+            userBuffer = buffer;
+        }
+        else
+        {
+            userBuffer = alloca( sizeof(void*) * stream->bufferProcessor.inputChannelCount );
+            if( !userBuffer )
+                return paInsufficientMemory;
+            for( i = 0; i<stream->bufferProcessor.inputChannelCount; ++i )
+                ((void**)userBuffer)[i] = ((void**)buffer)[i];
+        }
+        
+        do{
+            if( CurrentInputBuffersAreDone( stream ) )
+            {
+                if( NoBuffersAreQueued( &stream->input ) )
+                {
+                    /** @todo REVIEW: consider what to do if the input overflows.
+                        do we requeue all of the buffers? should we be running
+                        a thread to make sure they are always queued? */
+
+                    result = paInputOverflowed;
+                }
+
+                hostInputBufferIndex = stream->input.currentBufferIndex;
+
+                PaUtil_SetInputFrameCount( &stream->bufferProcessor,
+                        stream->input.framesPerBuffer - stream->input.framesUsedInCurrentBuffer );
+                
+                channel = 0;
+                for( i=0; i<stream->input.deviceCount; ++i )
+                {
+                    /* we have stored the number of channels in the buffer in dwUser */
+                    int channelCount = stream->input.waveHeaders[i][ hostInputBufferIndex ].dwUser;
+
+                    PaUtil_SetInterleavedInputChannels( &stream->bufferProcessor, channel,
+                            stream->input.waveHeaders[i][ hostInputBufferIndex ].lpData +
+                                stream->input.framesUsedInCurrentBuffer * channelCount *
+                                stream->bufferProcessor.bytesPerHostInputSample,
+                            channelCount );
+
+                    channel += channelCount;
+                }
+                
+                framesProcessed = PaUtil_CopyInput( &stream->bufferProcessor, &userBuffer, frames - framesRead );
+
+                stream->input.framesUsedInCurrentBuffer += framesProcessed;
+                if( stream->input.framesUsedInCurrentBuffer == stream->input.framesPerBuffer )
+                {
+                    result = AdvanceToNextInputBuffer( stream );
+                    if( result != paNoError )
+                        break;
+                }
+
+                framesRead += framesProcessed;      
+
+            }else{
+                /* wait for MME to signal that a buffer is available */
+                waitResult = WaitForSingleObject( stream->input.bufferEvent, timeout );
+                if( waitResult == WAIT_FAILED )
+                {
+                    result = paUnanticipatedHostError;
+                    break;
+                }
+                else if( waitResult == WAIT_TIMEOUT )
+                {
+                    /* if a timeout is encountered, continue,
+                        perhaps we should give up eventually
+                    */
+                }         
+            }
+        }while( framesRead < frames );
+    }
+    else
+    {
+        result = paCanNotReadFromAnOutputOnlyStream;
+    }
+
+    return result;
+}
+
+
+static PaError WriteStream( PaStream* s,
+                            const void *buffer,
+                            unsigned long frames )
+{
+    PaError result = paNoError;
+    PaWinMmeStream *stream = (PaWinMmeStream*)s;
+    const void *userBuffer;
+    unsigned long framesWritten = 0;
+    unsigned long framesProcessed;
+    signed int hostOutputBufferIndex;
+    DWORD waitResult;
+    DWORD timeout = (unsigned long)(stream->allBuffersDurationMs * 0.5);
+    unsigned int channel, i;
+
+        
+    if( PA_IS_OUTPUT_STREAM_(stream) )
+    {
+        /* make a local copy of the user buffer pointer(s). this is necessary
+            because PaUtil_CopyOutput() advances these pointers every time
+            it is called.
+        */
+        if( stream->bufferProcessor.userOutputIsInterleaved )
+        {
+            userBuffer = buffer;
+        }
+        else
+        {
+            userBuffer = alloca( sizeof(void*) * stream->bufferProcessor.outputChannelCount );
+            if( !userBuffer )
+                return paInsufficientMemory;
+            for( i = 0; i<stream->bufferProcessor.outputChannelCount; ++i )
+                ((const void**)userBuffer)[i] = ((const void**)buffer)[i];
+        }
+
+        do{
+            if( CurrentOutputBuffersAreDone( stream ) )
+            {
+                if( NoBuffersAreQueued( &stream->output ) )
+                {
+                    /** @todo REVIEW: consider what to do if the output
+                    underflows. do we requeue all the existing buffers with
+                    zeros? should we run a separate thread to keep the buffers
+                    enqueued at all times? */
+
+                    result = paOutputUnderflowed;
+                }
+
+                hostOutputBufferIndex = stream->output.currentBufferIndex;
+
+                PaUtil_SetOutputFrameCount( &stream->bufferProcessor,
+                        stream->output.framesPerBuffer - stream->output.framesUsedInCurrentBuffer );
+                
+                channel = 0;
+                for( i=0; i<stream->output.deviceCount; ++i )
+                {
+                    /* we have stored the number of channels in the buffer in dwUser */
+                    int channelCount = stream->output.waveHeaders[i][ hostOutputBufferIndex ].dwUser;
+
+                    PaUtil_SetInterleavedOutputChannels( &stream->bufferProcessor, channel,
+                            stream->output.waveHeaders[i][ hostOutputBufferIndex ].lpData +
+                                stream->output.framesUsedInCurrentBuffer * channelCount *
+                                stream->bufferProcessor.bytesPerHostOutputSample,
+                            channelCount );
+
+                    channel += channelCount;
+                }
+                
+                framesProcessed = PaUtil_CopyOutput( &stream->bufferProcessor, &userBuffer, frames - framesWritten );
+
+                stream->output.framesUsedInCurrentBuffer += framesProcessed;
+                if( stream->output.framesUsedInCurrentBuffer == stream->output.framesPerBuffer )
+                {
+                    result = AdvanceToNextOutputBuffer( stream );
+                    if( result != paNoError )
+                        break;
+                }
+
+                framesWritten += framesProcessed;
+            }
+            else
+            {
+                /* wait for MME to signal that a buffer is available */
+                waitResult = WaitForSingleObject( stream->output.bufferEvent, timeout );
+                if( waitResult == WAIT_FAILED )
+                {
+                    result = paUnanticipatedHostError;
+                    break;
+                }
+                else if( waitResult == WAIT_TIMEOUT )
+                {
+                    /* if a timeout is encountered, continue,
+                        perhaps we should give up eventually
+                    */
+                }             
+            }        
+        }while( framesWritten < frames );
+    }
+    else
+    {
+        result = paCanNotWriteToAnInputOnlyStream;
+    }
+    
+    return result;
+}
+
+
+static signed long GetStreamReadAvailable( PaStream* s )
+{
+    PaWinMmeStream *stream = (PaWinMmeStream*)s;
+    
+    if( PA_IS_INPUT_STREAM_(stream) )
+        return GetAvailableFrames( &stream->input );
+    else
+        return paCanNotReadFromAnOutputOnlyStream;
+}
+
+
+static signed long GetStreamWriteAvailable( PaStream* s )
+{
+    PaWinMmeStream *stream = (PaWinMmeStream*)s;
+    
+    if( PA_IS_OUTPUT_STREAM_(stream) )
+        return GetAvailableFrames( &stream->output );
+    else
+        return paCanNotWriteToAnInputOnlyStream;
+}
+
+
+/* NOTE: the following functions are MME-stream specific, and are called directly
+    by client code. We need to check for many more error conditions here because
+    we don't have the benefit of pa_front.c's parameter checking.
+*/
+
+static PaError GetWinMMEStreamPointer( PaWinMmeStream **stream, PaStream *s )
+{
+    PaError result;
+    PaUtilHostApiRepresentation *hostApi;
+    PaWinMmeHostApiRepresentation *winMmeHostApi;
+    
+    result = PaUtil_ValidateStreamPointer( s );
+    if( result != paNoError )
+        return result;
+
+    result = PaUtil_GetHostApiRepresentation( &hostApi, paMME );
+    if( result != paNoError )
+        return result;
+
+    winMmeHostApi = (PaWinMmeHostApiRepresentation*)hostApi;
+    
+    /* note, the following would be easier if there was a generic way of testing
+        that a stream belongs to a specific host API */
+    
+    if( PA_STREAM_REP( s )->streamInterface == &winMmeHostApi->callbackStreamInterface
+            || PA_STREAM_REP( s )->streamInterface == &winMmeHostApi->blockingStreamInterface )
+    {
+        /* s is a WinMME stream */
+        *stream = (PaWinMmeStream *)s;
+        return paNoError;
+    }
+    else
+    {
+        return paIncompatibleStreamHostApi;
+    }
+}
+
+
+int PaWinMME_GetStreamInputHandleCount( PaStream* s )
+{
+    PaWinMmeStream *stream;
+    PaError result = GetWinMMEStreamPointer( &stream, s );
+
+    if( result == paNoError )
+        return (PA_IS_INPUT_STREAM_(stream)) ? stream->input.deviceCount : 0;
+    else
+        return result;
+}
+
+
+HWAVEIN PaWinMME_GetStreamInputHandle( PaStream* s, int handleIndex )
+{
+    PaWinMmeStream *stream;
+    PaError result = GetWinMMEStreamPointer( &stream, s );
+
+    if( result == paNoError
+            && PA_IS_INPUT_STREAM_(stream)
+            && handleIndex >= 0
+            && (unsigned int)handleIndex < stream->input.deviceCount )
+        return ((HWAVEIN*)stream->input.waveHandles)[handleIndex];
+    else
+        return 0;
+}
+
+
+int PaWinMME_GetStreamOutputHandleCount( PaStream* s)
+{
+    PaWinMmeStream *stream;
+    PaError result = GetWinMMEStreamPointer( &stream, s );
+
+    if( result == paNoError )
+        return (PA_IS_OUTPUT_STREAM_(stream)) ? stream->output.deviceCount : 0;
+    else
+        return result;
+}
+
+
+HWAVEOUT PaWinMME_GetStreamOutputHandle( PaStream* s, int handleIndex )
+{
+    PaWinMmeStream *stream;
+    PaError result = GetWinMMEStreamPointer( &stream, s );
+
+    if( result == paNoError
+            && PA_IS_OUTPUT_STREAM_(stream)
+            && handleIndex >= 0
+            && (unsigned int)handleIndex < stream->output.deviceCount )
+        return ((HWAVEOUT*)stream->output.waveHandles)[handleIndex];
+    else
+        return 0;
+}
+
+
+
+
+
diff --git a/utils/iaxclient/lib/portaudio/src/os/mac_osx/pa_mac_hostapis.c b/utils/iaxclient/lib/portaudio/src/os/mac_osx/pa_mac_hostapis.c
new file mode 100644 (file)
index 0000000..7823d2e
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * $Id: pa_mac_hostapis.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * Portable Audio I/O Library Windows initialization table
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2002 Ross Bencina, Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file
+Mac OS host API initialization function table.
+*/
+
+
+#include "pa_hostapi.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+    
+    PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
+    PaError PaMacCore_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
+    PaError PaMacSm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
+    PaError PaJack_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
+    PaError PaMacAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
+    
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+PaUtilHostApiInitializer *paHostApiInitializers[] =
+{
+#ifdef PA_USE_COREAUDIO
+    PaMacCore_Initialize,
+#endif
+    
+#ifdef PA_USE_SM
+    PaMacSm_Initialize,
+#endif
+    
+#ifdef PA_USE_JACK
+    PaJack_Initialize,
+#endif
+
+#ifdef PA_USE_ASIO
+    PaMacAsio_Initialize,
+#endif
+    
+    PaSkeleton_Initialize, /* just for testing */
+    
+    0   /* NULL terminated array */
+};
+
+
+int paDefaultHostApiIndex = 0;
diff --git a/utils/iaxclient/lib/portaudio/src/os/unix/pa_unix_hostapis.c b/utils/iaxclient/lib/portaudio/src/os/unix/pa_unix_hostapis.c
new file mode 100644 (file)
index 0000000..21c0cf2
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * $Id: pa_unix_hostapis.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * Portable Audio I/O Library UNIX initialization table
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2002 Ross Bencina, Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#include "pa_hostapi.h"
+
+PaError PaJack_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
+PaError PaAlsa_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
+PaError PaOSS_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
+/* Added for IRIX, Pieter, oct 2, 2003: */
+PaError PaSGI_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
+
+
+PaUtilHostApiInitializer *paHostApiInitializers[] =
+    {
+#ifdef PA_USE_OSS
+        PaOSS_Initialize,
+#endif
+
+#ifdef PA_USE_ALSA
+        PaAlsa_Initialize,
+#endif
+
+#ifdef PA_USE_JACK
+        PaJack_Initialize,
+#endif
+                    /* Added for IRIX, Pieter, oct 2, 2003: */
+#ifdef PA_USE_SGI 
+        PaSGI_Initialize,
+#endif
+        0   /* NULL terminated array */
+    };
+
+int paDefaultHostApiIndex = 0;
+
+
diff --git a/utils/iaxclient/lib/portaudio/src/os/unix/pa_unix_util.c b/utils/iaxclient/lib/portaudio/src/os/unix/pa_unix_util.c
new file mode 100644 (file)
index 0000000..9a401e4
--- /dev/null
@@ -0,0 +1,672 @@
+/*
+ * $Id: pa_unix_util.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * Portable Audio I/O Library
+ * UNIX platform-specific support functions
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2000 Ross Bencina
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <pthread.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <time.h>
+#include <sys/time.h>
+#include <assert.h>
+#include <string.h> /* For memset */
+#include <math.h>
+#include <errno.h>
+
+#include "pa_util.h"
+#include "pa_unix_util.h"
+
+/*
+   Track memory allocations to avoid leaks.
+ */
+
+#if PA_TRACK_MEMORY
+static int numAllocations_ = 0;
+#endif
+
+
+void *PaUtil_AllocateMemory( long size )
+{
+    void *result = malloc( size );
+
+#if PA_TRACK_MEMORY
+    if( result != NULL ) numAllocations_ += 1;
+#endif
+    return result;
+}
+
+
+void PaUtil_FreeMemory( void *block )
+{
+    if( block != NULL )
+    {
+        free( block );
+#if PA_TRACK_MEMORY
+        numAllocations_ -= 1;
+#endif
+
+    }
+}
+
+
+int PaUtil_CountCurrentlyAllocatedBlocks( void )
+{
+#if PA_TRACK_MEMORY
+    return numAllocations_;
+#else
+    return 0;
+#endif
+}
+
+
+void Pa_Sleep( long msec )
+{
+#ifdef HAVE_NANOSLEEP
+    struct timespec req = {0}, rem = {0};
+    PaTime time = msec / 1.e3;
+    req.tv_sec = (time_t)time;
+    assert(time - req.tv_sec < 1.0);
+    req.tv_nsec = (long)((time - req.tv_sec) * 1.e9);
+    nanosleep(&req, &rem);
+    /* XXX: Try sleeping the remaining time (contained in rem) if interrupted by a signal? */
+#else
+    while( msec > 999 )     /* For OpenBSD and IRIX, argument */
+        {                   /* to usleep must be < 1000000.   */
+        usleep( 999000 );
+        msec -= 999;
+        }
+    usleep( msec * 1000 );
+#endif
+}
+
+/*            *** NOT USED YET: ***
+static int usePerformanceCounter_;
+static double microsecondsPerTick_;
+*/
+
+void PaUtil_InitializeClock( void )
+{
+    /* TODO */
+}
+
+
+PaTime PaUtil_GetTime( void )
+{
+#ifdef HAVE_CLOCK_GETTIME
+    struct timespec tp;
+    clock_gettime(CLOCK_REALTIME, &tp);
+    return (PaTime)(tp.tv_sec + tp.tv_nsec / 1.e9);
+#else
+    struct timeval tv;
+    gettimeofday( &tv, NULL );
+    return (PaTime) tv.tv_usec / 1000000. + tv.tv_sec;
+#endif
+}
+
+PaError PaUtil_InitializeThreading( PaUtilThreading *threading )
+{
+    (void) paUtilErr_;
+    return paNoError;
+}
+
+void PaUtil_TerminateThreading( PaUtilThreading *threading )
+{
+}
+
+PaError PaUtil_StartThreading( PaUtilThreading *threading, void *(*threadRoutine)(void *), void *data )
+{
+    pthread_create( &threading->callbackThread, NULL, threadRoutine, data );
+    return paNoError;
+}
+
+PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *exitResult )
+{
+    PaError result = paNoError;
+    void *pret;
+
+    if( exitResult )
+        *exitResult = paNoError;
+
+    /* Only kill the thread if it isn't in the process of stopping (flushing adaptation buffers) */
+    if( !wait )
+        pthread_cancel( threading->callbackThread );   /* XXX: Safe to call this if the thread has exited on its own? */
+    pthread_join( threading->callbackThread, &pret );
+
+#ifdef PTHREAD_CANCELED
+    if( pret && PTHREAD_CANCELED != pret )
+#else
+    /* !wait means the thread may have been canceled */
+    if( pret && wait )
+#endif
+    {
+        if( exitResult )
+            *exitResult = *(PaError *) pret;
+        free( pret );
+    }
+
+    return result;
+}
+
+/* Threading */
+/* paUnixMainThread 
+ * We have to be a bit careful with defining this global variable,
+ * as explained below. */
+#ifdef __apple__
+/* apple/gcc has a "problem" with global vars and dynamic libs.
+   Initializing it seems to fix the problem.
+   Described a bit in this thread:
+   http://gcc.gnu.org/ml/gcc/2005-06/msg00179.html
+*/
+pthread_t paUnixMainThread = 0;
+#else
+/*pthreads are opaque. We don't know that asigning it an int value
+  always makes sense, so we don't initialize it unless we have to.*/
+pthread_t paUnixMainThread = 0;
+#endif
+
+PaError PaUnixThreading_Initialize()
+{
+    paUnixMainThread = pthread_self();
+    return paNoError;
+}
+
+#if 0
+PaError PaUnixThread_Initialize( PaUnixThread* self )
+{
+    th->watchdogRunning = 0;
+    th->rtSched = 0;
+    th->callbackTime = 0;
+    th->callbackCpuTime = 0;
+    th->useWatchdog = 1;
+    th->throttledSleepTime = 0;
+    th->cpuLoadMeasurer = clm;
+
+    th->rtPrio = (sched_get_priority_max( SCHED_FIFO ) - sched_get_priority_min( SCHED_FIFO )) / 2
+            + sched_get_priority_min( SCHED_FIFO );
+}
+#endif
+
+PaError PaUnixThread_New( PaUnixThread* self, void* (*threadFunc)( void* ), void* threadArg, PaTime waitForChild )
+{
+    PaError result = paNoError;
+    pthread_attr_t attr;
+    int started = 0;
+
+    memset( self, 0, sizeof (PaUnixThread) );
+    PaUnixMutex_Initialize( &self->mtx );
+    PA_ASSERT_CALL( pthread_cond_init( &self->cond, NULL ), 0 );
+
+    self->parentWaiting = 0 != waitForChild;
+
+    /* Spawn thread */
+
+#if 0 && defined _POSIX_MEMLOCK && (_POSIX_MEMLOCK != -1)
+    if( th->rtSched )
+    {
+        if( mlockall( MCL_CURRENT | MCL_FUTURE ) < 0 )
+        {
+            int savedErrno = errno;             /* In case errno gets overwritten */
+            assert( savedErrno != EINVAL );     /* Most likely a programmer error */
+            PA_UNLESS( (savedErrno == EPERM), paInternalError );
+            PA_DEBUG(( "%s: Failed locking memory\n", __FUNCTION__ ));
+        }
+        else
+            PA_DEBUG(( "%s: Successfully locked memory\n", __FUNCTION__ ));
+    }
+#endif
+
+    PA_UNLESS( !pthread_attr_init( &attr ), paInternalError );
+    /* Priority relative to other processes */
+    PA_UNLESS( !pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ), paInternalError );   
+
+    PA_UNLESS( !pthread_create( &self->thread, &attr, threadFunc, threadArg ), paInternalError );
+    started = 1;
+
+#if 0
+    if( th->rtSched )
+    {
+        if( th->useWatchdog )
+        {
+            int err;
+            struct sched_param wdSpm = { 0 };
+            /* Launch watchdog, watchdog sets callback thread priority */
+            int prio = PA_MIN( th->rtPrio + 4, sched_get_priority_max( SCHED_FIFO ) );
+            wdSpm.sched_priority = prio;
+
+            PA_UNLESS( !pthread_attr_init( &attr ), paInternalError );
+            PA_UNLESS( !pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED ), paInternalError );
+            PA_UNLESS( !pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM ), paInternalError );
+            PA_UNLESS( !pthread_attr_setschedpolicy( &attr, SCHED_FIFO ), paInternalError );
+            PA_UNLESS( !pthread_attr_setschedparam( &attr, &wdSpm ), paInternalError );
+            if( (err = pthread_create( &th->watchdogThread, &attr, &WatchdogFunc, th )) )
+            {
+                PA_UNLESS( err == EPERM, paInternalError );
+                /* Permission error, go on without realtime privileges */
+                PA_DEBUG(( "Failed bumping priority\n" ));
+            }
+            else
+            {
+                int policy;
+                th->watchdogRunning = 1;
+                PA_ENSURE_SYSTEM( pthread_getschedparam( th->watchdogThread, &policy, &wdSpm ), 0 );
+                /* Check if priority is right, policy could potentially differ from SCHED_FIFO (but that's alright) */
+                if( wdSpm.sched_priority != prio )
+                {
+                    PA_DEBUG(( "Watchdog priority not set correctly (%d)\n", wdSpm.sched_priority ));
+                    PA_ENSURE( paInternalError );
+                }
+            }
+        }
+        else
+            PA_ENSURE( BoostPriority( th ) );
+    }
+#endif
+    
+    if( self->parentWaiting )
+    {
+        PaTime till;
+        struct timespec ts;
+        int res = 0;
+        PaTime now;
+
+        PA_ENSURE( PaUnixMutex_Lock( &self->mtx ) );
+
+        /* Wait for stream to be started */
+        now = PaUtil_GetTime();
+        till = now + waitForChild;
+
+        while( self->parentWaiting && !res )
+        {
+            if( waitForChild > 0 )
+            {
+                ts.tv_sec = (time_t) floor( till );
+                ts.tv_nsec = (long) ((till - floor( till )) * 1e9);
+                res = pthread_cond_timedwait( &self->cond, &self->mtx.mtx, &ts );
+            }
+            else
+            {
+                res = pthread_cond_wait( &self->cond, &self->mtx.mtx );
+            }
+        }
+
+        PA_ENSURE( PaUnixMutex_Unlock( &self->mtx ) );
+
+        PA_UNLESS( !res || ETIMEDOUT == res, paInternalError );
+        PA_DEBUG(( "%s: Waited for %g seconds for stream to start\n", __FUNCTION__, PaUtil_GetTime() - now ));
+        if( ETIMEDOUT == res )
+        {
+            PA_ENSURE( paTimedOut );
+        }
+    }
+
+end:
+    return result;
+error:
+    if( started )
+    {
+        PaUnixThread_Terminate( self, 0, NULL );
+    }
+
+    goto end;
+}
+
+PaError PaUnixThread_Terminate( PaUnixThread* self, int wait, PaError* exitResult )
+{
+    PaError result = paNoError;
+    void* pret;
+
+    if( exitResult )
+    {
+        *exitResult = paNoError;
+    }
+#if 0
+    if( watchdogExitResult )
+        *watchdogExitResult = paNoError;
+
+    if( th->watchdogRunning )
+    {
+        pthread_cancel( th->watchdogThread );
+        PA_ENSURE_SYSTEM( pthread_join( th->watchdogThread, &pret ), 0 );
+
+        if( pret && pret != PTHREAD_CANCELED )
+        {
+            if( watchdogExitResult )
+                *watchdogExitResult = *(PaError *) pret;
+            free( pret );
+        }
+    }
+#endif
+
+    /* Only kill the thread if it isn't in the process of stopping (flushing adaptation buffers) */
+    /* TODO: Make join time out */
+    self->stopRequested = wait;
+    if( !wait )
+    {
+        PA_DEBUG(( "%s: Canceling thread %d\n", __FUNCTION__, self->thread ));
+        /* XXX: Safe to call this if the thread has exited on its own? */
+        pthread_cancel( self->thread );
+    }
+    PA_DEBUG(( "%s: Joining thread %d\n", __FUNCTION__, self->thread ));
+    PA_ENSURE_SYSTEM( pthread_join( self->thread, &pret ), 0 );
+
+    if( pret && PTHREAD_CANCELED != pret )
+    {
+        if( exitResult )
+        {
+            *exitResult = *(PaError*)pret;
+        }
+        free( pret );
+    }
+
+error:
+    PA_ASSERT_CALL( PaUnixMutex_Terminate( &self->mtx ), paNoError );
+    PA_ASSERT_CALL( pthread_cond_destroy( &self->cond ), 0 );
+
+    return result;
+}
+
+PaError PaUnixThread_PrepareNotify( PaUnixThread* self )
+{
+    PaError result = paNoError;
+    PA_UNLESS( self->parentWaiting, paInternalError );
+
+    PA_ENSURE( PaUnixMutex_Lock( &self->mtx ) );
+    self->locked = 1;
+
+error:
+    return result;
+}
+
+PaError PaUnixThread_NotifyParent( PaUnixThread* self )
+{
+    PaError result = paNoError;
+    PA_UNLESS( self->parentWaiting, paInternalError );
+
+    if( !self->locked )
+    {
+        PA_ENSURE( PaUnixMutex_Lock( &self->mtx ) );
+        self->locked = 1;
+    }
+    self->parentWaiting = 0;
+    pthread_cond_signal( &self->cond );
+    PA_ENSURE( PaUnixMutex_Unlock( &self->mtx ) );
+    self->locked = 0;
+
+error:
+    return result;
+}
+
+int PaUnixThread_StopRequested( PaUnixThread* self )
+{
+    return self->stopRequested;
+}
+
+PaError PaUnixMutex_Initialize( PaUnixMutex* self )
+{
+    PaError result = paNoError;
+    PA_ASSERT_CALL( pthread_mutex_init( &self->mtx, NULL ), 0 );
+    return result;
+}
+
+PaError PaUnixMutex_Terminate( PaUnixMutex* self )
+{
+    PaError result = paNoError;
+    PA_ASSERT_CALL( pthread_mutex_destroy( &self->mtx ), 0 );
+    return result;
+}
+
+/** Lock mutex.
+ *
+ * We're disabling thread cancellation while the thread is holding a lock, so mutexes are 
+ * properly unlocked at termination time.
+ */
+PaError PaUnixMutex_Lock( PaUnixMutex* self )
+{
+    PaError result = paNoError;
+    int oldState;
+    
+    PA_ENSURE_SYSTEM( pthread_setcancelstate( PTHREAD_CANCEL_DISABLE, &oldState ), 0 );
+    PA_ENSURE_SYSTEM( pthread_mutex_lock( &self->mtx ), 0 );
+
+error:
+    return result;
+}
+
+/** Unlock mutex.
+ *
+ * Thread cancellation is enabled again after the mutex is properly unlocked.
+ */
+PaError PaUnixMutex_Unlock( PaUnixMutex* self )
+{
+    PaError result = paNoError;
+    int oldState;
+
+    PA_ENSURE_SYSTEM( pthread_mutex_unlock( &self->mtx ), 0 );
+    PA_ENSURE_SYSTEM( pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, &oldState ), 0 );
+
+error:
+    return result;
+}
+
+#if 0
+/* Threading utility struct */
+typedef struct PaAlsaThreading
+{
+    pthread_t watchdogThread;
+    pthread_t callbackThread;
+    int watchdogRunning;
+    int rtSched;
+    int rtPrio;
+    int useWatchdog;
+    unsigned long throttledSleepTime;
+    volatile PaTime callbackTime;
+    volatile PaTime callbackCpuTime;
+    PaUtilCpuLoadMeasurer *cpuLoadMeasurer;
+} PaAlsaThreading;
+
+static void OnWatchdogExit( void *userData )
+{
+    PaAlsaThreading *th = (PaAlsaThreading *) userData;
+    struct sched_param spm = { 0 };
+    assert( th );
+
+    PA_ASSERT_CALL( pthread_setschedparam( th->callbackThread, SCHED_OTHER, &spm ), 0 );    /* Lower before exiting */
+    PA_DEBUG(( "Watchdog exiting\n" ));
+}
+
+static PaError BoostPriority( PaAlsaThreading *th )
+{
+    PaError result = paNoError;
+    struct sched_param spm = { 0 };
+    spm.sched_priority = th->rtPrio;
+
+    assert( th );
+
+    if( pthread_setschedparam( th->callbackThread, SCHED_FIFO, &spm ) != 0 )
+    {
+        PA_UNLESS( errno == EPERM, paInternalError );  /* Lack permission to raise priority */
+        PA_DEBUG(( "Failed bumping priority\n" ));
+        result = 0;
+    }
+    else
+        result = 1; /* Success */
+error:
+    return result;
+}
+
+static void *WatchdogFunc( void *userData )
+{
+    PaError result = paNoError, *pres = NULL;
+    int err;
+    PaAlsaThreading *th = (PaAlsaThreading *) userData;
+    unsigned intervalMsec = 500;
+    const PaTime maxSeconds = 3.;   /* Max seconds between callbacks */
+    PaTime timeThen = PaUtil_GetTime(), timeNow, timeElapsed, cpuTimeThen, cpuTimeNow, cpuTimeElapsed;
+    double cpuLoad, avgCpuLoad = 0.;
+    int throttled = 0;
+
+    assert( th );
+
+    /* Execute OnWatchdogExit when exiting */
+    pthread_cleanup_push( &OnWatchdogExit, th );
+
+    /* Boost priority of callback thread */
+    PA_ENSURE( result = BoostPriority( th ) );
+    if( !result )
+    {
+        /* Boost failed, might as well exit */
+        pthread_exit( NULL );
+    }
+
+    cpuTimeThen = th->callbackCpuTime;
+    {
+        int policy;
+        struct sched_param spm = { 0 };
+        pthread_getschedparam( pthread_self(), &policy, &spm );
+        PA_DEBUG(( "%s: Watchdog priority is %d\n", __FUNCTION__, spm.sched_priority ));
+    }
+
+    while( 1 )
+    {
+        double lowpassCoeff = 0.9, lowpassCoeff1 = 0.99999 - lowpassCoeff;
+        
+        /* Test before and after in case whatever underlying sleep call isn't interrupted by pthread_cancel */
+        pthread_testcancel();
+        Pa_Sleep( intervalMsec );
+        pthread_testcancel();
+
+        if( PaUtil_GetTime() - th->callbackTime > maxSeconds )
+        {
+            PA_DEBUG(( "Watchdog: Terminating callback thread\n" ));
+            /* Tell thread to terminate */
+            err = pthread_kill( th->callbackThread, SIGKILL );
+            pthread_exit( NULL );
+        }
+
+        PA_DEBUG(( "%s: PortAudio reports CPU load: %g\n", __FUNCTION__, PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) ));
+
+        /* Check if we should throttle, or unthrottle :P */
+        cpuTimeNow = th->callbackCpuTime;
+        cpuTimeElapsed = cpuTimeNow - cpuTimeThen;
+        cpuTimeThen = cpuTimeNow;
+
+        timeNow = PaUtil_GetTime();
+        timeElapsed = timeNow - timeThen;
+        timeThen = timeNow;
+        cpuLoad = cpuTimeElapsed / timeElapsed;
+        avgCpuLoad = avgCpuLoad * lowpassCoeff + cpuLoad * lowpassCoeff1;
+        /*
+        if( throttled )
+            PA_DEBUG(( "Watchdog: CPU load: %g, %g\n", avgCpuLoad, cpuTimeElapsed ));
+            */
+        if( PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) > .925 )
+        {
+            static int policy;
+            static struct sched_param spm = { 0 };
+            static const struct sched_param defaultSpm = { 0 };
+            PA_DEBUG(( "%s: Throttling audio thread, priority %d\n", __FUNCTION__, spm.sched_priority ));
+
+            pthread_getschedparam( th->callbackThread, &policy, &spm );
+            if( !pthread_setschedparam( th->callbackThread, SCHED_OTHER, &defaultSpm ) )
+            {
+                throttled = 1;
+            }
+            else
+                PA_DEBUG(( "Watchdog: Couldn't lower priority of audio thread: %s\n", strerror( errno ) ));
+
+            /* Give other processes a go, before raising priority again */
+            PA_DEBUG(( "%s: Watchdog sleeping for %lu msecs before unthrottling\n", __FUNCTION__, th->throttledSleepTime ));
+            Pa_Sleep( th->throttledSleepTime );
+
+            /* Reset callback priority */
+            if( pthread_setschedparam( th->callbackThread, SCHED_FIFO, &spm ) != 0 )
+            {
+                PA_DEBUG(( "%s: Couldn't raise priority of audio thread: %s\n", __FUNCTION__, strerror( errno ) ));
+            }
+
+            if( PaUtil_GetCpuLoad( th->cpuLoadMeasurer ) >= .99 )
+                intervalMsec = 50;
+            else
+                intervalMsec = 100;
+
+            /*
+            lowpassCoeff = .97;
+            lowpassCoeff1 = .99999 - lowpassCoeff;
+            */
+        }
+        else if( throttled && avgCpuLoad < .8 )
+        {
+            intervalMsec = 500;
+            throttled = 0;
+
+            /*
+            lowpassCoeff = .9;
+            lowpassCoeff1 = .99999 - lowpassCoeff;
+            */
+        }
+    }
+
+    pthread_cleanup_pop( 1 );   /* Execute cleanup on exit */
+
+error:
+    /* Shouldn't get here in the normal case */
+
+    /* Pass on error code */
+    pres = malloc( sizeof (PaError) );
+    *pres = result;
+    
+    pthread_exit( pres );
+}
+
+static void CallbackUpdate( PaAlsaThreading *th )
+{
+    th->callbackTime = PaUtil_GetTime();
+    th->callbackCpuTime = PaUtil_GetCpuLoad( th->cpuLoadMeasurer );
+}
+#endif
+
+/*
+static void *CanaryFunc( void *userData )
+{
+    const unsigned intervalMsec = 1000;
+    PaUtilThreading *th = (PaUtilThreading *) userData;
+
+    while( 1 )
+    {
+        th->canaryTime = PaUtil_GetTime();
+
+        pthread_testcancel();
+        Pa_Sleep( intervalMsec );
+    }
+
+    pthread_exit( NULL );
+}
+*/
diff --git a/utils/iaxclient/lib/portaudio/src/os/unix/pa_unix_util.h b/utils/iaxclient/lib/portaudio/src/os/unix/pa_unix_util.h
new file mode 100644 (file)
index 0000000..49bfedf
--- /dev/null
@@ -0,0 +1,179 @@
+#ifndef PA_UNIX_UTIL_H
+#define PA_UNIX_UTIL_H
+
+#include "pa_cpuload.h"
+#include <assert.h>
+#include <pthread.h>
+#include <signal.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+#define PA_MIN(x,y) ( (x) < (y) ? (x) : (y) )
+#define PA_MAX(x,y) ( (x) > (y) ? (x) : (y) )
+
+/* Utilize GCC branch prediction for error tests */
+#if defined __GNUC__ && __GNUC__ >= 3
+#define UNLIKELY(expr) __builtin_expect( (expr), 0 )
+#else
+#define UNLIKELY(expr) (expr)
+#endif
+
+#define STRINGIZE_HELPER(expr) #expr
+#define STRINGIZE(expr) STRINGIZE_HELPER(expr)
+
+#define PA_UNLESS(expr, code) \
+    do { \
+        if( UNLIKELY( (expr) == 0 ) ) \
+        { \
+            PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
+            result = (code); \
+            goto error; \
+        } \
+    } while (0);
+
+static PaError paUtilErr_;          /* Used with PA_ENSURE */
+
+/* Check PaError */
+#define PA_ENSURE(expr) \
+    do { \
+        if( UNLIKELY( (paUtilErr_ = (expr)) < paNoError ) ) \
+        { \
+            PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \
+            result = paUtilErr_; \
+            goto error; \
+        } \
+    } while (0);
+
+#define PA_ASSERT_CALL(expr, success) \
+    paUtilErr_ = (expr); \
+    assert( success == paUtilErr_ );
+
+#define PA_ENSURE_SYSTEM(expr, success) \
+    do { \
+        if( UNLIKELY( (paUtilErr_ = (expr)) != success ) ) \
+        { \
+            /* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \
+            if( pthread_equal(pthread_self(), paUnixMainThread) ) \
+            { \
+                PaUtil_SetLastHostErrorInfo( paALSA, paUtilErr_, strerror( paUtilErr_ ) ); \
+            } \
+            PaUtil_DebugPrint( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" ); \
+            result = paUnanticipatedHostError; \
+            goto error; \
+        } \
+    } while( 0 );
+
+typedef struct {
+    pthread_t callbackThread;
+} PaUtilThreading;
+
+PaError PaUtil_InitializeThreading( PaUtilThreading *threading );
+void PaUtil_TerminateThreading( PaUtilThreading *threading );
+PaError PaUtil_StartThreading( PaUtilThreading *threading, void *(*threadRoutine)(void *), void *data );
+PaError PaUtil_CancelThreading( PaUtilThreading *threading, int wait, PaError *exitResult );
+
+/* State accessed by utility functions */
+
+/*
+void PaUnix_SetRealtimeScheduling( int rt );
+
+void PaUtil_InitializeThreading( PaUtilThreading *th, PaUtilCpuLoadMeasurer *clm );
+
+PaError PaUtil_CreateCallbackThread( PaUtilThreading *th, void *(*CallbackThreadFunc)( void * ), PaStream *s );
+
+PaError PaUtil_KillCallbackThread( PaUtilThreading *th, PaError *exitResult );
+
+void PaUtil_CallbackUpdate( PaUtilThreading *th );
+*/
+
+extern pthread_t paUnixMainThread;
+
+typedef struct
+{
+    pthread_mutex_t mtx;
+} PaUnixMutex;
+
+PaError PaUnixMutex_Initialize( PaUnixMutex* self );
+PaError PaUnixMutex_Terminate( PaUnixMutex* self );
+PaError PaUnixMutex_Lock( PaUnixMutex* self );
+PaError PaUnixMutex_Unlock( PaUnixMutex* self );
+
+typedef struct
+{
+    pthread_t thread;
+    int parentWaiting;
+    int stopRequested;
+    int locked;
+    PaUnixMutex mtx;
+    pthread_cond_t cond;
+    volatile sig_atomic_t stopRequest;
+} PaUnixThread;
+
+/** Initialize global threading state.
+ */
+PaError PaUnixThreading_Initialize();
+
+/** Perish, passing on eventual error code.
+ *
+ * A thin wrapper around pthread_exit, will automatically pass on any error code to the joining thread.
+ * If the result indicates an error, i.e. it is not equal to paNoError, this function will automatically
+ * allocate a pointer so the error is passed on with pthread_exit. If the result indicates that all is
+ * well however, only a NULL pointer will be handed to pthread_exit. Thus, the joining thread should
+ * check whether a non-NULL result pointer is obtained from pthread_join and make sure to free it.
+ * @param result: The error code to pass on to the joining thread.
+ */
+#define PaUnixThreading_EXIT(result) \
+    do { \
+        PaError* pres = NULL; \
+        if( paNoError != (result) ) \
+        { \
+            pres = malloc( sizeof (PaError) ); \
+            *pres = (result); \
+        } \
+        pthread_exit( pres ); \
+    } while (0);
+
+/** Spawn a thread.
+ *
+ * Intended for spawning the callback thread from the main thread. This function can even block (for a certain
+ * time or indefinitely) untill notified by the callback thread (using PaUnixThread_NotifyParent), which can be
+ * useful in order to make sure that callback has commenced before returning from Pa_StartStream.
+ * @param threadFunc: The function to be executed in the child thread.
+ * @param waitForChild: If not 0, wait for child thread to call PaUnixThread_NotifyParent. Less than 0 means
+ * wait for ever, greater than 0 wait for the specified time.
+ * @return: If timed out waiting on child, paTimedOut.
+ */
+PaError PaUnixThread_New( PaUnixThread* self, void* (*threadFunc)( void* ), void* threadArg, PaTime waitForChild );
+
+/** Terminate thread.
+ *
+ * @param wait: If true, request that background thread stop and wait untill it does, else cancel it.
+ * @param exitResult: If non-null this will upon return contain the exit status of the thread.
+ */
+PaError PaUnixThread_Terminate( PaUnixThread* self, int wait, PaError* exitResult );
+
+/** Prepare to notify waiting parent thread.
+ *
+ * An internal lock must be held before the parent is notified in PaUnixThread_NotifyParent, call this to
+ * acquire it beforehand.
+ * @return: If parent is not waiting, paInternalError.
+ */
+PaError PaUnixThread_PrepareNotify( PaUnixThread* self );
+
+/** Notify waiting parent thread.
+ *
+ * @return: If parent timed out waiting, paTimedOut. If parent was never waiting, paInternalError.
+ */
+PaError PaUnixThread_NotifyParent( PaUnixThread* self );
+
+/** Has the parent thread requested this thread to stop?
+ */
+int PaUnixThread_StopRequested( PaUnixThread* self );
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif
diff --git a/utils/iaxclient/lib/portaudio/src/os/win/pa_win_hostapis.c b/utils/iaxclient/lib/portaudio/src/os/win/pa_win_hostapis.c
new file mode 100644 (file)
index 0000000..c21ed17
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * $Id: pa_win_hostapis.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * Portable Audio I/O Library Windows initialization table
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2002 Ross Bencina, Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file
+    Win32 host API initialization function table.
+
+    @todo Consider using PA_USE_WMME etc instead of PA_NO_WMME. This is what
+    the Unix version does, we should consider being consistent.
+*/
+
+
+#include "pa_hostapi.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+PaError PaSkeleton_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
+PaError PaWinMme_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
+PaError PaWinDs_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
+PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
+PaError PaWinWdm_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
+PaError PaWinWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex index );
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+PaUtilHostApiInitializer *paHostApiInitializers[] =
+    {
+
+#ifndef PA_NO_WMME
+        PaWinMme_Initialize,
+#endif
+
+#ifndef PA_NO_DS
+        PaWinDs_Initialize,
+#endif
+
+#ifndef PA_NO_ASIO
+        PaAsio_Initialize,
+#endif
+
+/*
+#ifndef PA_NO_WASAPI
+               PaWinWasapi_Initialize,
+#endif
+
+#ifndef PA_NO_WDMKS
+       PaWinWdm_Initialize,
+#endif
+*/
+
+        PaSkeleton_Initialize, /* just for testing */
+
+        0   /* NULL terminated array */
+    };
+
+
+int paDefaultHostApiIndex = 0;
+
diff --git a/utils/iaxclient/lib/portaudio/src/os/win/pa_win_util.c b/utils/iaxclient/lib/portaudio/src/os/win/pa_win_util.c
new file mode 100644 (file)
index 0000000..bae01df
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * $Id: pa_win_util.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * Portable Audio I/O Library
+ * Win32 platform-specific support functions
+ *
+ * Based on the Open Source API proposed by Ross Bencina
+ * Copyright (c) 1999-2000 Ross Bencina
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file
+ Win32 platform-specific support functions.
+
+    @todo Implement workaround for QueryPerformanceCounter() skipping forward
+    bug. (see msdn kb Q274323).
+*/
+#include "winpoop.h"
+#include <mmsystem.h> /* for timeGetTime() */
+
+#include "pa_util.h"
+
+
+/*
+   Track memory allocations to avoid leaks.
+ */
+
+#if PA_TRACK_MEMORY
+static int numAllocations_ = 0;
+#endif
+
+
+void *PaUtil_AllocateMemory( long size )
+{
+    void *result = GlobalAlloc( GPTR, size );
+
+#if PA_TRACK_MEMORY
+    if( result != NULL ) numAllocations_ += 1;
+#endif
+    return result;
+}
+
+
+void PaUtil_FreeMemory( void *block )
+{
+    if( block != NULL )
+    {
+        GlobalFree( block );
+#if PA_TRACK_MEMORY
+        numAllocations_ -= 1;
+#endif
+
+    }
+}
+
+
+int PaUtil_CountCurrentlyAllocatedBlocks( void )
+{
+#if PA_TRACK_MEMORY
+    return numAllocations_;
+#else
+    return 0;
+#endif
+}
+
+
+void Pa_Sleep( long msec )
+{
+    Sleep( msec );
+}
+
+static int usePerformanceCounter_;
+static double secondsPerTick_;
+
+void PaUtil_InitializeClock( void )
+{
+    LARGE_INTEGER ticksPerSecond;
+
+    if( QueryPerformanceFrequency( &ticksPerSecond ) != 0 )
+    {
+        usePerformanceCounter_ = 1;
+        secondsPerTick_ = 1.0 / (double)ticksPerSecond.QuadPart;
+    }
+    else
+    {
+        usePerformanceCounter_ = 0;
+    }
+}
+
+
+double PaUtil_GetTime( void )
+{
+    LARGE_INTEGER time;
+
+    if( usePerformanceCounter_ )
+    {
+        /* FIXME:
+            according to this knowledge-base article, QueryPerformanceCounter
+            can skip forward by seconds!
+            http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q274323&
+
+            it may be better to use the rtdsc instruction using inline asm,
+            however then a method is needed to calculate a ticks/seconds ratio.
+        */
+        QueryPerformanceCounter( &time );
+        return time.QuadPart * secondsPerTick_;
+    }
+    else
+    {
+        return timeGetTime() * .001;
+    }
+}
diff --git a/utils/iaxclient/lib/portaudio/src/os/win/pa_x86_plain_converters.c b/utils/iaxclient/lib/portaudio/src/os/win/pa_x86_plain_converters.c
new file mode 100644 (file)
index 0000000..98442a8
--- /dev/null
@@ -0,0 +1,1167 @@
+#include "pa_x86_plain_converters.h"
+
+#include "pa_converters.h"
+#include "pa_dither.h"
+
+/*
+    plain intel assemby versions of standard pa converter functions.
+
+    the main reason these versions are faster than the equivalent C versions
+    is that float -> int casting is expensive in C on x86 because the rounding
+    mode needs to be changed for every cast. these versions only set
+    the rounding mode once outside the loop.
+
+    small additional speed gains are made by the way that clamping is
+    implemented.
+
+TODO:
+    o- inline dither code
+    o- implement Dither only (no-clip) versions
+    o- implement int8 and uint8 versions
+    o- test thouroughly
+
+    o- the packed 24 bit functions could benefit from unrolling and avoiding
+        byte and word sized register access.
+*/
+
+/* -------------------------------------------------------------------------- */
+
+/*
+#define PA_CLIP_( val, min, max )\
+    { val = ((val) < (min)) ? (min) : (((val) > (max)) ? (max) : (val)); }
+*/
+
+/*
+    the following notes were used to determine whether a floating point
+    value should be saturated (ie >1 or <-1) by loading it into an integer
+    register. these should be rewritten so that they make sense.
+
+    an ieee floating point value
+
+    1.xxxxxxxxxxxxxxxxxxxx?
+
+
+    is less than  or equal to 1 and greater than or equal to -1 either:
+
+        if the mantissa is 0 and the unbiased exponent is 0
+
+        OR
+
+        if the unbiased exponent < 0
+
+    this translates to:
+
+        if the mantissa is 0 and the biased exponent is 7F
+
+        or
+
+        if the biased exponent is less than 7F
+
+
+    therefore the value is greater than 1 or less than -1 if
+
+        the mantissa is not 0 and the biased exponent is 7F
+
+        or
+
+        if the biased exponent is greater than 7F
+
+
+    in other words, if we mask out the sign bit, the value is
+    greater than 1 or less than -1 if its integer representation is greater than:
+
+    0 01111111 0000 0000 0000 0000 0000 000
+
+    0011 1111 1000 0000 0000 0000 0000 0000 => 0x3F800000
+*/
+
+/* -------------------------------------------------------------------------- */
+
+static const short fpuControlWord_ = 0x033F; /*round to nearest, 64 bit precision, all exceptions masked*/
+static const double int32Scaler_ = 0x7FFFFFFF;
+static const double ditheredInt32Scaler_ = 0x7FFFFFFE;
+static const double int24Scaler_ = 0x7FFFFF;
+static const double ditheredInt24Scaler_ = 0x7FFFFE;
+static const double int16Scaler_ = 0x7FFF;
+static const double ditheredInt16Scaler_ = 0x7FFE;
+
+#define PA_DITHER_BITS_   (15)
+/* Multiply by PA_FLOAT_DITHER_SCALE_ to get a float between -2.0 and +1.99999 */
+#define PA_FLOAT_DITHER_SCALE_  (1.0 / ((1<<PA_DITHER_BITS_)-1))
+static const float const_float_dither_scale_ = PA_FLOAT_DITHER_SCALE_;
+#define PA_DITHER_SHIFT_  ((32 - PA_DITHER_BITS_) + 1)
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int32(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+/*
+    float *src = (float*)sourceBuffer;
+    signed long *dest =  (signed long*)destinationBuffer;
+    (void)ditherGenerator; // unused parameter
+
+    while( count-- )
+    {
+        // REVIEW
+        double scaled = *src * 0x7FFFFFFF;
+        *dest = (signed long) scaled;
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+*/
+
+    short savedFpuControlWord;
+
+    (void) ditherGenerator; /* unused parameter */
+
+
+    __asm{
+        // esi -> source ptr
+        // eax -> source byte stride
+        // edi -> destination ptr
+        // ebx -> destination byte stride
+        // ecx -> source end ptr
+        // edx -> temp
+
+        mov     esi, sourceBuffer
+
+        mov     edx, 4                  // sizeof float32 and int32
+        mov     eax, sourceStride
+        imul    eax, edx
+
+        mov     ecx, count
+        imul    ecx, eax
+        add     ecx, esi
+    
+        mov     edi, destinationBuffer
+        
+        mov     ebx, destinationStride
+        imul    ebx, edx
+
+        fwait
+        fstcw   savedFpuControlWord
+        fldcw   fpuControlWord_
+
+        fld     int32Scaler_             // stack:  (int)0x7FFFFFFF
+
+    Float32_To_Int32_loop:
+
+        // load unscaled value into st(0)
+        fld     dword ptr [esi]         // stack:  value, (int)0x7FFFFFFF
+        add     esi, eax                // increment source ptr
+        //lea     esi, [esi+eax]
+        fmul    st(0), st(1)            // st(0) *= st(1), stack:  value*0x7FFFFFFF, (int)0x7FFFFFFF
+        /*
+            note: we could store to a temporary qword here which would cause
+            wraparound distortion instead of int indefinite 0x10. that would
+            be more work, and given that not enabling clipping is only advisable
+            when you know that your signal isn't going to clip it isn't worth it.
+        */
+        fistp   dword ptr [edi]         // pop st(0) into dest, stack:  (int)0x7FFFFFFF
+
+        add     edi, ebx                // increment destination ptr
+        //lea     edi, [edi+ebx]
+
+        cmp     esi, ecx                // has src ptr reached end?
+        jne     Float32_To_Int32_loop
+
+        ffree   st(0)
+        fincstp
+
+        fwait
+        fnclex
+        fldcw   savedFpuControlWord
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int32_Clip(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+/*
+    float *src = (float*)sourceBuffer;
+    signed long *dest =  (signed long*)destinationBuffer;
+    (void) ditherGenerator; // unused parameter
+
+    while( count-- )
+    {
+        // REVIEW
+        double scaled = *src * 0x7FFFFFFF;
+        PA_CLIP_( scaled, -2147483648., 2147483647.  );
+        *dest = (signed long) scaled;
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+*/
+
+    short savedFpuControlWord;
+
+    (void) ditherGenerator; /* unused parameter */
+
+    __asm{
+        // esi -> source ptr
+        // eax -> source byte stride
+        // edi -> destination ptr
+        // ebx -> destination byte stride
+        // ecx -> source end ptr
+        // edx -> temp
+
+        mov     esi, sourceBuffer
+
+        mov     edx, 4                  // sizeof float32 and int32
+        mov     eax, sourceStride
+        imul    eax, edx
+
+        mov     ecx, count
+        imul    ecx, eax
+        add     ecx, esi
+    
+        mov     edi, destinationBuffer
+        
+        mov     ebx, destinationStride
+        imul    ebx, edx
+
+        fwait
+        fstcw   savedFpuControlWord
+        fldcw   fpuControlWord_
+
+        fld     int32Scaler_             // stack:  (int)0x7FFFFFFF
+
+    Float32_To_Int32_Clip_loop:
+
+        mov     edx, dword ptr [esi]    // load floating point value into integer register
+
+        and     edx, 0x7FFFFFFF         // mask off sign
+        cmp     edx, 0x3F800000         // greater than 1.0 or less than -1.0
+
+        jg      Float32_To_Int32_Clip_clamp
+
+        // load unscaled value into st(0)
+        fld     dword ptr [esi]         // stack:  value, (int)0x7FFFFFFF
+        add     esi, eax                // increment source ptr
+        //lea     esi, [esi+eax]
+        fmul    st(0), st(1)            // st(0) *= st(1), stack:  value*0x7FFFFFFF, (int)0x7FFFFFFF
+        fistp   dword ptr [edi]         // pop st(0) into dest, stack:  (int)0x7FFFFFFF
+        jmp     Float32_To_Int32_Clip_stored
+    
+    Float32_To_Int32_Clip_clamp:
+        mov     edx, dword ptr [esi]    // load floating point value into integer register
+        shr     edx, 31                 // move sign bit into bit 0
+        add     esi, eax                // increment source ptr
+        //lea     esi, [esi+eax]
+        add     edx, 0x7FFFFFFF         // convert to maximum range integers
+        mov     dword ptr [edi], edx
+
+    Float32_To_Int32_Clip_stored:
+
+        //add     edi, ebx                // increment destination ptr
+        lea     edi, [edi+ebx]
+
+        cmp     esi, ecx                // has src ptr reached end?
+        jne     Float32_To_Int32_Clip_loop
+
+        ffree   st(0)
+        fincstp
+
+        fwait
+        fnclex
+        fldcw   savedFpuControlWord
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int32_DitherClip(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+    /*
+    float *src = (float*)sourceBuffer;
+    signed long *dest =  (signed long*)destinationBuffer;
+
+    while( count-- )
+    {
+        // REVIEW
+        double dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
+        // use smaller scaler to prevent overflow when we add the dither
+        double dithered = ((double)*src * (2147483646.0)) + dither;
+        PA_CLIP_( dithered, -2147483648., 2147483647.  );
+        *dest = (signed long) dithered;
+
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+    */
+
+    short savedFpuControlWord;
+
+    // spill storage:
+    signed long sourceByteStride;
+    signed long highpassedDither;
+
+    // dither state:
+    unsigned long ditherPrevious = ditherGenerator->previous;
+    unsigned long ditherRandSeed1 = ditherGenerator->randSeed1;
+    unsigned long ditherRandSeed2 = ditherGenerator->randSeed2;
+                    
+    __asm{
+        // esi -> source ptr
+        // eax -> source byte stride
+        // edi -> destination ptr
+        // ebx -> destination byte stride
+        // ecx -> source end ptr
+        // edx -> temp
+
+        mov     esi, sourceBuffer
+
+        mov     edx, 4                  // sizeof float32 and int32
+        mov     eax, sourceStride
+        imul    eax, edx
+
+        mov     ecx, count
+        imul    ecx, eax
+        add     ecx, esi
+    
+        mov     edi, destinationBuffer
+        
+        mov     ebx, destinationStride
+        imul    ebx, edx
+
+        fwait
+        fstcw   savedFpuControlWord
+        fldcw   fpuControlWord_
+
+        fld     ditheredInt32Scaler_    // stack:  int scaler
+
+    Float32_To_Int32_DitherClip_loop:
+
+        mov     edx, dword ptr [esi]    // load floating point value into integer register
+
+        and     edx, 0x7FFFFFFF         // mask off sign
+        cmp     edx, 0x3F800000         // greater than 1.0 or less than -1.0
+
+        jg      Float32_To_Int32_DitherClip_clamp
+
+        // load unscaled value into st(0)
+        fld     dword ptr [esi]         // stack:  value, int scaler
+        add     esi, eax                // increment source ptr
+        //lea     esi, [esi+eax]
+        fmul    st(0), st(1)            // st(0) *= st(1), stack:  value*(int scaler), int scaler
+
+        /*
+        // call PaUtil_GenerateFloatTriangularDither with C calling convention
+        mov     sourceByteStride, eax   // save eax
+        mov     sourceEnd, ecx          // save ecx
+        push    ditherGenerator         // pass ditherGenerator parameter on stack
+           call    PaUtil_GenerateFloatTriangularDither  // stack:  dither, value*(int scaler), int scaler
+           pop     edx                     // clear parameter off stack
+        mov     ecx, sourceEnd          // restore ecx
+        mov     eax, sourceByteStride   // restore eax
+        */
+
+    // generate dither
+        mov     sourceByteStride, eax   // save eax
+        mov     edx, 196314165
+        mov     eax, ditherRandSeed1
+        mul     edx                     // eax:edx = eax * 196314165
+        //add     eax, 907633515
+        lea     eax, [eax+907633515]
+        mov     ditherRandSeed1, eax
+        mov     edx, 196314165
+        mov     eax, ditherRandSeed2
+        mul     edx                     // eax:edx = eax * 196314165
+        //add     eax, 907633515
+        lea     eax, [eax+907633515]
+        mov     edx, ditherRandSeed1
+        shr     edx, PA_DITHER_SHIFT_
+        mov     ditherRandSeed2, eax
+        shr     eax, PA_DITHER_SHIFT_
+        //add     eax, edx                // eax -> current
+        lea     eax, [eax+edx]
+        mov     edx, ditherPrevious
+        neg     edx
+        lea     edx, [eax+edx]          // highpass = current - previous
+        mov     highpassedDither, edx
+        mov     ditherPrevious, eax     // previous = current
+        mov     eax, sourceByteStride   // restore eax
+        fild    highpassedDither
+        fmul    const_float_dither_scale_
+    // end generate dither, dither signal in st(0)
+    
+        faddp   st(1), st(0)            // stack: dither + value*(int scaler), int scaler
+        fistp   dword ptr [edi]         // pop st(0) into dest, stack:  int scaler
+        jmp     Float32_To_Int32_DitherClip_stored
+    
+    Float32_To_Int32_DitherClip_clamp:
+        mov     edx, dword ptr [esi]    // load floating point value into integer register
+        shr     edx, 31                 // move sign bit into bit 0
+        add     esi, eax                // increment source ptr
+        //lea     esi, [esi+eax]
+        add     edx, 0x7FFFFFFF         // convert to maximum range integers
+        mov     dword ptr [edi], edx
+
+    Float32_To_Int32_DitherClip_stored:
+
+        //add     edi, ebx              // increment destination ptr
+        lea     edi, [edi+ebx]
+
+        cmp     esi, ecx                // has src ptr reached end?
+        jne     Float32_To_Int32_DitherClip_loop
+
+        ffree   st(0)
+        fincstp
+
+        fwait
+        fnclex
+        fldcw   savedFpuControlWord
+    }
+
+    ditherGenerator->previous = ditherPrevious;
+    ditherGenerator->randSeed1 = ditherRandSeed1;
+    ditherGenerator->randSeed2 = ditherRandSeed2;
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int24(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+/*
+    float *src = (float*)sourceBuffer;
+    unsigned char *dest = (unsigned char*)destinationBuffer;
+    signed long temp;
+
+    (void) ditherGenerator; // unused parameter
+    
+    while( count-- )
+    {
+        // convert to 32 bit and drop the low 8 bits
+        double scaled = *src * 0x7FFFFFFF;
+        temp = (signed long) scaled;
+
+        dest[0] = (unsigned char)(temp >> 8);
+        dest[1] = (unsigned char)(temp >> 16);
+        dest[2] = (unsigned char)(temp >> 24);
+
+        src += sourceStride;
+        dest += destinationStride * 3;
+    }
+*/
+
+    short savedFpuControlWord;
+    
+    signed long tempInt32;
+
+    (void) ditherGenerator; /* unused parameter */
+                 
+    __asm{
+        // esi -> source ptr
+        // eax -> source byte stride
+        // edi -> destination ptr
+        // ebx -> destination byte stride
+        // ecx -> source end ptr
+        // edx -> temp
+
+        mov     esi, sourceBuffer
+
+        mov     edx, 4                  // sizeof float32
+        mov     eax, sourceStride
+        imul    eax, edx
+
+        mov     ecx, count
+        imul    ecx, eax
+        add     ecx, esi
+
+        mov     edi, destinationBuffer
+
+        mov     edx, 3                  // sizeof int24
+        mov     ebx, destinationStride
+        imul    ebx, edx
+
+        fwait
+        fstcw   savedFpuControlWord
+        fldcw   fpuControlWord_
+
+        fld     int24Scaler_             // stack:  (int)0x7FFFFF
+
+    Float32_To_Int24_loop:
+
+        // load unscaled value into st(0)
+        fld     dword ptr [esi]         // stack:  value, (int)0x7FFFFF
+        add     esi, eax                // increment source ptr
+        //lea     esi, [esi+eax]
+        fmul    st(0), st(1)            // st(0) *= st(1), stack:  value*0x7FFFFF, (int)0x7FFFFF
+        fistp   tempInt32               // pop st(0) into tempInt32, stack:  (int)0x7FFFFF
+        mov     edx, tempInt32
+
+        mov     byte ptr [edi], DL
+        shr     edx, 8
+        //mov     byte ptr [edi+1], DL
+        //mov     byte ptr [edi+2], DH
+        mov     word ptr [edi+1], DX
+
+        //add     edi, ebx                // increment destination ptr
+        lea     edi, [edi+ebx]
+
+        cmp     esi, ecx                // has src ptr reached end?
+        jne     Float32_To_Int24_loop
+
+        ffree   st(0)
+        fincstp
+
+        fwait
+        fnclex
+        fldcw   savedFpuControlWord
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int24_Clip(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+/*
+    float *src = (float*)sourceBuffer;
+    unsigned char *dest = (unsigned char*)destinationBuffer;
+    signed long temp;
+
+    (void) ditherGenerator; // unused parameter
+    
+    while( count-- )
+    {
+        // convert to 32 bit and drop the low 8 bits
+        double scaled = *src * 0x7FFFFFFF;
+        PA_CLIP_( scaled, -2147483648., 2147483647.  );
+        temp = (signed long) scaled;
+
+        dest[0] = (unsigned char)(temp >> 8);
+        dest[1] = (unsigned char)(temp >> 16);
+        dest[2] = (unsigned char)(temp >> 24);
+
+        src += sourceStride;
+        dest += destinationStride * 3;
+    }
+*/
+
+    short savedFpuControlWord;
+    
+    signed long tempInt32;
+
+    (void) ditherGenerator; /* unused parameter */
+                 
+    __asm{
+        // esi -> source ptr
+        // eax -> source byte stride
+        // edi -> destination ptr
+        // ebx -> destination byte stride
+        // ecx -> source end ptr
+        // edx -> temp
+
+        mov     esi, sourceBuffer
+
+        mov     edx, 4                  // sizeof float32
+        mov     eax, sourceStride
+        imul    eax, edx
+
+        mov     ecx, count
+        imul    ecx, eax
+        add     ecx, esi
+
+        mov     edi, destinationBuffer
+
+        mov     edx, 3                  // sizeof int24
+        mov     ebx, destinationStride
+        imul    ebx, edx
+
+        fwait
+        fstcw   savedFpuControlWord
+        fldcw   fpuControlWord_
+
+        fld     int24Scaler_             // stack:  (int)0x7FFFFF
+
+    Float32_To_Int24_Clip_loop:
+
+        mov     edx, dword ptr [esi]    // load floating point value into integer register
+
+        and     edx, 0x7FFFFFFF         // mask off sign
+        cmp     edx, 0x3F800000         // greater than 1.0 or less than -1.0
+
+        jg      Float32_To_Int24_Clip_clamp
+
+        // load unscaled value into st(0)
+        fld     dword ptr [esi]         // stack:  value, (int)0x7FFFFF
+        add     esi, eax                // increment source ptr
+        //lea     esi, [esi+eax]
+        fmul    st(0), st(1)            // st(0) *= st(1), stack:  value*0x7FFFFF, (int)0x7FFFFF
+        fistp   tempInt32               // pop st(0) into tempInt32, stack:  (int)0x7FFFFF
+        mov     edx, tempInt32
+        jmp     Float32_To_Int24_Clip_store
+    
+    Float32_To_Int24_Clip_clamp:
+        mov     edx, dword ptr [esi]    // load floating point value into integer register
+        shr     edx, 31                 // move sign bit into bit 0
+        add     esi, eax                // increment source ptr
+        //lea     esi, [esi+eax]
+        add     edx, 0x7FFFFF           // convert to maximum range integers
+
+    Float32_To_Int24_Clip_store:
+
+        mov     byte ptr [edi], DL
+        shr     edx, 8
+        //mov     byte ptr [edi+1], DL
+        //mov     byte ptr [edi+2], DH
+        mov     word ptr [edi+1], DX
+
+        //add     edi, ebx                // increment destination ptr
+        lea     edi, [edi+ebx]
+
+        cmp     esi, ecx                // has src ptr reached end?
+        jne     Float32_To_Int24_Clip_loop
+
+        ffree   st(0)
+        fincstp
+
+        fwait
+        fnclex
+        fldcw   savedFpuControlWord
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int24_DitherClip(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+/*
+    float *src = (float*)sourceBuffer;
+    unsigned char *dest = (unsigned char*)destinationBuffer;
+    signed long temp;
+    
+    while( count-- )
+    {
+        // convert to 32 bit and drop the low 8 bits
+
+        // FIXME: the dither amplitude here appears to be too small by 8 bits
+        double dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
+        // use smaller scaler to prevent overflow when we add the dither
+        double dithered = ((double)*src * (2147483646.0)) + dither;
+        PA_CLIP_( dithered, -2147483648., 2147483647.  );
+        
+        temp = (signed long) dithered;
+
+        dest[0] = (unsigned char)(temp >> 8);
+        dest[1] = (unsigned char)(temp >> 16);
+        dest[2] = (unsigned char)(temp >> 24);
+
+        src += sourceStride;
+        dest += destinationStride * 3;
+    }
+*/
+
+    short savedFpuControlWord;
+
+    // spill storage:
+    signed long sourceByteStride;
+    signed long highpassedDither;
+
+    // dither state:
+    unsigned long ditherPrevious = ditherGenerator->previous;
+    unsigned long ditherRandSeed1 = ditherGenerator->randSeed1;
+    unsigned long ditherRandSeed2 = ditherGenerator->randSeed2;
+    
+    signed long tempInt32;
+                 
+    __asm{
+        // esi -> source ptr
+        // eax -> source byte stride
+        // edi -> destination ptr
+        // ebx -> destination byte stride
+        // ecx -> source end ptr
+        // edx -> temp
+
+        mov     esi, sourceBuffer
+
+        mov     edx, 4                  // sizeof float32
+        mov     eax, sourceStride
+        imul    eax, edx
+
+        mov     ecx, count
+        imul    ecx, eax
+        add     ecx, esi
+
+        mov     edi, destinationBuffer
+
+        mov     edx, 3                  // sizeof int24
+        mov     ebx, destinationStride
+        imul    ebx, edx
+
+        fwait
+        fstcw   savedFpuControlWord
+        fldcw   fpuControlWord_
+
+        fld     ditheredInt24Scaler_    // stack:  int scaler
+
+    Float32_To_Int24_DitherClip_loop:
+
+        mov     edx, dword ptr [esi]    // load floating point value into integer register
+
+        and     edx, 0x7FFFFFFF         // mask off sign
+        cmp     edx, 0x3F800000         // greater than 1.0 or less than -1.0
+
+        jg      Float32_To_Int24_DitherClip_clamp
+
+        // load unscaled value into st(0)
+        fld     dword ptr [esi]         // stack:  value, int scaler
+        add     esi, eax                // increment source ptr
+        //lea     esi, [esi+eax]
+        fmul    st(0), st(1)            // st(0) *= st(1), stack:  value*(int scaler), int scaler
+
+    /*
+        // call PaUtil_GenerateFloatTriangularDither with C calling convention
+        mov     sourceByteStride, eax   // save eax
+        mov     sourceEnd, ecx          // save ecx
+        push    ditherGenerator         // pass ditherGenerator parameter on stack
+           call    PaUtil_GenerateFloatTriangularDither  // stack:  dither, value*(int scaler), int scaler
+           pop     edx                     // clear parameter off stack
+        mov     ecx, sourceEnd          // restore ecx
+        mov     eax, sourceByteStride   // restore eax
+    */
+    
+    // generate dither
+        mov     sourceByteStride, eax   // save eax
+        mov     edx, 196314165
+        mov     eax, ditherRandSeed1
+        mul     edx                     // eax:edx = eax * 196314165
+        //add     eax, 907633515
+        lea     eax, [eax+907633515]
+        mov     ditherRandSeed1, eax
+        mov     edx, 196314165
+        mov     eax, ditherRandSeed2
+        mul     edx                     // eax:edx = eax * 196314165
+        //add     eax, 907633515
+        lea     eax, [eax+907633515]
+        mov     edx, ditherRandSeed1
+        shr     edx, PA_DITHER_SHIFT_
+        mov     ditherRandSeed2, eax
+        shr     eax, PA_DITHER_SHIFT_
+        //add     eax, edx                // eax -> current
+        lea     eax, [eax+edx]
+        mov     edx, ditherPrevious
+        neg     edx
+        lea     edx, [eax+edx]          // highpass = current - previous
+        mov     highpassedDither, edx
+        mov     ditherPrevious, eax     // previous = current
+        mov     eax, sourceByteStride   // restore eax
+        fild    highpassedDither
+        fmul    const_float_dither_scale_
+    // end generate dither, dither signal in st(0)
+
+        faddp   st(1), st(0)            // stack: dither * value*(int scaler), int scaler
+        fistp   tempInt32               // pop st(0) into tempInt32, stack:  int scaler
+        mov     edx, tempInt32
+        jmp     Float32_To_Int24_DitherClip_store
+    
+    Float32_To_Int24_DitherClip_clamp:
+        mov     edx, dword ptr [esi]    // load floating point value into integer register
+        shr     edx, 31                 // move sign bit into bit 0
+        add     esi, eax                // increment source ptr
+        //lea     esi, [esi+eax]
+        add     edx, 0x7FFFFF           // convert to maximum range integers
+
+    Float32_To_Int24_DitherClip_store:
+
+        mov     byte ptr [edi], DL
+        shr     edx, 8
+        //mov     byte ptr [edi+1], DL
+        //mov     byte ptr [edi+2], DH
+        mov     word ptr [edi+1], DX
+
+        //add     edi, ebx                // increment destination ptr
+        lea     edi, [edi+ebx]
+
+        cmp     esi, ecx                // has src ptr reached end?
+        jne     Float32_To_Int24_DitherClip_loop
+
+        ffree   st(0)
+        fincstp
+
+        fwait
+        fnclex
+        fldcw   savedFpuControlWord
+    }
+
+    ditherGenerator->previous = ditherPrevious;
+    ditherGenerator->randSeed1 = ditherRandSeed1;
+    ditherGenerator->randSeed2 = ditherRandSeed2;
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int16(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+/*
+    float *src = (float*)sourceBuffer;
+    signed short *dest =  (signed short*)destinationBuffer;
+    (void)ditherGenerator; // unused parameter
+
+    while( count-- )
+    {
+
+        short samp = (short) (*src * (32767.0f));
+        *dest = samp;
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+*/
+
+    short savedFpuControlWord;
+   
+    (void) ditherGenerator; /* unused parameter */
+
+    __asm{
+        // esi -> source ptr
+        // eax -> source byte stride
+        // edi -> destination ptr
+        // ebx -> destination byte stride
+        // ecx -> source end ptr
+        // edx -> temp
+
+        mov     esi, sourceBuffer
+
+        mov     edx, 4                  // sizeof float32
+        mov     eax, sourceStride
+        imul    eax, edx                // source byte stride
+
+        mov     ecx, count
+        imul    ecx, eax
+        add     ecx, esi                // source end ptr = count * source byte stride + source ptr
+
+        mov     edi, destinationBuffer
+
+        mov     edx, 2                  // sizeof int16
+        mov     ebx, destinationStride
+        imul    ebx, edx                // destination byte stride
+
+        fwait
+        fstcw   savedFpuControlWord
+        fldcw   fpuControlWord_
+
+        fld     int16Scaler_            // stack:  (int)0x7FFF
+
+    Float32_To_Int16_loop:
+
+        // load unscaled value into st(0)
+        fld     dword ptr [esi]         // stack:  value, (int)0x7FFF
+        add     esi, eax                // increment source ptr
+        //lea     esi, [esi+eax]
+        fmul    st(0), st(1)            // st(0) *= st(1), stack:  value*0x7FFF, (int)0x7FFF
+        fistp   word ptr [edi]          // store scaled int into dest, stack:  (int)0x7FFF
+
+        add     edi, ebx                // increment destination ptr
+        //lea     edi, [edi+ebx]
+        
+        cmp     esi, ecx                // has src ptr reached end?
+        jne     Float32_To_Int16_loop
+
+        ffree   st(0)
+        fincstp
+
+        fwait
+        fnclex
+        fldcw   savedFpuControlWord
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int16_Clip(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+/*
+    float *src = (float*)sourceBuffer;
+    signed short *dest =  (signed short*)destinationBuffer;
+    (void)ditherGenerator; // unused parameter
+
+    while( count-- )
+    {
+        long samp = (signed long) (*src * (32767.0f));
+        PA_CLIP_( samp, -0x8000, 0x7FFF );
+        *dest = (signed short) samp;
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+*/
+
+    short savedFpuControlWord;
+   
+    (void) ditherGenerator; /* unused parameter */
+
+    __asm{
+        // esi -> source ptr
+        // eax -> source byte stride
+        // edi -> destination ptr
+        // ebx -> destination byte stride
+        // ecx -> source end ptr
+        // edx -> temp
+
+        mov     esi, sourceBuffer
+
+        mov     edx, 4                  // sizeof float32
+        mov     eax, sourceStride
+        imul    eax, edx                // source byte stride
+
+        mov     ecx, count
+        imul    ecx, eax
+        add     ecx, esi                // source end ptr = count * source byte stride + source ptr
+
+        mov     edi, destinationBuffer
+
+        mov     edx, 2                  // sizeof int16
+        mov     ebx, destinationStride
+        imul    ebx, edx                // destination byte stride
+
+        fwait
+        fstcw   savedFpuControlWord
+        fldcw   fpuControlWord_
+
+        fld     int16Scaler_            // stack:  (int)0x7FFF
+
+    Float32_To_Int16_Clip_loop:
+
+        mov     edx, dword ptr [esi]    // load floating point value into integer register
+
+        and     edx, 0x7FFFFFFF         // mask off sign
+        cmp     edx, 0x3F800000         // greater than 1.0 or less than -1.0
+
+        jg      Float32_To_Int16_Clip_clamp
+
+        // load unscaled value into st(0)
+        fld     dword ptr [esi]         // stack:  value, (int)0x7FFF
+        add     esi, eax                // increment source ptr
+        //lea     esi, [esi+eax]
+        fmul    st(0), st(1)            // st(0) *= st(1), stack:  value*0x7FFF, (int)0x7FFF
+        fistp   word ptr [edi]          // store scaled int into dest, stack:  (int)0x7FFF
+        jmp     Float32_To_Int16_Clip_stored
+    
+    Float32_To_Int16_Clip_clamp:
+        mov     edx, dword ptr [esi]    // load floating point value into integer register
+        shr     edx, 31                 // move sign bit into bit 0
+        add     esi, eax                // increment source ptr
+        //lea     esi, [esi+eax]
+        add     dx, 0x7FFF              // convert to maximum range integers
+        mov     word ptr [edi], dx      // store clamped into into dest
+
+    Float32_To_Int16_Clip_stored:
+
+        add     edi, ebx                // increment destination ptr
+        //lea     edi, [edi+ebx]
+        
+        cmp     esi, ecx                // has src ptr reached end?
+        jne     Float32_To_Int16_Clip_loop
+
+        ffree   st(0)
+        fincstp
+
+        fwait
+        fnclex
+        fldcw   savedFpuControlWord
+    }
+}
+
+/* -------------------------------------------------------------------------- */
+
+static void Float32_To_Int16_DitherClip(
+    void *destinationBuffer, signed int destinationStride,
+    void *sourceBuffer, signed int sourceStride,
+    unsigned int count, PaUtilTriangularDitherGenerator *ditherGenerator )
+{
+/*
+    float *src = (float*)sourceBuffer;
+    signed short *dest =  (signed short*)destinationBuffer;
+    (void)ditherGenerator; // unused parameter
+
+    while( count-- )
+    {
+
+        float dither  = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
+        // use smaller scaler to prevent overflow when we add the dither 
+        float dithered = (*src * (32766.0f)) + dither;
+        signed long samp = (signed long) dithered;
+        PA_CLIP_( samp, -0x8000, 0x7FFF );
+        *dest = (signed short) samp;
+
+        src += sourceStride;
+        dest += destinationStride;
+    }
+*/
+
+    short savedFpuControlWord;
+
+    // spill storage:
+    signed long sourceByteStride;
+    signed long highpassedDither;
+
+    // dither state:
+    unsigned long ditherPrevious = ditherGenerator->previous;
+    unsigned long ditherRandSeed1 = ditherGenerator->randSeed1;
+    unsigned long ditherRandSeed2 = ditherGenerator->randSeed2;
+
+    __asm{
+        // esi -> source ptr
+        // eax -> source byte stride
+        // edi -> destination ptr
+        // ebx -> destination byte stride
+        // ecx -> source end ptr
+        // edx -> temp
+
+        mov     esi, sourceBuffer
+
+        mov     edx, 4                  // sizeof float32
+        mov     eax, sourceStride
+        imul    eax, edx                // source byte stride
+
+        mov     ecx, count
+        imul    ecx, eax
+        add     ecx, esi                // source end ptr = count * source byte stride + source ptr
+
+        mov     edi, destinationBuffer
+
+        mov     edx, 2                  // sizeof int16
+        mov     ebx, destinationStride
+        imul    ebx, edx                // destination byte stride
+
+        fwait
+        fstcw   savedFpuControlWord
+        fldcw   fpuControlWord_
+
+        fld     ditheredInt16Scaler_    // stack:  int scaler
+
+    Float32_To_Int16_DitherClip_loop:
+
+        mov     edx, dword ptr [esi]    // load floating point value into integer register
+
+        and     edx, 0x7FFFFFFF         // mask off sign
+        cmp     edx, 0x3F800000         // greater than 1.0 or less than -1.0
+
+        jg      Float32_To_Int16_DitherClip_clamp
+
+        // load unscaled value into st(0)
+        fld     dword ptr [esi]         // stack:  value, int scaler
+        add     esi, eax                // increment source ptr
+        //lea     esi, [esi+eax]
+        fmul    st(0), st(1)            // st(0) *= st(1), stack:  value*(int scaler), int scaler
+
+        /*
+        // call PaUtil_GenerateFloatTriangularDither with C calling convention
+        mov     sourceByteStride, eax   // save eax
+        mov     sourceEnd, ecx          // save ecx
+        push    ditherGenerator         // pass ditherGenerator parameter on stack
+           call    PaUtil_GenerateFloatTriangularDither  // stack:  dither, value*(int scaler), int scaler
+           pop     edx                     // clear parameter off stack
+        mov     ecx, sourceEnd          // restore ecx
+        mov     eax, sourceByteStride   // restore eax
+        */
+
+    // generate dither
+        mov     sourceByteStride, eax   // save eax
+        mov     edx, 196314165
+        mov     eax, ditherRandSeed1
+        mul     edx                     // eax:edx = eax * 196314165
+        //add     eax, 907633515
+        lea     eax, [eax+907633515]
+        mov     ditherRandSeed1, eax
+        mov     edx, 196314165
+        mov     eax, ditherRandSeed2
+        mul     edx                     // eax:edx = eax * 196314165
+        //add     eax, 907633515
+        lea     eax, [eax+907633515]
+        mov     edx, ditherRandSeed1
+        shr     edx, PA_DITHER_SHIFT_
+        mov     ditherRandSeed2, eax
+        shr     eax, PA_DITHER_SHIFT_
+        //add     eax, edx                // eax -> current
+        lea     eax, [eax+edx]            // current = randSeed1>>x + randSeed2>>x
+        mov     edx, ditherPrevious
+        neg     edx
+        lea     edx, [eax+edx]          // highpass = current - previous
+        mov     highpassedDither, edx
+        mov     ditherPrevious, eax     // previous = current
+        mov     eax, sourceByteStride   // restore eax
+        fild    highpassedDither
+        fmul    const_float_dither_scale_
+    // end generate dither, dither signal in st(0)
+        
+        faddp   st(1), st(0)            // stack: dither * value*(int scaler), int scaler
+        fistp   word ptr [edi]          // store scaled int into dest, stack:  int scaler
+        jmp     Float32_To_Int16_DitherClip_stored
+    
+    Float32_To_Int16_DitherClip_clamp:
+        mov     edx, dword ptr [esi]    // load floating point value into integer register
+        shr     edx, 31                 // move sign bit into bit 0
+        add     esi, eax                // increment source ptr
+        //lea     esi, [esi+eax]
+        add     dx, 0x7FFF              // convert to maximum range integers
+        mov     word ptr [edi], dx      // store clamped into into dest
+
+    Float32_To_Int16_DitherClip_stored:
+
+        add     edi, ebx                // increment destination ptr
+        //lea     edi, [edi+ebx]
+        
+        cmp     esi, ecx                // has src ptr reached end?
+        jne     Float32_To_Int16_DitherClip_loop
+
+        ffree   st(0)
+        fincstp
+
+        fwait
+        fnclex
+        fldcw   savedFpuControlWord
+    }
+
+    ditherGenerator->previous = ditherPrevious;
+    ditherGenerator->randSeed1 = ditherRandSeed1;
+    ditherGenerator->randSeed2 = ditherRandSeed2;
+}
+
+/* -------------------------------------------------------------------------- */
+
+void PaUtil_InitializeX86PlainConverters( void )
+{
+    paConverters.Float32_To_Int32 = Float32_To_Int32;
+    paConverters.Float32_To_Int32_Clip = Float32_To_Int32_Clip;
+    paConverters.Float32_To_Int32_DitherClip = Float32_To_Int32_DitherClip;
+
+    paConverters.Float32_To_Int24 = Float32_To_Int24;
+    paConverters.Float32_To_Int24_Clip = Float32_To_Int24_Clip;
+    paConverters.Float32_To_Int24_DitherClip = Float32_To_Int24_DitherClip;
+    
+    paConverters.Float32_To_Int16 = Float32_To_Int16;
+    paConverters.Float32_To_Int16_Clip = Float32_To_Int16_Clip;
+    paConverters.Float32_To_Int16_DitherClip = Float32_To_Int16_DitherClip;
+}
+
+/* -------------------------------------------------------------------------- */
diff --git a/utils/iaxclient/lib/portaudio/src/os/win/pa_x86_plain_converters.h b/utils/iaxclient/lib/portaudio/src/os/win/pa_x86_plain_converters.h
new file mode 100644 (file)
index 0000000..f56c710
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef PA_X86_PLAIN_CONVERTERS_H
+#define PA_X86_PLAIN_CONVERTERS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+
+/**
+ @brief Install optimised converter functions suitable for all IA32 processors
+*/
+void PaUtil_InitializeX86PlainConverters( void );
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* PA_X86_PLAIN_CONVERTERS_H */
diff --git a/utils/iaxclient/lib/portaudio/test/README.txt b/utils/iaxclient/lib/portaudio/test/README.txt
new file mode 100644 (file)
index 0000000..f3a0b82
--- /dev/null
@@ -0,0 +1,60 @@
+This directory contains various programs to test PortAudio. The files 
+named patest_* are tests, the files named debug_* are just scratch 
+files that may or may not work.
+
+All following tests are up to date with the V19 API. They should all compile
+(without any warnings on GCC 3.3). Note that this does not necissarily mean that 
+the tests pass, just that they compile.
+
+    x- paqa_devs.c 
+    x- paqa_errs.c   (needs reviewing)
+    x- patest1.c
+    x- patest_buffer.c
+    x- patest_callbackstop.c
+    x- patest_clip.c (last test fails, dither doesn't currently force clip in V19)
+    x- patest_dither.c
+    x- patest_hang.c
+    x- patest_latency.c
+    x- patest_leftright.c
+    x- patest_longsine.c
+    x- patest_many.c
+    x- patest_maxsines.c
+       o- patest_mono.c
+    x- patest_multi_sine.c
+    x- patest_pink.c
+    x- patest_prime.c
+    x- patest_read_record.c
+    x- patest_record.c
+    x- patest_ringmix.c
+    x- patest_saw.c
+    x- patest_sine.c
+    x- patest_sine8.c
+    x- patest_sine_formats.c
+    x- patest_sine_time.c
+    x- patest_start_stop.c
+    x- patest_stop.c
+    x- patest_sync.c
+    x- patest_toomanysines.c
+       o- patest_two_rates.c
+    x- patest_underflow.c
+    x- patest_wire.c
+    x- patest_write_sine.c
+    x- pa_devs.c
+    x- pa_fuzz.c
+    x- pa_minlat.c
+
+The debug_ files are still in V18 format and may need some V19 adaption.
+Feel free to fix them, most simply require adjusting to the new API.
+
+o- pa_tests/debug_convert.c
+o- pa_tests/debug_dither_calc.c
+o- pa_tests/debug_dual.c
+o- pa_tests/debug_multi_in.c
+o- pa_tests/debug_multi_out.c
+o- pa_tests/debug_record.c
+o- pa_tests/debug_record_reuse.c
+o- pa_tests/debug_sine.c
+o- pa_tests/debug_sine_amp.c
+o- pa_tests/debug_sine_formats.c
+o- pa_tests/debug_srate.c
+o- pa_tests/debug_test1.c
diff --git a/utils/iaxclient/lib/portaudio/test/debug_convert.c b/utils/iaxclient/lib/portaudio/test/debug_convert.c
new file mode 100644 (file)
index 0000000..58c1700
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * $Id: debug_convert.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * Convert tagged values.
+ *
+ * Author: Phil Burk <philburk@softsynth.com>
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+#define OUTPUT_DEVICE       (Pa_GetDefaultOutputDeviceID())
+//#define OUTPUT_DEVICE       (11)
+#define NUM_SECONDS         (8)
+#define SLEEP_DUR           (800)
+#define SAMPLE_RATE         (44100)
+#define FRAMES_PER_BUFFER   (256)
+
+#define NUM_BUFFERS         (0)
+
+typedef struct
+{
+    unsigned int framesToGo;
+}
+paTestData;
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( void *inputBuffer, void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                           PaTimestamp outTime, void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    short *out = (short*)outputBuffer;
+    int i;
+    int finished = 0;
+    (void) outTime; /* Prevent unused variable warnings. */
+    (void) inputBuffer;
+
+    if( data->framesToGo < framesPerBuffer )  finished = 1;
+
+    for( i=0; i<framesPerBuffer; i++ )
+    {
+        *out++ = 0x0000 + i;  /* left */
+        *out++ = 0x1000 + i;  /* right */
+    }
+    return finished;
+}
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PortAudioStream *stream;
+    PaError err;
+    paTestData data;
+    int i;
+    int totalSamps;
+    printf("PortAudio Test: output debug values\n" );
+    data.framesToGo = totalSamps =  NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */
+    printf("totalSamps = %d\n", totalSamps );
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+    printf("PortAudio Test: output device = %d\n", OUTPUT_DEVICE );
+    
+    err = Pa_OpenStream(
+              &stream,
+              paNoDevice,
+              0,              /* no input */
+              paFloat32,  /* 32 bit floating point input */
+              NULL,
+              OUTPUT_DEVICE,
+              2,              /* stereo output */
+              paInt16,      /* 32 bit floating point output */
+              NULL,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              NUM_BUFFERS,    /* number of buffers, if zero then use default minimum */
+              paClipOff|paDitherOff, /* we won't output out of range samples so don't bother clipping them */
+              patestCallback,
+              &data );
+    if( err != paNoError ) goto error;
+    
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+    printf("Is callback being called?\n");
+    for( i=0; i<((NUM_SECONDS+1)*1000); i+=SLEEP_DUR )
+    {
+        printf("data.framesToGo = %d\n", data.framesToGo ); fflush(stdout);
+        Pa_Sleep( SLEEP_DUR );
+    }
+    /* Stop sound until ENTER hit. */
+    printf("Call Pa_StopStream()\n");
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+    Pa_Terminate();
+    printf("Test finished.\n");
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/debug_dither_calc.c b/utils/iaxclient/lib/portaudio/test/debug_dither_calc.c
new file mode 100644 (file)
index 0000000..72cd4b6
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * $Id: debug_dither_calc.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * Test Dither calculations.
+ *
+ * Author: Phil Burk  http://www.softsynth.com
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+#include "pa_host.h"
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    long max,min;
+    int   i;
+    
+    for( i=0; i<10000; i++ )
+    {
+        long dither = PaConvert_TriangularDither();
+        // printf("dither = 0x%08X\n", dither );
+        if( dither < min ) min = dither;
+        else if( dither > max ) max = dither;
+    }
+    printf("min = 0x%08X = %d, max = 0x%08X = %d\n", min, min, max, max );
+}
diff --git a/utils/iaxclient/lib/portaudio/test/debug_dual.c b/utils/iaxclient/lib/portaudio/test/debug_dual.c
new file mode 100644 (file)
index 0000000..3e0a5c3
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * $Id: debug_dual.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * debug_dual.c
+ * Try to open TWO streams on separate cards.
+ * Play a sine sweep using the Portable Audio api for several seconds.
+ * Hacked test for debugging PA.
+ *
+ * Author: Phil Burk <philburk@softsynth.com>
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+#define DEV_ID_1            (13)
+#define DEV_ID_2            (15)
+#define NUM_SECONDS         (8)
+#define SLEEP_DUR           (800)
+#define SAMPLE_RATE         (44100)
+#define FRAMES_PER_BUFFER   (256)
+#if 0
+#define MIN_LATENCY_MSEC    (200)
+#define NUM_BUFFERS         ((MIN_LATENCY_MSEC * SAMPLE_RATE) / (FRAMES_PER_BUFFER * 1000))
+#else
+#define NUM_BUFFERS         (0)
+#endif
+#define MIN_FREQ            (100.0f)
+#define MAX_FREQ            (4000.0f)
+#define FREQ_SCALAR         (1.00002f)
+#define CalcPhaseIncrement(freq)  (freq/SAMPLE_RATE)
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+#define TABLE_SIZE   (400)
+typedef struct
+{
+    float sine[TABLE_SIZE + 1]; // add one for guard point for interpolation
+    float phase_increment;
+    float left_phase;
+    float right_phase;
+}
+paTestData;
+/* Convert phase between and 1.0 to sine value
+ * using linear interpolation.
+ */
+float LookupSine( paTestData *data, float phase );
+float LookupSine( paTestData *data, float phase )
+{
+    float fIndex = phase*TABLE_SIZE;
+    int   index = (int) fIndex;
+    float fract = fIndex - index;
+    float lo = data->sine[index];
+    float hi = data->sine[index+1];
+    float val = lo + fract*(hi-lo);
+    return val;
+}
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( void *inputBuffer, void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                           PaTimestamp outTime, void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    unsigned long i;
+    int finished = 0;
+    (void) outTime; /* Prevent unused variable warnings. */
+    (void) inputBuffer;
+
+
+    for( i=0; i<framesPerBuffer; i++ )
+    {
+        *out++ = LookupSine(data, data->left_phase);  /* left */
+        *out++ = LookupSine(data, data->right_phase);  /* right */
+        data->left_phase += data->phase_increment;
+        if( data->left_phase >= 1.0f ) data->left_phase -= 1.0f;
+        data->right_phase += (data->phase_increment * 1.5f); /* fifth above */
+        if( data->right_phase >= 1.0f ) data->right_phase -= 1.0f;
+        /* sweep frequency then start over. */
+        data->phase_increment *= FREQ_SCALAR;
+        if( data->phase_increment > CalcPhaseIncrement(MAX_FREQ) ) data->phase_increment = CalcPhaseIncrement(MIN_FREQ);
+    }
+    return 0;
+}
+
+PaError TestStart( PortAudioStream **streamPtr, PaDeviceID devID,
+                   paTestData *data );
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PortAudioStream *stream1, *stream2;
+    PaError err;
+    paTestData DATA1, DATA2;
+    printf("PortAudio Test: DUAL sine sweep. ask for %d buffers\n", NUM_BUFFERS );
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+    err = TestStart( &stream1, DEV_ID_1, &DATA1 );
+    if( err != paNoError ) goto error;
+    err = TestStart( &stream2, DEV_ID_2, &DATA2 );
+    if( err != paNoError ) goto error;
+    printf("Hit ENTER\n");
+    getchar();
+    err = Pa_StopStream( stream1 );
+    if( err != paNoError ) goto error;
+    err = Pa_StopStream( stream2 );
+    if( err != paNoError ) goto error;
+    Pa_Terminate();
+    printf("Test finished.\n");
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
+PaError TestStart( PortAudioStream **streamPtr, PaDeviceID devID, paTestData *data )
+{
+    PortAudioStream *stream;
+    PaError err;
+    int i;
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<TABLE_SIZE; i++ )
+    {
+        data->sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
+    }
+    data->sine[TABLE_SIZE] = data->sine[0]; // set guard point
+    data->left_phase = data->right_phase = 0.0;
+    data->phase_increment = CalcPhaseIncrement(MIN_FREQ);
+    printf("PortAudio Test: output device = %d\n", devID );
+    err = Pa_OpenStream(
+              &stream,
+              paNoDevice,
+              0,              /* no input */
+              paFloat32,  /* 32 bit floating point input */
+              NULL,
+              devID,
+              2,              /* stereo output */
+              paFloat32,      /* 32 bit floating point output */
+              NULL,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              NUM_BUFFERS,    /* number of buffers, if zero then use default minimum */
+              paClipOff|paDitherOff, /* we won't output out of range samples so don't bother clipping them */
+              patestCallback,
+              data );
+    if( err != paNoError ) goto error;
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+    *streamPtr = stream;
+    return 0;
+error:
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/debug_multi_in.c b/utils/iaxclient/lib/portaudio/test/debug_multi_in.c
new file mode 100644 (file)
index 0000000..3d8ec38
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * $Id: debug_multi_in.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * debug_multi_in.c
+ * Pass output from each of multiple channels
+ * to a stereo output using the Portable Audio api.
+ * Hacked test for debugging PA.
+ *
+ * Author: Phil Burk  http://www.softsynth.com
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include "portaudio.h"
+//#define INPUT_DEVICE_NAME   ("EWS88 MT Interleaved Rec")
+#define OUTPUT_DEVICE       (Pa_GetDefaultOutputDeviceID())
+//#define OUTPUT_DEVICE       (18)
+#define SAMPLE_RATE         (22050)
+#define FRAMES_PER_BUFFER   (256)
+#define MIN_LATENCY_MSEC    (400)
+#define NUM_BUFFERS         ((MIN_LATENCY_MSEC * SAMPLE_RATE) / (FRAMES_PER_BUFFER * 1000))
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+typedef struct
+{
+    int      liveChannel;
+    int      numChannels;
+}
+paTestData;
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( void *inputBuffer, void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                           PaTimestamp outTime, void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    float *in = (float*)inputBuffer;
+    int i;
+    int finished = 0;
+    (void) outTime; /* Prevent unused variable warnings. */
+    (void) inputBuffer;
+
+    if( in == NULL ) return 0;
+    for( i=0; i<(int)framesPerBuffer; i++ )
+    {
+        /* Copy one channel of input to output. */
+        *out++ = in[data->liveChannel];
+        *out++ = in[data->liveChannel];
+        in += data->numChannels;
+    }
+    return 0;
+}
+/*******************************************************************/
+int PaFindDeviceByName( const char *name )
+{
+    int   i;
+    int   numDevices;
+    const PaDeviceInfo *pdi;
+    int   len = strlen( name );
+    PaDeviceID   result = paNoDevice;
+    numDevices = Pa_CountDevices();
+    for( i=0; i<numDevices; i++ )
+    {
+        pdi = Pa_GetDeviceInfo( i );
+        if( strncmp( name, pdi->name, len ) == 0 )
+        {
+            result = i;
+            break;
+        }
+    }
+    return result;
+}
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PortAudioStream *stream;
+    PaError err;
+    paTestData data;
+    int i;
+    PaDeviceID inputDevice;
+    const PaDeviceInfo *pdi;
+    printf("PortAudio Test: input signal from each channel. %d buffers\n", NUM_BUFFERS );
+    data.liveChannel = 0;
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+#ifdef INPUT_DEVICE_NAME
+    printf("Try to use device: %s\n", INPUT_DEVICE_NAME );
+    inputDevice = PaFindDeviceByName(INPUT_DEVICE_NAME);
+    if( inputDevice == paNoDevice )
+    {
+        printf("Could not find %s. Using default instead.\n", INPUT_DEVICE_NAME );
+        inputDevice = Pa_GetDefaultInputDeviceID();
+    }
+#else
+    printf("Using default input device.\n");
+    inputDevice = Pa_GetDefaultInputDeviceID();
+#endif
+    pdi = Pa_GetDeviceInfo( inputDevice );
+    if( pdi == NULL )
+    {
+        printf("Could not get device info!\n");
+        goto error;
+    }
+    data.numChannels = pdi->maxInputChannels;
+    printf("Input Device name is %s\n", pdi->name );
+    printf("Input Device has %d channels.\n", pdi->maxInputChannels);
+    err = Pa_OpenStream(
+              &stream,
+              inputDevice,
+              pdi->maxInputChannels,
+              paFloat32,  /* 32 bit floating point input */
+              NULL,
+              OUTPUT_DEVICE,
+              2,
+              paFloat32,  /* 32 bit floating point output */
+              NULL,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,  /* frames per buffer */
+              NUM_BUFFERS,    /* number of buffers, if zero then use default minimum */
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              patestCallback,
+              &data );
+    if( err != paNoError ) goto error;
+    data.liveChannel = 0;
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+    for( i=0; i<data.numChannels; i++ )
+    {
+        data.liveChannel = i;
+        printf("Channel %d being sent to output. Hit ENTER for next channel.", i );
+        fflush(stdout);
+        getchar();
+    }
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+
+    err = Pa_CloseStream( stream );
+    Pa_Terminate();
+    printf("Test finished.\n");
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/debug_multi_out.c b/utils/iaxclient/lib/portaudio/test/debug_multi_out.c
new file mode 100644 (file)
index 0000000..6ae6047
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * $Id: debug_multi_out.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * debug_multi_out.c
+ * Play a different sine wave on each channels,
+ * using the Portable Audio api.
+ *
+ * Author: Phil Burk  http://www.softsynth.com
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define OUTPUT_DEVICE       (Pa_GetDefaultOutputDeviceID())
+#define SAMPLE_RATE         (44100)
+#define FRAMES_PER_BUFFER   (256)
+#define FREQ_INCR           (300.0 / SAMPLE_RATE)
+#define MAX_CHANNELS        (64)
+
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+
+typedef struct
+{
+    int      numChannels;
+    double   phases[MAX_CHANNELS];
+}
+paTestData;
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( void *inputBuffer, void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                           PaTimestamp outTime, void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    int frameIndex, channelIndex;
+    int finished = 0;
+    (void) outTime; /* Prevent unused variable warnings. */
+    (void) inputBuffer;
+
+    for( frameIndex=0; frameIndex<(int)framesPerBuffer; frameIndex++ )
+    {
+        for( channelIndex=0; channelIndex<data->numChannels; channelIndex++ )
+        {
+            /* Output sine wave on every channel. */
+            *out++ = (float) sin(data->phases[channelIndex]);
+
+            /* Play each channel at a higher frequency. */
+            data->phases[channelIndex] += FREQ_INCR * (4 + channelIndex);
+            if( data->phases[channelIndex] >= (2.0 * M_PI) ) data->phases[channelIndex] -= (2.0 * M_PI);
+        }
+    }
+
+    return 0;
+}
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PortAudioStream *stream;
+    PaError err;
+    const PaDeviceInfo *pdi;
+    paTestData data = {0};
+    printf("PortAudio Test: output sine wave on each channel.\n" );
+
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    pdi = Pa_GetDeviceInfo( OUTPUT_DEVICE );
+    data.numChannels = pdi->maxOutputChannels;
+    if( data.numChannels > MAX_CHANNELS ) data.numChannels = MAX_CHANNELS;
+    printf("Number of Channels = %d\n", data.numChannels );
+    
+    err = Pa_OpenStream(
+              &stream,
+              paNoDevice, /* default input device */
+              0,              /* no input */
+              paFloat32,  /* 32 bit floating point input */
+              NULL,
+              OUTPUT_DEVICE,
+              data.numChannels,
+              paFloat32,  /* 32 bit floating point output */
+              NULL,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,  /* frames per buffer */
+              0,    /* number of buffers, if zero then use default minimum */
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              patestCallback,
+              &data );
+    if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+    printf("Hit ENTER to stop sound.\n");
+    fflush(stdout);
+    getchar();
+
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+
+    Pa_CloseStream( stream );
+    Pa_Terminate();
+    printf("Test finished.\n");
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/debug_record.c b/utils/iaxclient/lib/portaudio/test/debug_record.c
new file mode 100644 (file)
index 0000000..5a72a81
--- /dev/null
@@ -0,0 +1,339 @@
+/*
+ * $Id: debug_record.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * debug_record.c
+ * Record input into an array.
+ * Save array to a file.
+ * Based on patest_record.c but with various ugly debug hacks thrown in.
+ *
+ * Author: Phil Burk  http://www.softsynth.com
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
+#include "portaudio.h"
+#define SAMPLE_RATE     (22050)
+#define NUM_SECONDS     (10)
+#define SLEEP_DUR_MSEC  (200)
+#define FRAMES_PER_BUFFER  (1<<10)
+#define NUM_REC_BUFS    (0)
+
+#if 1
+#define PA_SAMPLE_TYPE  paFloat32
+typedef float SAMPLE;
+#else
+#define PA_SAMPLE_TYPE  paInt16
+typedef short SAMPLE;
+#endif
+
+typedef struct
+{
+    long         frameIndex;  /* Index into sample array. */
+    long         maxFrameIndex;
+    long         samplesPerFrame;
+    long         numSamples;
+    SAMPLE      *recordedSamples;
+}
+paTestData;
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may be called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int recordCallback( void *inputBuffer, void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                           PaTimestamp outTime, void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    SAMPLE *rptr = (SAMPLE*)inputBuffer;
+    SAMPLE *wptr = &data->recordedSamples[data->frameIndex * data->samplesPerFrame];
+    long framesToCalc;
+    unsigned long i;
+    int finished;
+    unsigned long framesLeft = data->maxFrameIndex - data->frameIndex;
+
+    (void) outputBuffer; /* Prevent unused variable warnings. */
+    (void) outTime;
+
+    if( framesLeft < framesPerBuffer )
+    {
+        framesToCalc = framesLeft;
+        finished = 1;
+    }
+    else
+    {
+        framesToCalc = framesPerBuffer;
+        finished = 0;
+    }
+    if( inputBuffer == NULL )
+    {
+        for( i=0; i<framesToCalc; i++ )
+        {
+            *wptr++ = 0;  /* left */
+            *wptr++ = 0;  /* right */
+        }
+    }
+    else
+    {
+        for( i=0; i<framesToCalc; i++ )
+        {
+            *wptr++ = *rptr++;  /* left */
+            *wptr++ = *rptr++;  /* right */
+        }
+    }
+    data->frameIndex += framesToCalc;
+    return finished;
+}
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may be called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int playCallback( void *inputBuffer, void *outputBuffer,
+                         unsigned long framesPerBuffer,
+                         PaTimestamp outTime, void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    SAMPLE *rptr = &data->recordedSamples[data->frameIndex * data->samplesPerFrame];
+    SAMPLE *wptr = (SAMPLE*)outputBuffer;
+    unsigned long i;
+    int finished;
+    unsigned int framesLeft = data->maxFrameIndex - data->frameIndex;
+    if( outputBuffer == NULL ) return 0;
+    (void) inputBuffer; /* Prevent unused variable warnings. */
+    (void) outTime;
+
+    if( framesLeft < framesPerBuffer )
+    {
+        /* final buffer... */
+        for( i=0; i<framesLeft; i++ )
+        {
+            *wptr++ = *rptr++;  /* left */
+            *wptr++ = *rptr++;  /* right */
+        }
+        for( ; i<framesPerBuffer; i++ )
+        {
+            *wptr++ = 0;  /* left */
+            *wptr++ = 0;  /* right */
+        }
+        data->frameIndex += framesLeft;
+        finished = 1;
+    }
+    else
+    {
+        for( i=0; i<framesPerBuffer; i++ )
+        {
+            *wptr++ = *rptr++;  /* left */
+            *wptr++ = *rptr++;  /* right */
+        }
+        data->frameIndex += framesPerBuffer;
+        finished = 0;
+    }
+    return finished;
+}
+
+/****************************************************************/
+PaError TestRecording( paTestData *dataPtr )
+{
+    PortAudioStream *stream;
+    PaError    err;
+    int        i;
+
+    /* Record some audio. */
+    err = Pa_OpenStream(
+              &stream,
+              Pa_GetDefaultInputDeviceID(),
+              dataPtr->samplesPerFrame,               /* stereo input */
+              PA_SAMPLE_TYPE,
+              NULL,
+              paNoDevice,
+              0,
+              PA_SAMPLE_TYPE,
+              NULL,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,            /* frames per buffer */
+              NUM_REC_BUFS,               /* number of buffers, if zero then use default minimum */
+              paClipOff,       /* we won't output out of range samples so don't bother clipping them */
+              recordCallback,
+              dataPtr );
+    if( err != paNoError ) goto error;
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+    printf("Now recording!\n"); fflush(stdout);
+    for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ )
+    {
+        if( Pa_StreamActive( stream ) <= 0)
+        {
+            printf("Stream inactive!\n");
+            break;
+        }
+        if( dataPtr->maxFrameIndex <= dataPtr->frameIndex )
+        {
+            printf("Buffer recording complete.\n");
+            break;
+        }
+        Pa_Sleep(100);
+        printf("index = %d\n", dataPtr->frameIndex ); fflush(stdout);
+    }
+
+    printf("Finished loop. Close stream.\n"); fflush(stdout);
+
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+
+    printf("Done.\n"); fflush(stdout);
+    {
+        SAMPLE max = 0;
+        SAMPLE posVal;
+        int i;
+        for( i=0; i<dataPtr->numSamples; i++ )
+        {
+            posVal = dataPtr->recordedSamples[i];
+            if( posVal < 0 ) posVal = -posVal;
+            if( posVal > max ) max = posVal;
+        }
+        printf("Largest recorded sample = %d\n", max );
+    }
+    /* Write recorded data to a file. */
+#if 0
+    {
+        FILE  *fid;
+        fid = fopen("recorded.raw", "wb");
+        if( fid == NULL )
+        {
+            printf("Could not open file.");
+        }
+        else
+        {
+            fwrite( dataPtr->recordedSamples, dataPtr->samplesPerFrame * sizeof(SAMPLE), totalFrames, fid );
+            fclose( fid );
+            printf("Wrote data to 'recorded.raw'\n");
+        }
+    }
+#endif
+
+error:
+    return err;
+}
+
+/****************************************************************/
+PaError TestPlayback( paTestData *dataPtr )
+{
+    PortAudioStream *stream;
+    PaError    err;
+    int        i;
+
+    /* Playback recorded data. */
+    dataPtr->frameIndex = 0;
+    printf("Begin playback.\n"); fflush(stdout);
+    err = Pa_OpenStream(
+              &stream,
+              paNoDevice,
+              0,               /* NO input */
+              PA_SAMPLE_TYPE,
+              NULL,
+              Pa_GetDefaultOutputDeviceID(),
+              dataPtr->samplesPerFrame,               /* stereo output */
+              PA_SAMPLE_TYPE,
+              NULL,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,            /* frames per buffer */
+              0,               /* number of buffers, if zero then use default minimum */
+              paClipOff,       /* we won't output out of range samples so don't bother clipping them */
+              playCallback,
+              dataPtr );
+    if( err != paNoError ) goto error;
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+    printf("Waiting for playback to finish.\n"); fflush(stdout);
+    for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ )
+    {
+        Pa_Sleep(100);
+        printf("index = %d\n", dataPtr->frameIndex );
+    }
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+    
+error:
+    return err;
+}
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaError    err;
+    paTestData data;
+    long       totalFrames;
+    long       numBytes;
+    long       i;
+    printf("patest_record.c\n"); fflush(stdout);
+
+    data.frameIndex = 0;
+    data.samplesPerFrame = 2;
+    data.maxFrameIndex = totalFrames = NUM_SECONDS*SAMPLE_RATE;
+
+    printf("totalFrames = %d\n", totalFrames ); fflush(stdout);
+    data.numSamples = totalFrames * data.samplesPerFrame;
+
+    numBytes = data.numSamples * sizeof(SAMPLE);
+    data.recordedSamples = (SAMPLE *) malloc( numBytes );
+    if( data.recordedSamples == NULL )
+    {
+        printf("Could not allocate record array.\n");
+        exit(1);
+    }
+    for( i=0; i<data.numSamples; i++ ) data.recordedSamples[i] = 0;
+
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    for( i=0; i<2; i++ )
+    {
+        err = TestRecording( &data );
+        if( err != paNoError ) goto error;
+
+        err = TestPlayback( &data );
+        if( err != paNoError ) goto error;
+    }
+
+    free( data.recordedSamples );
+    Pa_Terminate();
+    return 0;
+
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    if( err == paHostError )
+    {
+        fprintf( stderr, "Host Error number: %d\n", Pa_GetHostError() );
+    }
+    return -1;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/debug_record_reuse.c b/utils/iaxclient/lib/portaudio/test/debug_record_reuse.c
new file mode 100644 (file)
index 0000000..b4ca501
--- /dev/null
@@ -0,0 +1,351 @@
+/*
+ * $Id: debug_record_reuse.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * debug_record_reuse.c
+ * Record input into an array.
+ * Save array to a file.
+ * Based on patest_record.c but with various ugly debug hacks thrown in.
+ * Loop twice and reuse same streams.
+ *
+ * Author: Phil Burk  http://www.softsynth.com
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
+#include "portaudio.h"
+#define SAMPLE_RATE     (22050)
+#define NUM_SECONDS     (4)
+#define SLEEP_DUR_MSEC  (200)
+#define FRAMES_PER_BUFFER  (256)
+#define NUM_REC_BUFS    (0)
+
+#if 1
+#define PA_SAMPLE_TYPE  paFloat32
+typedef float SAMPLE;
+#else
+#define PA_SAMPLE_TYPE  paInt16
+typedef short SAMPLE;
+#endif
+
+typedef struct
+{
+    long         frameIndex;  /* Index into sample array. */
+    long         maxFrameIndex;
+    long         samplesPerFrame;
+    long         numSamples;
+    PortAudioStream *outputStream;
+    PortAudioStream *inputStream;
+    SAMPLE      *recordedSamples;
+}
+paTestData;
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may be called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int recordCallback( void *inputBuffer, void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                           PaTimestamp outTime, void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    SAMPLE *rptr = (SAMPLE*)inputBuffer;
+    SAMPLE *wptr = &data->recordedSamples[data->frameIndex * data->samplesPerFrame];
+    long framesToCalc;
+    unsigned long i;
+    int finished;
+    unsigned long framesLeft = data->maxFrameIndex - data->frameIndex;
+
+    (void) outputBuffer; /* Prevent unused variable warnings. */
+    (void) outTime;
+
+    if( framesLeft < framesPerBuffer )
+    {
+        framesToCalc = framesLeft;
+        finished = 1;
+    }
+    else
+    {
+        framesToCalc = framesPerBuffer;
+        finished = 0;
+    }
+    if( inputBuffer == NULL )
+    {
+        for( i=0; i<framesToCalc; i++ )
+        {
+            *wptr++ = 0;  /* left */
+            *wptr++ = 0;  /* right */
+        }
+    }
+    else
+    {
+        for( i=0; i<framesToCalc; i++ )
+        {
+            *wptr++ = *rptr++;  /* left */
+            *wptr++ = *rptr++;  /* right */
+        }
+    }
+    data->frameIndex += framesToCalc;
+    return finished;
+}
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may be called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int playCallback( void *inputBuffer, void *outputBuffer,
+                         unsigned long framesPerBuffer,
+                         PaTimestamp outTime, void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    SAMPLE *rptr = &data->recordedSamples[data->frameIndex * data->samplesPerFrame];
+    SAMPLE *wptr = (SAMPLE*)outputBuffer;
+    unsigned long i;
+    int finished;
+    unsigned int framesLeft = data->maxFrameIndex - data->frameIndex;
+    if( outputBuffer == NULL ) return 0;
+    (void) inputBuffer; /* Prevent unused variable warnings. */
+    (void) outTime;
+
+    if( framesLeft < framesPerBuffer )
+    {
+        /* final buffer... */
+        for( i=0; i<framesLeft; i++ )
+        {
+            *wptr++ = *rptr++;  /* left */
+            *wptr++ = *rptr++;  /* right */
+        }
+        for( ; i<framesPerBuffer; i++ )
+        {
+            *wptr++ = 0;  /* left */
+            *wptr++ = 0;  /* right */
+        }
+        data->frameIndex += framesLeft;
+        finished = 1;
+    }
+    else
+    {
+        for( i=0; i<framesPerBuffer; i++ )
+        {
+            *wptr++ = *rptr++;  /* left */
+            *wptr++ = *rptr++;  /* right */
+        }
+        data->frameIndex += framesPerBuffer;
+        finished = 0;
+    }
+    return finished;
+}
+
+/****************************************************************/
+PaError TestRecording( paTestData *dataPtr )
+{
+    PaError    err;
+    int        i;
+    int        lastIndex = 0;
+
+/* Open input stream if not already open. */
+    if( dataPtr->inputStream == NULL )
+    {
+        /* Record some audio. */
+        err = Pa_OpenStream(
+                  &dataPtr->inputStream,
+                  Pa_GetDefaultInputDeviceID(),
+                  dataPtr->samplesPerFrame,               /* stereo input */
+                  PA_SAMPLE_TYPE,
+                  NULL,
+                  paNoDevice,
+                  0,
+                  PA_SAMPLE_TYPE,
+                  NULL,
+                  SAMPLE_RATE,
+                  FRAMES_PER_BUFFER,            /* frames per buffer */
+                  NUM_REC_BUFS,               /* number of buffers, if zero then use default minimum */
+                  paClipOff,       /* we won't output out of range samples so don't bother clipping them */
+                  recordCallback,
+                  dataPtr );
+        if( err != paNoError ) goto error;
+    }
+
+    dataPtr->frameIndex = 0;
+
+    err = Pa_StartStream( dataPtr->inputStream );
+    if( err != paNoError ) goto error;
+
+    printf("Now recording!\n"); fflush(stdout);
+    for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ )
+    {
+        int frameIndex, delta;
+        Pa_Sleep(SLEEP_DUR_MSEC);
+
+        frameIndex = dataPtr->frameIndex;
+        if( Pa_StreamActive( dataPtr->inputStream ) <= 0)
+        {
+            printf("Stream inactive!\n");
+            break;
+        }
+        if( dataPtr->maxFrameIndex <= frameIndex )
+        {
+            printf("Buffer recording complete.\n");
+            break;
+        }
+
+        delta = frameIndex - lastIndex;
+        lastIndex = frameIndex;
+        printf("index = %d, delta = %d\n", frameIndex, delta ); fflush(stdout);
+    }
+
+    err = Pa_StopStream( dataPtr->inputStream );
+    if( err != paNoError ) goto error;
+
+    printf("Done.\n"); fflush(stdout);
+
+error:
+    return err;
+}
+
+/****************************************************************/
+PaError TestPlayback( paTestData *dataPtr )
+{
+    PaError    err;
+    int        i;
+    int        lastIndex = 0;
+
+    /* Playback recorded data. */
+    dataPtr->frameIndex = 0;
+    printf("Begin playback.\n"); fflush(stdout);
+
+/* Open output stream if not already open. */
+    if( dataPtr->outputStream == NULL )
+    {
+        err = Pa_OpenStream(
+                  &dataPtr->outputStream,
+                  paNoDevice,
+                  0,               /* NO input */
+                  PA_SAMPLE_TYPE,
+                  NULL,
+                  Pa_GetDefaultOutputDeviceID(),
+                  dataPtr->samplesPerFrame,               /* stereo output */
+                  PA_SAMPLE_TYPE,
+                  NULL,
+                  SAMPLE_RATE,
+                  FRAMES_PER_BUFFER,            /* frames per buffer */
+                  0,               /* number of buffers, if zero then use default minimum */
+                  paClipOff,       /* we won't output out of range samples so don't bother clipping them */
+                  playCallback,
+                  dataPtr );
+        if( err != paNoError ) goto error;
+    }
+
+    err = Pa_StartStream( dataPtr->outputStream );
+    if( err != paNoError ) goto error;
+
+    printf("Waiting for playback to finish.\n"); fflush(stdout);
+    for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ )
+    {
+        int frameIndex, delta;
+        Pa_Sleep(SLEEP_DUR_MSEC);
+        frameIndex = dataPtr->frameIndex;
+        delta = frameIndex - lastIndex;
+        lastIndex = frameIndex;
+        printf("index = %d, delta = %d\n", frameIndex, delta ); fflush(stdout);
+    }
+
+    err = Pa_StopStream( dataPtr->outputStream );
+    if( err != paNoError ) goto error;
+    
+error:
+    return err;
+}
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaError    err;
+    paTestData data = { 0 };
+    long       totalFrames;
+    long       numBytes;
+    long       i;
+    printf("patest_record.c\n"); fflush(stdout);
+
+/* Set up test data structure and sample array. */
+    data.frameIndex = 0;
+    data.samplesPerFrame = 2;
+    data.maxFrameIndex = totalFrames = NUM_SECONDS*SAMPLE_RATE;
+
+    printf("totalFrames = %d\n", totalFrames ); fflush(stdout);
+    data.numSamples = totalFrames * data.samplesPerFrame;
+
+    numBytes = data.numSamples * sizeof(SAMPLE);
+    data.recordedSamples = (SAMPLE *) malloc( numBytes );
+    if( data.recordedSamples == NULL )
+    {
+        printf("Could not allocate record array.\n");
+        exit(1);
+    }
+    for( i=0; i<data.numSamples; i++ ) data.recordedSamples[i] = 0;
+
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+/* Record and playback multiple times. */
+    for( i=0; i<2; i++ )
+    {
+        err = TestRecording( &data );
+        if( err != paNoError ) goto error;
+
+        err = TestPlayback( &data );
+        if( err != paNoError ) goto error;
+    }
+
+/* Clean up. */
+    err = Pa_CloseStream( data.inputStream );
+    if( err != paNoError ) goto error;
+
+    err = Pa_CloseStream( data.outputStream );
+    if( err != paNoError ) goto error;
+
+    if( err != paNoError ) goto error;
+
+    free( data.recordedSamples );
+    Pa_Terminate();
+    
+    printf("Test complete.\n"); fflush(stdout);
+    return 0;
+
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    if( err == paHostError )
+    {
+        fprintf( stderr, "Host Error number: %d\n", Pa_GetHostError() );
+    }
+    return -1;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/debug_sine.c b/utils/iaxclient/lib/portaudio/test/debug_sine.c
new file mode 100644 (file)
index 0000000..261f9b4
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * $Id: debug_sine.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * debug_sine.c
+ * Play a sine sweep using the Portable Audio api for several seconds.
+ * Hacked test for debugging PA.
+ *
+ * Author: Phil Burk <philburk@softsynth.com>
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+#define OUTPUT_DEVICE       (Pa_GetDefaultOutputDeviceID())
+//#define OUTPUT_DEVICE       (11)
+#define NUM_SECONDS         (8)
+#define SLEEP_DUR           (800)
+#define SAMPLE_RATE         (44100)
+#define FRAMES_PER_BUFFER   (256)
+#if 0
+#define MIN_LATENCY_MSEC    (200)
+#define NUM_BUFFERS         ((MIN_LATENCY_MSEC * SAMPLE_RATE) / (FRAMES_PER_BUFFER * 1000))
+#else
+#define NUM_BUFFERS         (0)
+#endif
+#define MIN_FREQ            (100.0f)
+#define MAX_FREQ            (4000.0f)
+#define FREQ_SCALAR         (1.00002f)
+#define CalcPhaseIncrement(freq)  (freq/SAMPLE_RATE)
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+#define TABLE_SIZE   (400)
+typedef struct
+{
+    float sine[TABLE_SIZE + 1]; // add one for guard point for interpolation
+    float phase_increment;
+    float left_phase;
+    float right_phase;
+    unsigned int framesToGo;
+}
+paTestData;
+/* Convert phase between and 1.0 to sine value
+ * using linear interpolation.
+ */
+float LookupSine( paTestData *data, float phase );
+float LookupSine( paTestData *data, float phase )
+{
+    float fIndex = phase*TABLE_SIZE;
+    int   index = (int) fIndex;
+    float fract = fIndex - index;
+    float lo = data->sine[index];
+    float hi = data->sine[index+1];
+    float val = lo + fract*(hi-lo);
+    return val;
+}
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( void *inputBuffer, void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                           PaTimestamp outTime, void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    int      framesToCalc;
+    int i;
+    int finished = 0;
+    (void) outTime; /* Prevent unused variable warnings. */
+    (void) inputBuffer;
+
+    if( data->framesToGo < framesPerBuffer )
+    {
+        framesToCalc = data->framesToGo;
+        data->framesToGo = 0;
+        finished = 1;
+    }
+    else
+    {
+        framesToCalc = framesPerBuffer;
+        data->framesToGo -= framesPerBuffer;
+    }
+
+    for( i=0; i<framesToCalc; i++ )
+    {
+        *out++ = LookupSine(data, data->left_phase);  /* left */
+        *out++ = LookupSine(data, data->right_phase);  /* right */
+        data->left_phase += data->phase_increment;
+        if( data->left_phase >= 1.0f ) data->left_phase -= 1.0f;
+        data->right_phase += (data->phase_increment * 1.5f); /* fifth above */
+        if( data->right_phase >= 1.0f ) data->right_phase -= 1.0f;
+        /* sweep frequency then start over. */
+        data->phase_increment *= FREQ_SCALAR;
+        if( data->phase_increment > CalcPhaseIncrement(MAX_FREQ) ) data->phase_increment = CalcPhaseIncrement(MIN_FREQ);
+    }
+    /* zero remainder of final buffer */
+    for( ; i<(int)framesPerBuffer; i++ )
+    {
+        *out++ = 0; /* left */
+        *out++ = 0; /* right */
+    }
+    return finished;
+}
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PortAudioStream *stream;
+    PaError err;
+    paTestData data;
+    int i;
+    int totalSamps;
+    printf("PortAudio Test: output sine sweep. ask for %d buffers\n", NUM_BUFFERS );
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<TABLE_SIZE; i++ )
+    {
+        data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
+    }
+    data.sine[TABLE_SIZE] = data.sine[0]; // set guard point
+    data.left_phase = data.right_phase = 0.0;
+    data.phase_increment = CalcPhaseIncrement(MIN_FREQ);
+    data.framesToGo = totalSamps =  NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */
+    printf("totalSamps = %d\n", totalSamps );
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+    printf("PortAudio Test: output device = %d\n", OUTPUT_DEVICE );
+    err = Pa_OpenStream(
+              &stream,
+              paNoDevice,
+              0,              /* no input */
+              paFloat32,  /* 32 bit floating point input */
+              NULL,
+              OUTPUT_DEVICE,
+              2,              /* stereo output */
+              paFloat32,      /* 32 bit floating point output */
+              NULL,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              NUM_BUFFERS,    /* number of buffers, if zero then use default minimum */
+              paClipOff|paDitherOff, /* we won't output out of range samples so don't bother clipping them */
+              patestCallback,
+              &data );
+    if( err != paNoError ) goto error;
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+    printf("Is callback being called?\n");
+    for( i=0; i<((NUM_SECONDS+1)*1000); i+=SLEEP_DUR )
+    {
+        printf("data.framesToGo = %d\n", data.framesToGo ); fflush(stdout);
+        Pa_Sleep( SLEEP_DUR );
+    }
+    /* Stop sound until ENTER hit. */
+    printf("Call Pa_StopStream()\n");
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+    Pa_Terminate();
+    printf("Test finished.\n");
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/debug_sine_amp.c b/utils/iaxclient/lib/portaudio/test/debug_sine_amp.c
new file mode 100644 (file)
index 0000000..52cd02a
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * $Id: debug_sine_amp.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * Play a different sine wave on each channels,
+ * using the Portable Audio api.
+ * Allos amplitude to be set interactively.
+ *
+ * Author: Phil Burk  http://www.softsynth.com
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define OUTPUT_DEVICE       (Pa_GetDefaultOutputDeviceID())
+#define SAMPLE_RATE         (44100)
+#define FRAMES_PER_BUFFER   (256)
+#define FREQ_INCR           (300.0 / SAMPLE_RATE)
+#define MAX_CHANNELS        (64)
+
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+
+typedef struct
+{
+    int      numChannels;
+    double   phases[MAX_CHANNELS];
+    float    amplitude;
+}
+paTestData;
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( void *inputBuffer, void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                           PaTimestamp outTime, void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    int frameIndex, channelIndex;
+    (void) outTime; /* Prevent unused variable warnings. */
+    (void) inputBuffer;
+
+    for( frameIndex=0; frameIndex<(int)framesPerBuffer; frameIndex++ )
+    {
+        for( channelIndex=0; channelIndex<data->numChannels; channelIndex++ )
+        {
+            /* Output sine wave on every channel. */
+            *out++ = (float) ( data->amplitude * sin(data->phases[channelIndex]) );
+
+            /* Play each channel at a higher frequency. */
+            data->phases[channelIndex] += FREQ_INCR * (4 + channelIndex);
+            if( data->phases[channelIndex] >= (2.0 * M_PI) ) data->phases[channelIndex] -= (2.0 * M_PI);
+        }
+    }
+
+    return 0;
+}
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    char  pad[256];
+    PortAudioStream *stream;
+    PaError err;
+    const PaDeviceInfo *pdi;
+    paTestData data = {0};
+    printf("PortAudio Test: output sine wave on each channel.\n" );
+
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    pdi = Pa_GetDeviceInfo( OUTPUT_DEVICE );
+    data.numChannels = pdi->maxOutputChannels;
+    if( data.numChannels > MAX_CHANNELS ) data.numChannels = MAX_CHANNELS;
+    printf("Number of Channels = %d\n", data.numChannels );
+    data.amplitude = 1.0;
+    
+    err = Pa_OpenStream(
+              &stream,
+              paNoDevice, /* default input device */
+              0,              /* no input */
+              paFloat32,  /* 32 bit floating point input */
+              NULL,
+              OUTPUT_DEVICE,
+              data.numChannels,
+              paFloat32,  /* 32 bit floating point output */
+              NULL,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,  /* frames per buffer */
+              0,    /* number of buffers, if zero then use default minimum */
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              patestCallback,
+              &data );
+    if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+    do
+    {
+        printf("Current amplitude = %f\n", data.amplitude );
+        printf("Enter new amplitude or 'q' to quit.\n");
+        fflush(stdout);
+        gets( pad );
+        if( pad[0] != 'q' )
+        {
+        // I tried to use atof but it seems to be broken on Mac OS X 10.1
+            float amp;
+            sscanf( pad, "%f", &amp );
+            data.amplitude = amp;
+        }
+    } while( pad[0] != 'q' );
+
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+
+    Pa_CloseStream( stream );
+    Pa_Terminate();
+    printf("Test finished.\n");
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/debug_sine_formats.c b/utils/iaxclient/lib/portaudio/test/debug_sine_formats.c
new file mode 100644 (file)
index 0000000..a483b2d
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+ * $Id: debug_sine_formats.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * patest_sine_formats.c
+ * Play a sine wave using the Portable Audio api for several seconds.
+ * Test various data formats.
+ *
+ * Author: Phil Burk
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define NUM_SECONDS        (10)
+#define SAMPLE_RATE        (44100)
+#define FRAMES_PER_BUFFER  (256)
+
+#define LEFT_FREQ          (SAMPLE_RATE/512.0)  /* So we hit 1.0 */
+#define RIGHT_FREQ         (500.0)
+
+#define AMPLITUDE          (1.0)
+
+/* Select ONE format for testing. */
+#define TEST_UINT8    (1)
+#define TEST_INT8     (0)
+#define TEST_INT16    (0)
+#define TEST_FLOAT32  (0)
+
+#if TEST_UINT8
+#define TEST_FORMAT         paUInt8
+typedef unsigned char       SAMPLE_t;
+#define SAMPLE_ZERO         (0x80)
+#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(127.0 * (x)))
+#define FORMAT_NAME         "Unsigned 8 Bit"
+
+#elif TEST_INT8
+#define TEST_FORMAT         paInt8
+typedef char                SAMPLE_t;
+#define SAMPLE_ZERO         (0)
+#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(127.0 * (x)))
+#define FORMAT_NAME         "Signed 8 Bit"
+
+#elif TEST_INT16
+#define TEST_FORMAT         paInt16
+typedef short               SAMPLE_t;
+#define SAMPLE_ZERO         (0)
+#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(32767 * (x)))
+#define FORMAT_NAME         "Signed 16 Bit"
+
+#elif TEST_FLOAT32
+#define TEST_FORMAT         paFloat32
+typedef float               SAMPLE_t;
+#define SAMPLE_ZERO         (0.0)
+#define DOUBLE_TO_SAMPLE(x) ((SAMPLE_t)(x))
+#define FORMAT_NAME         "Float 32 Bit"
+#endif
+
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+
+
+typedef struct
+{
+    double left_phase;
+    double right_phase;
+    unsigned int framesToGo;
+}
+paTestData;
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( void *inputBuffer, void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                           PaTimestamp outTime, void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    SAMPLE_t *out = (SAMPLE_t *)outputBuffer;
+    SAMPLE_t sample;
+    int i;
+    int framesToCalc;
+    int finished = 0;
+    (void) outTime; /* Prevent unused variable warnings. */
+    (void) inputBuffer;
+
+    if( data->framesToGo < framesPerBuffer )
+    {
+        framesToCalc = data->framesToGo;
+        data->framesToGo = 0;
+        finished = 1;
+    }
+    else
+    {
+        framesToCalc = framesPerBuffer;
+        data->framesToGo -= framesPerBuffer;
+    }
+
+    for( i=0; i<framesToCalc; i++ )
+    {
+        data->left_phase += (LEFT_FREQ / SAMPLE_RATE);
+        if( data->left_phase > 1.0) data->left_phase -= 1.0;
+        sample = DOUBLE_TO_SAMPLE( AMPLITUDE * sin( (data->left_phase * M_PI * 2. ))); /**/
+        *out++ = sample;
+/*        *out++ = sample; /**/
+/*        *out++ = 0;  /**/
+
+        data->right_phase += (RIGHT_FREQ / SAMPLE_RATE);
+        if( data->right_phase > 1.0) data->right_phase -= 1.0;
+        *out++ = DOUBLE_TO_SAMPLE( AMPLITUDE * sin( (data->right_phase * M_PI * 2. ))); /**/
+/*        *out++ = 0;  /* */
+    }
+    /* zero remainder of final buffer */
+    for( ; i<(int)framesPerBuffer; i++ )
+    {
+        *out++ = SAMPLE_ZERO; /* left */
+        *out++ = SAMPLE_ZERO; /* right */
+    }
+    return finished;
+}
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PortAudioStream *stream;
+    PaError err;
+    paTestData data;
+    int totalSamps;
+
+    printf("PortAudio Test: output " FORMAT_NAME "\n");
+
+
+    data.left_phase = data.right_phase = 0.0;
+    data.framesToGo = totalSamps =  NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    err = Pa_OpenStream(
+              &stream,
+              paNoDevice,/* default input device */
+              0,              /* no input */
+              TEST_FORMAT,
+              NULL,
+              Pa_GetDefaultOutputDeviceID(), /* default output device */
+              2,          /* stereo output */
+              TEST_FORMAT,
+              NULL,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              0,              /* number of buffers, if zero then use default minimum */
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              patestCallback,
+              &data );
+    if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+    printf("Waiting %d seconds for sound to finish.\n", NUM_SECONDS );
+    while( Pa_StreamActive( stream ) ) Pa_Sleep(10);
+
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+    Pa_Terminate();
+
+    printf("PortAudio Test Finished: " FORMAT_NAME "\n");
+
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/debug_srate.c b/utils/iaxclient/lib/portaudio/test/debug_srate.c
new file mode 100644 (file)
index 0000000..4f5bc54
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * $Id: debug_srate.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * debug_record_reuse.c
+ * Record input into an array.
+ * Save array to a file.
+ * Based on patest_record.c but with various ugly debug hacks thrown in.
+ * Loop twice and reuse same streams.
+ *
+ * Author: Phil Burk  http://www.softsynth.com
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
+#include "portaudio.h"
+
+#define EWS88MT_12_REC     (1)
+#define EWS88MT_12_PLAY   (10)
+#define SBLIVE_REC         (2)
+#define SBLIVE_PLAY       (11)
+
+#if 0
+#define INPUT_DEVICE_ID    Pa_GetDefaultInputDeviceID()
+#define OUTPUT_DEVICE_ID   Pa_GetDefaultOutputDeviceID()
+#else
+#define INPUT_DEVICE_ID    (EWS88MT_12_REC)
+#define OUTPUT_DEVICE_ID   (SBLIVE_PLAY)
+#endif
+
+#define INPUT_SAMPLE_RATE     (22050.0)
+#define OUTPUT_SAMPLE_RATE    (22050.0)
+#define NUM_SECONDS               (4)
+#define SLEEP_DUR_MSEC         (1000)
+#define FRAMES_PER_BUFFER        (64)
+#define NUM_REC_BUFS              (0)
+#define SAMPLES_PER_FRAME         (2)
+
+#define PA_SAMPLE_TYPE  paInt16
+typedef short SAMPLE;
+
+typedef struct
+{
+    long             frameIndex;  /* Index into sample array. */
+}
+paTestData;
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may be called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int recordCallback( void *inputBuffer, void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                           PaTimestamp outTime, void *userData )
+{
+    paTestData *data = (paTestData *) userData;
+    (void) outputBuffer; /* Prevent unused variable warnings. */
+    (void) outTime;
+
+    if( inputBuffer != NULL )
+    {
+        data->frameIndex += framesPerBuffer;
+    }
+    return 0;
+}
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may be called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int playCallback( void *inputBuffer, void *outputBuffer,
+                         unsigned long framesPerBuffer,
+                         PaTimestamp outTime, void *userData )
+{
+    paTestData *data = (paTestData *) userData;
+    (void) inputBuffer; /* Prevent unused variable warnings. */
+    (void) outTime;
+
+    if( outputBuffer != NULL )
+    {
+        data->frameIndex += framesPerBuffer;
+    }
+    return 0;
+}
+
+/****************************************************************/
+PaError MeasureStreamRate( PortAudioStream *stream, paTestData *dataPtr, double *ratePtr )
+{
+    PaError    err;
+    int        i;
+    int        totalFrames = 0;
+    int        totalMSec = 0;
+
+    dataPtr->frameIndex = 0;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+    for( i=0; i<(NUM_SECONDS*1000/SLEEP_DUR_MSEC); i++ )
+    {
+        int delta, endIndex;
+
+        int startIndex = dataPtr->frameIndex;
+        Pa_Sleep(SLEEP_DUR_MSEC);
+        endIndex = dataPtr->frameIndex;
+
+        delta = endIndex - startIndex;
+        totalFrames += delta;
+        totalMSec += SLEEP_DUR_MSEC;
+
+        printf("index = %d, delta = %d\n", endIndex, delta ); fflush(stdout);
+    }
+
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+
+    *ratePtr = (totalFrames * 1000.0) / totalMSec;
+
+error:
+    return err;
+}
+
+void ReportRate( double measuredRate, double expectedRate )
+{
+    double error;
+
+    error = (measuredRate - expectedRate) / expectedRate;
+    error = (error < 0 ) ? -error : error;
+
+    printf("Measured rate = %6.1f, expected rate = %6.1f\n",
+            measuredRate, expectedRate );
+    if( error > 0.1 )
+    {
+        printf("ERROR: unexpected rate! ---------------------   ERROR!\n");
+    }
+    else
+    {
+        printf("SUCCESS: rate within tolerance!\n");
+    }
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaError    err;
+    paTestData data = { 0 };
+    long       i;
+    double     rate;
+    const    PaDeviceInfo *pdi;
+
+    PortAudioStream *outputStream;
+    PortAudioStream *inputStream;
+
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+
+    pdi = Pa_GetDeviceInfo( INPUT_DEVICE_ID );
+    printf("Input device  = %s\n", pdi->name );
+    pdi = Pa_GetDeviceInfo( OUTPUT_DEVICE_ID );
+    printf("Output device = %s\n", pdi->name );
+
+/* Open input stream. */
+    err = Pa_OpenStream(
+              &inputStream,
+              INPUT_DEVICE_ID,
+              SAMPLES_PER_FRAME,               /* stereo input */
+              PA_SAMPLE_TYPE,
+              NULL,
+              paNoDevice,
+              0,
+              PA_SAMPLE_TYPE,
+              NULL,
+              INPUT_SAMPLE_RATE,
+              FRAMES_PER_BUFFER,            /* frames per buffer */
+              NUM_REC_BUFS,               /* number of buffers, if zero then use default minimum */
+              paClipOff,       /* we won't output out of range samples so don't bother clipping them */
+              recordCallback,
+              &data );
+    if( err != paNoError ) goto error;
+
+    err = Pa_OpenStream(
+              &outputStream,
+              paNoDevice,
+              0,               /* NO input */
+              PA_SAMPLE_TYPE,
+              NULL,
+              OUTPUT_DEVICE_ID,
+              SAMPLES_PER_FRAME,               /* stereo output */
+              PA_SAMPLE_TYPE,
+              NULL,
+              OUTPUT_SAMPLE_RATE,
+              FRAMES_PER_BUFFER,            /* frames per buffer */
+              0,               /* number of buffers, if zero then use default minimum */
+              paClipOff,       /* we won't output out of range samples so don't bother clipping them */
+              playCallback,
+              &data );
+    if( err != paNoError ) goto error;
+
+/* Record and playback multiple times. */
+    for( i=0; i<2; i++ )
+    {
+        printf("Measuring INPUT ------------------------- \n");
+        err = MeasureStreamRate( inputStream, &data, &rate );
+        if( err != paNoError ) goto error;
+        ReportRate( rate, INPUT_SAMPLE_RATE );
+
+        printf("Measuring OUTPUT ------------------------- \n");
+        err = MeasureStreamRate( outputStream, &data, &rate );
+        if( err != paNoError ) goto error;
+        ReportRate( rate, OUTPUT_SAMPLE_RATE );
+    }
+
+/* Clean up. */
+    err = Pa_CloseStream( inputStream );
+    if( err != paNoError ) goto error;
+
+    err = Pa_CloseStream( outputStream );
+    if( err != paNoError ) goto error;
+
+    if( err != paNoError ) goto error;
+
+    Pa_Terminate();
+    
+    printf("Test complete.\n"); fflush(stdout);
+    return 0;
+
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    if( err == paHostError )
+    {
+        fprintf( stderr, "Host Error number: %d\n", Pa_GetHostError() );
+    }
+    return -1;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/debug_test1.c b/utils/iaxclient/lib/portaudio/test/debug_test1.c
new file mode 100644 (file)
index 0000000..55a190f
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * $Id: debug_test1.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ patest1.c
+ Ring modulate the audio input with a 441hz sine wave for 20 seconds
+    using the Portable Audio api
+    Author: Ross Bencina <rossb@audiomulch.com>
+    Modifications:
+ April 5th, 2001 - PLB - Check for NULL inputBuffer.
+*/
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+typedef struct
+{
+    float sine[100];
+    int phase;
+    int sampsToGo;
+}
+patest1data;
+static int patest1Callback( void *inputBuffer, void *outputBuffer,
+                            unsigned long bufferFrames,
+                            PaTimestamp outTime, void *userData )
+{
+    patest1data *data = (patest1data*)userData;
+    float *in = (float*)inputBuffer;
+    float *out = (float*)outputBuffer;
+    int framesToCalc = bufferFrames;
+    unsigned long i;
+    int finished = 0;
+    if(inputBuffer == NULL) return 0;
+    if( data->sampsToGo < bufferFrames )
+    {
+        finished = 1;
+    }
+    for( i=0; i<bufferFrames; i++ )
+    {
+        *out++ = *in++;
+        *out++ = *in++;
+        if( data->phase >= 100 )
+            data->phase = 0;
+    }
+    data->sampsToGo -= bufferFrames;
+    /* zero remainder of final buffer if not already done */
+    for( ; i<bufferFrames; i++ )
+    {
+        *out++ = 0; /* left */
+        *out++ = 0; /* right */
+    }
+    return finished;
+}
+int main(int argc, char* argv[]);
+int main(int argc, char* argv[])
+{
+    PaStream *stream;
+    PaError err;
+    patest1data data;
+    int i;
+    int inputDevice = Pa_GetDefaultInputDeviceID();
+    int outputDevice = Pa_GetDefaultOutputDeviceID();
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<100; i++ )
+        data.sine[i] = sin( ((double)i/100.) * M_PI * 2. );
+    data.phase = 0;
+    data.sampsToGo = 44100 * 4;   // 20 seconds
+    /* initialise portaudio subsytem */
+    Pa_Initialize();
+    err = Pa_OpenStream(
+              &stream,
+              inputDevice,
+              2,              /* stereo input */
+              paFloat32,  /* 32 bit floating point input */
+              NULL,
+              outputDevice,
+              2,              /* stereo output */
+              paFloat32,      /* 32 bit floating point output */
+              NULL,
+              44100.,
+              //    22050,          /* half second buffers */
+              //    4,              /* four buffers */
+              512,          /* half second buffers */
+              0,              /* four buffers */
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              patest1Callback,
+              &data );
+    if( err == paNoError )
+    {
+        err = Pa_StartStream( stream );
+        //       printf( "Press any key to end.\n" );
+        //       getc( stdin ); //wait for input before exiting
+        //       Pa_AbortStream( stream );
+
+        printf( "Waiting for stream to complete...\n" );
+
+        while( Pa_StreamActive( stream ) )
+            Pa_Sleep(1000); /* sleep until playback has finished */
+
+        err = Pa_CloseStream( stream );
+    }
+    else
+    {
+        fprintf( stderr, "An error occured while opening the portaudio stream\n" );
+        if( err == paHostError )
+            fprintf( stderr, "Host error number: %d\n", Pa_GetHostError() );
+        else
+            fprintf( stderr, "Error number: %d\n", err );
+    }
+    Pa_Terminate();
+    printf( "bye\n" );
+
+    return 0;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/pa_devs.c b/utils/iaxclient/lib/portaudio/test/pa_devs.c
new file mode 100644 (file)
index 0000000..d5b4943
--- /dev/null
@@ -0,0 +1,230 @@
+/** @file pa_devs.c
+    @brief List available devices, including device information.
+       @author Phil Burk http://www.softsynth.com
+
+    @note Define PA_NO_ASIO to compile this code on Windows without
+        ASIO support.
+*/
+/*
+ * $Id: pa_devs.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#ifdef WIN32
+#ifndef PA_NO_ASIO
+#include "pa_asio.h"
+#endif
+#endif
+
+/*******************************************************************/
+static void PrintSupportedStandardSampleRates(
+        const PaStreamParameters *inputParameters,
+        const PaStreamParameters *outputParameters )
+{
+    static double standardSampleRates[] = {
+        8000.0, 9600.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0,
+        44100.0, 48000.0, 88200.0, 96000.0, 192000.0, -1 /* negative terminated  list */
+    };
+    int     i, printCount;
+    PaError err;
+
+    printCount = 0;
+    for( i=0; standardSampleRates[i] > 0; i++ )
+    {
+        err = Pa_IsFormatSupported( inputParameters, outputParameters, standardSampleRates[i] );
+        if( err == paFormatIsSupported )
+        {
+            if( printCount == 0 )
+            {
+                printf( "\t%8.2f", standardSampleRates[i] );
+                printCount = 1;
+            }
+            else if( printCount == 4 )
+            {
+                printf( ",\n\t%8.2f", standardSampleRates[i] );
+                printCount = 1;
+            }
+            else
+            {
+                printf( ", %8.2f", standardSampleRates[i] );
+                ++printCount;
+            }
+        }
+    }
+    if( !printCount )
+        printf( "None\n" );
+    else
+        printf( "\n" );
+}
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    int     i, numDevices, defaultDisplayed;
+    const   PaDeviceInfo *deviceInfo;
+    PaStreamParameters inputParameters, outputParameters;
+    PaError err;
+
+    
+    Pa_Initialize();
+
+    printf( "PortAudio version number = %d\nPortAudio version text = '%s'\n",
+            Pa_GetVersion(), Pa_GetVersionText() );
+
+            
+    numDevices = Pa_GetDeviceCount();
+    if( numDevices < 0 )
+    {
+        printf( "ERROR: Pa_CountDevices returned 0x%x\n", numDevices );
+        err = numDevices;
+        goto error;
+    }
+    
+    printf( "Number of devices = %d\n", numDevices );
+    for( i=0; i<numDevices; i++ )
+    {
+        deviceInfo = Pa_GetDeviceInfo( i );
+        printf( "--------------------------------------- device #%d\n", i );
+                
+    /* Mark global and API specific default devices */
+        defaultDisplayed = 0;
+        if( i == Pa_GetDefaultInputDevice() )
+        {
+            printf( "[ Default Input" );
+            defaultDisplayed = 1;
+        }
+        else if( i == Pa_GetHostApiInfo( deviceInfo->hostApi )->defaultInputDevice )
+        {
+            const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo( deviceInfo->hostApi );
+            printf( "[ Default %s Input", hostInfo->name );
+            defaultDisplayed = 1;
+        }
+        
+        if( i == Pa_GetDefaultOutputDevice() )
+        {
+            printf( (defaultDisplayed ? "," : "[") );
+            printf( " Default Output" );
+            defaultDisplayed = 1;
+        }
+        else if( i == Pa_GetHostApiInfo( deviceInfo->hostApi )->defaultOutputDevice )
+        {
+            const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo( deviceInfo->hostApi );
+            printf( (defaultDisplayed ? "," : "[") );                
+            printf( " Default %s Output", hostInfo->name );
+            defaultDisplayed = 1;
+        }
+
+        if( defaultDisplayed )
+            printf( " ]\n" );
+
+    /* print device info fields */
+        printf( "Name                        = %s\n", deviceInfo->name );
+        printf( "Host API                    = %s\n",  Pa_GetHostApiInfo( deviceInfo->hostApi )->name );
+        printf( "Max inputs = %d", deviceInfo->maxInputChannels  );
+        printf( ", Max outputs = %d\n", deviceInfo->maxOutputChannels  );
+
+        printf( "Default low input latency   = %8.3f\n", deviceInfo->defaultLowInputLatency  );
+        printf( "Default low output latency  = %8.3f\n", deviceInfo->defaultLowOutputLatency  );
+        printf( "Default high input latency  = %8.3f\n", deviceInfo->defaultHighInputLatency  );
+        printf( "Default high output latency = %8.3f\n", deviceInfo->defaultHighOutputLatency  );
+
+#ifdef WIN32
+#ifndef PA_NO_ASIO
+/* ASIO specific latency information */
+        if( Pa_GetHostApiInfo( deviceInfo->hostApi )->type == paASIO ){
+            long minLatency, maxLatency, preferredLatency, granularity;
+
+            err = PaAsio_GetAvailableLatencyValues( i,
+                           &minLatency, &maxLatency, &preferredLatency, &granularity );
+
+            printf( "ASIO minimum buffer size    = %ld\n", minLatency  );
+            printf( "ASIO maximum buffer size    = %ld\n", maxLatency  );
+            printf( "ASIO preferred buffer size  = %ld\n", preferredLatency  );
+
+            if( granularity == -1 )
+                printf( "ASIO buffer granularity     = power of 2\n" );
+            else
+                printf( "ASIO buffer granularity     = %ld\n", granularity  );
+        }
+#endif /* !PA_NO_ASIO */
+#endif /* WIN32 */
+
+        printf( "Default sample rate         = %8.2f\n", deviceInfo->defaultSampleRate );
+
+    /* poll for standard sample rates */
+        inputParameters.device = i;
+        inputParameters.channelCount = deviceInfo->maxInputChannels;
+        inputParameters.sampleFormat = paInt16;
+        inputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
+        inputParameters.hostApiSpecificStreamInfo = NULL;
+        
+        outputParameters.device = i;
+        outputParameters.channelCount = deviceInfo->maxOutputChannels;
+        outputParameters.sampleFormat = paInt16;
+        outputParameters.suggestedLatency = 0; /* ignored by Pa_IsFormatSupported() */
+        outputParameters.hostApiSpecificStreamInfo = NULL;
+
+        if( inputParameters.channelCount > 0 )
+        {
+            printf("Supported standard sample rates\n for half-duplex 16 bit %d channel input = \n",
+                    inputParameters.channelCount );
+            PrintSupportedStandardSampleRates( &inputParameters, NULL );
+        }
+
+        if( outputParameters.channelCount > 0 )
+        {
+            printf("Supported standard sample rates\n for half-duplex 16 bit %d channel output = \n",
+                    outputParameters.channelCount );
+            PrintSupportedStandardSampleRates( NULL, &outputParameters );
+        }
+
+        if( inputParameters.channelCount > 0 && outputParameters.channelCount > 0 )
+        {
+            printf("Supported standard sample rates\n for full-duplex 16 bit %d channel input, %d channel output = \n",
+                    inputParameters.channelCount, outputParameters.channelCount );
+            PrintSupportedStandardSampleRates( &inputParameters, &outputParameters );
+        }
+    }
+
+    Pa_Terminate();
+
+    printf("----------------------------------------------\n");
+    return 0;
+
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/pa_fuzz.c b/utils/iaxclient/lib/portaudio/test/pa_fuzz.c
new file mode 100644 (file)
index 0000000..bdf440c
--- /dev/null
@@ -0,0 +1,168 @@
+/** @file pa_fuzz.c
+    @brief Distort input like a fuzz boz.
+       @author Phil Burk  http://www.softsynth.com
+*/
+/*
+ * $Id: pa_fuzz.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+/*
+** Note that many of the older ISA sound cards on PCs do NOT support
+** full duplex audio (simultaneous record and playback).
+** And some only support full duplex at lower sample rates.
+*/
+#define SAMPLE_RATE         (44100)
+#define PA_SAMPLE_TYPE      paFloat32
+#define FRAMES_PER_BUFFER   (64)
+
+typedef float SAMPLE;
+
+float CubicAmplifier( float input );
+static int fuzzCallback( const void *inputBuffer, void *outputBuffer,
+                         unsigned long framesPerBuffer,
+                         const PaStreamCallbackTimeInfo* timeInfo,
+                         PaStreamCallbackFlags statusFlags,
+                         void *userData );
+
+/* Non-linear amplifier with soft distortion curve. */
+float CubicAmplifier( float input )
+{
+    float output, temp;
+    if( input < 0.0 )
+    {
+        temp = input + 1.0f;
+        output = (temp * temp * temp) - 1.0f;
+    }
+    else
+    {
+        temp = input - 1.0f;
+        output = (temp * temp * temp) + 1.0f;
+    }
+
+    return output;
+}
+#define FUZZ(x) CubicAmplifier(CubicAmplifier(CubicAmplifier(CubicAmplifier(x))))
+
+static int gNumNoInputs = 0;
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may be called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int fuzzCallback( const void *inputBuffer, void *outputBuffer,
+                         unsigned long framesPerBuffer,
+                         const PaStreamCallbackTimeInfo* timeInfo,
+                         PaStreamCallbackFlags statusFlags,
+                         void *userData )
+{
+    SAMPLE *out = (SAMPLE*)outputBuffer;
+    const SAMPLE *in = (const SAMPLE*)inputBuffer;
+    unsigned int i;
+    (void) timeInfo; /* Prevent unused variable warnings. */
+    (void) statusFlags;
+    (void) userData;
+
+    if( inputBuffer == NULL )
+    {
+        for( i=0; i<framesPerBuffer; i++ )
+        {
+            *out++ = 0;  /* left - silent */
+            *out++ = 0;  /* right - silent */
+        }
+        gNumNoInputs += 1;
+    }
+    else
+    {
+        for( i=0; i<framesPerBuffer; i++ )
+        {
+            *out++ = FUZZ(*in++);  /* left - distorted */
+            *out++ = *in++;          /* right - clean */
+        }
+    }
+    
+    return paContinue;
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaStreamParameters inputParameters, outputParameters;
+    PaStream *stream;
+    PaError err;
+
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+
+    inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
+    inputParameters.channelCount = 2;       /* stereo input */
+    inputParameters.sampleFormat = PA_SAMPLE_TYPE;
+    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
+    inputParameters.hostApiSpecificStreamInfo = NULL;
+
+    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
+    outputParameters.channelCount = 2;       /* stereo output */
+    outputParameters.sampleFormat = PA_SAMPLE_TYPE;
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+
+    err = Pa_OpenStream(
+              &stream,
+              &inputParameters,
+              &outputParameters,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              0, /* paClipOff, */  /* we won't output out of range samples so don't bother clipping them */
+              fuzzCallback,
+              NULL );
+    if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+    printf("Hit ENTER to stop program.\n");
+    getchar();
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+
+    printf("Finished. gNumNoInputs = %d\n", gNumNoInputs );
+    Pa_Terminate();
+    return 0;
+
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return -1;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/pa_minlat.c b/utils/iaxclient/lib/portaudio/test/pa_minlat.c
new file mode 100644 (file)
index 0000000..4816a51
--- /dev/null
@@ -0,0 +1,187 @@
+/** @file pa_minlat.c
+    @brief Experiment with different numbers of buffers to determine the
+       minimum latency for a computer.
+       @author Phil Burk  http://www.softsynth.com
+*/
+/*
+ * $Id: pa_minlat.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include "portaudio.h"
+
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+#define TWOPI (M_PI * 2.0)
+
+#define DEFAULT_BUFFER_SIZE   (32)
+
+typedef struct
+{
+    double left_phase;
+    double right_phase;
+}
+paTestData;
+
+/* Very simple synthesis routine to generate two sine waves. */
+static int paminlatCallback( const void *inputBuffer, void *outputBuffer,
+                             unsigned long framesPerBuffer,
+                             const PaStreamCallbackTimeInfo* timeInfo,
+                             PaStreamCallbackFlags statusFlags,
+                             void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    unsigned int i;
+    double left_phaseInc = 0.02;
+    double right_phaseInc = 0.06;
+
+    double left_phase = data->left_phase;
+    double right_phase = data->right_phase;
+
+    for( i=0; i<framesPerBuffer; i++ )
+    {
+        left_phase += left_phaseInc;
+        if( left_phase > TWOPI ) left_phase -= TWOPI;
+        *out++ = (float) sin( left_phase );
+
+        right_phase += right_phaseInc;
+        if( right_phase > TWOPI ) right_phase -= TWOPI;
+        *out++ = (float) sin( right_phase );
+    }
+
+    data->left_phase = left_phase;
+    data->right_phase = right_phase;
+    return 0;
+}
+
+int main( int argc, char **argv );
+int main( int argc, char **argv )
+{
+    PaStreamParameters outputParameters;
+    PaStream *stream;
+    PaError err;
+    paTestData data;
+    int    go;
+    int    outLatency = 0;
+    int    minLatency = DEFAULT_BUFFER_SIZE * 2;
+    int    framesPerBuffer;
+    double sampleRate = 44100.0;
+    char   str[256];
+
+    printf("pa_minlat - Determine minimum latency for your computer.\n");
+    printf("  usage:         pa_minlat {userBufferSize}\n");
+    printf("  for example:   pa_minlat 64\n");
+    printf("Adjust your stereo until you hear a smooth tone in each speaker.\n");
+    printf("Then try to find the smallest number of frames that still sounds smooth.\n");
+    printf("Note that the sound will stop momentarily when you change the number of buffers.\n");
+
+    /* Get bufferSize from command line. */
+    framesPerBuffer = ( argc > 1 ) ? atol( argv[1] ) : DEFAULT_BUFFER_SIZE;
+    printf("Frames per buffer = %d\n", framesPerBuffer );
+
+    data.left_phase = data.right_phase = 0.0;
+
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    outLatency = sampleRate * 200.0 / 1000.0; /* 200 msec. */
+
+    /* Try different numBuffers in a loop. */
+    go = 1;
+    while( go )
+    {
+        outputParameters.device                    = Pa_GetDefaultOutputDevice(); /* Default output device. */
+        outputParameters.channelCount              = 2;                           /* Stereo output */
+        outputParameters.sampleFormat              = paFloat32;                   /* 32 bit floating point output. */
+        outputParameters.suggestedLatency          = (double)outLatency / sampleRate; /* In seconds. */
+        outputParameters.hostApiSpecificStreamInfo = NULL;
+        
+        printf("Latency = %d frames = %6.1f msec.\n", outLatency, outputParameters.suggestedLatency * 1000.0 );
+
+        err = Pa_OpenStream(
+                  &stream,
+                  NULL, /* no input */
+                  &outputParameters,
+                  sampleRate,
+                  framesPerBuffer,
+                  paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+                  paminlatCallback,
+                  &data );
+        if( err != paNoError ) goto error;
+        if( stream == NULL ) goto error;
+
+        /* Start audio. */
+        err = Pa_StartStream( stream );
+        if( err != paNoError ) goto error;
+
+        /* Ask user for a new nlatency. */
+        printf("\nMove windows around to see if the sound glitches.\n");
+        printf("Latency now %d, enter new number of frames, or 'q' to quit: ", outLatency );
+        fgets( str, 256, stdin );
+        {
+            /* Get rid of newline */
+            size_t l = strlen( str ) - 1;
+            if( str[ l ] == '\n')
+                str[ l ] = '\0';
+        }
+        if( str[0] == 'q' ) go = 0;
+        else
+        {
+            outLatency = atol( str );
+            if( outLatency < minLatency )
+            {
+                printf( "Latency below minimum of %d! Set to minimum!!!\n", minLatency );
+                outLatency = minLatency;
+            }
+        }
+        /* Stop sound until ENTER hit. */
+        err = Pa_StopStream( stream );
+        if( err != paNoError ) goto error;
+        err = Pa_CloseStream( stream );
+        if( err != paNoError ) goto error;
+    }
+    printf("A good setting for latency would be somewhat higher than\n");
+    printf("the minimum latency that worked.\n");
+    printf("PortAudio: Test finished.\n");
+    Pa_Terminate();
+    return 0;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return 1;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/paqa_devs.c b/utils/iaxclient/lib/portaudio/test/paqa_devs.c
new file mode 100644 (file)
index 0000000..49d0532
--- /dev/null
@@ -0,0 +1,347 @@
+/** @file paqa_devs.c
+    @brief Self Testing Quality Assurance app for PortAudio
+       Try to open each device and run through all the
+       possible configurations.
+
+       @author Phil Burk  http://www.softsynth.com
+    
+    Pieter adapted to V19 API. Test now relies heavily on 
+    Pa_IsFormatSupported(). Uses same 'standard' sample rates
+    as in test pa_devs.c.
+*/
+/*
+ * $Id: paqa_devs.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+#include "pa_trace.h"
+
+/****************************************** Definitions ***********/
+#define MODE_INPUT      (0)
+#define MODE_OUTPUT     (1)
+
+typedef struct PaQaData
+{
+    unsigned long  framesLeft;
+    int            numChannels;
+    int            bytesPerSample;
+    int            mode;
+    short          sawPhase;
+    PaSampleFormat format;
+}
+PaQaData;
+
+/****************************************** Prototypes ***********/
+static void TestDevices( int mode );
+static void TestFormats( int mode, PaDeviceIndex deviceID, double sampleRate,
+                         int numChannels );
+static int TestAdvance( int mode, PaDeviceIndex deviceID, double sampleRate,
+                        int numChannels, PaSampleFormat format );
+static int QaCallback( const void *inputBuffer, void *outputBuffer,
+                       unsigned long framesPerBuffer,
+                       const PaStreamCallbackTimeInfo* timeInfo,
+                       PaStreamCallbackFlags statusFlags,
+                       void *userData );
+
+/****************************************** Globals ***********/
+static int gNumPassed = 0;
+static int gNumFailed = 0;
+
+/****************************************** Macros ***********/
+/* Print ERROR if it fails. Tally success or failure. */
+/* Odd do-while wrapper seems to be needed for some compilers. */
+#define EXPECT(_exp) \
+    do \
+    { \
+        if ((_exp)) {\
+            /* printf("SUCCESS for %s\n", #_exp ); */ \
+            gNumPassed++; \
+        } \
+        else { \
+            printf("ERROR - 0x%x - %s for %s\n", result, \
+                   ((result == 0) ? "-" : Pa_GetErrorText(result)), \
+                   #_exp ); \
+            gNumFailed++; \
+            goto error; \
+        } \
+    } while(0)
+
+/*******************************************************************/
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may be called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int QaCallback( const void *inputBuffer, void *outputBuffer,
+                       unsigned long framesPerBuffer,
+                       const PaStreamCallbackTimeInfo* timeInfo,
+                       PaStreamCallbackFlags statusFlags,
+                       void *userData )
+{
+    unsigned long  i;
+    short          phase;
+    PaQaData *data = (PaQaData *) userData;
+    (void) inputBuffer;
+
+    /* Play simle sawtooth wave. */
+    if( data->mode == MODE_OUTPUT )
+    {
+        phase = data->sawPhase;
+        switch( data->format )
+        {
+        case paFloat32:
+            {
+                float *out =  (float *) outputBuffer;
+                for( i=0; i<framesPerBuffer; i++ )
+                {
+                    phase += 0x123;
+                    *out++ = (float) (phase * (1.0 / 32768.0));
+                    if( data->numChannels == 2 )
+                    {
+                        *out++ = (float) (phase * (1.0 / 32768.0));
+                    }
+                }
+            }
+            break;
+
+        case paInt32:
+            {
+                int *out =  (int *) outputBuffer;
+                for( i=0; i<framesPerBuffer; i++ )
+                {
+                    phase += 0x123;
+                    *out++ = ((int) phase ) << 16;
+                    if( data->numChannels == 2 )
+                    {
+                        *out++ = ((int) phase ) << 16;
+                    }
+                }
+            }
+            break;
+        case paInt16:
+            {
+                short *out =  (short *) outputBuffer;
+                for( i=0; i<framesPerBuffer; i++ )
+                {
+                    phase += 0x123;
+                    *out++ = phase;
+                    if( data->numChannels == 2 )
+                    {
+                        *out++ = phase;
+                    }
+                }
+            }
+            break;
+
+        default:
+            {
+                unsigned char *out =  (unsigned char *) outputBuffer;
+                unsigned long numBytes = framesPerBuffer * data->numChannels * data->bytesPerSample;
+                for( i=0; i<numBytes; i++ )
+                {
+                    *out++ = 0;
+                }
+            }
+            break;
+        }
+        data->sawPhase = phase;
+    }
+    /* Are we through yet? */
+    if( data->framesLeft > framesPerBuffer )
+    {
+        PaUtil_AddTraceMessage("QaCallback: running. framesLeft", data->framesLeft );
+        data->framesLeft -= framesPerBuffer;
+        return 0;
+    }
+    else
+    {
+        PaUtil_AddTraceMessage("QaCallback: DONE! framesLeft", data->framesLeft );
+        data->framesLeft = 0;
+        return 1;
+    }
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaError result;
+    EXPECT( ((result=Pa_Initialize()) == 0) );
+    printf("Test OUTPUT ---------------\n");
+    TestDevices( MODE_OUTPUT );
+    printf("Test INPUT ---------------\n");
+    TestDevices( MODE_INPUT );
+error:
+    Pa_Terminate();
+    printf("QA Report: %d passed, %d failed.\n", gNumPassed, gNumFailed );
+    return 0;
+}
+
+/*******************************************************************
+* Try each output device, through its full range of capabilities. */
+static void TestDevices( int mode )
+{
+    int id, jc, i;
+    int maxChannels;
+    const PaDeviceInfo *pdi;
+    static double standardSampleRates[] = {  8000.0,  9600.0, 11025.0, 12000.0,
+                                            16000.0,          22050.0, 24000.0,
+                                            32000.0,          44100.0, 48000.0,
+                                                              88200.0, 96000.0,
+                                               -1.0 }; /* Negative terminated list. */
+    int numDevices = Pa_GetDeviceCount();
+    for( id=0; id<numDevices; id++ )            /* Iterate through all devices. */
+    {
+        pdi = Pa_GetDeviceInfo( id );
+        /* Try 1 to maxChannels on each device. */
+        maxChannels = (( mode == MODE_INPUT ) ? pdi->maxInputChannels : pdi->maxOutputChannels);
+        
+        for( jc=1; jc<=maxChannels; jc++ )
+        {
+            printf("Name         = %s\n", pdi->name );
+            /* Try each standard sample rate. */
+            for( i=0; standardSampleRates[i] > 0; i++ )
+            {
+                TestFormats( mode, (PaDeviceIndex)id, standardSampleRates[i], jc );
+            }
+        }
+    }
+}
+
+/*******************************************************************/
+static void TestFormats( int mode, PaDeviceIndex deviceID, double sampleRate,
+                         int numChannels )
+{
+    TestAdvance( mode, deviceID, sampleRate, numChannels, paFloat32 );
+    TestAdvance( mode, deviceID, sampleRate, numChannels, paInt16 );
+    TestAdvance( mode, deviceID, sampleRate, numChannels, paInt32 );
+    /* TestAdvance( mode, deviceID, sampleRate, numChannels, paInt24 ); */
+}
+
+/*******************************************************************/
+static int TestAdvance( int mode, PaDeviceIndex deviceID, double sampleRate,
+                        int numChannels, PaSampleFormat format )
+{
+    PaStreamParameters inputParameters, outputParameters, *ipp, *opp;
+    PaStream *stream = NULL;
+    PaError result = paNoError;
+    PaQaData myData;
+    #define FRAMES_PER_BUFFER  (64)
+    
+    /* Setup data for synthesis thread. */
+    myData.framesLeft = (unsigned long) (sampleRate * 100); /* 100 seconds */
+    myData.numChannels = numChannels;
+    myData.mode = mode;
+    myData.format = format;
+    switch( format )
+    {
+    case paFloat32:
+    case paInt32:
+    case paInt24:
+        myData.bytesPerSample = 4;
+        break;
+/*  case paPackedInt24:
+        myData.bytesPerSample = 3;
+        break; */
+    default:
+        myData.bytesPerSample = 2;
+        break;
+    }
+
+    if( mode == MODE_INPUT )
+    {
+        inputParameters.device       = deviceID;
+        inputParameters.channelCount = numChannels;
+        inputParameters.sampleFormat = format;
+        inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
+        inputParameters.hostApiSpecificStreamInfo = NULL;
+        ipp = &inputParameters;
+    }
+    else
+        ipp = NULL;
+    if( mode == MODE_OUTPUT )           /* Pa_GetDeviceInfo(paNoDevice) COREDUMPS!!! */
+    {
+        outputParameters.device       = deviceID;
+        outputParameters.channelCount = numChannels;
+        outputParameters.sampleFormat = format;
+        outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
+        outputParameters.hostApiSpecificStreamInfo = NULL;
+        opp = &outputParameters;
+    }
+    else
+        opp = NULL;
+
+    if(paFormatIsSupported == Pa_IsFormatSupported( ipp, opp, sampleRate ))
+    {
+        printf("------ TestAdvance: %s, device = %d, rate = %g, numChannels = %d, format = %lu -------\n",
+                ( mode == MODE_INPUT ) ? "INPUT" : "OUTPUT",
+                deviceID, sampleRate, numChannels, (unsigned long)format);
+        EXPECT( ((result = Pa_OpenStream( &stream,
+                                          ipp,
+                                          opp,
+                                          sampleRate,
+                                          FRAMES_PER_BUFFER,
+                                          paClipOff,  /* we won't output out of range samples so don't bother clipping them */
+                                          QaCallback,
+                                          &myData ) ) == 0) );
+        if( stream )
+        {
+            PaTime oldStamp, newStamp;
+            unsigned long oldFrames;
+            int minDelay = ( mode == MODE_INPUT ) ? 1000 : 400;
+            /* Was:
+            int minNumBuffers = Pa_GetMinNumBuffers( FRAMES_PER_BUFFER, sampleRate );
+            int msec = (int) ((minNumBuffers * 3 * 1000.0 * FRAMES_PER_BUFFER) / sampleRate);
+            */
+            int msec = (int)( 3.0 *
+                       (( mode == MODE_INPUT ) ? inputParameters.suggestedLatency : outputParameters.suggestedLatency ));
+            if( msec < minDelay ) msec = minDelay;
+            printf("msec = %d\n", msec);  /**/
+            EXPECT( ((result=Pa_StartStream( stream )) == 0) );
+            /* Check to make sure PortAudio is advancing timeStamp. */
+            oldStamp = Pa_GetStreamTime(stream);
+            Pa_Sleep(msec);
+            newStamp = Pa_GetStreamTime(stream);
+            printf("oldStamp = %g,newStamp = %g\n", oldStamp, newStamp ); /**/
+            EXPECT( (oldStamp < newStamp) );
+            /* Check to make sure callback is decrementing framesLeft. */
+            oldFrames = myData.framesLeft;
+            Pa_Sleep(msec);
+            printf("oldFrames = %lu, myData.framesLeft = %lu\n", oldFrames,  myData.framesLeft ); /**/
+            EXPECT( (oldFrames > myData.framesLeft) );
+            EXPECT( ((result=Pa_CloseStream( stream )) == 0) );
+            stream = NULL;
+        }
+    }
+error:
+    if( stream != NULL ) Pa_CloseStream( stream );
+    return result;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/paqa_errs.c b/utils/iaxclient/lib/portaudio/test/paqa_errs.c
new file mode 100644 (file)
index 0000000..8092f9a
--- /dev/null
@@ -0,0 +1,380 @@
+/** @file paqa_errs.c
+       @brief Self Testing Quality Assurance app for PortAudio
+       Do lots of bad things to test error reporting.
+       @author Phil Burk  http://www.softsynth.com
+    Pieter Suurmond adapted to V19 API.
+*/
+/*
+ * $Id: paqa_errs.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+
+#include "portaudio.h"
+
+/*--------- Definitions ---------*/
+#define MODE_INPUT        (0)
+#define MODE_OUTPUT       (1)
+#define FRAMES_PER_BUFFER (64)
+#define SAMPLE_RATE       (44100.0)
+
+typedef struct PaQaData
+{
+    unsigned long  framesLeft;
+    int            numChannels;
+    int            bytesPerSample;
+    int            mode;
+}
+PaQaData;
+
+static int gNumPassed = 0; /* Two globals */
+static int gNumFailed = 0;
+
+/*------------------- Macros ------------------------------*/
+/* Print ERROR if it fails. Tally success or failure. Odd  */
+/* do-while wrapper seems to be needed for some compilers. */
+
+#define EXPECT(_exp) \
+    do \
+    { \
+        if ((_exp)) {\
+            gNumPassed++; \
+        } \
+        else { \
+            printf("\nERROR - 0x%x - %s for %s\n", result, Pa_GetErrorText(result), #_exp ); \
+            gNumFailed++; \
+            goto error; \
+        } \
+    } while(0)
+
+#define HOPEFOR(_exp) \
+    do \
+    { \
+        if ((_exp)) {\
+            gNumPassed++; \
+        } \
+        else { \
+            printf("\nERROR - 0x%x - %s for %s\n", result, Pa_GetErrorText(result), #_exp ); \
+            gNumFailed++; \
+        } \
+    } while(0)
+
+/*-------------------------------------------------------------------------*/
+/* This routine will be called by the PortAudio engine when audio is needed.
+   It may be called at interrupt level on some machines so don't do anything
+   that could mess up the system like calling malloc() or free().
+*/
+static int QaCallback( const void*                      inputBuffer,
+                       void*                            outputBuffer,
+                       unsigned long                    framesPerBuffer,
+                                  const PaStreamCallbackTimeInfo*  timeInfo,
+                                  PaStreamCallbackFlags            statusFlags,
+                       void*                            userData )
+{
+    unsigned long   i;
+    unsigned char*  out = (unsigned char *) outputBuffer;
+    PaQaData*       data = (PaQaData *) userData;
+    
+    (void)inputBuffer; /* Prevent "unused variable" warnings. */
+
+    /* Zero out buffer so we don't hear terrible noise. */
+    if( data->mode == MODE_OUTPUT )
+    {
+        unsigned long numBytes = framesPerBuffer * data->numChannels * data->bytesPerSample;
+        for( i=0; i<numBytes; i++ )
+        {
+            *out++ = 0;
+        }
+    }
+    /* Are we through yet? */
+    if( data->framesLeft > framesPerBuffer )
+    {
+        data->framesLeft -= framesPerBuffer;
+        return 0;
+    }
+    else
+    {
+        data->framesLeft = 0;
+        return 1;
+    }
+}
+
+static PaDeviceIndex FindInputOnlyDevice(void)
+{
+    PaDeviceIndex result = Pa_GetDefaultInputDevice();
+    if( result != paNoDevice && Pa_GetDeviceInfo(result)->maxOutputChannels == 0 )
+        return result;
+
+    for( result = 0; result < Pa_GetDeviceCount(); ++result )
+    {
+        if( Pa_GetDeviceInfo(result)->maxOutputChannels == 0 )
+            return result;
+    }
+
+    return paNoDevice;
+}
+
+static PaDeviceIndex FindOutputOnlyDevice(void)
+{
+    PaDeviceIndex result = Pa_GetDefaultOutputDevice();
+    if( result != paNoDevice && Pa_GetDeviceInfo(result)->maxInputChannels == 0 )
+        return result;
+
+    for( result = 0; result < Pa_GetDeviceCount(); ++result )
+    {
+        if( Pa_GetDeviceInfo(result)->maxInputChannels == 0 )
+            return result;
+    }
+
+    return paNoDevice;
+}
+
+/*-------------------------------------------------------------------------------------------------*/
+static int TestBadOpens( void )
+{
+    PaStream*           stream = NULL;
+    PaError             result;
+    PaQaData            myData;
+    PaStreamParameters  ipp, opp;
+    
+    /* Setup data for synthesis thread. */
+    myData.framesLeft = (unsigned long) (SAMPLE_RATE * 100); /* 100 seconds */
+    myData.numChannels = 1;
+    myData.mode = MODE_OUTPUT;
+
+    /*----------------------------- No devices specified: */
+    ipp.device                    = opp.device                    = paNoDevice;
+    ipp.channelCount              = opp.channelCount              = 0; /* Also no channels. */
+    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
+    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
+    /* Take the low latency of the default device for all subsequent tests. */
+    ipp.suggestedLatency          = Pa_GetDeviceInfo(Pa_GetDefaultInputDevice())->defaultLowInputLatency;
+    opp.suggestedLatency          = Pa_GetDeviceInfo(Pa_GetDefaultOutputDevice())->defaultLowOutputLatency;
+    HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, &opp,
+                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
+                                     paClipOff, QaCallback, &myData )) == paInvalidDevice));
+
+    /*----------------------------- No devices specified #2: */
+    HOPEFOR(((result = Pa_OpenStream(&stream, NULL, NULL,
+                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
+                                     paClipOff, QaCallback, &myData )) == paInvalidDevice));
+
+    /*----------------------------- Out of range input device specified: */
+    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
+    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
+    ipp.channelCount = 0;           ipp.device = Pa_GetDeviceCount(); /* And no output device, and no channels. */
+    opp.channelCount = 0;           opp.device = paNoDevice;
+    HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, NULL,
+                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
+                                     paClipOff, QaCallback, &myData )) == paInvalidDevice));
+
+    /*----------------------------- Out of range output device specified: */
+    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
+    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
+    ipp.channelCount = 0;           ipp.device = paNoDevice; /* And no input device, and no channels. */
+    opp.channelCount = 0;           opp.device = Pa_GetDeviceCount();
+    HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
+                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
+                                     paClipOff, QaCallback, &myData )) == paInvalidDevice));
+
+    /*----------------------------- Zero input channels: */
+    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
+    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
+    ipp.channelCount = 0;           ipp.device = Pa_GetDefaultInputDevice();
+    opp.channelCount = 0;           opp.device = paNoDevice;    /* And no output device, and no output channels. */   
+    HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, NULL,
+                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
+                                     paClipOff, QaCallback, &myData )) == paInvalidChannelCount));
+
+    /*----------------------------- Zero output channels: */
+    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
+    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
+    ipp.channelCount = 0;           ipp.device = paNoDevice; /* And no input device, and no input channels. */
+    opp.channelCount = 0;           opp.device = Pa_GetDefaultOutputDevice();
+    HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
+                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
+                                     paClipOff, QaCallback, &myData )) == paInvalidChannelCount));
+
+    /*----------------------------- Nonzero input and output channels but no output device: */
+    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
+    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
+    ipp.channelCount = 2;           ipp.device = Pa_GetDefaultInputDevice();        /* Both stereo. */
+    opp.channelCount = 2;           opp.device = paNoDevice;
+    HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, &opp,
+                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
+                                     paClipOff, QaCallback, &myData )) == paInvalidDevice));
+
+    /*----------------------------- Nonzero input and output channels but no input device: */
+    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
+    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
+    ipp.channelCount = 2;           ipp.device = paNoDevice;
+    opp.channelCount = 2;           opp.device = Pa_GetDefaultOutputDevice();
+    HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, &opp,
+                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
+                                     paClipOff, QaCallback, &myData )) == paInvalidDevice));
+
+    /*----------------------------- NULL stream pointer: */
+    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
+    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
+    ipp.channelCount = 0;           ipp.device = paNoDevice;           /* Output is more likely than input. */
+    opp.channelCount = 2;           opp.device = Pa_GetDefaultOutputDevice();    /* Only 2 output channels. */
+    HOPEFOR(((result = Pa_OpenStream(NULL, &ipp, &opp,
+                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
+                                     paClipOff, QaCallback, &myData )) == paBadStreamPtr));
+
+    /*----------------------------- Low sample rate: */
+    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
+    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
+    ipp.channelCount = 0;           ipp.device = paNoDevice;
+    opp.channelCount = 2;           opp.device = Pa_GetDefaultOutputDevice();
+    HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
+                                     1.0, FRAMES_PER_BUFFER, /* 1 cycle per second (1 Hz) is too low. */
+                                     paClipOff, QaCallback, &myData )) == paInvalidSampleRate));
+
+    /*----------------------------- High sample rate: */
+    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
+    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
+    ipp.channelCount = 0;           ipp.device = paNoDevice;
+    opp.channelCount = 2;           opp.device = Pa_GetDefaultOutputDevice();
+    HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
+                                     10000000.0, FRAMES_PER_BUFFER, /* 10^6 cycles per second (10 MHz) is too high. */
+                                     paClipOff, QaCallback, &myData )) == paInvalidSampleRate));
+
+    /*----------------------------- NULL callback: */
+    /* NULL callback is valid in V19 -- it means use blocking read/write stream
+    
+    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
+    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
+    ipp.channelCount = 0;           ipp.device = paNoDevice;
+    opp.channelCount = 2;           opp.device = Pa_GetDefaultOutputDevice();
+    HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
+                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
+                                     paClipOff,
+                                     NULL,
+                                     &myData )) == paNullCallback));
+    */
+
+    /*----------------------------- Bad flag: */
+    ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
+    ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
+    ipp.channelCount = 0;           ipp.device = paNoDevice;
+    opp.channelCount = 2;           opp.device = Pa_GetDefaultOutputDevice();
+    HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
+                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
+                                     255,                      /* Is 8 maybe legal V19 API? */
+                                     QaCallback, &myData )) == paInvalidFlag));
+
+    /*----------------------------- using input device as output device: */
+    if( FindInputOnlyDevice() != paNoDevice )
+    {
+        ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
+        ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
+        ipp.channelCount = 0;           ipp.device = paNoDevice; /* And no input device, and no channels. */
+        opp.channelCount = 2;           opp.device = FindInputOnlyDevice();
+        HOPEFOR(((result = Pa_OpenStream(&stream, NULL, &opp,
+                                         SAMPLE_RATE, FRAMES_PER_BUFFER,
+                                         paClipOff, QaCallback, &myData )) == paInvalidChannelCount));
+    }
+
+    /*----------------------------- using output device as input device: */
+    if( FindOutputOnlyDevice() != paNoDevice )
+    {
+        ipp.hostApiSpecificStreamInfo = opp.hostApiSpecificStreamInfo = NULL;
+        ipp.sampleFormat              = opp.sampleFormat              = paFloat32;
+        ipp.channelCount = 2;           ipp.device = FindOutputOnlyDevice();
+        opp.channelCount = 0;           opp.device = paNoDevice;  /* And no output device, and no channels. */
+        HOPEFOR(((result = Pa_OpenStream(&stream, &ipp, NULL,
+                                         SAMPLE_RATE, FRAMES_PER_BUFFER,
+                                         paClipOff, QaCallback, &myData )) == paInvalidChannelCount));
+
+    }
+
+    if( stream != NULL ) Pa_CloseStream( stream );
+    return result;
+}
+
+/*-----------------------------------------------------------------------------------------*/
+static int TestBadActions( void )
+{
+    PaStream*           stream = NULL;
+    PaError             result;
+    PaQaData            myData;
+    PaStreamParameters  opp;
+
+    /* Setup data for synthesis thread. */
+    myData.framesLeft = (unsigned long)(SAMPLE_RATE * 100); /* 100 seconds */
+    myData.numChannels = 1;
+    myData.mode = MODE_OUTPUT;
+
+    opp.device                    = Pa_GetDefaultOutputDevice(); /* Default output. */
+    opp.channelCount              = 2;                           /* Stereo output.  */
+    opp.hostApiSpecificStreamInfo = NULL;
+    opp.sampleFormat              = paFloat32;
+    opp.suggestedLatency          = Pa_GetDeviceInfo(opp.device)->defaultLowOutputLatency;
+
+    HOPEFOR(((result = Pa_OpenStream(&stream, NULL, /* Take NULL as input parame-     */
+                                     &opp,          /* ters, meaning try only output. */
+                                     SAMPLE_RATE, FRAMES_PER_BUFFER,
+                                     paClipOff, QaCallback, &myData )) == paNoError));
+
+    HOPEFOR(((result = Pa_StartStream(NULL))    == paBadStreamPtr));
+    HOPEFOR(((result = Pa_StopStream(NULL))     == paBadStreamPtr));
+    HOPEFOR(((result = Pa_IsStreamStopped(NULL)) == paBadStreamPtr));
+    HOPEFOR(((result = Pa_IsStreamActive(NULL)) == paBadStreamPtr));
+    HOPEFOR(((result = Pa_CloseStream(NULL))    == paBadStreamPtr));
+    HOPEFOR(((result = Pa_SetStreamFinishedCallback(NULL, NULL)) == paBadStreamPtr));
+    HOPEFOR(((result = !Pa_GetStreamInfo(NULL))));
+    HOPEFOR(((result = Pa_GetStreamTime(NULL))  == 0.0));
+    HOPEFOR(((result = Pa_GetStreamCpuLoad(NULL))  == 0.0));
+    HOPEFOR(((result = Pa_ReadStream(NULL, NULL, 0))  == paBadStreamPtr));
+    HOPEFOR(((result = Pa_WriteStream(NULL, NULL, 0))  == paBadStreamPtr));
+
+    /** @todo test Pa_GetStreamReadAvailable and Pa_GetStreamWriteAvailable */
+
+    if (stream != NULL) Pa_CloseStream(stream);
+    return result;
+}
+
+/*---------------------------------------------------------------------*/
+int main(void);
+int main(void)
+{
+    PaError result;
+    
+    EXPECT(((result = Pa_Initialize()) == paNoError));
+    TestBadOpens();
+    TestBadActions();
+error:
+    Pa_Terminate();
+    printf("QA Report: %d passed, %d failed.\n", gNumPassed, gNumFailed);
+    return 0;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest1.c b/utils/iaxclient/lib/portaudio/test/patest1.c
new file mode 100644 (file)
index 0000000..07a00fd
--- /dev/null
@@ -0,0 +1,192 @@
+/** @file patest1.c
+       @brief Ring modulate the audio input with a sine wave for 20 seconds.
+       @author Ross Bencina <rossb@audiomulch.com>
+*/
+/*
+ * $Id: patest1.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#ifndef M_PI
+#define M_PI (3.14159265)
+#endif
+
+#define SAMPLE_RATE (44100)
+
+typedef struct
+{
+    float sine[100];
+    int phase;
+    int sampsToGo;
+}
+patest1data;
+
+static int patest1Callback( const void *inputBuffer, void *outputBuffer,
+                            unsigned long framesPerBuffer,
+                            const PaStreamCallbackTimeInfo* timeInfo,
+                            PaStreamCallbackFlags statusFlags,
+                            void *userData )
+{
+    patest1data *data = (patest1data*)userData;
+    float *in = (float*)inputBuffer;
+    float *out = (float*)outputBuffer;
+    int framesToCalc = framesPerBuffer;
+    unsigned long i = 0;
+    int finished;
+
+    if( data->sampsToGo < framesPerBuffer )
+    {
+        framesToCalc = data->sampsToGo;
+        finished = paComplete;
+    }
+    else
+    {
+        finished = paContinue;
+    }
+
+    for( ; i<framesToCalc; i++ )
+    {
+        *out++ = *in++ * data->sine[data->phase];  /* left */
+        *out++ = *in++ * data->sine[data->phase++];  /* right */
+        if( data->phase >= 100 )
+            data->phase = 0;
+    }
+
+    data->sampsToGo -= framesToCalc;
+
+    /* zero remainder of final buffer if not already done */
+    for( ; i<framesPerBuffer; i++ )
+    {
+        *out++ = 0; /* left */
+        *out++ = 0; /* right */
+    }
+    
+    return finished;
+}
+
+int main(int argc, char* argv[]);
+int main(int argc, char* argv[])
+{
+    PaStream                *stream;
+    PaError                 err;
+    patest1data             data;
+    int                     i;
+    PaStreamParameters      inputParameters, outputParameters;
+    const PaHostErrorInfo*  herr;
+
+    printf("patest1.c\n"); fflush(stdout);
+    printf("Ring modulate input for 20 seconds.\n"); fflush(stdout);
+    
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<100; i++ )
+        data.sine[i] = sin( ((double)i/100.) * M_PI * 2. );
+    data.phase = 0;
+    data.sampsToGo = SAMPLE_RATE * 20;        /* 20 seconds. */
+
+    /* initialise portaudio subsytem */
+    err = Pa_Initialize();
+
+    inputParameters.device = Pa_GetDefaultInputDevice();    /* default input device */
+    inputParameters.channelCount = 2;                       /* stereo input */
+    inputParameters.sampleFormat = paFloat32;               /* 32 bit floating point input */
+    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
+    inputParameters.hostApiSpecificStreamInfo = NULL;
+
+    outputParameters.device = Pa_GetDefaultOutputDevice();  /* default output device */
+    outputParameters.channelCount = 2;                      /* stereo output */
+    outputParameters.sampleFormat = paFloat32;              /* 32 bit floating point output */
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+
+    err = Pa_OpenStream(
+                        &stream,
+                        &inputParameters,
+                        &outputParameters,
+                        (double)SAMPLE_RATE, /* Samplerate in Hertz. */
+                        512,                 /* Small buffers */
+                        paClipOff,           /* We won't output out of range samples so don't bother clipping them. */
+                        patest1Callback,
+                        &data );
+    if( err != paNoError ) goto done;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto done;
+    
+    printf( "Press any key to end.\n" ); fflush(stdout);
+         
+    getc( stdin ); /* wait for input before exiting */
+
+    err = Pa_AbortStream( stream );
+    if( err != paNoError ) goto done;
+    
+    printf( "Waiting for stream to complete...\n" );
+
+    /* sleep until playback has finished */
+    while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(1000);
+    if( err < 0 ) goto done;
+
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto done;
+
+done:
+    Pa_Terminate();
+
+    if( err != paNoError )
+    {
+        fprintf( stderr, "An error occured while using portaudio\n" );
+        if( err == paUnanticipatedHostError )
+        {
+            fprintf( stderr, " unanticipated host error.\n");
+            herr = Pa_GetLastHostErrorInfo();
+            if (herr)
+            {
+                fprintf( stderr, " Error number: %ld\n", herr->errorCode );
+                if (herr->errorText)
+                    fprintf( stderr, " Error text: %s\n", herr->errorText );
+            }
+            else
+                fprintf( stderr, " Pa_GetLastHostErrorInfo() failed!\n" );
+        }
+        else
+        {
+            fprintf( stderr, " Error number: %d\n", err );
+            fprintf( stderr, " Error text: %s\n", Pa_GetErrorText( err ) );
+        }
+
+        err = 1;          /* Always return 0 or 1, but no other return codes. */
+    }
+
+    printf( "bye\n" );
+
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_buffer.c b/utils/iaxclient/lib/portaudio/test/patest_buffer.c
new file mode 100644 (file)
index 0000000..7dff242
--- /dev/null
@@ -0,0 +1,192 @@
+/** @file patest_buffer.c
+       @brief Test opening streams with different buffer sizes.
+       @author Phil Burk  http://www.softsynth.com
+*/
+/*
+ * $Id: patest_buffer.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "portaudio.h"
+#define NUM_SECONDS   (3)
+#define SAMPLE_RATE   (44100)
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+#define TABLE_SIZE   (200)
+
+#define BUFFER_TABLE  14
+long buffer_table[] = {paFramesPerBufferUnspecified,16,32,64,128,200,256,500,512,600,723,1000,1024,2345};
+
+typedef struct
+{
+    short sine[TABLE_SIZE];
+    int left_phase;
+    int right_phase;
+    unsigned int sampsToGo;
+}
+paTestData;
+PaError TestOnce( int buffersize, PaDeviceIndex );
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patest1Callback( const void *inputBuffer, void *outputBuffer,
+                            unsigned long framesPerBuffer,
+                            const PaStreamCallbackTimeInfo* timeInfo,
+                            PaStreamCallbackFlags statusFlags,
+                            void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    short *out = (short*)outputBuffer;
+    unsigned int i;
+    int finished = 0;
+    (void) inputBuffer; /* Prevent "unused variable" warnings. */
+
+    if( data->sampsToGo < framesPerBuffer )
+    {
+        /* final buffer... */
+
+        for( i=0; i<data->sampsToGo; i++ )
+        {
+            *out++ = data->sine[data->left_phase];  /* left */
+            *out++ = data->sine[data->right_phase];  /* right */
+            data->left_phase += 1;
+            if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
+            data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
+            if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
+        }
+        /* zero remainder of final buffer */
+        for( ; i<framesPerBuffer; i++ )
+        {
+            *out++ = 0; /* left */
+            *out++ = 0; /* right */
+        }
+
+        finished = 1;
+    }
+    else
+    {
+        for( i=0; i<framesPerBuffer; i++ )
+        {
+            *out++ = data->sine[data->left_phase];  /* left */
+            *out++ = data->sine[data->right_phase];  /* right */
+            data->left_phase += 1;
+            if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
+            data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
+            if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
+        }
+        data->sampsToGo -= framesPerBuffer;
+    }
+    return finished;
+}
+
+/*******************************************************************/
+int main(int argc, char **args);
+int main(int argc, char **args)
+{
+    int i;
+    int device = -1;
+    PaError err;
+    printf("Test opening streams with different buffer sizes\n");
+    if( argc > 1 ) {
+       device=atoi( args[1] );
+       printf("Using device number %d.\n\n", device );
+    } else {
+       printf("Using default device.\n\n" );
+    }
+
+    for (i = 0 ; i < BUFFER_TABLE; i++)
+    {
+        printf("Buffer size %ld\n", buffer_table[i]);
+        err = TestOnce(buffer_table[i], device);
+        if( err < 0 ) return 0;
+
+    }
+    return 0;
+}
+
+
+PaError TestOnce( int buffersize, PaDeviceIndex device )
+{
+    PaStreamParameters outputParameters;
+    PaStream *stream;
+    PaError err;
+    paTestData data;
+    int i;
+    int totalSamps;
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<TABLE_SIZE; i++ )
+    {
+        data.sine[i] = (short) (32767.0 * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ));
+    }
+    data.left_phase = data.right_phase = 0;
+    data.sampsToGo = totalSamps =  NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+    
+    if( device == -1 )
+        outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
+    else
+        outputParameters.device = device ;
+    outputParameters.channelCount = 2;                      /* stereo output */
+    outputParameters.sampleFormat = paInt16;                /* 32 bit floating point output */
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+    err = Pa_OpenStream(
+              &stream,
+              NULL,                         /* no input */
+              &outputParameters,
+              SAMPLE_RATE,
+              buffersize,                   /* frames per buffer */
+              (paClipOff | paDitherOff),
+              patest1Callback,
+              &data );
+    if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+    printf("Waiting for sound to finish.\n");
+    Pa_Sleep(1000*NUM_SECONDS);
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+    Pa_Terminate();
+    return paNoError;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    fprintf( stderr, "Host Error message: %s\n", Pa_GetLastHostErrorInfo()->errorText );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_callbackstop.c b/utils/iaxclient/lib/portaudio/test/patest_callbackstop.c
new file mode 100644 (file)
index 0000000..dc2c438
--- /dev/null
@@ -0,0 +1,221 @@
+/** @file patest_callbackstop.c
+       @brief Test the paComplete callback result code.
+       @author Ross Bencina <rossb@audiomulch.com>
+*/
+/*
+ * $Id: patest_callbackstop.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define NUM_SECONDS   (5)
+#define NUM_LOOPS     (4)
+#define SAMPLE_RATE   (44100)
+#define FRAMES_PER_BUFFER  (67)
+
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+
+#define TABLE_SIZE   (200)
+typedef struct
+{
+    float sine[TABLE_SIZE];
+    int phase;
+    unsigned long generatedFramesCount;
+    volatile int callbackReturnedPaComplete;
+    volatile int callbackInvokedAfterReturningPaComplete;
+}
+TestData;
+
+/*
+   This routine will be called by the PortAudio stream when audio is needed.
+   It may be called at interrupt level on some machines so don't do anything
+   that could mess up the system like calling malloc() or free().
+*/
+static int TestCallback( const void *input, void *output,
+                            unsigned long frameCount,
+                            const PaStreamCallbackTimeInfo* timeInfo,
+                            PaStreamCallbackFlags statusFlags,
+                            void *userData )
+{
+    TestData *data = (TestData*)userData;
+    float *out = (float*)output;
+    unsigned long i;
+    float x;
+
+    (void) input;       /* Prevent unused variable warnings. */
+    (void) timeInfo;
+    (void) statusFlags;
+
+    
+    if( data->callbackReturnedPaComplete )
+        data->callbackInvokedAfterReturningPaComplete = 1;
+
+    for( i=0; i<frameCount; i++ )
+    {
+        /* generate tone */
+        
+        x = data->sine[ data->phase++ ];
+        if( data->phase >= TABLE_SIZE )
+            data->phase -= TABLE_SIZE;
+        
+        *out++ = x;  /* left */
+        *out++ = x;  /* right */
+    }
+
+    data->generatedFramesCount += frameCount;
+    if( data->generatedFramesCount >= (NUM_SECONDS * SAMPLE_RATE) )
+    {
+        data->callbackReturnedPaComplete = 1;
+        return paComplete;
+    }
+    else
+    {
+        return paContinue;
+    }
+}
+
+/*----------------------------------------------------------------------------*/
+int main(void);
+int main(void)
+{
+    PaStreamParameters outputParameters;
+    PaStream *stream;
+    PaError err;
+    TestData data;
+    int i, j;
+
+    
+    printf( "PortAudio Test: output sine wave. SR = %d, BufSize = %d\n",
+            SAMPLE_RATE, FRAMES_PER_BUFFER );
+    
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<TABLE_SIZE; i++ )
+    {
+        data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
+    }
+    
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    outputParameters.device                    = Pa_GetDefaultOutputDevice();
+    outputParameters.channelCount              = 2;               /* stereo output */
+    outputParameters.sampleFormat              = paFloat32;       /* 32 bit floating point output */
+    outputParameters.suggestedLatency          = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+
+    err = Pa_OpenStream(
+              &stream,
+              NULL, /* no input */
+              &outputParameters,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              paClipOff,      /* output will be in-range, so no need to clip */
+              TestCallback,
+              &data );
+    if( err != paNoError ) goto error;
+
+    printf("Repeating test %d times.\n", NUM_LOOPS );
+    
+    for( i=0; i < NUM_LOOPS; ++i )
+    {
+        data.phase = 0;
+        data.generatedFramesCount = 0;
+        data.callbackReturnedPaComplete = 0;
+        data.callbackInvokedAfterReturningPaComplete = 0;
+
+        err = Pa_StartStream( stream );
+        if( err != paNoError ) goto error;
+
+        printf("Play for %d seconds.\n", NUM_SECONDS );
+
+        /* wait for the callback to complete generating NUM_SECONDS of tone */
+
+        do
+        {
+            Pa_Sleep( 500 );
+        }
+        while( !data.callbackReturnedPaComplete );
+
+        printf( "Callback returned paComplete.\n" );
+        printf( "Waiting for buffers to finish playing...\n" );
+
+        /* wait for stream to become inactive,
+           or for a timeout of approximately NUM_SECONDS
+         */
+     
+        j = 0;
+        while( (err = Pa_IsStreamActive( stream )) == 1 && j < NUM_SECONDS * 2 )
+        {
+            printf(".\n" );
+            Pa_Sleep( 500 );
+            ++j;
+        }
+
+        if( err < 0 )
+        {
+            goto error;
+        }
+        else if( err == 1 )
+        {
+            printf( "TEST FAILED: Timed out waiting for buffers to finish playing.\n" );
+        }
+        else
+        {
+            printf("Buffers finished.\n" );
+        }
+
+        if( data.callbackInvokedAfterReturningPaComplete )
+        {
+            printf( "TEST FAILED: Callback was invoked after returning paComplete.\n" );
+        }
+
+
+        err = Pa_StopStream( stream );
+        if( err != paNoError ) goto error;
+    }
+
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+
+    Pa_Terminate();
+    printf("Test finished.\n");
+    
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_clip.c b/utils/iaxclient/lib/portaudio/test/patest_clip.c
new file mode 100644 (file)
index 0000000..cb9a7fe
--- /dev/null
@@ -0,0 +1,178 @@
+/** @file patest_clip.c
+       @brief Play a sine wave for several seconds at an amplitude 
+       that would require clipping.
+
+       @author Phil Burk  http://www.softsynth.com
+*/
+/*
+ * $Id: patest_clip.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define NUM_SECONDS   (4)
+#define SAMPLE_RATE   (44100)
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+#define TABLE_SIZE   (200)
+
+typedef struct paTestData
+{
+    float sine[TABLE_SIZE];
+    float amplitude;
+    int left_phase;
+    int right_phase;
+}
+paTestData;
+
+PaError PlaySine( paTestData *data, unsigned long flags, float amplitude );
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int sineCallback( const void *inputBuffer, void *outputBuffer,
+                            unsigned long framesPerBuffer,
+                            const PaStreamCallbackTimeInfo* timeInfo,
+                            PaStreamCallbackFlags statusFlags,
+                            void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    float amplitude = data->amplitude;
+    unsigned int i;
+    (void) inputBuffer; /* Prevent "unused variable" warnings. */
+    (void) timeInfo;
+    (void) statusFlags;
+
+    for( i=0; i<framesPerBuffer; i++ )
+    {
+        *out++ = amplitude * data->sine[data->left_phase];  /* left */
+        *out++ = amplitude * data->sine[data->right_phase];  /* right */
+        data->left_phase += 1;
+        if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
+        data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
+        if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
+    }
+    return 0;
+}
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaError err;
+    paTestData data;
+    int i;
+
+    printf("PortAudio Test: output sine wave with and without clipping.\n");
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<TABLE_SIZE; i++ )
+    {
+        data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
+    }
+
+    printf("\nHalf amplitude. Should sound like sine wave.\n"); fflush(stdout);
+    err = PlaySine( &data, paClipOff | paDitherOff, 0.5f );
+    if( err < 0 ) goto error;
+
+    printf("\nFull amplitude. Should sound like sine wave.\n"); fflush(stdout);
+    err = PlaySine( &data, paClipOff | paDitherOff, 0.999f );
+    if( err < 0 ) goto error;
+
+    printf("\nOver range with clipping and dithering turned OFF. Should sound very nasty.\n");
+    fflush(stdout);
+    err = PlaySine( &data, paClipOff | paDitherOff, 1.1f );
+    if( err < 0 ) goto error;
+
+    printf("\nOver range with clipping and dithering turned ON.  Should sound smoother than previous.\n");
+    fflush(stdout);
+    err = PlaySine( &data, paNoFlag, 1.1f );
+    if( err < 0 ) goto error;
+
+    printf("\nOver range with paClipOff but dithering ON.\n"
+           "That forces clipping ON so it should sound the same as previous.\n");
+    fflush(stdout);
+    err = PlaySine( &data, paClipOff, 1.1f );
+    if( err < 0 ) goto error;
+    
+    return 0;
+error:
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return 1;
+}
+/*****************************************************************************/
+PaError PlaySine( paTestData *data, unsigned long flags, float amplitude )
+{
+    PaStreamParameters outputParameters;
+    PaStream *stream;
+    PaError err;
+
+    data->left_phase = data->right_phase = 0;
+    data->amplitude = amplitude;
+    
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
+    outputParameters.channelCount = 2;       /* stereo output */
+    outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+    
+    err = Pa_OpenStream(
+              &stream,
+              NULL, /* no input */
+              &outputParameters,
+              SAMPLE_RATE,
+              1024,
+              flags,
+              sineCallback,
+              data );
+    if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+    Pa_Sleep( NUM_SECONDS * 1000 );
+    printf("CPULoad = %8.6f\n", Pa_GetStreamCpuLoad( stream ) );
+
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+    
+    Pa_Terminate();
+    return paNoError;
+error:
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_dither.c b/utils/iaxclient/lib/portaudio/test/patest_dither.c
new file mode 100644 (file)
index 0000000..edc759e
--- /dev/null
@@ -0,0 +1,178 @@
+/** @file patest_dither.c
+       @brief Attempt to hear difference between dithered and non-dithered signal.
+
+       This only has an effect if the native format is 16 bit.
+
+       @author Phil Burk  http://www.softsynth.com
+*/
+/*
+ * $Id: patest_dither.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+
+#include "portaudio.h"
+
+#define NUM_SECONDS   (5)
+#define SAMPLE_RATE   (44100)
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+#define TABLE_SIZE   (200)
+
+typedef struct paTestData
+{
+    float sine[TABLE_SIZE];
+    float amplitude;
+    int   left_phase;
+    int   right_phase;
+}
+paTestData;
+                         
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int sineCallback( const void *inputBuffer, void *outputBuffer,
+                         unsigned long framesPerBuffer,
+                                    const PaStreamCallbackTimeInfo *timeInfo,
+                                    PaStreamCallbackFlags statusFlags, void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    float amplitude = data->amplitude;
+    unsigned int i;
+    (void) inputBuffer;
+    
+    for( i=0; i<framesPerBuffer; i++ )
+    {
+        *out++ = amplitude * data->sine[data->left_phase];  /* left */
+        *out++ = amplitude * data->sine[data->right_phase];  /* right */
+        data->left_phase += 1;
+        if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
+        data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
+        if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
+    }
+    return 0;
+}
+
+/*****************************************************************************/
+/*
+    V18 version did not call Pa_Terminate() if Pa_Initialize() failed.
+    This V19 version ALWAYS calls Pa_Terminate(). PS.
+*/
+PaError PlaySine( paTestData *data, PaStreamFlags flags, float amplitude );
+PaError PlaySine( paTestData *data, PaStreamFlags flags, float amplitude )
+{
+    PaStream*           stream;
+    PaStreamParameters  outputParameters;
+    PaError             err;
+
+    data->left_phase = data->right_phase = 0;
+    data->amplitude  = amplitude;
+
+    err = Pa_Initialize();
+    if (err != paNoError)
+        goto done;
+
+    outputParameters.device = Pa_GetDefaultOutputDevice();  /* default output device */
+    outputParameters.channelCount = 2;                      /* stereo output */
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+    outputParameters.sampleFormat = paFloat32;      /* 32 bit floating point output. */
+                                                    /* When you change this, also    */
+                                                    /* adapt the callback routine!   */ 
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )
+                                        ->defaultLowOutputLatency;   /* Low latency. */
+    err = Pa_OpenStream( &stream,
+                         NULL,                              /* No input. */
+                         &outputParameters,
+                         SAMPLE_RATE,
+                         1024,                              /* frames per buffer */
+                         flags,
+                         sineCallback,
+                         (void*)data );
+    if (err != paNoError)
+        goto done;
+
+    err = Pa_StartStream( stream );
+    if (err != paNoError)
+        goto done;
+
+    Pa_Sleep( NUM_SECONDS * 1000 );
+    printf("CPULoad = %8.6f\n", Pa_GetStreamCpuLoad(stream));
+    
+    err = Pa_CloseStream( stream );
+done:
+    Pa_Sleep( 250 );  /* Just a small silence. */
+    Pa_Terminate();
+    return err;
+}
+
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaError     err;
+    paTestData  DATA;
+    int         i;
+    float       amplitude = 4.0 / (1<<15);
+    
+    printf("PortAudio Test: output EXTREMELY QUIET sine wave with and without dithering.\n");
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<TABLE_SIZE; i++ )
+    {
+        DATA.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
+    }
+    printf("\nNo treatment..\n"); fflush(stdout);
+    err = PlaySine( &DATA, paClipOff | paDitherOff, amplitude );
+    if( err < 0 ) goto done;
+
+    printf("\nClip..\n");
+    fflush(stdout);
+    err = PlaySine( &DATA, paDitherOff, amplitude );
+    if( err < 0 ) goto done;
+
+    printf("\nClip and Dither..\n");
+    fflush(stdout);
+    err = PlaySine( &DATA, paNoFlag, amplitude );
+done:
+    if (err)
+        {
+        fprintf( stderr, "An error occured while using the portaudio stream\n" );
+        fprintf( stderr, "Error number: %d\n", err );
+        fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+        err = 1; /* Though PlaySine() already called Pa_Terminate(), */
+        }        /* we may still call Pa_GetErrorText().             */
+    else
+        printf("\n(Don't forget to turn the VOLUME DOWN after listening so carefully.)\n");
+    return err;  /* 0 or 1. */
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_hang.c b/utils/iaxclient/lib/portaudio/test/patest_hang.c
new file mode 100644 (file)
index 0000000..3cad056
--- /dev/null
@@ -0,0 +1,152 @@
+/** @file patest_hang.c
+       @brief Play a sine then hang audio callback to test watchdog.
+       @author Ross Bencina <rossb@audiomulch.com>
+       @author Phil Burk <philburk@softsynth.com>
+*/
+/*
+ * $Id: patest_hang.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+
+#include "portaudio.h"
+
+#define SAMPLE_RATE       (44100)
+#define FRAMES_PER_BUFFER (1024)
+#ifndef M_PI
+#define M_PI              (3.14159265)
+#endif
+#define TWOPI             (M_PI * 2.0)
+
+typedef struct paTestData
+{
+    int    sleepFor;
+    double phase;
+}
+paTestData;
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( const void *inputBuffer, void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                           const PaStreamCallbackTimeInfo* timeInfo,
+                           PaStreamCallbackFlags statusFlags,
+                           void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    unsigned long i;
+    int finished = 0;
+    double phaseInc = 0.02;
+    double phase = data->phase;
+    
+    (void) inputBuffer; /* Prevent unused argument warning. */
+
+    for( i=0; i<framesPerBuffer; i++ )
+    {
+        phase += phaseInc;
+        if( phase > TWOPI ) phase -= TWOPI;
+        /* This is not a very efficient way to calc sines. */
+        *out++ = (float) sin( phase ); /* mono */
+    }
+    
+    if( data->sleepFor > 0 )
+    {
+        Pa_Sleep( data->sleepFor );
+    }
+    
+    data->phase = phase;
+    return finished;
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaStream*           stream;
+    PaStreamParameters  outputParameters;
+    PaError             err;
+    int                 i;
+    paTestData          data = {0};
+    
+    printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n",
+        SAMPLE_RATE, FRAMES_PER_BUFFER );
+
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    outputParameters.device = Pa_GetDefaultOutputDevice(); /* Default output device. */
+    outputParameters.channelCount = 1;                     /* Mono output. */
+    outputParameters.sampleFormat = paFloat32;             /* 32 bit floating point. */
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+    outputParameters.suggestedLatency          = Pa_GetDeviceInfo(outputParameters.device)
+                                                 ->defaultLowOutputLatency;
+    err = Pa_OpenStream(&stream,
+                        NULL,                    /* No input. */
+                        &outputParameters,
+                        SAMPLE_RATE,
+                        FRAMES_PER_BUFFER,
+                        paClipOff,               /* No out of range samples. */
+                        patestCallback,
+                        &data);
+    if (err != paNoError) goto error;
+    
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+    /* Gradually increase sleep time. */
+    /* Was: for( i=0; i<10000; i+= 1000 ) */
+    for(i=0; i <= 1000; i += 100)
+    {
+        printf("Sleep for %d milliseconds in audio callback.\n", i );
+        data.sleepFor = i;
+        Pa_Sleep( ((i<1000) ? 1000 : i) );
+    }
+    
+    printf("Suffer for 10 seconds.\n");
+    Pa_Sleep( 10000 );
+    
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+    Pa_Terminate();
+    printf("Test finished.\n");
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_in_overflow.c b/utils/iaxclient/lib/portaudio/test/patest_in_overflow.c
new file mode 100644 (file)
index 0000000..6496f32
--- /dev/null
@@ -0,0 +1,224 @@
+/** @file patest_in_overflow.c
+       @brief Count input overflows (using paInputOverflow flag) under 
+       overloaded and normal conditions.
+    This test uses the same method to overload the stream as does
+    patest_out_underflow.c -- it generates sine waves until the cpu load
+    exceeds a certain level. However this test is only concerned with
+    input and so doesn't ouput any sound.
+    
+    @author Ross Bencina <rossb@audiomulch.com>
+       @author Phil Burk <philburk@softsynth.com>
+*/
+/*
+ * $Id: patest_in_overflow.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2004 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define MAX_SINES     (500)
+#define MAX_LOAD      (1.2)
+#define SAMPLE_RATE   (44100)
+#define FRAMES_PER_BUFFER  (512)
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+#define TWOPI (M_PI * 2.0)
+
+typedef struct paTestData
+{
+    int sineCount;
+    double phases[MAX_SINES];
+    int countOverflows;
+    int inputOverflowCount;
+}
+paTestData;
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( const void *inputBuffer, void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                           const PaStreamCallbackTimeInfo* timeInfo,
+                           PaStreamCallbackFlags statusFlags,
+                           void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    float out;          /* variable to hold dummy output */
+    unsigned long i;
+    int j;
+    int finished = paContinue;
+    (void) timeInfo;    /* Prevent unused variable warning. */
+    (void) inputBuffer; /* Prevent unused variable warning. */
+    (void) outputBuffer; /* Prevent unused variable warning. */
+
+    if( data->countOverflows && (statusFlags & paInputOverflow) )
+        data->inputOverflowCount++;
+
+    for( i=0; i<framesPerBuffer; i++ )
+    {
+        float output = 0.0;
+        double phaseInc = 0.02;
+        double phase;
+
+        for( j=0; j<data->sineCount; j++ )
+        {
+            /* Advance phase of next oscillator. */
+            phase = data->phases[j];
+            phase += phaseInc;
+            if( phase > TWOPI ) phase -= TWOPI;
+
+            phaseInc *= 1.02;
+            if( phaseInc > 0.5 ) phaseInc *= 0.5;
+
+            /* This is not a very efficient way to calc sines. */
+            output += (float) sin( phase );
+            data->phases[j] = phase;
+        }
+        /* this is an input-only stream so we don't actually use the output */
+        out = (float) (output / data->sineCount);
+        (void) out; /* suppress unused variable warning*/
+    }
+
+    return finished;
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaStreamParameters inputParameters;
+    PaStream *stream;
+    PaError err;
+    int safeSineCount, stressedSineCount;
+    int safeOverflowCount, stressedOverflowCount;
+    paTestData data = {0};
+    double load;
+
+
+    printf("PortAudio Test: input only, no sound output. Load callback by performing calculations, count input overflows. SR = %d, BufSize = %d. MAX_LOAD = %f\n",
+        SAMPLE_RATE, FRAMES_PER_BUFFER, (float)MAX_LOAD );
+
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    inputParameters.device = Pa_GetDefaultInputDevice();  /* default input device */
+    inputParameters.channelCount = 1;                      /* mono output */
+    inputParameters.sampleFormat = paFloat32;              /* 32 bit floating point output */
+    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
+    inputParameters.hostApiSpecificStreamInfo = NULL;
+
+    err = Pa_OpenStream(
+              &stream,
+              &inputParameters,
+              NULL,    /* no output */
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              paClipOff,    /* we won't output out of range samples so don't bother clipping them */
+              patestCallback,
+              &data );    
+    if( err != paNoError ) goto error;
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+    printf("Establishing load conditions...\n" );
+
+    /* Determine number of sines required to get to 50% */
+    do
+    {
+        data.sineCount++;
+        Pa_Sleep( 100 );
+
+        load = Pa_GetStreamCpuLoad( stream );
+        printf("sineCount = %d, CPU load = %f\n", data.sineCount, load );
+    }
+    while( load < 0.5 && data.sineCount < (MAX_SINES-1));
+
+    safeSineCount = data.sineCount;
+
+    /* Calculate target stress value then ramp up to that level*/
+    stressedSineCount = (int) (2.0 * data.sineCount * MAX_LOAD );
+    if( stressedSineCount > MAX_SINES )
+        stressedSineCount = MAX_SINES;
+    for( ; data.sineCount < stressedSineCount; data.sineCount++ )
+    {
+        Pa_Sleep( 100 );
+        load = Pa_GetStreamCpuLoad( stream );
+        printf("STRESSING: sineCount = %d, CPU load = %f\n", data.sineCount, load );
+    }
+    
+    printf("Counting overflows for 5 seconds.\n");
+    data.countOverflows = 1;
+    Pa_Sleep( 5000 );
+
+    stressedOverflowCount = data.inputOverflowCount;
+
+    data.countOverflows = 0;
+    data.sineCount = safeSineCount;
+
+    printf("Resuming safe load...\n");
+    Pa_Sleep( 1500 );
+    data.inputOverflowCount = 0;
+    Pa_Sleep( 1500 );
+    load = Pa_GetStreamCpuLoad( stream );
+    printf("sineCount = %d, CPU load = %f\n", data.sineCount, load );
+
+    printf("Counting overflows for 5 seconds.\n");
+    data.countOverflows = 1;
+    Pa_Sleep( 5000 );
+
+    safeOverflowCount = data.inputOverflowCount;
+    
+    printf("Stop stream.\n");
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+    
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+    
+    Pa_Terminate();
+
+    if( stressedOverflowCount == 0 )
+        printf("Test failed, no input overflows detected under stress.\n");
+    else if( safeOverflowCount != 0 )
+        printf("Test failed, %d unexpected overflows detected under safe load.\n", safeOverflowCount);
+    else
+        printf("Test passed, %d expected input overflows detected under stress, 0 unexpected overflows detected under safe load.\n", stressedOverflowCount );
+
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_latency.c b/utils/iaxclient/lib/portaudio/test/patest_latency.c
new file mode 100644 (file)
index 0000000..eaa478a
--- /dev/null
@@ -0,0 +1,182 @@
+/** @file
+       @brief Hear the latency caused by big buffers.
+       Play a sine wave and change frequency based on letter input.
+       @author Phil Burk <philburk@softsynth.com>, and Darren Gibbs
+*/
+/*
+ * $Id: patest_latency.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define OUTPUT_DEVICE       (Pa_GetDefaultOutputDevice())
+#define SAMPLE_RATE         (44100)
+#define FRAMES_PER_BUFFER   (64)
+
+#define MIN_FREQ            (100.0f)
+#define CalcPhaseIncrement(freq)  ((freq)/SAMPLE_RATE)
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+#define TABLE_SIZE   (400)
+
+typedef struct
+{
+    float sine[TABLE_SIZE + 1]; /* add one for guard point for interpolation */
+    float phase_increment;
+    float left_phase;
+    float right_phase;
+}
+paTestData;
+
+float LookupSine( paTestData *data, float phase );
+/* Convert phase between and 1.0 to sine value
+ * using linear interpolation.
+ */
+float LookupSine( paTestData *data, float phase )
+{
+    float fIndex = phase*TABLE_SIZE;
+    int   index = (int) fIndex;
+    float fract = fIndex - index;
+    float lo = data->sine[index];
+    float hi = data->sine[index+1];
+    float val = lo + fract*(hi-lo);
+    return val;
+}
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( const void *inputBuffer, void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                           const PaStreamCallbackTimeInfo* timeInfo,
+                           PaStreamCallbackFlags statusFlags,
+                           void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    int i;
+
+    (void) inputBuffer; /* Prevent unused variable warning. */
+
+    for( i=0; i<framesPerBuffer; i++ )
+    {
+        *out++ = LookupSine(data, data->left_phase);  /* left */
+        *out++ = LookupSine(data, data->right_phase);  /* right */
+        data->left_phase += data->phase_increment;
+        if( data->left_phase >= 1.0f ) data->left_phase -= 1.0f;
+        data->right_phase += (data->phase_increment * 1.5f); /* fifth above */
+        if( data->right_phase >= 1.0f ) data->right_phase -= 1.0f;
+    }
+    return 0;
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaStream *stream;
+    PaStreamParameters outputParameters;
+    PaError err;
+    paTestData data;
+    int i;
+    int done = 0;
+
+    printf("PortAudio Test: enter letter then hit ENTER.\n" );
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<TABLE_SIZE; i++ )
+    {
+        data.sine[i] = 0.90f * (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
+    }
+    data.sine[TABLE_SIZE] = data.sine[0]; /* set guard point. */
+    data.left_phase = data.right_phase = 0.0;
+    data.phase_increment = CalcPhaseIncrement(MIN_FREQ);
+
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+    printf("PortAudio Test: output device = %d\n", OUTPUT_DEVICE );
+
+    outputParameters.device = OUTPUT_DEVICE;
+    outputParameters.channelCount = 2;         /* stereo output */
+    outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+    
+    printf("Requested output latency = %.4f seconds.\n", outputParameters.suggestedLatency );
+    printf("%d frames per buffer.\n.", FRAMES_PER_BUFFER );
+
+    err = Pa_OpenStream(
+              &stream,
+              NULL, /* no input */
+              &outputParameters,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              paClipOff|paDitherOff,      /* we won't output out of range samples so don't bother clipping them */
+              patestCallback,
+              &data );
+    if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+    printf("Play ASCII keyboard. Hit 'q' to stop. (Use RETURN key on Mac)\n");
+    fflush(stdout);
+    while ( !done )
+    {
+        float  freq;
+        int index;
+        char c;
+        do
+        {
+            c = getchar();
+        }
+        while( c < ' '); /* Strip white space and control chars. */
+
+        if( c == 'q' ) done = 1;
+        index = c % 26;
+        freq = MIN_FREQ + (index * 40.0);
+        data.phase_increment = CalcPhaseIncrement(freq);
+    }
+    printf("Call Pa_StopStream()\n");
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+    Pa_Terminate();
+    printf("Test finished.\n");
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_leftright.c b/utils/iaxclient/lib/portaudio/test/patest_leftright.c
new file mode 100644 (file)
index 0000000..7d6a6f2
--- /dev/null
@@ -0,0 +1,173 @@
+/** @file patest_leftright.c
+       @brief Play different tone sine waves that 
+               alternate between left and right channel.
+
+       The low tone should be on the left channel.
+
+       @author Ross Bencina <rossb@audiomulch.com>
+       @author Phil Burk <philburk@softsynth.com>
+*/
+/*
+ * $Id: patest_leftright.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define NUM_SECONDS   (8)
+#define SAMPLE_RATE   (44100)
+#define FRAMES_PER_BUFFER  (512)
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+#define TABLE_SIZE   (200)
+typedef struct
+{
+    float sine[TABLE_SIZE];
+    int left_phase;
+    int right_phase;
+    int toggle;
+    int countDown;
+}
+paTestData;
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( const void *inputBuffer,
+                           void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                           const PaStreamCallbackTimeInfo* timeInfo,
+                           PaStreamCallbackFlags statusFlags,
+                           void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    unsigned long i;
+    int finished = 0;
+    /* Prevent unused variable warnings. */
+    (void) inputBuffer;
+
+    for( i=0; i<framesPerBuffer; i++ )
+    {
+        if( data->toggle )
+        {
+            *out++ = data->sine[data->left_phase];  /* left */
+            *out++ = 0;  /* right */
+        }
+        else
+        {
+            *out++ = 0;  /* left */
+            *out++ = data->sine[data->right_phase];  /* right */
+        }
+
+        data->left_phase += 1;
+        if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
+        data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
+        if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
+    }
+
+    if( data->countDown < 0 )
+    {
+        data->countDown = SAMPLE_RATE;
+        data->toggle = !data->toggle;
+    }
+    data->countDown -= framesPerBuffer;
+
+    return finished;
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaStream *stream;
+    PaStreamParameters outputParameters;
+    PaError err;
+    paTestData data;
+    int i;
+    int timeout;
+    
+    printf("Play different tone sine waves that alternate between left and right channel.\n");
+    printf("The low tone should be on the left channel.\n");
+    
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<TABLE_SIZE; i++ )
+    {
+        data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
+    }
+    data.left_phase = data.right_phase = data.toggle = 0;
+    data.countDown = SAMPLE_RATE;
+
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
+    outputParameters.channelCount = 2;       /* stereo output */
+    outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+
+    err = Pa_OpenStream( &stream,
+                         NULL,                  /* No input. */
+                         &outputParameters,     /* As above. */
+                         SAMPLE_RATE,
+                         FRAMES_PER_BUFFER,
+                         paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+                         patestCallback,
+                         &data );
+    if( err != paNoError ) goto error;
+    
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+    
+    printf("Play for several seconds.\n");
+    timeout = NUM_SECONDS * 4;
+    while( timeout > 0 )
+    {
+        Pa_Sleep( 300 );        /*(Irix very much likes sleeps <= 1000 ms.)*/
+        timeout -= 1;
+    }
+
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+    Pa_Terminate();
+    printf("Test finished.\n");
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_longsine.c b/utils/iaxclient/lib/portaudio/test/patest_longsine.c
new file mode 100644 (file)
index 0000000..5a34918
--- /dev/null
@@ -0,0 +1,140 @@
+/** @file patest_longsine.c
+       @brief Play a sine wave until ENTER hit.
+       @author Phil Burk  http://www.softsynth.com
+*/
+/*
+ * $Id: patest_longsine.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+
+#include "portaudio.h"
+
+#define SAMPLE_RATE   (44100)
+
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+
+#define TABLE_SIZE   (200)
+typedef struct
+{
+    float sine[TABLE_SIZE];
+    int left_phase;
+    int right_phase;
+}
+paTestData;
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback(const void*                     inputBuffer,
+                          void*                           outputBuffer,
+                          unsigned long                   framesPerBuffer,
+                          const PaStreamCallbackTimeInfo* timeInfo,
+                          PaStreamCallbackFlags           statusFlags,
+                          void*                           userData)
+{
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    unsigned int i;
+    (void) inputBuffer; /* Prevent unused argument warning. */
+    for( i=0; i<framesPerBuffer; i++ )
+    {
+        *out++ = data->sine[data->left_phase];  /* left */
+        *out++ = data->sine[data->right_phase];  /* right */
+        data->left_phase += 1;
+        if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
+        data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
+        if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
+    }
+    return 0;
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaStreamParameters outputParameters;
+    PaStream *stream;
+    PaError err;
+    paTestData data;
+    int i;
+    printf("PortAudio Test: output sine wave.\n");
+
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<TABLE_SIZE; i++ )
+    {
+        data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
+    }
+    data.left_phase = data.right_phase = 0;
+
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
+    outputParameters.channelCount = 2;                     /* stereo output */
+    outputParameters.sampleFormat = paFloat32;             /* 32 bit floating point output */
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+
+    err = Pa_OpenStream( &stream,
+                         NULL,              /* No input. */
+                         &outputParameters, /* As above. */
+                         SAMPLE_RATE,
+                         256,               /* Frames per buffer. */
+                         paClipOff,         /* No out of range samples expected. */
+                         patestCallback,
+                         &data );
+    if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+    printf("Hit ENTER to stop program.\n");
+    getchar();
+
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+    Pa_Terminate();
+
+    printf("Test finished.\n");
+    return err;
+
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_many.c b/utils/iaxclient/lib/portaudio/test/patest_many.c
new file mode 100644 (file)
index 0000000..969c6fe
--- /dev/null
@@ -0,0 +1,198 @@
+/** @file patest_many.c
+       @brief Start and stop the PortAudio Driver multiple times.
+       @author Phil Burk  http://www.softsynth.com
+*/
+/*
+ * $Id: patest_many.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "portaudio.h"
+#define NUM_SECONDS   (1)
+#define SAMPLE_RATE   (44100)
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+#define TABLE_SIZE   (200)
+typedef struct
+{
+    short sine[TABLE_SIZE];
+    int left_phase;
+    int right_phase;
+    unsigned int sampsToGo;
+}
+paTestData;
+PaError TestOnce( void );
+static int patest1Callback( const void *inputBuffer, void *outputBuffer,
+                            unsigned long framesPerBuffer,
+                            const PaStreamCallbackTimeInfo* timeInfo,
+                            PaStreamCallbackFlags statusFlags,
+                            void *userData );
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patest1Callback( const void *inputBuffer, void *outputBuffer,
+                            unsigned long framesPerBuffer,
+                            const PaStreamCallbackTimeInfo* timeInfo,
+                            PaStreamCallbackFlags statusFlags,
+                            void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    short *out = (short*)outputBuffer;
+    unsigned int i;
+    int finished = 0;
+    (void) inputBuffer; /* Prevent "unused variable" warnings. */
+
+    if( data->sampsToGo < framesPerBuffer )
+    {
+        /* final buffer... */
+
+        for( i=0; i<data->sampsToGo; i++ )
+        {
+            *out++ = data->sine[data->left_phase];  /* left */
+            *out++ = data->sine[data->right_phase];  /* right */
+            data->left_phase += 1;
+            if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
+            data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
+            if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
+        }
+        /* zero remainder of final buffer */
+        for( ; i<framesPerBuffer; i++ )
+        {
+            *out++ = 0; /* left */
+            *out++ = 0; /* right */
+        }
+
+        finished = 1;
+    }
+    else
+    {
+        for( i=0; i<framesPerBuffer; i++ )
+        {
+            *out++ = data->sine[data->left_phase];  /* left */
+            *out++ = data->sine[data->right_phase];  /* right */
+            data->left_phase += 1;
+            if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
+            data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
+            if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
+        }
+        data->sampsToGo -= framesPerBuffer;
+    }
+    return finished;
+}
+/*******************************************************************/
+#ifdef MACINTOSH
+int main(void);
+int main(void)
+{
+    int i;
+    PaError err;
+    int numLoops = 10;
+    printf("Loop %d times.\n", numLoops );
+    for( i=0; i<numLoops; i++ )
+    {
+        printf("Loop %d out of %d.\n", i+1, numLoops );
+        err = TestOnce();
+        if( err < 0 ) return 0;
+    }
+}
+#else
+int main(int argc, char **argv);
+int main(int argc, char **argv)
+{
+    PaError err;
+    int i, numLoops = 10;
+    if( argc > 1 )
+    {
+        numLoops = atoi(argv[1]);
+    }
+    for( i=0; i<numLoops; i++ )
+    {
+        printf("Loop %d out of %d.\n", i+1, numLoops );
+        err = TestOnce();
+        if( err < 0 ) return 1;
+    }
+    printf("Test complete.\n");
+    return 0;
+}
+#endif
+PaError TestOnce( void )
+{
+    PaStreamParameters outputParameters;
+    PaStream *stream;
+    PaError err;
+    paTestData data;
+    int i;
+    int totalSamps;
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<TABLE_SIZE; i++ )
+    {
+        data.sine[i] = (short) (32767.0 * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ));
+    }
+    data.left_phase = data.right_phase = 0;
+    data.sampsToGo = totalSamps =  NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    outputParameters.device = Pa_GetDefaultOutputDevice();  /* default output device */
+    outputParameters.channelCount = 2;                      /* stereo output */
+    outputParameters.sampleFormat = paInt16;
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+    err = Pa_OpenStream(
+              &stream,
+              NULL,         /* no input */
+              &outputParameters,
+              SAMPLE_RATE,
+              1024,         /* frames per buffer */
+              paClipOff,    /* we won't output out of range samples so don't bother clipping them */
+              patest1Callback,
+              &data );
+    if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+    printf("Waiting for sound to finish.\n");
+    Pa_Sleep(1000);
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+    Pa_Terminate();
+    return paNoError;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_maxsines.c b/utils/iaxclient/lib/portaudio/test/patest_maxsines.c
new file mode 100644 (file)
index 0000000..04a6cc8
--- /dev/null
@@ -0,0 +1,204 @@
+/** @file patest_maxsines.c
+       @brief How many sine waves can we calculate and play in less than 80% CPU Load.
+       @author Ross Bencina <rossb@audiomulch.com>
+       @author Phil Burk <philburk@softsynth.com>
+*/
+/*
+ * $Id: patest_maxsines.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define MAX_SINES     (500)
+#define MAX_USAGE     (0.8)
+#define SAMPLE_RATE   (44100)
+#define FREQ_TO_PHASE_INC(freq)   (freq/(float)SAMPLE_RATE)
+
+#define MIN_PHASE_INC  FREQ_TO_PHASE_INC(200.0f)
+#define MAX_PHASE_INC  (MIN_PHASE_INC * (1 << 5))
+
+#define FRAMES_PER_BUFFER  (512)
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+#define TWOPI (M_PI * 2.0)
+
+#define TABLE_SIZE   (512)
+
+typedef struct paTestData
+{
+    int numSines;
+    float sine[TABLE_SIZE + 1]; /* add one for guard point for interpolation */
+    float phases[MAX_SINES];
+}
+paTestData;
+
+/* Convert phase between and 1.0 to sine value
+ * using linear interpolation.
+ */
+float LookupSine( paTestData *data, float phase );
+float LookupSine( paTestData *data, float phase )
+{
+    float fIndex = phase*TABLE_SIZE;
+    int   index = (int) fIndex;
+    float fract = fIndex - index;
+    float lo = data->sine[index];
+    float hi = data->sine[index+1];
+    float val = lo + fract*(hi-lo);
+    return val;
+}
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback(const void*                     inputBuffer,
+                          void*                           outputBuffer,
+                          unsigned long                   framesPerBuffer,
+                          const PaStreamCallbackTimeInfo* timeInfo,
+                          PaStreamCallbackFlags           statusFlags,
+                          void*                           userData )
+{
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    float outSample;
+    float scaler;
+    int numForScale;
+    unsigned long i;
+    int j;
+    int finished = 0;
+    (void) inputBuffer; /* Prevent unused argument warning. */
+
+    /* Determine amplitude scaling factor */
+    numForScale = data->numSines;
+    if( numForScale < 8 ) numForScale = 8;  /* prevent pops at beginning */
+    scaler = 1.0f / numForScale;
+    
+    for( i=0; i<framesPerBuffer; i++ )
+    {
+        float output = 0.0;
+        float phaseInc = MIN_PHASE_INC;
+        float phase;
+        for( j=0; j<data->numSines; j++ )
+        {
+            /* Advance phase of next oscillator. */
+            phase = data->phases[j];
+            phase += phaseInc;
+            if( phase >= 1.0 ) phase -= 1.0;
+
+            output += LookupSine(data, phase); 
+            data->phases[j] = phase;
+            
+            phaseInc *= 1.02f;
+            if( phaseInc > MAX_PHASE_INC ) phaseInc = MIN_PHASE_INC;
+        }
+
+        outSample = (float) (output * scaler);
+        *out++ = outSample; /* Left */
+        *out++ = outSample; /* Right */
+    }
+    return finished;
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+       int                 i;
+    PaStream*           stream;
+    PaStreamParameters  outputParameters;
+    PaError             err;
+    paTestData          data = {0};
+    double              load;
+
+    printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
+
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<TABLE_SIZE; i++ )
+    {
+        data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
+    }
+    data.sine[TABLE_SIZE] = data.sine[0]; /* set guard point */
+
+    err = Pa_Initialize();
+    if( err != paNoError )
+        goto error;
+    outputParameters.device                    = Pa_GetDefaultOutputDevice(); /* Default output device. */
+    outputParameters.channelCount              = 2;                           /* Stereo output. */
+    outputParameters.sampleFormat              = paFloat32;                   /* 32 bit floating point output. */
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+    outputParameters.suggestedLatency          = Pa_GetDeviceInfo(outputParameters.device)
+                                                 ->defaultHighOutputLatency;
+    err = Pa_OpenStream(&stream,
+                        NULL,               /* no input */
+                        &outputParameters,
+                        SAMPLE_RATE,
+                        FRAMES_PER_BUFFER,
+                        paClipOff,          /* No out of range samples should occur. */
+                        patestCallback,
+                        &data);
+    if( err != paNoError )
+        goto error;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError )
+        goto error;
+
+    /* Play an increasing number of sine waves until we hit MAX_USAGE */
+    do  {
+        data.numSines++;
+        Pa_Sleep(200);
+        load = Pa_GetStreamCpuLoad(stream);
+        printf("numSines = %d, CPU load = %f\n", data.numSines, load );
+        fflush(stdout);
+        } while((load < MAX_USAGE) && (data.numSines < MAX_SINES));
+
+    Pa_Sleep(2000);     /* Stay for 2 seconds around 80% CPU. */
+
+    err = Pa_StopStream( stream );
+    if( err != paNoError )
+        goto error;
+
+    err = Pa_CloseStream( stream );
+    if( err != paNoError )
+        goto error;
+
+    Pa_Terminate();
+    printf("Test finished.\n");
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_mono.c b/utils/iaxclient/lib/portaudio/test/patest_mono.c
new file mode 100644 (file)
index 0000000..744f0a6
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * $Id: patest_mono.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * patest_sine.c
+ * Play a monophonic sine wave using the Portable Audio api for several seconds.
+ *
+ * Authors:
+ *    Ross Bencina <rossb@audiomulch.com>
+ *    Phil Burk <philburk@softsynth.com>
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define NUM_SECONDS   (10)
+#define SAMPLE_RATE   (44100)
+#define AMPLITUDE     (0.8)
+#define FRAMES_PER_BUFFER  (64)
+#define OUTPUT_DEVICE Pa_GetDefaultOutputDevice()
+
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+
+#define TABLE_SIZE   (200)
+typedef struct
+{
+    float sine[TABLE_SIZE];
+    int phase;
+}
+paTestData;
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( const void *inputBuffer, void *outputBuffer,
+                            unsigned long framesPerBuffer,
+                            const PaStreamCallbackTimeInfo* timeInfo,
+                            PaStreamCallbackFlags statusFlags,
+                            void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    unsigned long i;
+    int finished = 0;
+    /* avoid unused variable warnings */
+    (void) inputBuffer;
+    (void) timeInfo;
+    (void) statusFlags;
+    for( i=0; i<framesPerBuffer; i++ )
+    {
+        *out++ = data->sine[data->phase];  /* left */
+        data->phase += 1;
+        if( data->phase >= TABLE_SIZE ) data->phase -= TABLE_SIZE;
+    }
+    return finished;
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaStreamParameters outputParameters;
+    PaStream *stream;
+    PaError err;
+    paTestData data;
+    int i;
+    printf("PortAudio Test: output MONO sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<TABLE_SIZE; i++ )
+    {
+        data.sine[i] = (float) (AMPLITUDE * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ));
+    }
+    data.phase = 0;
+    
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    outputParameters.device = OUTPUT_DEVICE;
+    outputParameters.channelCount = 1;       /* MONO output */
+    outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+
+    err = Pa_OpenStream(
+              &stream,
+              NULL, /* no input */
+              &outputParameters,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              patestCallback,
+              &data );
+    if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+    
+    printf("Play for %d seconds.\n", NUM_SECONDS ); fflush(stdout);
+    Pa_Sleep( NUM_SECONDS * 1000 );
+
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+    
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+    
+    Pa_Terminate();
+    printf("Test finished.\n");
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
\ No newline at end of file
diff --git a/utils/iaxclient/lib/portaudio/test/patest_mono_asio_channel_select.c b/utils/iaxclient/lib/portaudio/test/patest_mono_asio_channel_select.c
new file mode 100644 (file)
index 0000000..ed58cfe
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * $Id: patest_mono_asio_channel_select.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ * patest_sine.c
+ * Play a monophonic sine wave using the Portable Audio api for several seconds.
+ *
+ * Authors:
+ *    Ross Bencina <rossb@audiomulch.com>
+ *    Phil Burk <philburk@softsynth.com>
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+#include "pa_asio.h"
+
+#define NUM_SECONDS   (10)
+#define SAMPLE_RATE   (44100)
+#define AMPLITUDE     (0.8)
+#define FRAMES_PER_BUFFER  (64)
+#define OUTPUT_DEVICE Pa_GetDefaultOutputDevice()
+
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+
+#define TABLE_SIZE   (200)
+typedef struct
+{
+    float sine[TABLE_SIZE];
+    int phase;
+}
+paTestData;
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( const void *inputBuffer, void *outputBuffer,
+                            unsigned long framesPerBuffer,
+                            const PaStreamCallbackTimeInfo* timeInfo,
+                            PaStreamCallbackFlags statusFlags,
+                            void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    unsigned long i;
+    int finished = 0;
+    /* avoid unused variable warnings */
+    (void) inputBuffer;
+    (void) timeInfo;
+    (void) statusFlags;
+    for( i=0; i<framesPerBuffer; i++ )
+    {
+        *out++ = data->sine[data->phase];  /* left */
+        data->phase += 1;
+        if( data->phase >= TABLE_SIZE ) data->phase -= TABLE_SIZE;
+    }
+    return finished;
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaStreamParameters outputParameters;
+    PaAsioStreamInfo asioOutputInfo;
+    PaStream *stream;
+    PaError err;
+    paTestData data;
+    int outputChannelSelectors[1];
+    int i;
+    printf("PortAudio Test: output MONO sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<TABLE_SIZE; i++ )
+    {
+        data.sine[i] = (float) (AMPLITUDE * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ));
+    }
+    data.phase = 0;
+    
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    outputParameters.device = OUTPUT_DEVICE;
+    outputParameters.channelCount = 1;       /* MONO output */
+    outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
+
+    asioOutputInfo.size = sizeof(PaAsioStreamInfo);
+    asioOutputInfo.hostApiType = paASIO;
+    asioOutputInfo.version = 1;
+    asioOutputInfo.flags = paAsioUseChannelSelectors;
+    outputChannelSelectors[0] = 1; /* select the second (right) ASIO device channel */
+    asioOutputInfo.channelSelectors = outputChannelSelectors;
+    outputParameters.hostApiSpecificStreamInfo = &asioOutputInfo;
+
+    err = Pa_OpenStream(
+              &stream,
+              NULL, /* no input */
+              &outputParameters,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              patestCallback,
+              &data );
+    if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+    
+    printf("Play for %d seconds.\n", NUM_SECONDS ); fflush(stdout);
+    Pa_Sleep( NUM_SECONDS * 1000 );
+
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+    
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+    
+    Pa_Terminate();
+    printf("Test finished.\n");
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_multi_sine.c b/utils/iaxclient/lib/portaudio/test/patest_multi_sine.c
new file mode 100644 (file)
index 0000000..293db0e
--- /dev/null
@@ -0,0 +1,194 @@
+/** @file patest_multi_sine.c
+       @brief Play a different sine wave on each channel.
+       @author Phil Burk  http://www.softsynth.com
+*/
+/*
+ * $Id: patest_multi_sine.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+
+#include "portaudio.h"
+
+#define SAMPLE_RATE       (44100)
+#define FRAMES_PER_BUFFER (256)
+#define FREQ_INCR         (300.0 / SAMPLE_RATE)
+#define MAX_CHANNELS      (64)
+
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+
+typedef struct
+{
+    short   interleaved;          /* Nonzero for interleaved / zero for non-interleaved. */
+    int     numChannels;          /* Actually used. */
+    double  phases[MAX_CHANNELS]; /* Each channel gets its' own frequency. */
+}
+paTestData;
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback(const void*                     inputBuffer,
+                          void*                           outputBuffer,
+                          unsigned long                   framesPerBuffer,
+                          const PaStreamCallbackTimeInfo* timeInfo,
+                          PaStreamCallbackFlags           statusFlags,
+                          void*                           userData)
+{
+    int         frameIndex, channelIndex;
+    float**     outputs = (float**)outputBuffer;
+    paTestData* data    = (paTestData*)userData;
+
+    (void) inputBuffer;     /* Prevent unused arg warning. */
+    if (data->interleaved)
+        {
+        float *out = (float*)outputBuffer;      /* interleaved version */
+        for( frameIndex=0; frameIndex<(int)framesPerBuffer; frameIndex++ )
+            {
+            for( channelIndex=0; channelIndex<data->numChannels; channelIndex++ )
+                {
+                /* Output sine wave on every channel. */
+                *out++ = (float) sin(data->phases[channelIndex]);
+
+                /* Play each channel at a higher frequency. */
+                data->phases[channelIndex] += FREQ_INCR * (4 + channelIndex);
+                if( data->phases[channelIndex] >= (2.0 * M_PI) ) data->phases[channelIndex] -= (2.0 * M_PI);
+                }
+            }
+        }
+    else
+        {
+        for( frameIndex=0; frameIndex<(int)framesPerBuffer; frameIndex++ )
+            {
+            for( channelIndex=0; channelIndex<data->numChannels; channelIndex++ )
+                {
+                /* Output sine wave on every channel. */
+                outputs[channelIndex][frameIndex] = (float) sin(data->phases[channelIndex]);
+
+                /* Play each channel at a higher frequency. */
+                data->phases[channelIndex] += FREQ_INCR * (4 + channelIndex);
+                if( data->phases[channelIndex] >= (2.0 * M_PI) ) data->phases[channelIndex] -= (2.0 * M_PI);
+                }
+            }
+        }
+    return 0;
+}
+
+/*******************************************************************/
+int test(short interleaved)
+{
+    PaStream*           stream;
+    PaStreamParameters  outputParameters;
+    PaError             err;
+    const PaDeviceInfo* pdi;
+    paTestData          data;
+    short               n;
+
+    outputParameters.device = Pa_GetDefaultOutputDevice();  /* Default output device, max channels. */
+    pdi = Pa_GetDeviceInfo(outputParameters.device);
+    outputParameters.channelCount = pdi->maxOutputChannels;
+    if (outputParameters.channelCount > MAX_CHANNELS)
+        outputParameters.channelCount = MAX_CHANNELS;
+    outputParameters.sampleFormat = paFloat32;              /* 32 bit floating point output */
+    outputParameters.suggestedLatency = pdi->defaultLowOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+    
+    data.interleaved = interleaved;
+    data.numChannels = outputParameters.channelCount;
+    for (n = 0; n < data.numChannels; n++)
+        data.phases[n] = 0.0; /* Phases wrap and maybe don't need initialisation. */
+    printf("%d ", data.numChannels);
+    if (interleaved)
+        printf("interleaved ");
+    else
+        {
+        printf(" non-interleaved ");
+        outputParameters.sampleFormat |= paNonInterleaved;
+        }
+    printf("channels.\n");
+
+    err = Pa_OpenStream(&stream,
+                        NULL,               /* No input. */
+                        &outputParameters,
+                        SAMPLE_RATE,        /* Sample rate. */
+                        FRAMES_PER_BUFFER,  /* Frames per buffer. */
+                        paClipOff,          /* Samples never out of range, no clipping. */
+                        patestCallback,
+                        &data);
+    if (err == paNoError)
+        {
+        err = Pa_StartStream(stream);
+        if (err == paNoError)
+            {
+            printf("Hit ENTER to stop this test.\n");
+            getchar();
+            err = Pa_StopStream(stream);
+            }
+        Pa_CloseStream( stream );
+        }
+    return err;    
+}
+
+
+/*******************************************************************/
+int main(void)
+{
+    PaError err;
+
+    printf("PortAudio Test: output sine wave on each channel.\n" );
+
+    err = Pa_Initialize();
+    if (err != paNoError)
+        goto done;
+
+    err = test(1);          /* 1 means interleaved. */
+    if (err != paNoError)
+        goto done;
+
+    err = test(0);          /* 0 means not interleaved. */
+    if (err != paNoError)
+        goto done;
+
+    printf("Test finished.\n");
+done:
+    if (err)
+        {
+        fprintf(stderr, "An error occured while using the portaudio stream\n");
+        fprintf(stderr, "Error number: %d\n", err );
+        fprintf(stderr, "Error message: %s\n", Pa_GetErrorText(err));
+        }
+    Pa_Terminate();
+    return 0;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_out_underflow.c b/utils/iaxclient/lib/portaudio/test/patest_out_underflow.c
new file mode 100644 (file)
index 0000000..dde17d0
--- /dev/null
@@ -0,0 +1,217 @@
+/** @file patest_out_underflow.c
+       @brief Count output underflows (using paOutputUnderflow flag) 
+       under overloaded and normal conditions.
+       @author Ross Bencina <rossb@audiomulch.com>
+       @author Phil Burk <philburk@softsynth.com>
+*/
+/*
+ * $Id: patest_out_underflow.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2004 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define MAX_SINES     (500)
+#define MAX_LOAD      (1.2)
+#define SAMPLE_RATE   (44100)
+#define FRAMES_PER_BUFFER  (512)
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+#define TWOPI (M_PI * 2.0)
+
+typedef struct paTestData
+{
+    int sineCount;
+    double phases[MAX_SINES];
+    int countUnderflows;
+    int outputUnderflowCount;
+}
+paTestData;
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( const void *inputBuffer, void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                           const PaStreamCallbackTimeInfo* timeInfo,
+                           PaStreamCallbackFlags statusFlags,
+                           void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    unsigned long i;
+    int j;
+    int finished = paContinue;
+    (void) timeInfo;    /* Prevent unused variable warning. */
+    (void) inputBuffer; /* Prevent unused variable warning. */
+
+
+    if( data->countUnderflows && (statusFlags & paOutputUnderflow) )
+        data->outputUnderflowCount++;
+
+    for( i=0; i<framesPerBuffer; i++ )
+    {
+        float output = 0.0;
+        double phaseInc = 0.02;
+        double phase;
+
+        for( j=0; j<data->sineCount; j++ )
+        {
+            /* Advance phase of next oscillator. */
+            phase = data->phases[j];
+            phase += phaseInc;
+            if( phase > TWOPI ) phase -= TWOPI;
+
+            phaseInc *= 1.02;
+            if( phaseInc > 0.5 ) phaseInc *= 0.5;
+
+            /* This is not a very efficient way to calc sines. */
+            output += (float) sin( phase );
+            data->phases[j] = phase;
+        }
+        *out++ = (float) (output / data->sineCount);
+    }
+
+    return finished;
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaStreamParameters outputParameters;
+    PaStream *stream;
+    PaError err;
+    int safeSineCount, stressedSineCount;
+    int safeUnderflowCount, stressedUnderflowCount;
+    paTestData data = {0};
+    double load;
+
+
+    printf("PortAudio Test: output sine waves, count underflows. SR = %d, BufSize = %d. MAX_LOAD = %f\n",
+        SAMPLE_RATE, FRAMES_PER_BUFFER, (float)MAX_LOAD );
+
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+    
+    outputParameters.device = Pa_GetDefaultOutputDevice();  /* default output device */
+    outputParameters.channelCount = 1;                      /* mono output */
+    outputParameters.sampleFormat = paFloat32;              /* 32 bit floating point output */
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+
+    err = Pa_OpenStream(
+              &stream,
+              NULL,         /* no input */
+              &outputParameters,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              paClipOff,    /* we won't output out of range samples so don't bother clipping them */
+              patestCallback,
+              &data );    
+    if( err != paNoError ) goto error;
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+    printf("Establishing load conditions...\n" );
+
+    /* Determine number of sines required to get to 50% */
+    do
+    {
+        data.sineCount++;
+        Pa_Sleep( 100 );
+
+        load = Pa_GetStreamCpuLoad( stream );
+        printf("sineCount = %d, CPU load = %f\n", data.sineCount, load );
+    }
+    while( load < 0.5 && data.sineCount < (MAX_SINES-1));
+
+    safeSineCount = data.sineCount;
+
+    /* Calculate target stress value then ramp up to that level*/
+    stressedSineCount = (int) (2.0 * data.sineCount * MAX_LOAD );
+    if( stressedSineCount > MAX_SINES )
+        stressedSineCount = MAX_SINES;
+    for( ; data.sineCount < stressedSineCount; data.sineCount++ )
+    {
+        Pa_Sleep( 100 );
+        load = Pa_GetStreamCpuLoad( stream );
+        printf("STRESSING: sineCount = %d, CPU load = %f\n", data.sineCount, load );
+    }
+    
+    printf("Counting underflows for 5 seconds.\n");
+    data.countUnderflows = 1;
+    Pa_Sleep( 5000 );
+
+    stressedUnderflowCount = data.outputUnderflowCount;
+
+    data.countUnderflows = 0;
+    data.sineCount = safeSineCount;
+
+    printf("Resuming safe load...\n");
+    Pa_Sleep( 1500 );
+    data.outputUnderflowCount = 0;
+    Pa_Sleep( 1500 );
+    load = Pa_GetStreamCpuLoad( stream );
+    printf("sineCount = %d, CPU load = %f\n", data.sineCount, load );
+
+    printf("Counting underflows for 5 seconds.\n");
+    data.countUnderflows = 1;
+    Pa_Sleep( 5000 );
+
+    safeUnderflowCount = data.outputUnderflowCount;
+    
+    printf("Stop stream.\n");
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+    
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+    
+    Pa_Terminate();
+
+    if( stressedUnderflowCount == 0 )
+        printf("Test failed, no output underflows detected under stress.\n");
+    else if( safeUnderflowCount != 0 )
+        printf("Test failed, %d unexpected underflows detected under safe load.\n", safeUnderflowCount);
+    else
+        printf("Test passed, %d expected output underflows detected under stress, 0 unexpected underflows detected under safe load.\n", stressedUnderflowCount );
+
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_pink.c b/utils/iaxclient/lib/portaudio/test/patest_pink.c
new file mode 100644 (file)
index 0000000..7093e9d
--- /dev/null
@@ -0,0 +1,269 @@
+/** @file patest_pink.c
+       @brief Generate Pink Noise using Gardner method.
+
+       Optimization suggested by James McCartney uses a tree
+       to select which random value to replace.
+<pre>
+       x x x x x x x x x x x x x x x x 
+       x   x   x   x   x   x   x   x   
+       x       x       x       x       
+        x               x               
+          x   
+</pre>                            
+       Tree is generated by counting trailing zeros in an increasing index.
+       When the index is zero, no random number is selected.
+
+       @author Phil Burk  http://www.softsynth.com
+*/
+/*
+ * $Id: patest_pink.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define PINK_MAX_RANDOM_ROWS   (30)
+#define PINK_RANDOM_BITS       (24)
+#define PINK_RANDOM_SHIFT      ((sizeof(long)*8)-PINK_RANDOM_BITS)
+
+typedef struct
+{
+    long      pink_Rows[PINK_MAX_RANDOM_ROWS];
+    long      pink_RunningSum;   /* Used to optimize summing of generators. */
+    int       pink_Index;        /* Incremented each sample. */
+    int       pink_IndexMask;    /* Index wrapped by ANDing with this mask. */
+    float     pink_Scalar;       /* Used to scale within range of -1.0 to +1.0 */
+}
+PinkNoise;
+
+/* Prototypes */
+static unsigned long GenerateRandomNumber( void );
+void InitializePinkNoise( PinkNoise *pink, int numRows );
+float GeneratePinkNoise( PinkNoise *pink );
+
+/************************************************************/
+/* Calculate pseudo-random 32 bit number based on linear congruential method. */
+static unsigned long GenerateRandomNumber( void )
+{
+    /* Change this seed for different random sequences. */
+    static unsigned long randSeed = 22222;
+    randSeed = (randSeed * 196314165) + 907633515;
+    return randSeed;
+}
+
+/************************************************************/
+/* Setup PinkNoise structure for N rows of generators. */
+void InitializePinkNoise( PinkNoise *pink, int numRows )
+{
+    int i;
+    long pmax;
+    pink->pink_Index = 0;
+    pink->pink_IndexMask = (1<<numRows) - 1;
+    /* Calculate maximum possible signed random value. Extra 1 for white noise always added. */
+    pmax = (numRows + 1) * (1<<(PINK_RANDOM_BITS-1));
+    pink->pink_Scalar = 1.0f / pmax;
+    /* Initialize rows. */
+    for( i=0; i<numRows; i++ ) pink->pink_Rows[i] = 0;
+    pink->pink_RunningSum = 0;
+}
+
+#define PINK_MEASURE
+#ifdef PINK_MEASURE
+float pinkMax = -999.0;
+float pinkMin =  999.0;
+#endif
+
+/* Generate Pink noise values between -1.0 and +1.0 */
+float GeneratePinkNoise( PinkNoise *pink )
+{
+    long newRandom;
+    long sum;
+    float output;
+    /* Increment and mask index. */
+    pink->pink_Index = (pink->pink_Index + 1) & pink->pink_IndexMask;
+    /* If index is zero, don't update any random values. */
+    if( pink->pink_Index != 0 )
+    {
+        /* Determine how many trailing zeros in PinkIndex. */
+        /* This algorithm will hang if n==0 so test first. */
+        int numZeros = 0;
+        int n = pink->pink_Index;
+        while( (n & 1) == 0 )
+        {
+            n = n >> 1;
+            numZeros++;
+        }
+        /* Replace the indexed ROWS random value.
+         * Subtract and add back to RunningSum instead of adding all the random
+         * values together. Only one changes each time.
+         */
+        pink->pink_RunningSum -= pink->pink_Rows[numZeros];
+        newRandom = ((long)GenerateRandomNumber()) >> PINK_RANDOM_SHIFT;
+        pink->pink_RunningSum += newRandom;
+        pink->pink_Rows[numZeros] = newRandom;
+    }
+
+    /* Add extra white noise value. */
+    newRandom = ((long)GenerateRandomNumber()) >> PINK_RANDOM_SHIFT;
+    sum = pink->pink_RunningSum + newRandom;
+    /* Scale to range of -1.0 to 0.9999. */
+    output = pink->pink_Scalar * sum;
+#ifdef PINK_MEASURE
+    /* Check Min/Max */
+    if( output > pinkMax ) pinkMax = output;
+    else if( output < pinkMin ) pinkMin = output;
+#endif
+    return output;
+}
+
+/*******************************************************************/
+#define PINK_TEST
+#ifdef PINK_TEST
+
+/* Context for callback routine. */
+typedef struct
+{
+    PinkNoise   leftPink;
+    PinkNoise   rightPink;
+    unsigned int sampsToGo;
+}
+paTestData;
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback(const void*                     inputBuffer,
+                          void*                           outputBuffer,
+                          unsigned long                   framesPerBuffer,
+                                     const PaStreamCallbackTimeInfo* timeInfo,
+                                     PaStreamCallbackFlags           statusFlags,
+                          void*                           userData)
+{
+    int finished;
+    int i;
+    int numFrames;
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    (void) inputBuffer; /* Prevent "unused variable" warnings. */
+
+    /* Are we almost at end. */
+    if( data->sampsToGo < framesPerBuffer )
+    {
+        numFrames = data->sampsToGo;
+        finished = 1;
+    }
+    else
+    {
+        numFrames = framesPerBuffer;
+        finished = 0;
+    }
+    for( i=0; i<numFrames; i++ )
+    {
+        *out++ = GeneratePinkNoise( &data->leftPink );
+        *out++ = GeneratePinkNoise( &data->rightPink );
+    }
+    data->sampsToGo -= numFrames;
+    return finished;
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaStream*           stream;
+    PaError             err;
+    paTestData          data;
+    PaStreamParameters  outputParameters;
+    int                 totalSamps;
+    static const double SR  = 44100.0;
+    static const int    FPB = 2048; /* Frames per buffer: 46 ms buffers. */
+    
+    /* Initialize two pink noise signals with different numbers of rows. */
+    InitializePinkNoise( &data.leftPink,  12 );
+    InitializePinkNoise( &data.rightPink, 16 );
+
+    /* Look at a few values. */
+    {
+        int i;
+        float pink;
+        for( i=0; i<20; i++ )
+        {
+            pink = GeneratePinkNoise( &data.leftPink );
+            printf("Pink = %f\n", pink );
+        }
+    }
+
+    data.sampsToGo = totalSamps = (int)(60.0 * SR);   /* Play a whole minute. */
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    /* Open a stereo PortAudio stream so we can hear the result. */
+    outputParameters.device = Pa_GetDefaultOutputDevice(); /* Take the default output device. */
+    outputParameters.channelCount = 2;                     /* Stereo output, most likely supported. */
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+    outputParameters.sampleFormat = paFloat32;             /* 32 bit floating point output. */
+    outputParameters.suggestedLatency =
+                     Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
+    err = Pa_OpenStream(&stream,
+                        NULL,                              /* No input. */
+                        &outputParameters,
+                        SR,                                /* Sample rate. */
+                        FPB,                               /* Frames per buffer. */
+                        paClipOff, /* we won't output out of range samples so don't bother clipping them */
+                        patestCallback,
+                        &data);
+    if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+    printf("Stereo pink noise for one minute...\n");
+
+    while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(100);
+    if( err < 0 ) goto error;
+
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+#ifdef PINK_MEASURE
+    printf("Pink min = %f, max = %f\n", pinkMin, pinkMax );
+#endif
+    Pa_Terminate();
+    return 0;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return 0;
+}
+#endif /* PINK_TEST */
diff --git a/utils/iaxclient/lib/portaudio/test/patest_prime.c b/utils/iaxclient/lib/portaudio/test/patest_prime.c
new file mode 100644 (file)
index 0000000..0ac806b
--- /dev/null
@@ -0,0 +1,223 @@
+/** @file patest_prime.c
+       @brief Test stream priming mode.
+       @author Ross Bencina http://www.audiomulch.com/~rossb
+*/
+
+/*
+ * $Id: patest_prime.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+#include "pa_util.h"
+
+#define NUM_BEEPS           (3)
+#define SAMPLE_RATE         (44100)
+#define SAMPLE_PERIOD       (1.0/44100.0)
+#define FRAMES_PER_BUFFER   (256)
+#define BEEP_DURATION       (400)
+#define IDLE_DURATION       (SAMPLE_RATE*2)      /* 2 seconds */
+#define SLEEP_MSEC          (50)
+
+#define STATE_BKG_IDLE      (0)
+#define STATE_BKG_BEEPING   (1)
+
+typedef struct
+{
+    float        leftPhase;
+    float        rightPhase;
+    int          state;
+    int          beepCountdown;
+    int          idleCountdown;
+}
+paTestData;
+
+static void InitializeTestData( paTestData *testData )
+{
+    testData->leftPhase = 0;
+    testData->rightPhase = 0;
+    testData->state = STATE_BKG_BEEPING;
+    testData->beepCountdown = BEEP_DURATION;
+    testData->idleCountdown = IDLE_DURATION;
+}
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( const void *inputBuffer, void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                                      const PaStreamCallbackTimeInfo *timeInfo,
+                                      PaStreamCallbackFlags statusFlags, void *userData )
+{
+    /* Cast data passed through stream to our structure. */
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    unsigned int i;
+    int result = paContinue;
+
+    /* supress unused parameter warnings */
+    (void) inputBuffer;
+    (void) timeInfo;
+    (void) statusFlags;
+
+    for( i=0; i<framesPerBuffer; i++ )
+    {
+        switch( data->state )
+        {
+        case STATE_BKG_IDLE:
+            *out++ = 0.0;  /* left */
+            *out++ = 0.0;  /* right */
+            --data->idleCountdown;
+            
+            if( data->idleCountdown <= 0 ) result = paComplete;
+            break;
+
+        case STATE_BKG_BEEPING:
+            if( data->beepCountdown <= 0 )
+            {
+                data->state = STATE_BKG_IDLE;
+                *out++ = 0.0;  /* left */
+                *out++ = 0.0;  /* right */
+            }
+            else
+            {
+                /* Play sawtooth wave. */
+                *out++ = data->leftPhase;  /* left */
+                *out++ = data->rightPhase;  /* right */
+                /* Generate simple sawtooth phaser that ranges between -1.0 and 1.0. */
+                data->leftPhase += 0.01f;
+                /* When signal reaches top, drop back down. */
+                if( data->leftPhase >= 1.0f ) data->leftPhase -= 2.0f;
+                /* higher pitch so we can distinguish left and right. */
+                data->rightPhase += 0.03f;
+                if( data->rightPhase >= 1.0f ) data->rightPhase -= 2.0f;
+            }
+            --data->beepCountdown;
+            break;
+        }
+    }
+    
+    return result;
+}
+
+/*******************************************************************/
+static PaError DoTest( int flags )
+{
+    PaStream *stream;
+    PaError    err;
+    paTestData data;
+    PaStreamParameters outputParameters;
+
+    InitializeTestData( &data );       
+
+    outputParameters.device = Pa_GetDefaultOutputDevice();
+    outputParameters.channelCount = 2;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+    outputParameters.sampleFormat = paFloat32;
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency;
+
+    /* Open an audio I/O stream. */
+    err = Pa_OpenStream(
+        &stream,
+        NULL,                         /* no input */
+        &outputParameters,
+        SAMPLE_RATE,
+        FRAMES_PER_BUFFER,            /* frames per buffer */
+        paClipOff | flags,      /* we won't output out of range samples so don't bother clipping them */
+        patestCallback,
+        &data );
+    if( err != paNoError ) goto error;
+
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+    printf("hear \"BEEP\"\n" );
+    fflush(stdout);
+
+    while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(SLEEP_MSEC);
+    if( err < 0 ) goto error;
+
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+
+    return err;
+error:
+    return err;
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaError    err = paNoError;
+    int        i;
+
+    /* Initialize library before making any other calls. */
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+    
+    printf("PortAudio Test: Testing stream playback with no priming.\n");
+    printf("PortAudio Test: you should see BEEP before you hear it.\n");
+    printf("BEEP %d times.\n", NUM_BEEPS );
+
+    for( i=0; i< NUM_BEEPS; ++i )
+    {
+        err = DoTest( 0 );
+        if( err != paNoError )
+            goto error;
+    }
+
+    printf("PortAudio Test: Testing stream playback with priming.\n");
+    printf("PortAudio Test: you should see BEEP around the same time you hear it.\n");
+    for( i=0; i< NUM_BEEPS; ++i )
+    {
+        err = DoTest( paPrimeOutputBuffersUsingStreamCallback );
+        if( err != paNoError )
+            goto error;
+    }
+
+    printf("Test finished.\n");
+
+    Pa_Terminate();
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_read_record.c b/utils/iaxclient/lib/portaudio/test/patest_read_record.c
new file mode 100644 (file)
index 0000000..bb74b61
--- /dev/null
@@ -0,0 +1,229 @@
+/** @file patest_read_record.c
+       @brief Record input into an array; Save array to a file; Playback recorded
+    data. Implemented using the blocking API (Pa_ReadStream(), Pa_WriteStream() )
+       @author Phil Burk  http://www.softsynth.com
+    @author Ross Bencina rossb@audiomulch.com
+*/
+/*
+ * $Id: patest_read_record.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "portaudio.h"
+
+/* #define SAMPLE_RATE  (17932) // Test failure to open with this value. */
+#define SAMPLE_RATE  (44100)
+#define FRAMES_PER_BUFFER (1024)
+#define NUM_SECONDS     (5)
+#define NUM_CHANNELS    (2)
+/* #define DITHER_FLAG     (paDitherOff)  */
+#define DITHER_FLAG     (0) /**/
+
+/* Select sample format. */
+#if 1
+#define PA_SAMPLE_TYPE  paFloat32
+typedef float SAMPLE;
+#define SAMPLE_SILENCE  (0.0f)
+#define PRINTF_S_FORMAT "%.8f"
+#elif 1
+#define PA_SAMPLE_TYPE  paInt16
+typedef short SAMPLE;
+#define SAMPLE_SILENCE  (0)
+#define PRINTF_S_FORMAT "%d"
+#elif 0
+#define PA_SAMPLE_TYPE  paInt8
+typedef char SAMPLE;
+#define SAMPLE_SILENCE  (0)
+#define PRINTF_S_FORMAT "%d"
+#else
+#define PA_SAMPLE_TYPE  paUInt8
+typedef unsigned char SAMPLE;
+#define SAMPLE_SILENCE  (128)
+#define PRINTF_S_FORMAT "%d"
+#endif
+
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaStreamParameters inputParameters, outputParameters;
+    PaStream *stream;
+    PaError err;
+    SAMPLE *recordedSamples;
+    int i;
+    int totalFrames;
+    int numSamples;
+    int numBytes;
+    SAMPLE max, average, val;
+    
+    
+    printf("patest_read_record.c\n"); fflush(stdout);
+
+    totalFrames = NUM_SECONDS * SAMPLE_RATE; /* Record for a few seconds. */
+    numSamples = totalFrames * NUM_CHANNELS;
+
+    numBytes = numSamples * sizeof(SAMPLE);
+    recordedSamples = (SAMPLE *) malloc( numBytes );
+    if( recordedSamples == NULL )
+    {
+        printf("Could not allocate record array.\n");
+        exit(1);
+    }
+    for( i=0; i<numSamples; i++ ) recordedSamples[i] = 0;
+
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
+    inputParameters.channelCount = NUM_CHANNELS;
+    inputParameters.sampleFormat = PA_SAMPLE_TYPE;
+    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
+    inputParameters.hostApiSpecificStreamInfo = NULL;
+
+    /* Record some audio. -------------------------------------------- */
+    err = Pa_OpenStream(
+              &stream,
+              &inputParameters,
+              NULL,                  /* &outputParameters, */
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              NULL, /* no callback, use blocking API */
+              NULL ); /* no callback, so no callback userData */
+    if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+    printf("Now recording!!\n"); fflush(stdout);
+
+    err = Pa_ReadStream( stream, recordedSamples, totalFrames );
+    if( err != paNoError ) goto error;
+    
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+
+    /* Measure maximum peak amplitude. */
+    max = 0;
+    average = 0;
+    for( i=0; i<numSamples; i++ )
+    {
+        val = recordedSamples[i];
+        if( val < 0 ) val = -val; /* ABS */
+        if( val > max )
+        {
+            max = val;
+        }
+        average += val;
+    }
+
+    average = average / numSamples;
+
+    printf("Sample max amplitude = "PRINTF_S_FORMAT"\n", max );
+    printf("Sample average = "PRINTF_S_FORMAT"\n", average );
+/*  Was as below. Better choose at compile time because this
+    keeps generating compiler-warnings:
+    if( PA_SAMPLE_TYPE == paFloat32 )
+    {
+        printf("sample max amplitude = %f\n", max );
+        printf("sample average = %f\n", average );
+    }
+    else
+    {
+        printf("sample max amplitude = %d\n", max );
+        printf("sample average = %d\n", average );
+    }
+*/
+    /* Write recorded data to a file. */
+#if 0
+    {
+        FILE  *fid;
+        fid = fopen("recorded.raw", "wb");
+        if( fid == NULL )
+        {
+            printf("Could not open file.");
+        }
+        else
+        {
+            fwrite( recordedSamples, NUM_CHANNELS * sizeof(SAMPLE), totalFrames, fid );
+            fclose( fid );
+            printf("Wrote data to 'recorded.raw'\n");
+        }
+    }
+#endif
+
+    /* Playback recorded data.  -------------------------------------------- */
+    
+    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
+    outputParameters.channelCount = NUM_CHANNELS;
+    outputParameters.sampleFormat =  PA_SAMPLE_TYPE;
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+
+    printf("Begin playback.\n"); fflush(stdout);
+    err = Pa_OpenStream(
+              &stream,
+              NULL, /* no input */
+              &outputParameters,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              NULL, /* no callback, use blocking API */
+              NULL ); /* no callback, so no callback userData */
+    if( err != paNoError ) goto error;
+
+    if( stream )
+    {
+        err = Pa_StartStream( stream );
+        if( err != paNoError ) goto error;
+        printf("Waiting for playback to finish.\n"); fflush(stdout);
+
+        err = Pa_WriteStream( stream, recordedSamples, totalFrames );
+        if( err != paNoError ) goto error;
+
+        err = Pa_CloseStream( stream );
+        if( err != paNoError ) goto error;
+        printf("Done.\n"); fflush(stdout);
+    }
+    free( recordedSamples );
+
+    Pa_Terminate();
+    return 0;
+
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return -1;
+}
+
diff --git a/utils/iaxclient/lib/portaudio/test/patest_read_write_wire.c b/utils/iaxclient/lib/portaudio/test/patest_read_write_wire.c
new file mode 100644 (file)
index 0000000..323a413
--- /dev/null
@@ -0,0 +1,183 @@
+/** @file patest_read_write_wire.c
+       @brief Tests full duplex blocking I/O by passing input straight to output.
+       @author Bjorn Roche. XO Audio LLC for Z-Systems Engineering.
+    @author based on code by: Phil Burk  http://www.softsynth.com
+    @author based on code by: Ross Bencina rossb@audiomulch.com
+*/
+/*
+ * $Id: patest_read_write_wire.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "portaudio.h"
+
+/* #define SAMPLE_RATE  (17932) // Test failure to open with this value. */
+#define SAMPLE_RATE  (44100)
+#define FRAMES_PER_BUFFER (1024)
+#define NUM_CHANNELS    (2)
+/* #define DITHER_FLAG     (paDitherOff)  */
+#define DITHER_FLAG     (0) /**/
+
+/* Select sample format. */
+#if 1
+#define PA_SAMPLE_TYPE  paFloat32
+typedef float SAMPLE;
+#define SAMPLE_SILENCE  (0.0f)
+#define PRINTF_S_FORMAT "%.8f"
+#elif 1
+#define PA_SAMPLE_TYPE  paInt16
+typedef short SAMPLE;
+#define SAMPLE_SILENCE  (0)
+#define PRINTF_S_FORMAT "%d"
+#elif 0
+#define PA_SAMPLE_TYPE  paInt8
+typedef char SAMPLE;
+#define SAMPLE_SILENCE  (0)
+#define PRINTF_S_FORMAT "%d"
+#else
+#define PA_SAMPLE_TYPE  paUInt8
+typedef unsigned char SAMPLE;
+#define SAMPLE_SILENCE  (128)
+#define PRINTF_S_FORMAT "%d"
+#endif
+
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaStreamParameters inputParameters, outputParameters;
+    PaStream *stream;
+    PaError err;
+    SAMPLE *sampleBlock;
+    int i;
+    int numBytes;
+    
+    
+    printf("patest_read_write_wire.c\n"); fflush(stdout);
+
+    numBytes = FRAMES_PER_BUFFER * NUM_CHANNELS * sizeof(SAMPLE);
+    sampleBlock = (SAMPLE *) malloc( numBytes );
+    if( sampleBlock == NULL )
+    {
+        printf("Could not allocate record array.\n");
+        exit(1);
+    }
+    for( i=0; i<FRAMES_PER_BUFFER*NUM_CHANNELS; i++ )
+        sampleBlock[i] = (SAMPLE_SILENCE);
+
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
+    printf( "Input device # %d.\n", inputParameters.device );
+    printf( "Input LL: %g s\n", Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency );
+    printf( "Input HL: %g s\n", Pa_GetDeviceInfo( inputParameters.device )->defaultHighInputLatency );
+    inputParameters.channelCount = NUM_CHANNELS;
+    inputParameters.sampleFormat = PA_SAMPLE_TYPE;
+    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultHighInputLatency ;
+    inputParameters.hostApiSpecificStreamInfo = NULL;
+
+    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
+    printf( "Output device # %d.\n", outputParameters.device );
+    printf( "Output LL: %g s\n", Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency );
+    printf( "Output HL: %g s\n", Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency );
+    outputParameters.channelCount = NUM_CHANNELS;
+    outputParameters.sampleFormat = PA_SAMPLE_TYPE;
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+
+    /* -- setup -- */
+
+   err = Pa_OpenStream(
+              &stream,
+              &inputParameters,
+              &outputParameters,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              NULL, /* no callback, use blocking API */
+              NULL ); /* no callback, so no callback userData */
+    if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+    printf("Wire on. Will run one minute.\n"); fflush(stdout);
+
+    for( i=0; i<(60*SAMPLE_RATE)/FRAMES_PER_BUFFER; ++i )
+    {
+       err = Pa_WriteStream( stream, sampleBlock, FRAMES_PER_BUFFER );
+       if( err ) goto xrun;
+       err = Pa_ReadStream( stream, sampleBlock, FRAMES_PER_BUFFER );
+       if( err ) goto xrun;
+    }
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+
+    for( i=0; i<FRAMES_PER_BUFFER*NUM_CHANNELS; i++ )
+        sampleBlock[i] = (SAMPLE_SILENCE);
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+    printf("Wire on. Interrupt to stop.\n"); fflush(stdout);
+
+    while( 1 )
+    {
+       err = Pa_WriteStream( stream, sampleBlock, FRAMES_PER_BUFFER );
+       if( err ) goto xrun;
+       err = Pa_ReadStream( stream, sampleBlock, FRAMES_PER_BUFFER );
+       if( err ) goto xrun;
+    }
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+
+    free( sampleBlock );
+
+    Pa_Terminate();
+    return 0;
+
+xrun:
+    Pa_Terminate();
+    if( err & paInputOverflow )
+       fprintf( stderr, "Input Overflow.\n" );
+    if( err & paOutputUnderflow )
+       fprintf( stderr, "Output Underflow.\n" );
+    return -2;
+
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return -1;
+}
+
diff --git a/utils/iaxclient/lib/portaudio/test/patest_record.c b/utils/iaxclient/lib/portaudio/test/patest_record.c
new file mode 100644 (file)
index 0000000..0e1e524
--- /dev/null
@@ -0,0 +1,337 @@
+/** @file patest_record.c
+       @brief Record input into an array; Save array to a file; Playback recorded data.
+       @author Phil Burk  http://www.softsynth.com
+*/
+/*
+ * $Id: patest_record.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "portaudio.h"
+
+/* #define SAMPLE_RATE  (17932) // Test failure to open with this value. */
+#define SAMPLE_RATE  (44100)
+#define FRAMES_PER_BUFFER (1024)
+#define NUM_SECONDS     (5)
+#define NUM_CHANNELS    (2)
+/* #define DITHER_FLAG     (paDitherOff) */
+#define DITHER_FLAG     (0) /**/
+
+/* Select sample format. */
+#if 1
+#define PA_SAMPLE_TYPE  paFloat32
+typedef float SAMPLE;
+#define SAMPLE_SILENCE  (0.0f)
+#define PRINTF_S_FORMAT "%.8f"
+#elif 1
+#define PA_SAMPLE_TYPE  paInt16
+typedef short SAMPLE;
+#define SAMPLE_SILENCE  (0)
+#define PRINTF_S_FORMAT "%d"
+#elif 0
+#define PA_SAMPLE_TYPE  paInt8
+typedef char SAMPLE;
+#define SAMPLE_SILENCE  (0)
+#define PRINTF_S_FORMAT "%d"
+#else
+#define PA_SAMPLE_TYPE  paUInt8
+typedef unsigned char SAMPLE;
+#define SAMPLE_SILENCE  (128)
+#define PRINTF_S_FORMAT "%d"
+#endif
+
+typedef struct
+{
+    int          frameIndex;  /* Index into sample array. */
+    int          maxFrameIndex;
+    SAMPLE      *recordedSamples;
+}
+paTestData;
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may be called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int recordCallback( const void *inputBuffer, void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                           const PaStreamCallbackTimeInfo* timeInfo,
+                           PaStreamCallbackFlags statusFlags,
+                           void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    const SAMPLE *rptr = (const SAMPLE*)inputBuffer;
+    SAMPLE *wptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS];
+    long framesToCalc;
+    long i;
+    int finished;
+    unsigned long framesLeft = data->maxFrameIndex - data->frameIndex;
+
+    (void) outputBuffer; /* Prevent unused variable warnings. */
+    (void) timeInfo;
+    (void) statusFlags;
+    (void) userData;
+
+    if( framesLeft < framesPerBuffer )
+    {
+        framesToCalc = framesLeft;
+        finished = paComplete;
+    }
+    else
+    {
+        framesToCalc = framesPerBuffer;
+        finished = paContinue;
+    }
+
+    if( inputBuffer == NULL )
+    {
+        for( i=0; i<framesToCalc; i++ )
+        {
+            *wptr++ = SAMPLE_SILENCE;  /* left */
+            if( NUM_CHANNELS == 2 ) *wptr++ = SAMPLE_SILENCE;  /* right */
+        }
+    }
+    else
+    {
+        for( i=0; i<framesToCalc; i++ )
+        {
+            *wptr++ = *rptr++;  /* left */
+            if( NUM_CHANNELS == 2 ) *wptr++ = *rptr++;  /* right */
+        }
+    }
+    data->frameIndex += framesToCalc;
+    return finished;
+}
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may be called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int playCallback( const void *inputBuffer, void *outputBuffer,
+                         unsigned long framesPerBuffer,
+                         const PaStreamCallbackTimeInfo* timeInfo,
+                         PaStreamCallbackFlags statusFlags,
+                         void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    SAMPLE *rptr = &data->recordedSamples[data->frameIndex * NUM_CHANNELS];
+    SAMPLE *wptr = (SAMPLE*)outputBuffer;
+    unsigned int i;
+    int finished;
+    unsigned int framesLeft = data->maxFrameIndex - data->frameIndex;
+
+    (void) inputBuffer; /* Prevent unused variable warnings. */
+    (void) timeInfo;
+    (void) statusFlags;
+    (void) userData;
+
+    if( framesLeft < framesPerBuffer )
+    {
+        /* final buffer... */
+        for( i=0; i<framesLeft; i++ )
+        {
+            *wptr++ = *rptr++;  /* left */
+            if( NUM_CHANNELS == 2 ) *wptr++ = *rptr++;  /* right */
+        }
+        for( ; i<framesPerBuffer; i++ )
+        {
+            *wptr++ = 0;  /* left */
+            if( NUM_CHANNELS == 2 ) *wptr++ = 0;  /* right */
+        }
+        data->frameIndex += framesLeft;
+        finished = paComplete;
+    }
+    else
+    {
+        for( i=0; i<framesPerBuffer; i++ )
+        {
+            *wptr++ = *rptr++;  /* left */
+            if( NUM_CHANNELS == 2 ) *wptr++ = *rptr++;  /* right */
+        }
+        data->frameIndex += framesPerBuffer;
+        finished = paContinue;
+    }
+    return finished;
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaStreamParameters  inputParameters,
+                        outputParameters;
+    PaStream*           stream;
+    PaError             err = paNoError;
+    paTestData          data;
+    int                 i;
+    int                 totalFrames;
+    int                 numSamples;
+    int                 numBytes;
+    SAMPLE              max, val;
+    double              average;
+
+    printf("patest_record.c\n"); fflush(stdout);
+
+    data.maxFrameIndex = totalFrames = NUM_SECONDS * SAMPLE_RATE; /* Record for a few seconds. */
+    data.frameIndex = 0;
+    numSamples = totalFrames * NUM_CHANNELS;
+    numBytes = numSamples * sizeof(SAMPLE);
+    data.recordedSamples = (SAMPLE *) malloc( numBytes ); /* From now on, recordedSamples is initialised. */
+    if( data.recordedSamples == NULL )
+    {
+        printf("Could not allocate record array.\n");
+        goto done;
+    }
+    for( i=0; i<numSamples; i++ ) data.recordedSamples[i] = 0;
+
+    err = Pa_Initialize();
+    if( err != paNoError ) goto done;
+
+    inputParameters.device = Pa_GetDefaultInputDevice(); /* default input device */
+    inputParameters.channelCount = 2;                    /* stereo input */
+    inputParameters.sampleFormat = PA_SAMPLE_TYPE;
+    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
+    inputParameters.hostApiSpecificStreamInfo = NULL;
+
+    /* Record some audio. -------------------------------------------- */
+    err = Pa_OpenStream(
+              &stream,
+              &inputParameters,
+              NULL,                  /* &outputParameters, */
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              recordCallback,
+              &data );
+    if( err != paNoError ) goto done;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto done;
+    printf("Now recording!!\n"); fflush(stdout);
+
+    while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
+    {
+        Pa_Sleep(1000);
+        printf("index = %d\n", data.frameIndex ); fflush(stdout);
+    }
+    if( err < 0 ) goto done;
+
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto done;
+
+    /* Measure maximum peak amplitude. */
+    max = 0;
+    average = 0.0;
+    for( i=0; i<numSamples; i++ )
+    {
+        val = data.recordedSamples[i];
+        if( val < 0 ) val = -val; /* ABS */
+        if( val > max )
+        {
+            max = val;
+        }
+        average += val;
+    }
+
+    average = average / (double)numSamples;
+
+    printf("sample max amplitude = "PRINTF_S_FORMAT"\n", max );
+    printf("sample average = %lf\n", average );
+
+    /* Write recorded data to a file. */
+#if 0
+    {
+        FILE  *fid;
+        fid = fopen("recorded.raw", "wb");
+        if( fid == NULL )
+        {
+            printf("Could not open file.");
+        }
+        else
+        {
+            fwrite( data.recordedSamples, NUM_CHANNELS * sizeof(SAMPLE), totalFrames, fid );
+            fclose( fid );
+            printf("Wrote data to 'recorded.raw'\n");
+        }
+    }
+#endif
+
+    /* Playback recorded data.  -------------------------------------------- */
+    data.frameIndex = 0;
+
+    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
+    outputParameters.channelCount = 2;                     /* stereo output */
+    outputParameters.sampleFormat =  PA_SAMPLE_TYPE;
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+
+    printf("Begin playback.\n"); fflush(stdout);
+    err = Pa_OpenStream(
+              &stream,
+              NULL, /* no input */
+              &outputParameters,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              playCallback,
+              &data );
+    if( err != paNoError ) goto done;
+
+    if( stream )
+    {
+        err = Pa_StartStream( stream );
+        if( err != paNoError ) goto done;
+        
+        printf("Waiting for playback to finish.\n"); fflush(stdout);
+
+        while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(100);
+        if( err < 0 ) goto done;
+        
+        err = Pa_CloseStream( stream );
+        if( err != paNoError ) goto done;
+        
+        printf("Done.\n"); fflush(stdout);
+    }
+
+done:
+    Pa_Terminate();
+    if( data.recordedSamples )       /* Sure it is NULL or valid. */
+        free( data.recordedSamples );
+    if( err != paNoError )
+    {
+        fprintf( stderr, "An error occured while using the portaudio stream\n" );
+        fprintf( stderr, "Error number: %d\n", err );
+        fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+        err = 1;          /* Always return 0 or 1, but no other return codes. */
+    }
+    return err;
+}
+
diff --git a/utils/iaxclient/lib/portaudio/test/patest_ringmix.c b/utils/iaxclient/lib/portaudio/test/patest_ringmix.c
new file mode 100644 (file)
index 0000000..c6c370c
--- /dev/null
@@ -0,0 +1,79 @@
+/** @file patest_ringmix.c
+       @brief Ring modulate inputs to left output, mix inputs to right output.
+*/
+/*
+ * $Id: patest_ringmix.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $ 
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+
+#include "stdio.h"
+#include "portaudio.h"
+/* This will be called asynchronously by the PortAudio engine. */
+static int myCallback( const void *inputBuffer, void *outputBuffer,
+                            unsigned long framesPerBuffer,
+                            const PaStreamCallbackTimeInfo* timeInfo,
+                            PaStreamCallbackFlags statusFlags,
+                            void *userData )
+{
+    const float *in  = (const float *) inputBuffer;
+       float *out = (float *) outputBuffer;    
+    float leftInput, rightInput;
+    unsigned int i;
+
+    /* Read input buffer, process data, and fill output buffer. */
+    for( i=0; i<framesPerBuffer; i++ )
+    {
+        leftInput = *in++;      /* Get interleaved samples from input buffer. */
+        rightInput = *in++;
+        *out++ = leftInput * rightInput;            /* ring modulation */
+        *out++ = 0.5f * (leftInput + rightInput);   /* mix */
+    }
+    return 0;
+}
+
+/* Open a PortAudioStream to input and output audio data. */
+int main(void)
+{
+    PaStream *stream;
+    Pa_Initialize();
+    Pa_OpenDefaultStream(
+        &stream,
+        2, 2,               /* stereo input and output */
+        paFloat32,  44100.0,
+        64,                 /* 64 frames per buffer */
+        myCallback, NULL );
+    Pa_StartStream( stream );
+    Pa_Sleep( 10000 );    /* Sleep for 10 seconds while processing. */
+    Pa_StopStream( stream );
+    Pa_CloseStream( stream );
+    Pa_Terminate();
+    return 0;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_saw.c b/utils/iaxclient/lib/portaudio/test/patest_saw.c
new file mode 100644 (file)
index 0000000..72368a8
--- /dev/null
@@ -0,0 +1,125 @@
+/** @file patest_saw.c
+       @brief Play a simple (aliasing) sawtooth wave.
+       @author Phil Burk  http://www.softsynth.com
+*/
+/*
+ * $Id: patest_saw.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+#define NUM_SECONDS   (4)
+#define SAMPLE_RATE   (44100)
+
+typedef struct
+{
+    float left_phase;
+    float right_phase;
+}
+paTestData;
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( const void *inputBuffer, void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                           const PaStreamCallbackTimeInfo* timeInfo,
+                           PaStreamCallbackFlags statusFlags,
+                           void *userData )
+{
+    /* Cast data passed through stream to our structure. */
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    unsigned int i;
+    (void) inputBuffer; /* Prevent unused variable warning. */
+
+    for( i=0; i<framesPerBuffer; i++ )
+    {
+        *out++ = data->left_phase;  /* left */
+        *out++ = data->right_phase;  /* right */
+        /* Generate simple sawtooth phaser that ranges between -1.0 and 1.0. */
+        data->left_phase += 0.01f;
+        /* When signal reaches top, drop back down. */
+        if( data->left_phase >= 1.0f ) data->left_phase -= 2.0f;
+        /* higher pitch so we can distinguish left and right. */
+        data->right_phase += 0.03f;
+        if( data->right_phase >= 1.0f ) data->right_phase -= 2.0f;
+    }
+    return 0;
+}
+
+/*******************************************************************/
+static paTestData data;
+int main(void);
+int main(void)
+{
+    PaStream *stream;
+    PaError err;
+    
+    printf("PortAudio Test: output sawtooth wave.\n");
+    /* Initialize our data for use by callback. */
+    data.left_phase = data.right_phase = 0.0;
+    /* Initialize library before making any other calls. */
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+    
+    /* Open an audio I/O stream. */
+    err = Pa_OpenDefaultStream( &stream,
+                                0,          /* no input channels */
+                                2,          /* stereo output */
+                                paFloat32,  /* 32 bit floating point output */
+                                SAMPLE_RATE,
+                                256,        /* frames per buffer */
+                                patestCallback,
+                                &data );
+    if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+    /* Sleep for several seconds. */
+    Pa_Sleep(NUM_SECONDS*1000);
+
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+    Pa_Terminate();
+    printf("Test finished.\n");
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_sine.c b/utils/iaxclient/lib/portaudio/test/patest_sine.c
new file mode 100644 (file)
index 0000000..922b80c
--- /dev/null
@@ -0,0 +1,151 @@
+/** @file patest_sine.c
+       @brief Play a sine wave for several seconds.
+       @author Ross Bencina <rossb@audiomulch.com>
+    @author Phil Burk <philburk@softsynth.com>
+*/
+/*
+ * $Id: patest_sine.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define NUM_SECONDS   (5)
+#define SAMPLE_RATE   (44100)
+#define FRAMES_PER_BUFFER  (64)
+
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+
+#define TABLE_SIZE   (200)
+typedef struct
+{
+    float sine[TABLE_SIZE];
+    int left_phase;
+    int right_phase;
+}
+paTestData;
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( const void *inputBuffer, void *outputBuffer,
+                            unsigned long framesPerBuffer,
+                            const PaStreamCallbackTimeInfo* timeInfo,
+                            PaStreamCallbackFlags statusFlags,
+                            void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    unsigned long i;
+
+    (void) timeInfo; /* Prevent unused variable warnings. */
+    (void) statusFlags;
+    (void) inputBuffer;
+    
+    for( i=0; i<framesPerBuffer; i++ )
+    {
+        *out++ = data->sine[data->left_phase];  /* left */
+        *out++ = data->sine[data->right_phase];  /* right */
+        data->left_phase += 1;
+        if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
+        data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
+        if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
+    }
+    
+    return paContinue;
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaStreamParameters outputParameters;
+    PaStream *stream;
+    PaError err;
+    paTestData data;
+    int i;
+
+    
+    printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
+    
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<TABLE_SIZE; i++ )
+    {
+        data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
+    }
+    data.left_phase = data.right_phase = 0;
+    
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
+    outputParameters.channelCount = 2;       /* stereo output */
+    outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+
+    err = Pa_OpenStream(
+              &stream,
+              NULL, /* no input */
+              &outputParameters,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              patestCallback,
+              &data );
+    if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+    printf("Play for %d seconds.\n", NUM_SECONDS );
+    Pa_Sleep( NUM_SECONDS * 1000 );
+
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+
+    Pa_Terminate();
+    printf("Test finished.\n");
+    
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_sine8.c b/utils/iaxclient/lib/portaudio/test/patest_sine8.c
new file mode 100644 (file)
index 0000000..2494eb5
--- /dev/null
@@ -0,0 +1,212 @@
+/** @file patest_sine8.c
+       @brief Test 8 bit data: play a sine wave for several seconds.
+       @author Ross Bencina <rossb@audiomulch.com>
+*/
+/*
+ * $Id: patest_sine8.c,v 1.1 2006/06/10 21:30:56 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define NUM_SECONDS   (8)
+#define SAMPLE_RATE   (44100)
+#define TABLE_SIZE    (200)
+#define TEST_UNSIGNED (0)
+
+#if TEST_UNSIGNED
+#define TEST_FORMAT   paUInt8
+#else
+#define TEST_FORMAT   paInt8
+#endif
+
+#ifndef M_PI
+#define M_PI (3.14159265)
+#endif
+
+typedef struct
+{
+#if TEST_UNSIGNED
+    unsigned char sine[TABLE_SIZE];
+#else
+    char sine[TABLE_SIZE];
+#endif
+    int left_phase;
+    int right_phase;
+    unsigned int framesToGo;
+}
+paTestData;
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( const void *inputBuffer, void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                           const PaStreamCallbackTimeInfo* timeInfo,
+                           PaStreamCallbackFlags statusFlags,
+                           void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    char *out = (char*)outputBuffer;
+    int i;
+    int framesToCalc;
+    int finished = 0;
+    (void) inputBuffer; /* Prevent unused variable warnings. */
+
+    if( data->framesToGo < framesPerBuffer )
+    {
+        framesToCalc = data->framesToGo;
+        data->framesToGo = 0;
+        finished = 1;
+    }
+    else
+    {
+        framesToCalc = framesPerBuffer;
+        data->framesToGo -= framesPerBuffer;
+    }
+
+    for( i=0; i<framesToCalc; i++ )
+    {
+        *out++ = data->sine[data->left_phase];  /* left */
+        *out++ = data->sine[data->right_phase];  /* right */
+        data->left_phase += 1;
+        if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
+        data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
+        if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
+    }
+    /* zero remainder of final buffer */
+    for( ; i<(int)framesPerBuffer; i++ )
+    {
+#if TEST_UNSIGNED
+        *out++ = (unsigned char) 0x80; /* left */
+        *out++ = (unsigned char) 0x80; /* right */
+#else
+        *out++ = 0; /* left */
+        *out++ = 0; /* right */
+#endif
+
+    }
+    return finished;
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaStreamParameters  outputParameters;
+    PaStream*           stream;
+    PaError             err;
+    paTestData          data;
+    PaTime              streamOpened;
+    int                 i, totalSamps;
+
+#if TEST_UNSIGNED
+    printf("PortAudio Test: output UNsigned 8 bit sine wave.\n");
+#else
+    printf("PortAudio Test: output signed 8 bit sine wave.\n");
+#endif
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<TABLE_SIZE; i++ )
+    {
+        data.sine[i] = (char) (127.0 * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. ));
+#if TEST_UNSIGNED
+        data.sine[i] += (unsigned char) 0x80;
+#endif
+    }
+    data.left_phase = data.right_phase = 0;
+    data.framesToGo = totalSamps =  NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */
+
+    err = Pa_Initialize();
+    if( err != paNoError )
+        goto error;
+
+    outputParameters.device = Pa_GetDefaultOutputDevice(); /* Default output device. */
+    outputParameters.channelCount = 2;                     /* Stereo output. */
+    outputParameters.sampleFormat = TEST_FORMAT;
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+    err = Pa_OpenStream( &stream,
+                         NULL,      /* No input. */
+                         &outputParameters,
+                         SAMPLE_RATE,
+                         256,       /* Frames per buffer. */
+                         paClipOff, /* We won't output out of range samples so don't bother clipping them. */
+                         patestCallback,
+                         &data );
+    if( err != paNoError )
+        goto error;
+
+    streamOpened = Pa_GetStreamTime( stream ); /* Time in seconds when stream was opened (approx). */
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError )
+        goto error;
+
+    /* Watch until sound is halfway finished. */
+    /* (Was ( Pa_StreamTime( stream ) < (totalSamps/2) ) in V18. */
+    while( (Pa_GetStreamTime( stream ) - streamOpened) < (PaTime)NUM_SECONDS / 2.0 )
+        Pa_Sleep(10);
+
+    /* Stop sound until ENTER hit. (Hu? don't see any keyboard-input here.) */
+    err = Pa_StopStream( stream );
+    if( err != paNoError )
+        goto error;
+
+    printf("Pause for 2 seconds.\n");
+    Pa_Sleep( 2000 );
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError )
+        goto error;
+
+    printf("Waiting for sound to finish.\n");
+
+    while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
+        Pa_Sleep(100);
+    if( err < 0 )
+        goto error;
+
+    err = Pa_CloseStream( stream );
+    if( err != paNoError )
+        goto error;
+
+    Pa_Terminate();
+    printf("Test finished.\n");
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_sine_formats.c b/utils/iaxclient/lib/portaudio/test/patest_sine_formats.c
new file mode 100644 (file)
index 0000000..5730dd9
--- /dev/null
@@ -0,0 +1,196 @@
+/** @file patest_sine_formats.c
+       @brief Play a sine wave for several seconds. Test various data formats.
+       @author Phil Burk
+*/
+/*
+ * $Id: patest_sine_formats.c,v 1.1 2006/06/10 21:30:57 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define NUM_SECONDS        (10)
+#define SAMPLE_RATE        (44100)
+#define FRAMES_PER_BUFFER  (512)
+#define LEFT_FREQ          (SAMPLE_RATE/256.0)  /* So we hit 1.0 */
+#define RIGHT_FREQ         (500.0)
+#define AMPLITUDE          (1.0)
+
+/* Select ONE format for testing. */
+#define TEST_UINT8    (0)
+#define TEST_INT8     (0)
+#define TEST_INT16    (1)
+#define TEST_FLOAT32  (0)
+
+#if TEST_UINT8
+#define TEST_FORMAT         paUInt8
+typedef unsigned char       SAMPLE_t;
+#define SAMPLE_ZERO         (0x80)
+#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(127.0 * (x)))
+#define FORMAT_NAME         "Unsigned 8 Bit"
+
+#elif TEST_INT8
+#define TEST_FORMAT         paInt8
+typedef char                SAMPLE_t;
+#define SAMPLE_ZERO         (0)
+#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(127.0 * (x)))
+#define FORMAT_NAME         "Signed 8 Bit"
+
+#elif TEST_INT16
+#define TEST_FORMAT         paInt16
+typedef short               SAMPLE_t;
+#define SAMPLE_ZERO         (0)
+#define DOUBLE_TO_SAMPLE(x) (SAMPLE_ZERO + (SAMPLE_t)(32767 * (x)))
+#define FORMAT_NAME         "Signed 16 Bit"
+
+#elif TEST_FLOAT32
+#define TEST_FORMAT         paFloat32
+typedef float               SAMPLE_t;
+#define SAMPLE_ZERO         (0.0)
+#define DOUBLE_TO_SAMPLE(x) ((SAMPLE_t)(x))
+#define FORMAT_NAME         "Float 32 Bit"
+#endif
+
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+
+
+typedef struct
+{
+    double left_phase;
+    double right_phase;
+    unsigned int framesToGo;
+}
+paTestData;
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( const void *inputBuffer,
+                           void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                           const PaStreamCallbackTimeInfo* timeInfo,
+                           PaStreamCallbackFlags statusFlags,
+                           void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    SAMPLE_t *out = (SAMPLE_t *)outputBuffer;
+    int i;
+    int framesToCalc;
+    int finished = 0;
+    (void) inputBuffer; /* Prevent unused variable warnings. */
+
+    if( data->framesToGo < framesPerBuffer )
+    {
+        framesToCalc = data->framesToGo;
+        data->framesToGo = 0;
+        finished = 1;
+    }
+    else
+    {
+        framesToCalc = framesPerBuffer;
+        data->framesToGo -= framesPerBuffer;
+    }
+
+    for( i=0; i<framesToCalc; i++ )
+    {
+        data->left_phase += (LEFT_FREQ / SAMPLE_RATE);
+        if( data->left_phase > 1.0) data->left_phase -= 1.0;
+        *out++ = DOUBLE_TO_SAMPLE( AMPLITUDE * sin( (data->left_phase * M_PI * 2. )));
+
+        data->right_phase += (RIGHT_FREQ / SAMPLE_RATE);
+        if( data->right_phase > 1.0) data->right_phase -= 1.0;
+        *out++ = DOUBLE_TO_SAMPLE( AMPLITUDE * sin( (data->right_phase * M_PI * 2. )));
+    }
+    /* zero remainder of final buffer */
+    for( ; i<(int)framesPerBuffer; i++ )
+    {
+        *out++ = SAMPLE_ZERO; /* left */
+        *out++ = SAMPLE_ZERO; /* right */
+    }
+    return finished;
+}
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaStream *stream;
+    PaStreamParameters outputParameters;
+    PaError err;
+    paTestData data;
+    int totalSamps;
+
+    printf("PortAudio Test: output " FORMAT_NAME "\n");
+
+    data.left_phase = data.right_phase = 0.0;
+    data.framesToGo = totalSamps =  NUM_SECONDS * SAMPLE_RATE; /* Play for a few seconds. */
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+
+    outputParameters.device           = Pa_GetDefaultOutputDevice(); /* Default output device. */
+    outputParameters.channelCount     = 2;                           /* Stereo output */
+    outputParameters.sampleFormat     = TEST_FORMAT;                 /* Selected above. */
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+    err = Pa_OpenStream( &stream,
+                         NULL,                  /* No input. */
+                         &outputParameters,     /* As above. */
+                         SAMPLE_RATE,
+                         FRAMES_PER_BUFFER,
+                         paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+                         patestCallback,
+                         &data );
+    if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+    printf("Waiting %d seconds for sound to finish.\n", NUM_SECONDS );
+
+    while( ( err = Pa_IsStreamActive( stream ) ) == 1 ) Pa_Sleep(100);
+    if( err < 0 ) goto error;
+
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+    Pa_Terminate();
+
+    printf("PortAudio Test Finished: " FORMAT_NAME "\n");
+
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_sine_time.c b/utils/iaxclient/lib/portaudio/test/patest_sine_time.c
new file mode 100644 (file)
index 0000000..8de40f5
--- /dev/null
@@ -0,0 +1,208 @@
+/** @file patest_sine_time.c
+       @brief Play a sine wave for several seconds, pausing in the middle.
+       Uses the Pa_GetStreamTime() call.
+       @author Ross Bencina <rossb@audiomulch.com>
+       @author Phil Burk <philburk@softsynth.com>
+*/
+/*
+ * $Id: patest_sine_time.c,v 1.1 2006/06/10 21:30:57 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+
+#include "portaudio.h"
+#include "pa_util.h"
+
+#define NUM_SECONDS   (8)
+#define SAMPLE_RATE   (44100)
+#define FRAMES_PER_BUFFER  (64)
+
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+#define TWOPI (M_PI * 2.0)
+
+#define TABLE_SIZE   (200)
+
+typedef struct
+{
+    double           left_phase;
+    double           right_phase;
+    volatile PaTime  outTime;
+}
+paTestData;
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( const void *inputBuffer, void *outputBuffer,
+                            unsigned long framesPerBuffer,
+                            const PaStreamCallbackTimeInfo* timeInfo,
+                            PaStreamCallbackFlags statusFlags,
+                            void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    unsigned int i;
+
+    double left_phaseInc = 0.02;
+    double right_phaseInc = 0.06;
+
+    double left_phase = data->left_phase;
+    double right_phase = data->right_phase;
+
+    (void) statusFlags; /* Prevent unused variable warnings. */
+    (void) inputBuffer;
+
+    data->outTime = timeInfo->outputBufferDacTime;
+
+    for( i=0; i<framesPerBuffer; i++ )
+    {
+        left_phase += left_phaseInc;
+        if( left_phase > TWOPI ) left_phase -= TWOPI;
+        *out++ = (float) sin( left_phase );
+
+        right_phase += right_phaseInc;
+        if( right_phase > TWOPI ) right_phase -= TWOPI;
+        *out++ = (float) sin( right_phase );
+    }
+
+    data->left_phase = left_phase;
+    data->right_phase = right_phase;
+
+    return paContinue;
+}
+
+/*******************************************************************/
+static void ReportStreamTime( PaStream *stream, paTestData *data );
+static void ReportStreamTime( PaStream *stream, paTestData *data )
+{
+    PaTime  streamTime, latency, outTime;
+    
+    streamTime = Pa_GetStreamTime( stream );
+    outTime = data->outTime;
+    if( outTime < 0.0 )
+    {
+        printf("Stream time = %8.1f\n", streamTime );
+    }
+    else
+    {
+        latency = outTime - streamTime;
+        printf("Stream time = %8.4f, outTime = %8.4f, latency = %8.4f\n",
+            streamTime, outTime, latency );
+    }
+    fflush(stdout);
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaStreamParameters outputParameters;
+    PaStream *stream;
+    PaError err;
+    paTestData data;
+    PaTime startTime;
+
+    printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
+
+    data.left_phase = data.right_phase = 0;
+
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
+    outputParameters.channelCount = 2;       /* stereo output */
+    outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+
+    err = Pa_OpenStream(
+              &stream,
+              NULL, /* no input */
+              &outputParameters,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              patestCallback,
+              &data );
+    if( err != paNoError ) goto error;
+          
+    /* Watch until sound is halfway finished. */
+    printf("Play for %d seconds.\n", NUM_SECONDS/2 ); fflush(stdout);
+
+    data.outTime = -1.0; /* mark time for callback as undefined */
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+    startTime = Pa_GetStreamTime( stream );
+
+    do
+    {
+        ReportStreamTime( stream, &data );
+        Pa_Sleep(100);
+    } while( (Pa_GetStreamTime( stream ) - startTime) < (NUM_SECONDS/2) );
+    
+    /* Stop sound for 2 seconds. */
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+    
+    printf("Pause for 2 seconds.\n"); fflush(stdout);
+    Pa_Sleep( 2000 );
+
+    data.outTime = -1.0; /* mark time for callback as undefined */
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+    startTime = Pa_GetStreamTime( stream );
+    
+    printf("Play until sound is finished.\n"); fflush(stdout);
+    do
+    {
+        ReportStreamTime( stream, &data );
+        Pa_Sleep(100);
+    } while( (Pa_GetStreamTime( stream ) - startTime) < (NUM_SECONDS/2) );
+    
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+
+    Pa_Terminate();
+    printf("Test finished.\n");
+    return err;
+    
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_start_stop.c b/utils/iaxclient/lib/portaudio/test/patest_start_stop.c
new file mode 100644 (file)
index 0000000..ac14d2f
--- /dev/null
@@ -0,0 +1,162 @@
+/** @file patest_start_stop.c
+       @brief Play a sine wave for several seconds
+        - start and stop the stream multiple times.
+        
+       @author Ross Bencina <rossb@audiomulch.com>
+       @author Phil Burk <philburk@softsynth.com>
+*/
+/*
+ * $Id: patest_start_stop.c,v 1.1 2006/06/10 21:30:57 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define OUTPUT_DEVICE Pa_GetDefaultOutputDevice()   /* default output device */
+
+#define NUM_SECONDS   (3)
+#define NUM_LOOPS     (4)
+#define SAMPLE_RATE   (44100)
+#define FRAMES_PER_BUFFER  (400)
+
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+
+#define TABLE_SIZE   (200)
+typedef struct
+{
+    float sine[TABLE_SIZE];
+    int left_phase;
+    int right_phase;
+}
+paTestData;
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( const void *inputBuffer, void *outputBuffer,
+                            unsigned long framesPerBuffer,
+                            const PaStreamCallbackTimeInfo* timeInfo,
+                            PaStreamCallbackFlags statusFlags,
+                            void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    unsigned long i;
+
+    (void) timeInfo; /* Prevent unused variable warnings. */
+    (void) statusFlags;
+    (void) inputBuffer;
+    
+    for( i=0; i<framesPerBuffer; i++ )
+    {
+        *out++ = data->sine[data->left_phase];  /* left */
+        *out++ = data->sine[data->right_phase];  /* right */
+        data->left_phase += 1;
+        if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
+        data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
+        if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
+    }
+    
+    return paContinue;
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaStreamParameters outputParameters;
+    PaStream *stream;
+    PaError err;
+    paTestData data;
+    int i;
+
+    
+    printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
+    
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<TABLE_SIZE; i++ )
+    {
+        data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
+    }
+    data.left_phase = data.right_phase = 0;
+    
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    outputParameters.device = OUTPUT_DEVICE;
+    outputParameters.channelCount = 2;       /* stereo output */
+    outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+
+    err = Pa_OpenStream(
+              &stream,
+              NULL, /* no input */
+              &outputParameters,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              patestCallback,
+              &data );
+    if( err != paNoError ) goto error;
+
+    for( i=0; i<NUM_LOOPS; i++ )
+    {
+        err = Pa_StartStream( stream );
+        if( err != paNoError ) goto error;
+
+        printf("Play for %d seconds.\n", NUM_SECONDS );
+        Pa_Sleep( NUM_SECONDS * 1000 );
+
+        err = Pa_StopStream( stream );
+        if( err != paNoError ) goto error;
+
+        printf("Stopped.\n" );
+        Pa_Sleep( 1000 );
+    }
+
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+
+    Pa_Terminate();
+    printf("Test finished.\n");
+    
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_stop.c b/utils/iaxclient/lib/portaudio/test/patest_stop.c
new file mode 100644 (file)
index 0000000..523a3a0
--- /dev/null
@@ -0,0 +1,313 @@
+/** @file patest_stop.c
+       @brief Test different ways of stopping audio.
+
+       Test the three ways of stopping audio:
+               - calling Pa_StopStream(),
+               - calling Pa_AbortStream(),
+               - and returning a 1 from the callback function.
+
+       A long latency is set up so that you can hear the difference.
+       Then a simple 8 note sequence is repeated twice.
+       The program will print what you should hear.
+
+       @author Phil Burk <philburk@softsynth.com>
+*/
+/*
+ * $Id: patest_stop.c,v 1.1 2006/06/10 21:30:57 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define OUTPUT_DEVICE       (Pa_GetDefaultOutputDevice())
+#define SLEEP_DUR           (200)
+#define SAMPLE_RATE         (44100)
+#define FRAMES_PER_BUFFER   (256)
+#define LATENCY_SECONDS     (3.f)
+#define FRAMES_PER_NOTE     (SAMPLE_RATE/2)
+#define MAX_REPEATS         (2)
+#define FUNDAMENTAL         (400.0f / SAMPLE_RATE)
+#define NOTE_0              (FUNDAMENTAL * 1.0f / 1.0f)
+#define NOTE_1              (FUNDAMENTAL * 5.0f / 4.0f)
+#define NOTE_2              (FUNDAMENTAL * 4.0f / 3.0f)
+#define NOTE_3              (FUNDAMENTAL * 3.0f / 2.0f)
+#define NOTE_4              (FUNDAMENTAL * 2.0f / 1.0f)
+#define MODE_FINISH    (0)
+#define MODE_STOP      (1)
+#define MODE_ABORT     (2)
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+#define TABLE_SIZE   (400)
+
+typedef struct
+{
+    float  waveform[TABLE_SIZE + 1]; /* Add one for guard point for interpolation. */
+    float  phase_increment;
+    float  phase;
+    float *tune;
+    int    notesPerTune;
+    int    frameCounter;
+    int    noteCounter;
+    int    repeatCounter;
+    PaTime outTime;
+    int    stopMode;
+    int    done;
+}
+paTestData;
+
+/************* Prototypes *****************************/
+int TestStopMode( paTestData *data );
+float LookupWaveform( paTestData *data, float phase );
+
+/******************************************************
+ * Convert phase between 0.0 and 1.0 to waveform value 
+ * using linear interpolation.
+ */
+float LookupWaveform( paTestData *data, float phase )
+{
+    float fIndex = phase*TABLE_SIZE;
+    int   index = (int) fIndex;
+    float fract = fIndex - index;
+    float lo = data->waveform[index];
+    float hi = data->waveform[index+1];
+    float val = lo + fract*(hi-lo);
+    return val;
+}
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( const void *inputBuffer, void *outputBuffer,
+                            unsigned long framesPerBuffer,
+                            const PaStreamCallbackTimeInfo* timeInfo,
+                            PaStreamCallbackFlags statusFlags,
+                            void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    float value;
+    unsigned int i = 0;
+    int finished = paContinue;
+
+    (void) inputBuffer;     /* Prevent unused variable warnings. */
+    (void) timeInfo;
+    (void) statusFlags;
+
+
+    /* data->outTime = outTime; */
+    
+    if( !data->done )
+    {
+        for( i=0; i<framesPerBuffer; i++ )
+        {
+            /* Are we done with this note? */
+            if( data->frameCounter >= FRAMES_PER_NOTE )
+            {
+                data->noteCounter += 1;
+                data->frameCounter = 0;
+                /* Are we done with this tune? */
+                if( data->noteCounter >= data->notesPerTune )
+                {
+                    data->noteCounter = 0;
+                    data->repeatCounter += 1;
+                    /* Are we totally done? */
+                    if( data->repeatCounter >= MAX_REPEATS )
+                    {
+                        data->done = 1;
+                        if( data->stopMode == MODE_FINISH )
+                        {
+                            finished = paComplete;
+                            break;
+                        }
+                    }
+                }
+                data->phase_increment = data->tune[data->noteCounter];
+            }
+            value = LookupWaveform(data, data->phase);
+            *out++ = value;  /* left */
+            *out++ = value;  /* right */
+            data->phase += data->phase_increment;
+            if( data->phase >= 1.0f ) data->phase -= 1.0f;
+
+            data->frameCounter += 1;
+        }
+    }
+    /* zero remainder of final buffer */
+    for( ; i<framesPerBuffer; i++ )
+    {
+        *out++ = 0; /* left */
+        *out++ = 0; /* right */
+    }
+    return finished;
+}
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    paTestData data;
+    int i;
+    float simpleTune[] = { NOTE_0, NOTE_1, NOTE_2, NOTE_3, NOTE_4, NOTE_3, NOTE_2, NOTE_1 };
+    
+    printf("PortAudio Test: play song and test stopping. ask for %f seconds latency\n", LATENCY_SECONDS );
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<TABLE_SIZE; i++ )
+    {
+        data.waveform[i] = (float) (
+                               (0.2 * sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. )) +
+                               (0.2 * sin( ((double)(3*i)/(double)TABLE_SIZE) * M_PI * 2. )) +
+                               (0.1 * sin( ((double)(5*i)/(double)TABLE_SIZE) * M_PI * 2. ))
+                           );
+    }
+    data.waveform[TABLE_SIZE] = data.waveform[0]; /* Set guard point. */
+    data.tune = &simpleTune[0];
+    data.notesPerTune = sizeof(simpleTune) / sizeof(float);
+
+    printf("Test MODE_FINISH - callback returns 1.\n");
+    printf("Should hear entire %d note tune repeated twice.\n", data.notesPerTune);
+    data.stopMode = MODE_FINISH;
+    if( TestStopMode( &data ) != paNoError )
+    {
+        printf("Test of MODE_FINISH failed!\n");
+        goto error;
+    }
+
+    printf("Test MODE_STOP - stop when song is done.\n");
+    printf("Should hear entire %d note tune repeated twice.\n", data.notesPerTune);
+    data.stopMode = MODE_STOP;
+    if( TestStopMode( &data ) != paNoError )
+    {
+        printf("Test of MODE_STOP failed!\n");
+        goto error;
+    }
+
+    printf("Test MODE_ABORT - abort immediately.\n");
+    printf("Should hear last repetition cut short by %f seconds.\n", LATENCY_SECONDS);
+    data.stopMode = MODE_ABORT;
+    if( TestStopMode( &data ) != paNoError )
+    {
+        printf("Test of MODE_ABORT failed!\n");
+        goto error;
+    }
+
+    return 0;
+
+error:
+    return 1;
+}
+
+int TestStopMode( paTestData *data )
+{
+    PaStreamParameters outputParameters;
+    PaStream *stream;
+    PaError err;
+    
+    data->done = 0;
+    data->phase = 0.0;
+    data->frameCounter = 0;
+    data->noteCounter = 0;
+    data->repeatCounter = 0;
+    data->phase_increment = data->tune[data->noteCounter];
+    
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    outputParameters.device = OUTPUT_DEVICE;
+    outputParameters.channelCount = 2;          /* stereo output */
+    outputParameters.sampleFormat = paFloat32;  /* 32 bit floating point output */
+    outputParameters.suggestedLatency = LATENCY_SECONDS;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+    
+    err = Pa_OpenStream(
+              &stream,
+              NULL, /* no input */
+              &outputParameters,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,            /* frames per buffer */
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              patestCallback,
+              data );
+    if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+    if( data->stopMode == MODE_FINISH )
+    {
+        while( ( err = Pa_IsStreamActive( stream ) ) == 1 )
+        {
+            /*printf("outTime = %g, note# = %d, repeat# = %d\n", data->outTime,
+             data->noteCounter, data->repeatCounter  );
+            fflush(stdout); */
+            Pa_Sleep( SLEEP_DUR );
+        }
+        if( err < 0 ) goto error;
+    }
+    else
+    {
+        while( data->repeatCounter < MAX_REPEATS )
+        {
+            /*printf("outTime = %g, note# = %d, repeat# = %d\n", data->outTime,
+             data->noteCounter, data->repeatCounter  );
+            fflush(stdout); */
+            Pa_Sleep( SLEEP_DUR );
+        }
+    }
+
+    if( data->stopMode == MODE_ABORT )
+    {
+        printf("Call Pa_AbortStream()\n");
+        err = Pa_AbortStream( stream );
+    }
+    else
+    {
+        printf("Call Pa_StopStream()\n");
+        err = Pa_StopStream( stream );
+    }
+    if( err != paNoError ) goto error;
+
+    printf("Call Pa_CloseStream()\n"); fflush(stdout);
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+
+    Pa_Terminate();
+    printf("Test finished.\n");
+
+    return err;
+
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_stop_playout.c b/utils/iaxclient/lib/portaudio/test/patest_stop_playout.c
new file mode 100644 (file)
index 0000000..8dc23c1
--- /dev/null
@@ -0,0 +1,432 @@
+/** @file patest_stop_playout.c
+       @brief Test whether all queued samples are played when Pa_StopStream()
+            is used with a callback or read/write stream, or when the callback
+            returns paComplete.
+       @author Ross Bencina <rossb@audiomulch.com>
+*/
+/*
+ * $Id: patest_stop_playout.c,v 1.1 2006/06/10 21:30:57 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com/
+ * Copyright (c) 1999-2004 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define SAMPLE_RATE         (44100)
+#define FRAMES_PER_BUFFER   (1024)
+
+#define TONE_SECONDS        (1)      /* long tone */
+#define TONE_FADE_SECONDS   (.04)    /* fades at start and end of long tone */
+#define GAP_SECONDS         (.25)     /* gap between long tone and blip */
+#define BLIP_SECONDS        (.035)   /* short blip */
+
+#define NUM_REPEATS         (3)
+
+#ifndef M_PI
+#define M_PI (3.14159265)
+#endif
+
+#define TABLE_SIZE          (2048)
+typedef struct
+{
+    float sine[TABLE_SIZE+1];
+
+    int repeatCount;
+    
+    double phase;
+    double lowIncrement, highIncrement;
+    
+    int gap1Length, toneLength, toneFadesLength, gap2Length, blipLength;
+    int gap1Countdown, toneCountdown, gap2Countdown, blipCountdown;
+}
+TestData;
+
+
+static void RetriggerTestSignalGenerator( TestData *data )
+{
+    data->phase = 0.;
+    data->gap1Countdown = data->gap1Length;
+    data->toneCountdown = data->toneLength;
+    data->gap2Countdown = data->gap2Length;
+    data->blipCountdown = data->blipLength;
+}
+
+
+static void ResetTestSignalGenerator( TestData *data )
+{
+    data->repeatCount = 0;
+    RetriggerTestSignalGenerator( data );
+}
+
+
+static void InitTestSignalGenerator( TestData *data )
+{
+    int signalLengthModBufferLength, i;
+
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<TABLE_SIZE; i++ )
+    {
+        data->sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
+    }
+    data->sine[TABLE_SIZE] = data->sine[0]; /* guard point for linear interpolation */
+
+
+    
+    data->lowIncrement = (330. / SAMPLE_RATE) * TABLE_SIZE;
+    data->highIncrement = (1760. / SAMPLE_RATE) * TABLE_SIZE;
+
+    data->gap1Length = GAP_SECONDS * SAMPLE_RATE;
+    data->toneLength = TONE_SECONDS * SAMPLE_RATE;
+    data->toneFadesLength = TONE_FADE_SECONDS * SAMPLE_RATE;
+    data->gap2Length = GAP_SECONDS * SAMPLE_RATE;
+    data->blipLength = BLIP_SECONDS * SAMPLE_RATE;
+
+    /* adjust signal length to be a multiple of the buffer length */
+    signalLengthModBufferLength = (data->gap1Length + data->toneLength + data->gap2Length + data->blipLength) % FRAMES_PER_BUFFER;
+    if( signalLengthModBufferLength > 0 )
+        data->toneLength += signalLengthModBufferLength;
+
+    ResetTestSignalGenerator( data );
+}
+
+
+#define MIN( a, b ) (((a)<(b))?(a):(b))
+
+static void GenerateTestSignal( TestData *data, float *stereo, int frameCount )
+{
+    int framesGenerated = 0;
+    float output;
+    long index;
+    float fraction;
+    int count, i;
+
+    while( framesGenerated < frameCount && data->repeatCount < NUM_REPEATS )
+    {
+        if( framesGenerated < frameCount && data->gap1Countdown > 0 ){
+            count = MIN( frameCount - framesGenerated, data->gap1Countdown );
+            for( i=0; i < count; ++i )
+            {
+                *stereo++ = 0.f;
+                *stereo++ = 0.f;
+            }
+
+            data->gap1Countdown -= count;
+            framesGenerated += count;
+        }
+    
+        if( framesGenerated < frameCount && data->toneCountdown > 0 ){
+            count = MIN( frameCount - framesGenerated, data->toneCountdown );
+            for( i=0; i < count; ++i )
+            {
+                /* tone with data->lowIncrement phase increment */
+                index = (long)data->phase;
+                fraction = data->phase - index;
+                output = data->sine[ index ] + (data->sine[ index + 1 ] - data->sine[ index ]) * fraction;
+
+                data->phase += data->lowIncrement;
+                while( data->phase >= TABLE_SIZE )
+                    data->phase -= TABLE_SIZE;
+
+                /* apply fade to ends */
+
+                if( data->toneCountdown < data->toneFadesLength )
+                {
+                    /* cosine-bell fade out at end */
+                    output *= (-cos(((float)data->toneCountdown / (float)data->toneFadesLength) * M_PI) + 1.) * .5;
+                }
+                else if( data->toneCountdown > data->toneLength - data->toneFadesLength ) 
+                {
+                    /* cosine-bell fade in at start */
+                    output *= (cos(((float)(data->toneCountdown - (data->toneLength - data->toneFadesLength)) / (float)data->toneFadesLength) * M_PI) + 1.) * .5;
+                }
+
+                output *= .5; /* play tone half as loud as blip */
+            
+                *stereo++ = output;
+                *stereo++ = output;
+
+                data->toneCountdown--;
+            }                         
+
+            framesGenerated += count;
+        }
+
+        if( framesGenerated < frameCount && data->gap2Countdown > 0 ){
+            count = MIN( frameCount - framesGenerated, data->gap2Countdown );
+            for( i=0; i < count; ++i )
+            {
+                *stereo++ = 0.f;
+                *stereo++ = 0.f;
+            }
+
+            data->gap2Countdown -= count;
+            framesGenerated += count;
+        }
+
+        if( framesGenerated < frameCount && data->blipCountdown > 0 ){
+            count = MIN( frameCount - framesGenerated, data->blipCountdown );
+            for( i=0; i < count; ++i )
+            {
+                /* tone with data->highIncrement phase increment */
+                index = (long)data->phase;
+                fraction = data->phase - index;
+                output = data->sine[ index ] + (data->sine[ index + 1 ] - data->sine[ index ]) * fraction;
+
+                data->phase += data->highIncrement;
+                while( data->phase >= TABLE_SIZE )
+                    data->phase -= TABLE_SIZE;
+
+                /* cosine-bell envelope over whole blip */
+                output *= (-cos( ((float)data->blipCountdown / (float)data->blipLength) * 2. * M_PI) + 1.) * .5;
+                
+                *stereo++ = output;
+                *stereo++ = output;
+
+                data->blipCountdown--;
+            }
+
+            framesGenerated += count;
+        }
+
+
+        if( data->blipCountdown == 0 )
+        {
+            RetriggerTestSignalGenerator( data );
+            data->repeatCount++;
+        }        
+    }
+
+    if( framesGenerated < frameCount )
+    {
+        count = frameCount - framesGenerated;
+        for( i=0; i < count; ++i )
+        {
+            *stereo++ = 0.f;
+            *stereo++ = 0.f;
+        }
+    }
+}
+
+
+static int IsTestSignalFinished( TestData *data )
+{
+    if( data->repeatCount >= NUM_REPEATS )
+        return 1;
+    else
+        return 0;
+}
+
+
+static int TestCallback1( const void *inputBuffer, void *outputBuffer,
+                            unsigned long frameCount,
+                            const PaStreamCallbackTimeInfo* timeInfo,
+                            PaStreamCallbackFlags statusFlags,
+                            void *userData )
+{
+    (void) inputBuffer; /* Prevent unused variable warnings. */
+    (void) timeInfo;
+    (void) statusFlags;
+
+    GenerateTestSignal( (TestData*)userData, (float*)outputBuffer, frameCount );
+
+    if( IsTestSignalFinished( (TestData*)userData ) )
+        return paComplete;
+    else
+        return paContinue;
+}
+
+
+volatile int testCallback2Finished = 0;
+
+static int TestCallback2( const void *inputBuffer, void *outputBuffer,
+                            unsigned long frameCount,
+                            const PaStreamCallbackTimeInfo* timeInfo,
+                            PaStreamCallbackFlags statusFlags,
+                            void *userData )
+{
+    (void) inputBuffer; /* Prevent unused variable warnings. */
+    (void) timeInfo;
+    (void) statusFlags;
+
+    GenerateTestSignal( (TestData*)userData, (float*)outputBuffer, frameCount );
+
+    if( IsTestSignalFinished( (TestData*)userData ) )
+        testCallback2Finished = 1;
+   
+    return paContinue;
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaStreamParameters outputParameters;
+    PaStream *stream;
+    PaError err;
+    TestData data;
+    float writeBuffer[ FRAMES_PER_BUFFER * 2 ];
+    
+    printf("PortAudio Test: check that stopping stream plays out all queued samples. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
+
+    InitTestSignalGenerator( &data );
+    
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
+    outputParameters.channelCount = 2;       /* stereo output */
+    outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+
+/* test paComplete ---------------------------------------------------------- */
+
+    ResetTestSignalGenerator( &data );
+
+    err = Pa_OpenStream(
+              &stream,
+              NULL, /* no input */
+              &outputParameters,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              TestCallback1,
+              &data );
+    if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+
+    printf("\nPlaying 'tone-blip' %d times using callback, stops by returning paComplete from callback.\n", NUM_REPEATS );
+    printf("If final blip is not intact, callback+paComplete implementation may be faulty.\n\n" );
+
+    while( (err = Pa_IsStreamActive( stream )) == 1 )
+        Pa_Sleep( 5 );
+
+    if( err != 0 ) goto error;
+
+    
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+
+    Pa_Sleep( 500 );
+
+/* test Pa_StopStream() with callback --------------------------------------- */
+
+    ResetTestSignalGenerator( &data );
+
+    testCallback2Finished = 0;
+    
+    err = Pa_OpenStream(
+              &stream,
+              NULL, /* no input */
+              &outputParameters,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              TestCallback2,
+              &data );
+    if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+
+    printf("\nPlaying 'tone-blip' %d times using callback, stops by calling Pa_StopStream.\n", NUM_REPEATS );
+    printf("If final blip is not intact, callback+Pa_StopStream implementation may be faulty.\n\n" );
+
+    /* note that polling a volatile flag is not a good way to synchronise with
+        the callback, but it's the best we can do portably. */
+    while( !testCallback2Finished )
+        Pa_Sleep( 2 );
+
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+    
+
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+
+    Pa_Sleep( 500 );
+
+/* test Pa_StopStream() with Pa_WriteStream --------------------------------- */
+
+    ResetTestSignalGenerator( &data );
+
+    err = Pa_OpenStream(
+              &stream,
+              NULL, /* no input */
+              &outputParameters,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              NULL, /* no callback, use blocking API */
+              NULL ); /* no callback, so no callback userData */
+    if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+
+    printf("\nPlaying 'tone-blip' %d times using Pa_WriteStream, stops by calling Pa_StopStream.\n", NUM_REPEATS );
+    printf("If final blip is not intact, Pa_WriteStream+Pa_StopStream implementation may be faulty.\n\n" );
+
+    do{
+        GenerateTestSignal( &data, writeBuffer, FRAMES_PER_BUFFER );
+        err = Pa_WriteStream( stream, writeBuffer, FRAMES_PER_BUFFER );
+        if( err != paNoError ) goto error;
+        
+    }while( !IsTestSignalFinished( &data ) );
+
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+    
+
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+
+/* -------------------------------------------------------------------------- */
+    
+    Pa_Terminate();
+    printf("Test finished.\n");
+    
+    return err;
+    
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_sync.c b/utils/iaxclient/lib/portaudio/test/patest_sync.c
new file mode 100644 (file)
index 0000000..18f2ecb
--- /dev/null
@@ -0,0 +1,259 @@
+/** @file patest_sync.c
+       @brief Test time stamping and synchronization of audio and video.
+
+       A high latency is used so we can hear the difference in time.
+       Random durations are used so we know we are hearing the right beep
+       and not the one before or after.
+
+       Sequence of events:
+               -# Foreground requests a beep.
+               -# Background randomly schedules a beep.
+               -# Foreground waits for the beep to be heard based on PaUtil_GetTime().
+               -# Foreground outputs video (printf) in sync with audio.
+               -# Repeat.
+       
+       @author Phil Burk  http://www.softsynth.com
+*/
+/*
+ * $Id: patest_sync.c,v 1.1 2006/06/10 21:30:57 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+#include "pa_util.h"
+#define NUM_BEEPS           (6)
+#define SAMPLE_RATE         (44100)
+#define SAMPLE_PERIOD       (1.0/44100.0)
+#define FRAMES_PER_BUFFER   (256)
+#define BEEP_DURATION       (400)
+#define LATENCY_MSEC        (2000)
+#define SLEEP_MSEC          (10)
+#define TIMEOUT_MSEC        (15000)
+
+#define STATE_BKG_IDLE      (0)
+#define STATE_BKG_PENDING   (1)
+#define STATE_BKG_BEEPING   (2)
+typedef struct
+{
+    float        left_phase;
+    float        right_phase;
+    int          state;
+    volatile int requestBeep;  /* Set by foreground, cleared by background. */
+    PaTime       beepTime;
+    int          beepCount;
+    double       latency;    /* For debugging. */
+}
+paTestData;
+
+static unsigned long GenerateRandomNumber( void );
+/************************************************************/
+/* Calculate pseudo-random 32 bit number based on linear congruential method. */
+static unsigned long GenerateRandomNumber( void )
+{
+    static unsigned long randSeed = 99887766;  /* Change this for different random sequences. */
+    randSeed = (randSeed * 196314165) + 907633515;
+    return randSeed;
+}
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( const void *inputBuffer, void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                          const PaStreamCallbackTimeInfo *timeInfo,
+                          PaStreamCallbackFlags statusFlags, void *userData )
+{
+    /* Cast data passed through stream to our structure. */
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    unsigned int i;
+    (void) inputBuffer;
+
+    data->latency = timeInfo->outputBufferDacTime - timeInfo->currentTime;
+
+    for( i=0; i<framesPerBuffer; i++ )
+    {
+        switch( data->state )
+        {
+        case STATE_BKG_IDLE:
+            /* Schedule beep at some random time in the future. */
+            if( data->requestBeep )
+            {
+                int random = GenerateRandomNumber() >> 14;
+                data->beepTime = timeInfo->outputBufferDacTime + (( (double)(random + SAMPLE_RATE)) * SAMPLE_PERIOD );
+                data->state = STATE_BKG_PENDING;
+            }
+            *out++ = 0.0;  /* left */
+            *out++ = 0.0;  /* right */
+            break;
+
+        case STATE_BKG_PENDING:
+            if( (timeInfo->outputBufferDacTime + (i*SAMPLE_PERIOD)) >= data->beepTime )
+            {
+                data->state = STATE_BKG_BEEPING;
+                data->beepCount = BEEP_DURATION;
+                data->left_phase = data->right_phase = 0.0;
+            }
+            *out++ = 0.0;  /* left */
+            *out++ = 0.0;  /* right */
+            break;
+
+        case STATE_BKG_BEEPING:
+            if( data->beepCount <= 0 )
+            {
+                data->state = STATE_BKG_IDLE;
+                data->requestBeep = 0;
+                *out++ = 0.0;  /* left */
+                *out++ = 0.0;  /* right */
+            }
+            else
+            {
+                /* Play sawtooth wave. */
+                *out++ = data->left_phase;  /* left */
+                *out++ = data->right_phase;  /* right */
+                /* Generate simple sawtooth phaser that ranges between -1.0 and 1.0. */
+                data->left_phase += 0.01f;
+                /* When signal reaches top, drop back down. */
+                if( data->left_phase >= 1.0f ) data->left_phase -= 2.0f;
+                /* higher pitch so we can distinguish left and right. */
+                data->right_phase += 0.03f;
+                if( data->right_phase >= 1.0f ) data->right_phase -= 2.0f;
+            }
+            data->beepCount -= 1;
+            break;
+
+        default:
+            data->state = STATE_BKG_IDLE;
+            break;
+        }
+    }
+    return 0;
+}
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaStream *stream;
+    PaError    err;
+    paTestData DATA;
+    int        i, timeout;
+    PaTime     previousTime;
+    PaStreamParameters outputParameters;
+    printf("PortAudio Test: you should see BEEP at the same time you hear it.\n");
+    printf("Wait for a few seconds random delay between BEEPs.\n");
+    printf("BEEP %d times.\n", NUM_BEEPS );
+    /* Initialize our DATA for use by callback. */
+    DATA.left_phase = DATA.right_phase = 0.0;
+    DATA.state = STATE_BKG_IDLE;
+    DATA.requestBeep = 0;
+    /* Initialize library before making any other calls. */
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+    
+    outputParameters.device = Pa_GetDefaultOutputDevice();
+    outputParameters.channelCount = 2;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+    outputParameters.sampleFormat = paFloat32;
+    outputParameters.suggestedLatency = (double)LATENCY_MSEC / 1000;
+
+    /* Open an audio I/O stream. */
+     err = Pa_OpenStream(
+              &stream,
+             NULL,                         /* no input */
+             &outputParameters,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,            /* frames per buffer */
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              patestCallback,
+              &DATA );
+   if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+    printf("started\n");
+    fflush(stdout);
+
+    previousTime = Pa_GetStreamTime( stream );
+    for( i=0; i<NUM_BEEPS; i++ )
+    {
+        /* Request a beep from background. */
+        DATA.requestBeep = 1;
+
+        /* Wait for background to acknowledge request. */
+        timeout = TIMEOUT_MSEC;
+        while( (DATA.requestBeep == 1) && (timeout-- > 0 ) ) Pa_Sleep(SLEEP_MSEC);
+        if( timeout <= 0 )
+        {
+            fprintf( stderr, "Timed out waiting for background to acknowledge request.\n" );
+            goto error;
+        }
+        printf("calc beep for %9.3f, latency = %6.3f\n", DATA.beepTime, DATA.latency );
+        fflush(stdout);
+
+        /* Wait for scheduled beep time. */
+        timeout =  TIMEOUT_MSEC + (10000/SLEEP_MSEC);
+        while( (Pa_GetStreamTime( stream ) < DATA.beepTime) && (timeout-- > 0 ) )
+        {
+            Pa_Sleep(SLEEP_MSEC);
+        }
+        if( timeout <= 0 )
+        {
+            fprintf( stderr, "Timed out waiting for time. Now = %9.3f, Beep for %9.3f.\n",
+                     PaUtil_GetTime(), DATA.beepTime );
+            goto error;
+        }
+
+        /* Beep should be sounding now so print synchronized BEEP. */
+        printf("hear \"BEEP\" at %9.3f, delta = %9.3f\n",
+               Pa_GetStreamTime( stream ), (DATA.beepTime - previousTime) );
+        fflush(stdout);
+
+        previousTime = DATA.beepTime;
+    }
+
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+
+    Pa_Terminate();
+    printf("Test finished.\n");
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_toomanysines.c b/utils/iaxclient/lib/portaudio/test/patest_toomanysines.c
new file mode 100644 (file)
index 0000000..097317c
--- /dev/null
@@ -0,0 +1,173 @@
+/** @file patest_toomanysines.c
+       @brief Play more sine waves than we can handle in real time as a stress test.
+       @author Ross Bencina <rossb@audiomulch.com>
+       @author Phil Burk <philburk@softsynth.com>
+*/
+/*
+ * $Id: patest_toomanysines.c,v 1.1 2006/06/10 21:30:57 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define MAX_SINES     (500)
+#define MAX_LOAD      (1.2)
+#define SAMPLE_RATE   (44100)
+#define FRAMES_PER_BUFFER  (512)
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+#define TWOPI (M_PI * 2.0)
+
+typedef struct paTestData
+{
+    int numSines;
+    double phases[MAX_SINES];
+}
+paTestData;
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( const void *inputBuffer, void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                           const PaStreamCallbackTimeInfo* timeInfo,
+                           PaStreamCallbackFlags statusFlags,
+                           void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    unsigned long i;
+    int j;
+    int finished = 0;
+    (void) inputBuffer; /* Prevent unused variable warning. */
+
+    for( i=0; i<framesPerBuffer; i++ )
+    {
+        float output = 0.0;
+        double phaseInc = 0.02;
+        double phase;
+        for( j=0; j<data->numSines; j++ )
+        {
+            /* Advance phase of next oscillator. */
+            phase = data->phases[j];
+            phase += phaseInc;
+            if( phase > TWOPI ) phase -= TWOPI;
+
+            phaseInc *= 1.02;
+            if( phaseInc > 0.5 ) phaseInc *= 0.5;
+
+            /* This is not a very efficient way to calc sines. */
+            output += (float) sin( phase );
+            data->phases[j] = phase;
+        }
+        *out++ = (float) (output / data->numSines);
+    }
+    return finished;
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaStreamParameters outputParameters;
+    PaStream *stream;
+    PaError err;
+    int numStress;
+    paTestData data = {0};
+    double load;
+
+    printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d. MAX_LOAD = %f\n",
+        SAMPLE_RATE, FRAMES_PER_BUFFER, MAX_LOAD );
+
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+    
+    outputParameters.device = Pa_GetDefaultOutputDevice();  /* default output device */
+    outputParameters.channelCount = 1;                      /* mono output */
+    outputParameters.sampleFormat = paFloat32;              /* 32 bit floating point output */
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+
+    err = Pa_OpenStream(
+              &stream,
+              NULL,         /* no input */
+              &outputParameters,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              paClipOff,    /* we won't output out of range samples so don't bother clipping them */
+              patestCallback,
+              &data );    
+    if( err != paNoError ) goto error;
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+    /* Determine number of sines required to get to 50% */
+    do
+    {
+        data.numSines++;
+        Pa_Sleep( 100 );
+
+        load = Pa_GetStreamCpuLoad( stream );
+        printf("numSines = %d, CPU load = %f\n", data.numSines, load );
+    }
+    while( load < 0.5 );
+    
+    /* Calculate target stress value then ramp up to that level*/
+    numStress = (int) (2.0 * data.numSines * MAX_LOAD );
+    for( ; data.numSines < numStress; data.numSines++ )
+    {
+        Pa_Sleep( 200 );
+        load = Pa_GetStreamCpuLoad( stream );
+        printf("STRESSING: numSines = %d, CPU load = %f\n", data.numSines, load );
+    }
+    
+    printf("Suffer for 5 seconds.\n");
+    Pa_Sleep( 5000 );
+    
+    printf("Stop stream.\n");
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+    
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+    
+    Pa_Terminate();
+    printf("Test finished.\n");
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_two_rates.c b/utils/iaxclient/lib/portaudio/test/patest_two_rates.c
new file mode 100644 (file)
index 0000000..18ae215
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * $Id: patest_two_rates.c,v 1.1 2006/06/10 21:30:57 dmazzoni Exp $
+ * patest_two_rates.c
+ * Play two streams at different rates to make sure they don't interfere.
+ *
+ * Author: Phil Burk  http://www.softsynth.com
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define OUTPUT_DEVICE       (Pa_GetDefaultOutputDeviceID())
+#define SAMPLE_RATE_1       (44100)
+#define SAMPLE_RATE_2       (44100)
+#define FRAMES_PER_BUFFER   (256)
+#define FREQ_INCR           (0.1)
+
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+
+typedef struct
+{
+    double phase;
+    double numFrames;
+} paTestData;
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( void *inputBuffer, void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                           PaTimestamp outTime, void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    int frameIndex, channelIndex;
+    int finished = 0;
+    (void) outTime; /* Prevent unused variable warnings. */
+    (void) inputBuffer;
+
+    for( frameIndex=0; frameIndex<(int)framesPerBuffer; frameIndex++ )
+    {
+        /* Generate sine wave. */
+        float value = (float) 0.3 * sin(data->phase);
+        /* Stereo - two channels. */
+        *out++ = value;
+        *out++ = value;
+
+        data->phase += FREQ_INCR;
+        if( data->phase >= (2.0 * M_PI) ) data->phase -= (2.0 * M_PI);
+    }
+
+    return 0;
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaError err;
+    PortAudioStream *stream1;
+    PortAudioStream *stream2;
+    paTestData data1 = {0};
+    paTestData data2 = {0};
+    printf("PortAudio Test: two rates.\n" );
+
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+    
+    /* Start first stream. **********************/
+    err = Pa_OpenStream(
+              &stream1,
+              paNoDevice, /* default input device */
+              0,              /* no input */
+              paFloat32,  /* 32 bit floating point input */
+              NULL,
+              OUTPUT_DEVICE,
+              2,          /* Stereo */
+              paFloat32,  /* 32 bit floating point output */
+              NULL,
+              SAMPLE_RATE_1,
+              FRAMES_PER_BUFFER,  /* frames per buffer */
+              0,    /* number of buffers, if zero then use default minimum */
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              patestCallback,
+              &data1 );
+    if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( stream1 );
+    if( err != paNoError ) goto error;
+
+    Pa_Sleep( 3 * 1000 );
+
+    /* Start second stream. **********************/
+    err = Pa_OpenStream(
+              &stream2,
+              paNoDevice, /* default input device */
+              0,              /* no input */
+              paFloat32,  /* 32 bit floating point input */
+              NULL,
+              OUTPUT_DEVICE,
+              2,          /* Stereo */
+              paFloat32,  /* 32 bit floating point output */
+              NULL,
+              SAMPLE_RATE_2,
+              FRAMES_PER_BUFFER,  /* frames per buffer */
+              0,    /* number of buffers, if zero then use default minimum */
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              patestCallback,
+              &data2 );
+    if( err != paNoError ) goto error;
+
+    err = Pa_StartStream( stream2 );
+    if( err != paNoError ) goto error;
+
+    Pa_Sleep( 3 * 1000 );
+    
+    err = Pa_StopStream( stream2 );
+    if( err != paNoError ) goto error;
+
+    Pa_Sleep( 3 * 1000 );
+    
+    err = Pa_StopStream( stream1 );
+    if( err != paNoError ) goto error;
+
+    Pa_CloseStream( stream2 );
+    Pa_CloseStream( stream1 );
+    
+    Pa_Terminate();
+    printf("Test finished.\n");
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_underflow.c b/utils/iaxclient/lib/portaudio/test/patest_underflow.c
new file mode 100644 (file)
index 0000000..2898bd4
--- /dev/null
@@ -0,0 +1,150 @@
+/** @file patest_underflow.c
+       @brief Simulate an output buffer underflow condition.
+       Tests whether the stream can be stopped when underflowing buffers.
+       @author Ross Bencina <rossb@audiomulch.com>
+       @author Phil Burk <philburk@softsynth.com>
+*/
+/*
+ * $Id: patest_underflow.c,v 1.1 2006/06/10 21:30:57 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.audiomulch.com/portaudio/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define NUM_SECONDS   (20)
+#define SAMPLE_RATE   (44100)
+#define FRAMES_PER_BUFFER  (2048)
+#define MSEC_PER_BUFFER  ( (FRAMES_PER_BUFFER * 1000) / SAMPLE_RATE )
+
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+
+#define TABLE_SIZE   (200)
+typedef struct
+{
+    float sine[TABLE_SIZE];
+    int left_phase;
+    int right_phase;
+    int sleepTime;
+}
+paTestData;
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+static int patestCallback( const void *inputBuffer, void *outputBuffer,
+                           unsigned long framesPerBuffer,
+                           const PaStreamCallbackTimeInfo* timeInfo,
+                           PaStreamCallbackFlags statusFlags,
+                           void *userData )
+{
+    paTestData *data = (paTestData*)userData;
+    float *out = (float*)outputBuffer;
+    unsigned long i;
+    int finished = 0;
+    (void) inputBuffer; /* Prevent unused variable warnings. */
+    for( i=0; i<framesPerBuffer; i++ )
+    {
+        *out++ = data->sine[data->left_phase];  /* left */
+        *out++ = data->sine[data->right_phase];  /* right */
+        data->left_phase += 1;
+        if( data->left_phase >= TABLE_SIZE ) data->left_phase -= TABLE_SIZE;
+        data->right_phase += 3; /* higher pitch so we can distinguish left and right. */
+        if( data->right_phase >= TABLE_SIZE ) data->right_phase -= TABLE_SIZE;
+    }
+
+    /* Cause underflow to occur. */
+    if( data->sleepTime > 0 ) Pa_Sleep( data->sleepTime );
+    data->sleepTime += 1;
+
+    return finished;
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaStreamParameters outputParameters;
+    PaStream *stream;
+    PaError err;
+    paTestData data;
+    int i;
+    printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<TABLE_SIZE; i++ )
+    {
+        data.sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
+    }
+    data.left_phase = data.right_phase = data.sleepTime = 0;
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+    
+    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
+    outputParameters.channelCount = 2;       /* stereo output */
+    outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+    err = Pa_OpenStream(
+              &stream,
+              NULL, /* no input */
+              &outputParameters,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              patestCallback,
+              &data );
+    if( err != paNoError ) goto error;
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+    while( data.sleepTime < (2 * MSEC_PER_BUFFER) )
+    {
+        printf("SleepTime = %d\n", data.sleepTime );
+        Pa_Sleep( data.sleepTime );
+    }
+
+    printf("Try to stop stream.\n");
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+    Pa_Terminate();
+    printf("Test finished.\n");
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_wire.c b/utils/iaxclient/lib/portaudio/test/patest_wire.c
new file mode 100644 (file)
index 0000000..7b61995
--- /dev/null
@@ -0,0 +1,284 @@
+/** @file patest_wire.c
+       @brief Pass input directly to output.
+
+       Note that some HW devices, for example many ISA audio cards
+       on PCs, do NOT support full duplex! For a PC, you normally need
+       a PCI based audio card such as the SBLive.
+
+       @author Phil Burk  http://www.softsynth.com
+    
+ While adapting to V19-API, I excluded configs with framesPerCallback=0
+ because of an assert in file pa_common/pa_process.c. Pieter, Oct 9, 2003.
+
+*/
+/*
+ * $Id: patest_wire.c,v 1.1 2006/06/10 21:30:57 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define SAMPLE_RATE            (44100)
+
+typedef struct WireConfig_s
+{
+    int isInputInterleaved;
+    int isOutputInterleaved;
+    int numInputChannels;
+    int numOutputChannels;
+    int framesPerCallback;
+} WireConfig_t;
+
+#define USE_FLOAT_INPUT        (1)
+#define USE_FLOAT_OUTPUT       (1)
+
+/* Latencies set to defaults. */
+
+#if USE_FLOAT_INPUT
+    #define INPUT_FORMAT  paFloat32
+    typedef float INPUT_SAMPLE;
+#else
+    #define INPUT_FORMAT  paInt16
+    typedef short INPUT_SAMPLE;
+#endif
+
+#if USE_FLOAT_OUTPUT
+    #define OUTPUT_FORMAT  paFloat32
+    typedef float OUTPUT_SAMPLE;
+#else
+    #define OUTPUT_FORMAT  paInt16
+    typedef short OUTPUT_SAMPLE;
+#endif
+
+double gInOutScaler = 1.0;
+#define CONVERT_IN_TO_OUT(in)  ((OUTPUT_SAMPLE) ((in) * gInOutScaler))
+
+#define INPUT_DEVICE           (Pa_GetDefaultInputDevice())
+#define OUTPUT_DEVICE          (Pa_GetDefaultOutputDevice())
+
+static PaError TestConfiguration( WireConfig_t *config );
+
+static int wireCallback( const void *inputBuffer, void *outputBuffer,
+                         unsigned long framesPerBuffer,
+                         const PaStreamCallbackTimeInfo* timeInfo,
+                         PaStreamCallbackFlags statusFlags,
+                         void *userData );
+
+/* This routine will be called by the PortAudio engine when audio is needed.
+** It may be called at interrupt level on some machines so don't do anything
+** that could mess up the system like calling malloc() or free().
+*/
+
+static int wireCallback( const void *inputBuffer, void *outputBuffer,
+                         unsigned long framesPerBuffer,
+                         const PaStreamCallbackTimeInfo* timeInfo,
+                         PaStreamCallbackFlags statusFlags,
+                         void *userData )
+{
+    INPUT_SAMPLE *in;
+    OUTPUT_SAMPLE *out;
+    int inStride;
+    int outStride;
+    int inDone = 0;
+    int outDone = 0;
+    WireConfig_t *config = (WireConfig_t *) userData;
+    unsigned int i;
+    int inChannel, outChannel;
+
+    /* This may get called with NULL inputBuffer during initial setup. */
+    if( inputBuffer == NULL) return 0;
+
+    inChannel=0, outChannel=0;
+    while( !(inDone && outDone) )
+    {
+        if( config->isInputInterleaved )
+        {
+            in = ((INPUT_SAMPLE*)inputBuffer) + inChannel;
+            inStride = config->numInputChannels;
+        }
+        else
+        {
+            in = ((INPUT_SAMPLE**)inputBuffer)[inChannel];
+            inStride = 1;
+        }
+
+        if( config->isOutputInterleaved )
+        {
+            out = ((OUTPUT_SAMPLE*)outputBuffer) + outChannel;
+            outStride = config->numOutputChannels;
+        }
+        else
+        {
+            out = ((OUTPUT_SAMPLE**)outputBuffer)[outChannel];
+            outStride = 1;
+        }
+
+        for( i=0; i<framesPerBuffer; i++ )
+        {
+            *out = CONVERT_IN_TO_OUT( *in );
+            out += outStride;
+            in += inStride;
+        }
+
+        if(inChannel < (config->numInputChannels - 1)) inChannel++;
+        else inDone = 1;
+        if(outChannel < (config->numOutputChannels - 1)) outChannel++;
+        else outDone = 1;
+    }
+    return 0;
+}
+
+/*******************************************************************/
+int main(void);
+int main(void)
+{
+    PaError err;
+    WireConfig_t CONFIG;
+    WireConfig_t *config = &CONFIG;
+    int configIndex = 0;;
+
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    printf("Please connect audio signal to input and listen for it on output!\n");
+    printf("input format = %lu\n", INPUT_FORMAT );
+    printf("output format = %lu\n", OUTPUT_FORMAT );
+    printf("input device ID  = %d\n", INPUT_DEVICE );
+    printf("output device ID = %d\n", OUTPUT_DEVICE );
+
+    if( INPUT_FORMAT == OUTPUT_FORMAT )
+    {
+        gInOutScaler = 1.0;
+    }
+    else if( (INPUT_FORMAT == paInt16) && (OUTPUT_FORMAT == paFloat32) )
+    {
+        gInOutScaler = 1.0/32768.0;
+    }
+    else if( (INPUT_FORMAT == paFloat32) && (OUTPUT_FORMAT == paInt16) )
+    {
+        gInOutScaler = 32768.0;
+    }
+
+    for( config->isInputInterleaved = 0; config->isInputInterleaved < 2; config->isInputInterleaved++ )
+    {
+        for( config->isOutputInterleaved = 0; config->isOutputInterleaved < 2; config->isOutputInterleaved++ )
+        {
+            for( config->numInputChannels = 1; config->numInputChannels < 3; config->numInputChannels++ )
+            {
+                for( config->numOutputChannels = 1; config->numOutputChannels < 3; config->numOutputChannels++ )
+                {
+                           /* If framesPerCallback = 0, assertion fails in file pa_common/pa_process.c, line 1413: EX. */
+                    for( config->framesPerCallback = 64; config->framesPerCallback < 129; config->framesPerCallback += 64 )
+                    {
+                        printf("-----------------------------------------------\n" );
+                        printf("Configuration #%d\n", configIndex++ );
+                        err = TestConfiguration( config );
+                        /* Give user a chance to bail out. */
+                        if( err == 1 )
+                        {
+                            err = paNoError;
+                            goto done;
+                        }
+                        else if( err != paNoError ) goto error;
+                    }
+               }
+            }
+        }
+    }
+
+done:
+    Pa_Terminate();
+    printf("Full duplex sound test complete.\n"); fflush(stdout);
+    printf("Hit ENTER to quit.\n");  fflush(stdout);
+    getchar();
+    return 0;
+
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    printf("Hit ENTER to quit.\n");  fflush(stdout);
+    getchar();
+    return -1;
+}
+
+static PaError TestConfiguration( WireConfig_t *config )
+{
+    int c;
+    PaError err;
+    PaStream *stream;
+    PaStreamParameters inputParameters, outputParameters;
+    
+    printf("input %sinterleaved!\n", (config->isInputInterleaved ? " " : "NOT ") );
+    printf("output %sinterleaved!\n", (config->isOutputInterleaved ? " " : "NOT ") );
+    printf("input channels = %d\n", config->numInputChannels );
+    printf("output channels = %d\n", config->numOutputChannels );
+    printf("framesPerCallback = %d\n", config->framesPerCallback );
+
+    inputParameters.device = INPUT_DEVICE;              /* default input device */
+    inputParameters.channelCount = config->numInputChannels;
+    inputParameters.sampleFormat = INPUT_FORMAT | (config->isInputInterleaved ? 0 : paNonInterleaved);
+    inputParameters.suggestedLatency = Pa_GetDeviceInfo( inputParameters.device )->defaultLowInputLatency;
+    inputParameters.hostApiSpecificStreamInfo = NULL;
+
+    outputParameters.device = OUTPUT_DEVICE;            /* default output device */
+    outputParameters.channelCount = config->numOutputChannels;
+    outputParameters.sampleFormat = OUTPUT_FORMAT | (config->isOutputInterleaved ? 0 : paNonInterleaved);
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+
+    err = Pa_OpenStream(
+              &stream,
+              &inputParameters,
+              &outputParameters,
+              SAMPLE_RATE,
+              config->framesPerCallback, /* frames per buffer */
+              paClipOff, /* we won't output out of range samples so don't bother clipping them */
+              wireCallback,
+              config );
+    if( err != paNoError ) goto error;
+    
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+    
+    printf("Hit ENTER for next configuration, or 'q' to quit.\n");  fflush(stdout);
+    c = getchar();
+    
+    printf("Closing stream.\n");
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+
+    if( c == 'q' ) return 1;
+
+error:
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_write_sine.c b/utils/iaxclient/lib/portaudio/test/patest_write_sine.c
new file mode 100644 (file)
index 0000000..25bae42
--- /dev/null
@@ -0,0 +1,147 @@
+/** @file patest_write_sine.c
+       @brief Play a sine wave for several seconds using the blocking API (Pa_WriteStream())
+       @author Ross Bencina <rossb@audiomulch.com>
+    @author Phil Burk <philburk@softsynth.com>
+*/
+/*
+ * $Id: patest_write_sine.c,v 1.1 2006/06/10 21:30:57 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define NUM_SECONDS         (5)
+#define SAMPLE_RATE         (44100)
+#define FRAMES_PER_BUFFER   (1024)
+
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+
+#define TABLE_SIZE   (200)
+
+
+int main(void);
+int main(void)
+{
+    PaStreamParameters outputParameters;
+    PaStream *stream;
+    PaError err;
+    float buffer[FRAMES_PER_BUFFER][2]; /* stereo output buffer */
+    float sine[TABLE_SIZE]; /* sine wavetable */
+    int left_phase = 0;
+    int right_phase = 0;
+    int left_inc = 1;
+    int right_inc = 3; /* higher pitch so we can distinguish left and right. */
+    int i, j, k;
+    int bufferCount;
+
+    
+    printf("PortAudio Test: output sine wave. SR = %d, BufSize = %d\n", SAMPLE_RATE, FRAMES_PER_BUFFER);
+    
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<TABLE_SIZE; i++ )
+    {
+        sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
+    }
+
+    
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
+    outputParameters.channelCount = 2;       /* stereo output */
+    outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+
+    err = Pa_OpenStream(
+              &stream,
+              NULL, /* no input */
+              &outputParameters,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              NULL, /* no callback, use blocking API */
+              NULL ); /* no callback, so no callback userData */
+    if( err != paNoError ) goto error;
+
+
+    printf( "Play 3 times, higher each time.\n" );
+    
+    for( k=0; k < 3; ++k )
+    {
+        err = Pa_StartStream( stream );
+        if( err != paNoError ) goto error;
+
+        printf("Play for %d seconds.\n", NUM_SECONDS );
+
+        bufferCount = ((NUM_SECONDS * SAMPLE_RATE) / FRAMES_PER_BUFFER);
+
+        for( i=0; i < bufferCount; i++ )
+        {
+            for( j=0; j < FRAMES_PER_BUFFER; j++ )
+            {
+                buffer[j][0] = sine[left_phase];  /* left */
+                buffer[j][1] = sine[right_phase];  /* right */
+                left_phase += left_inc;
+                if( left_phase >= TABLE_SIZE ) left_phase -= TABLE_SIZE;
+                right_phase += right_inc;
+                if( right_phase >= TABLE_SIZE ) right_phase -= TABLE_SIZE;
+            }
+
+            err = Pa_WriteStream( stream, buffer, FRAMES_PER_BUFFER );
+            if( err != paNoError ) goto error;
+        }   
+
+        err = Pa_StopStream( stream );
+        if( err != paNoError ) goto error;
+
+        ++left_inc;
+        ++right_inc;
+
+        Pa_Sleep( 1000 );
+    }
+
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+
+    Pa_Terminate();
+    printf("Test finished.\n");
+    
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/test/patest_write_stop.c b/utils/iaxclient/lib/portaudio/test/patest_write_stop.c
new file mode 100644 (file)
index 0000000..d70b3c2
--- /dev/null
@@ -0,0 +1,158 @@
+/** @file patest_write_stop.c
+       @brief Play a few seconds of silence followed by a few cycles of a sine wave. Tests to make sure that pa_StopStream() completes playback in blocking I/O
+       @author Bjorn Roche of XO Audio (www.xoaudio.com)
+       @author Ross Bencina
+       @author Phil Burk
+*/
+/*
+ * $Id: patest_write_stop.c,v 1.1 2006/06/10 21:30:57 dmazzoni Exp $
+ *
+ * This program uses the PortAudio Portable Audio Library.
+ * For more information see: http://www.portaudio.com/
+ * Copyright (c) 1999-2000 Ross Bencina and Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <math.h>
+#include "portaudio.h"
+
+#define NUM_SECONDS         (5)
+#define SAMPLE_RATE         (44100)
+#define FRAMES_PER_BUFFER   (1024)
+
+#ifndef M_PI
+#define M_PI  (3.14159265)
+#endif
+
+#define TABLE_SIZE   (200)
+
+
+int main(void);
+int main(void)
+{
+    PaStreamParameters outputParameters;
+    PaStream *stream;
+    PaError err;
+    float buffer[FRAMES_PER_BUFFER][2]; /* stereo output buffer */
+    float sine[TABLE_SIZE]; /* sine wavetable */
+    int left_phase = 0;
+    int right_phase = 0;
+    int left_inc = 1;
+    int right_inc = 3; /* higher pitch so we can distinguish left and right. */
+    int i, j;
+    int bufferCount;
+    const int   framesBy2  = FRAMES_PER_BUFFER >> 1;
+    const float framesBy2f = (float) framesBy2 ;
+
+    
+    printf( "PortAudio Test: output silence, followed by one buffer of a ramped sine wave. SR = %d, BufSize = %d\n",
+            SAMPLE_RATE, FRAMES_PER_BUFFER);
+    
+    /* initialise sinusoidal wavetable */
+    for( i=0; i<TABLE_SIZE; i++ )
+    {
+        sine[i] = (float) sin( ((double)i/(double)TABLE_SIZE) * M_PI * 2. );
+    }
+
+    
+    err = Pa_Initialize();
+    if( err != paNoError ) goto error;
+
+    outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
+    outputParameters.channelCount = 2;       /* stereo output */
+    outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
+    outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency * 5;
+    outputParameters.hostApiSpecificStreamInfo = NULL;
+
+    /* open the stream */
+    err = Pa_OpenStream(
+              &stream,
+              NULL, /* no input */
+              &outputParameters,
+              SAMPLE_RATE,
+              FRAMES_PER_BUFFER,
+              paClipOff,      /* we won't output out of range samples so don't bother clipping them */
+              NULL, /* no callback, use blocking API */
+              NULL ); /* no callback, so no callback userData */
+    if( err != paNoError ) goto error;
+
+    /* start the stream */
+    err = Pa_StartStream( stream );
+    if( err != paNoError ) goto error;
+
+    printf("Playing %d seconds of silence followed by one buffer of a ramped sinusoid.\n", NUM_SECONDS );
+
+    bufferCount = ((NUM_SECONDS * SAMPLE_RATE) / FRAMES_PER_BUFFER);
+
+    /* clear buffer */
+    for( j=0; j < FRAMES_PER_BUFFER; j++ )
+    {
+        buffer[j][0] = 0;  /* left */
+        buffer[j][1] = 0;  /* right */
+    }
+    /* play the silent buffer a bunch o' times */
+    for( i=0; i < bufferCount; i++ )
+    {
+        err = Pa_WriteStream( stream, buffer, FRAMES_PER_BUFFER );
+        if( err != paNoError ) goto error;
+    }   
+    /* play a non-silent buffer once */
+    for( j=0; j < FRAMES_PER_BUFFER; j++ )
+    {
+        float ramp = 1;
+        if( j < framesBy2 )
+           ramp = j / framesBy2f;
+        else
+           ramp = (FRAMES_PER_BUFFER - j) / framesBy2f ;
+
+        buffer[j][0] = sine[left_phase] * ramp;  /* left */
+        buffer[j][1] = sine[right_phase] * ramp;  /* right */
+        left_phase += left_inc;
+        if( left_phase >= TABLE_SIZE ) left_phase -= TABLE_SIZE;
+        right_phase += right_inc;
+        if( right_phase >= TABLE_SIZE ) right_phase -= TABLE_SIZE;
+    }
+    err = Pa_WriteStream( stream, buffer, FRAMES_PER_BUFFER );
+    if( err != paNoError ) goto error;
+
+    /* stop stream, close, and terminate */
+    err = Pa_StopStream( stream );
+    if( err != paNoError ) goto error;
+
+    err = Pa_CloseStream( stream );
+    if( err != paNoError ) goto error;
+
+    Pa_Terminate();
+    printf("Test finished.\n");
+    
+    return err;
+error:
+    Pa_Terminate();
+    fprintf( stderr, "An error occured while using the portaudio stream\n" );
+    fprintf( stderr, "Error number: %d\n", err );
+    fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
+    return err;
+}
diff --git a/utils/iaxclient/lib/portaudio/testcvs/changeme.txt b/utils/iaxclient/lib/portaudio/testcvs/changeme.txt
new file mode 100644 (file)
index 0000000..2866c3b
--- /dev/null
@@ -0,0 +1,8 @@
+This is just a dopy little file used to test the CVS repository.
+Feel free to trash this file.
+Minor change.
+Another tweak.
+philburk tweak
+stephane test
+Phil changed this again on 2/21/02. Yawn...
+
diff --git a/utils/iaxclient/lib/portmixer/LICENSE.txt b/utils/iaxclient/lib/portmixer/LICENSE.txt
new file mode 100644 (file)
index 0000000..99f1a53
--- /dev/null
@@ -0,0 +1,75 @@
+Portable header file to contain:\r
+/*\r
+ * PortMixer\r
+ * PortMixer API Header File\r
+ *\r
+ * Copyright (c) 2002\r
+ *\r
+ * Written by Dominic Mazzoni\r
+ *\r
+ * PortMixer is intended to work side-by-side with PortAudio,\r
+ * the Portable Real-Time Audio Library by Ross Bencina and\r
+ * Phil Burk.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining\r
+ * a copy of this software and associated documentation files\r
+ * (the "Software"), to deal in the Software without restriction,\r
+ * including without limitation the rights to use, copy, modify, merge,\r
+ * publish, distribute, sublicense, and/or sell copies of the Software,\r
+ * and to permit persons to whom the Software is furnished to do so,\r
+ * subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be\r
+ * included in all copies or substantial portions of the Software.\r
+ *\r
+ * Any person wishing to distribute modifications to the Software is\r
+ * requested to send the modifications to the original developer so that\r
+ * they can be incorporated into the canonical version.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ *\r
+ */\r
+\r
+Implementation files to contain:\r
+/*\r
+ * PortMixer\r
+ * <platform> Implementation\r
+ *\r
+ * <copyright message>\r
+ *\r
+ * <author>\r
+ *\r
+ * PortMixer is intended to work side-by-side with PortAudio,\r
+ * the Portable Real-Time Audio Library by Ross Bencina and\r
+ * Phil Burk.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining\r
+ * a copy of this software and associated documentation files\r
+ * (the "Software"), to deal in the Software without restriction,\r
+ * including without limitation the rights to use, copy, modify, merge,\r
+ * publish, distribute, sublicense, and/or sell copies of the Software,\r
+ * and to permit persons to whom the Software is furnished to do so,\r
+ * subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be\r
+ * included in all copies or substantial portions of the Software.\r
+ *\r
+ * Any person wishing to distribute modifications to the Software is\r
+ * requested to send the modifications to the original developer so that\r
+ * they can be incorporated into the canonical version.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ *\r
+ */\r
diff --git a/utils/iaxclient/lib/portmixer/macproj/portmixer.mcp b/utils/iaxclient/lib/portmixer/macproj/portmixer.mcp
new file mode 100755 (executable)
index 0000000..7775d72
Binary files /dev/null and b/utils/iaxclient/lib/portmixer/macproj/portmixer.mcp differ
diff --git a/utils/iaxclient/lib/portmixer/px_common/portmixer.h b/utils/iaxclient/lib/portmixer/px_common/portmixer.h
new file mode 100755 (executable)
index 0000000..f85d29e
--- /dev/null
@@ -0,0 +1,154 @@
+#ifndef PORT_MIXER_H
+#define PORT_MIXER_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+
+/*
+ * PortMixer
+ * PortMixer API Header File
+ *
+ * Copyright (c) 2002
+ *
+ * Written by Dominic Mazzoni
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "portaudio.h"
+
+typedef void PxMixer;
+
+typedef float PxVolume; /* 0.0 (min) --> 1.0 (max) */
+typedef float PxBalance; /* -1.0 (left) --> 1.0 (right) */
+
+/*
+ Px_GetNumMixers returns the number of mixers which could be
+ used with the given PortAudio device.  On most systems, there
+ will be only one mixer for each device; however there may be
+ multiple mixers for each device, or possibly multiple mixers
+ which are independent of any particular PortAudio device.
+*/
+
+int Px_GetNumMixers( void *pa_stream );
+const char *Px_GetMixerName( void *pa_stream, int i );
+
+/*
+ Px_OpenMixer() returns a mixer which will work with the given PortAudio
+ audio device.  Pass 0 as the index for the first (default) mixer.
+*/
+
+PxMixer *Px_OpenMixer( void *pa_stream, int i );
+
+/*
+ Px_CloseMixer() closes a mixer opened using Px_OpenMixer and frees any
+ memory associated with it. 
+*/
+
+void Px_CloseMixer(PxMixer *mixer);
+
+/*
+ Master (output) volume
+*/
+
+PxVolume Px_GetMasterVolume( PxMixer *mixer );
+void Px_SetMasterVolume( PxMixer *mixer, PxVolume volume );
+
+/*
+ Main output volume
+*/
+
+PxVolume Px_GetPCMOutputVolume( PxMixer *mixer );
+void Px_SetPCMOutputVolume( PxMixer *mixer, PxVolume volume );
+int Px_SupportsPCMOutputVolume( PxMixer* mixer ) ;
+
+/*
+ All output volumes
+*/
+
+int Px_GetNumOutputVolumes( PxMixer *mixer );
+const char *Px_GetOutputVolumeName( PxMixer *mixer, int i );
+PxVolume Px_GetOutputVolume( PxMixer *mixer, int i );
+void Px_SetOutputVolume( PxMixer *mixer, int i, PxVolume volume );
+
+/*
+ Input source
+*/
+
+int Px_GetNumInputSources( PxMixer *mixer );
+const char *Px_GetInputSourceName( PxMixer *mixer, int i);
+int Px_GetCurrentInputSource( PxMixer *mixer ); /* may return -1 == none */
+void Px_SetCurrentInputSource( PxMixer *mixer, int i );
+
+/*
+ Input volume
+*/
+
+PxVolume Px_GetInputVolume( PxMixer *mixer );
+void Px_SetInputVolume( PxMixer *mixer, PxVolume volume );
+
+/*
+  Balance
+*/
+
+int Px_SupportsOutputBalance( PxMixer *mixer );
+PxBalance Px_GetOutputBalance( PxMixer *mixer );
+void Px_SetOutputBalance( PxMixer *mixer, PxBalance balance );
+
+/*
+  Playthrough
+*/
+
+int Px_SupportsPlaythrough( PxMixer *mixer );
+PxVolume Px_GetPlaythrough( PxMixer *mixer );
+void Px_SetPlaythrough( PxMixer *mixer, PxVolume volume );
+
+/*
+  toggle microphone boost function
+*/
+
+/* returns 0 on success, 1 on failure, -1 if not available */
+int Px_SetMicrophoneBoost( PxMixer* mixer, int enable ) ;
+int Px_GetMicrophoneBoost( PxMixer* mixer ) ;
+
+/*
+  set input source by name
+*/
+
+/* returns 0 on sucess, 1 on failure */
+int Px_SetCurrentInputSourceByName( PxMixer* mixer, const char* line_name ) ;
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* PORT_AUDIO_H */
diff --git a/utils/iaxclient/lib/portmixer/px_mac/px_mac.c b/utils/iaxclient/lib/portmixer/px_mac/px_mac.c
new file mode 100755 (executable)
index 0000000..8d1f474
--- /dev/null
@@ -0,0 +1,406 @@
+/*
+ * PortMixer
+ * Mac OS 9 implementation
+ *
+ * Copyright (c) 2002
+ *
+ * Written by Dominic Mazzoni
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "portaudio.h"
+#include "pa_host.h"
+#include "portmixer.h"
+
+#define PA_MAX_NUM_HOST_BUFFERS           (16)   /* Do not exceed!! */
+
+typedef struct MultiBuffer
+{
+    char    *buffers[PA_MAX_NUM_HOST_BUFFERS];
+    int      numBuffers;
+    int      nextWrite;
+    int      nextRead;
+}
+MultiBuffer;
+
+/* Define structure to contain all Macintosh specific data. */
+typedef struct PaHostSoundControl
+{
+    UInt64                  pahsc_EntryCount;
+       double                  pahsc_InverseMicrosPerHostBuffer; /* 1/Microseconds of real-time audio per user buffer. */
+
+    /* Use char instead of Boolean for atomic operation. */
+    volatile char           pahsc_IsRecording;   /* Recording in progress. Set by foreground. Cleared by background. */
+    volatile char           pahsc_StopRecording; /* Signal sent to background. */
+    volatile char           pahsc_IfInsideCallback;
+    /* Input */
+    SPB                     pahsc_InputParams;
+    SICompletionUPP         pahsc_InputCompletionProc;
+    MultiBuffer             pahsc_InputMultiBuffer;
+    int32                   pahsc_BytesPerInputHostBuffer;
+    int32                   pahsc_InputRefNum;
+    /* Output */
+    CmpSoundHeader          pahsc_SoundHeaders[PA_MAX_NUM_HOST_BUFFERS];
+    int32                   pahsc_BytesPerOutputHostBuffer;
+    SndChannelPtr           pahsc_Channel;
+    SndCallBackUPP          pahsc_OutputCompletionProc;
+    int32                   pahsc_NumOutsQueued;
+    int32                   pahsc_NumOutsPlayed;
+    PaTimestamp             pahsc_NumFramesDone;
+    UInt64                  pahsc_WhenFramesDoneIncremented;
+    /* Init Time -------------- */
+    int32                   pahsc_NumHostBuffers;
+    int32                   pahsc_FramesPerHostBuffer;
+    int32                   pahsc_UserBuffersPerHostBuffer;
+    int32                   pahsc_MinFramesPerHostBuffer; /* Can vary depending on virtual memory usage. */
+}
+PaHostSoundControl;
+
+typedef struct PxSource
+{
+   char name[256];
+} PxSource;
+
+typedef struct PxInfo
+{
+   SPB           *input;
+   int32          inputRefNum;
+   SndChannelPtr  output;
+   int32          numSources;
+   PxSource      *sources;
+} PxInfo;
+
+int Px_GetNumMixers( void *pa_stream )
+{
+   return 0;
+}
+
+const char *Px_GetMixerName( void *pa_stream, int index )
+{
+   return "Mac Sound Manager";
+}
+
+PxMixer *Px_OpenMixer( void *pa_stream, int index )
+{
+   PxInfo                      *info;
+   internalPortAudioStream     *past;
+   PaHostSoundControl          *macInfo;
+   OSErr                        err;
+   int                          i, j;
+   Handle                       h;
+   unsigned char               *data;
+   
+   info = (PxInfo *)malloc(sizeof(PxInfo));   
+   past = (internalPortAudioStream *) pa_stream;
+   macInfo = (PaHostSoundControl *) past->past_DeviceData;
+
+   info->input = &macInfo->pahsc_InputParams;
+   info->inputRefNum = macInfo->pahsc_InputRefNum;
+   info->output = macInfo->pahsc_Channel;
+
+   info->numSources = 0;
+   info->sources = NULL;
+   
+   err = SPBGetDeviceInfo (info->inputRefNum, siInputSourceNames, &h);
+   if (err)
+      return (PxMixer *)info;
+   
+   HLock(h);
+   HNoPurge(h);
+   
+   data = (unsigned char *)*h;
+   info->numSources = ((short *)data)[0];
+   if (info->numSources <= 0 || info->numSources > 50) {
+      HUnlock(h);
+      return (PxMixer *)info;
+   }
+   
+   info->sources = (PxSource *)malloc(info->numSources * sizeof(PxSource));
+   data += 2;
+   for(i=0; i<info->numSources; i++) {
+      int len = *data++;
+      
+      if (len > 63) {
+         info->numSources = 0;
+         free(info->sources);
+         info->sources = NULL;
+         HUnlock(h);
+         return (PxMixer *)info;
+      }
+
+      for(j=0; j<len; j++)
+         info->sources[i].name[j] = *data++;
+
+      info->sources[i].name[len] = 0;
+   }
+   HUnlock(h);
+   
+   return (PxMixer *)info;
+}
+
+/*
+ Px_CloseMixer() closes a mixer opened using Px_OpenMixer and frees any
+ memory associated with it. 
+*/
+
+void Px_CloseMixer(PxMixer *mixer)
+{
+   PxInfo *info = (PxInfo *)mixer;
+   
+   if (info->sources)
+      free(info->sources);
+   free(info);
+}
+
+/*
+ Master (output) volume
+*/
+
+PxVolume Px_GetMasterVolume( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   return 0.0;
+}
+
+void Px_SetMasterVolume( PxMixer *mixer, PxVolume volume )
+{
+   PxInfo *info = (PxInfo *)mixer;
+}
+
+/*
+ PCM output volume
+*/
+
+int Px_SupportsPCMOutputVolume( PxMixer* mixer ) 
+{
+       return 1 ; 
+}
+
+PxVolume Px_GetPCMOutputVolume( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   OSErr err;
+   long packedVol;
+   SndCommand cmd;
+
+   cmd.cmd = getVolumeCmd;
+   cmd.param1 = 0;
+   cmd.param2 = (long)&packedVol;
+   
+   err = SndDoImmediate(info->output, &cmd);
+   if (err)
+      return 0.0;
+   
+   return ((packedVol & 0xFFFF) + ((packedVol & 0xFFFF0000) >> 16) / 2.0) / 256.0;
+}
+
+void Px_SetPCMOutputVolume( PxMixer *mixer, PxVolume volume )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   OSErr err;
+   long packedVol;
+   SndCommand cmd;
+
+   packedVol = (unsigned long)volume * 256.0;
+   packedVol += (packedVol << 16);
+   
+   cmd.cmd = volumeCmd;
+   cmd.param1 = 0;
+   cmd.param2 = packedVol;
+   err = SndDoImmediate(info->output, &cmd);
+}
+
+/*
+ All output volumes
+*/
+
+int Px_GetNumOutputVolumes( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   return 0;
+}
+
+const char *Px_GetOutputVolumeName( PxMixer *mixer, int i )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   
+   return NULL;
+}
+
+PxVolume Px_GetOutputVolume( PxMixer *mixer, int i )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   return NULL;
+}
+
+void Px_SetOutputVolume( PxMixer *mixer, int i, PxVolume volume )
+{
+   PxInfo *info = (PxInfo *)mixer;
+}
+
+/*
+ Input sources
+*/
+
+int Px_GetNumInputSources( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   
+   return info->numSources;
+}
+
+const char *Px_GetInputSourceName( PxMixer *mixer, int i)
+{
+   PxInfo *info = (PxInfo *)mixer;
+   
+   if (i >= 0 && i < info->numSources)
+      return info->sources[i].name;
+   else
+      return "";
+}
+
+int Px_GetCurrentInputSource( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   short selected;
+   OSErr err;
+
+   err = SPBGetDeviceInfo (info->inputRefNum, siInputSource, &selected);
+   if (err)
+      return 0;
+
+   return selected - 1;
+}
+
+void Px_SetCurrentInputSource( PxMixer *mixer, int i )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   short selected = i+1;
+   OSErr err;
+   
+   err = SPBSetDeviceInfo (info->inputRefNum, siInputSource, &selected);
+}
+
+/*
+ Input volume
+*/
+
+PxVolume Px_GetInputVolume( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   Fixed fixedGain;
+   PxVolume vol;
+   OSErr err;
+   
+   if (info->input) {
+      err = SPBGetDeviceInfo(info->inputRefNum, siInputGain, (Ptr)&fixedGain);
+      if (err)
+         return 0.0;
+      
+      vol = (fixedGain / 65536.0) - 0.5;
+      return vol;
+   }
+
+   return 0.0;
+}
+
+void Px_SetInputVolume( PxMixer *mixer, PxVolume volume )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   Fixed fixedGain;
+   OSErr err;
+   
+   if (info->input) {
+      fixedGain = (Fixed)((volume + 0.5) * 65536.0);
+      err = SPBSetDeviceInfo(info->inputRefNum, siInputGain, (Ptr)&fixedGain);
+   }
+}
+
+/*
+  Balance
+*/
+
+int Px_SupportsOutputBalance( PxMixer *mixer )
+{
+   return 0;
+}
+
+PxBalance Px_GetOutputBalance( PxMixer *mixer )
+{
+   return 0.0;
+}
+
+void Px_SetOutputBalance( PxMixer *mixer, PxBalance balance )
+{
+}
+
+/*
+  Playthrough
+*/
+
+int Px_SupportsPlaythrough( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   return (info->input != NULL);
+}
+
+PxVolume Px_GetPlaythrough( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   OSErr err;
+   short level;
+
+   err = SPBGetDeviceInfo(info->inputRefNum, siPlayThruOnOff, (Ptr)&level);
+   if (err)
+      return 0.0;
+
+   if (level < 0)
+      level = 0;
+   if (level > 7)
+      level = 7;
+   
+   return (PxVolume)(level / 7.0);
+}
+
+void Px_SetPlaythrough( PxMixer *mixer, PxVolume volume )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   OSErr err;
+   short level = (int)(volume * 7.0 + 0.5);
+
+   err = SPBSetDeviceInfo(info->inputRefNum, siPlayThruOnOff, (Ptr)&level);
+}
diff --git a/utils/iaxclient/lib/portmixer/px_mac_core/px_mac_core.c b/utils/iaxclient/lib/portmixer/px_mac_core/px_mac_core.c
new file mode 100755 (executable)
index 0000000..402f670
--- /dev/null
@@ -0,0 +1,349 @@
+/*
+ * PortMixer
+ * Mac OS X / CoreAudio implementation
+ *
+ * Copyright (c) 2002
+ *
+ * Written by Dominic Mazzoni
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <CoreServices/CoreServices.h>
+#include <CoreAudio/CoreAudio.h>
+#include <AudioToolbox/AudioConverter.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <portaudio.h>
+#if 0
+#include <pa_mac_core.h>
+#else
+/* TODO: Fix this when portaudio gets their hostapi-specific stuff
+ * straightened up.
+ */
+#include <AudioUnit/AudioUnit.h>
+AudioDeviceID PaMacCore_GetStreamInputDevice( PaStream* s );
+AudioDeviceID PaMacCore_GetStreamOutputDevice( PaStream* s );
+#endif
+
+#include "portmixer.h"
+
+// define value of isInput passed to CoreAudio routines
+#define IS_INPUT    (true)
+#define IS_OUTPUT   (false)
+
+typedef struct PxInfo
+{
+   AudioDeviceID   input;
+   AudioDeviceID   output;
+} PxInfo;
+
+int Px_GetNumMixers( void *pa_stream )
+{
+   return 1;
+}
+
+const char *Px_GetMixerName( void *pa_stream, int index )
+{
+   return "CoreAudio";
+}
+
+PxMixer *Px_OpenMixer( void *pa_stream, int index )
+{
+   PxInfo                      *info;
+   
+   info = (PxInfo *)malloc(sizeof(PxInfo));   
+   if (!info) {
+      return (PxMixer *)info;
+   }
+
+   info->input = PaMacCore_GetStreamInputDevice(pa_stream);
+   info->output = PaMacCore_GetStreamOutputDevice(pa_stream);
+
+   return (PxMixer *)info;
+}
+
+/*
+ Px_CloseMixer() closes a mixer opened using Px_OpenMixer and frees any
+ memory associated with it. 
+*/
+
+void Px_CloseMixer(PxMixer *mixer)
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   free(info);
+}
+
+/*
+ Master (output) volume
+*/
+
+PxVolume Px_GetMasterVolume( PxMixer *mixer )
+{
+   return 0.0;
+}
+
+void Px_SetMasterVolume( PxMixer *mixer, PxVolume volume )
+{
+}
+
+/*
+ PCM output volume
+*/
+
+static PxVolume Px_GetVolume(AudioDeviceID device, Boolean isInput)
+{
+   OSStatus err;
+   UInt32   outSize;
+   Float32  vol, maxvol=0.0;
+   UInt32   mute, anymuted=0;
+   int ch;
+
+   for(ch=0; ch<=2; ch++) {
+      outSize = sizeof(Float32);
+      err = AudioDeviceGetProperty(device, ch, isInput,
+                                   kAudioDevicePropertyVolumeScalar,
+                                   &outSize, &vol);
+      if (!err) {
+         if (vol > maxvol)
+            maxvol = vol;
+      }
+
+      outSize = sizeof(UInt32);
+      err = AudioDeviceGetProperty(device, ch, isInput,
+                                   kAudioDevicePropertyMute,
+                                   &outSize, &mute);
+
+      if (!err) {
+         if (mute)
+            anymuted = 1;
+      }
+   }
+
+   if (anymuted)
+      maxvol = 0.0;
+
+   return maxvol;
+}
+
+static void Px_SetVolume(AudioDeviceID device, Boolean isInput,
+                         PxVolume volume)
+{
+   Float32  vol = volume;
+   UInt32 mute = 0;
+   int ch;
+   OSStatus err;
+
+   /* Implement a passive attitude towards muting.  If they
+      drag the volume above 0.05, unmute it.  But if they
+      drag the volume down below that, just set the volume,
+      don't actually mute.
+   */
+
+   for(ch=0; ch<=2; ch++) {
+      err =  AudioDeviceSetProperty(device, 0, ch, isInput,
+                                    kAudioDevicePropertyVolumeScalar,
+                                    sizeof(Float32), &vol);
+      if (vol > 0.05) {
+         err =  AudioDeviceSetProperty(device, 0, ch, isInput,
+                                       kAudioDevicePropertyMute,
+                                       sizeof(UInt32), &mute);
+      }
+   }
+}
+
+int Px_SupportsPCMOutputVolume( PxMixer* mixer ) 
+{
+       return 1 ;
+}
+
+PxVolume Px_GetPCMOutputVolume( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   return Px_GetVolume(info->output, IS_OUTPUT);
+}
+
+void Px_SetPCMOutputVolume( PxMixer *mixer, PxVolume volume )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   Px_SetVolume(info->output, IS_OUTPUT, volume);
+}
+
+/*
+ All output volumes
+*/
+
+int Px_GetNumOutputVolumes( PxMixer *mixer )
+{
+   return 1;
+}
+
+const char *Px_GetOutputVolumeName( PxMixer *mixer, int i )
+{
+   if (i == 0)
+      return "PCM";
+   else
+      return "";
+}
+
+PxVolume Px_GetOutputVolume( PxMixer *mixer, int i )
+{
+   return Px_GetPCMOutputVolume(mixer);
+}
+
+void Px_SetOutputVolume( PxMixer *mixer, int i, PxVolume volume )
+{
+   Px_SetPCMOutputVolume(mixer, volume);
+}
+
+/*
+ Input sources
+*/
+
+int Px_GetNumInputSources( PxMixer *mixer )
+{
+   return 1 ;
+}
+
+const char *Px_GetInputSourceName( PxMixer *mixer, int i)
+{
+   return "Default Input Source" ;
+}
+
+int Px_GetCurrentInputSource( PxMixer *mixer )
+{
+   return -1; /* none */
+}
+
+void Px_SetCurrentInputSource( PxMixer *mixer, int i )
+{
+}
+
+/*
+ Input volume
+*/
+
+PxVolume Px_GetInputVolume( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   return Px_GetVolume(info->input, IS_INPUT);
+}
+
+void Px_SetInputVolume( PxMixer *mixer, PxVolume volume )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   Px_SetVolume(info->input, IS_INPUT, volume);
+}
+
+/*
+  Balance
+*/
+
+int Px_SupportsOutputBalance( PxMixer *mixer )
+{
+   return 0;
+}
+
+PxBalance Px_GetOutputBalance( PxMixer *mixer )
+{
+   return 0.0;
+}
+
+void Px_SetOutputBalance( PxMixer *mixer, PxBalance balance )
+{
+}
+
+/*
+  Playthrough
+*/
+
+int Px_SupportsPlaythrough( PxMixer *mixer )
+{
+   return 1;
+}
+
+PxVolume Px_GetPlaythrough( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   OSStatus err;
+   UInt32   outSize;
+   UInt32   flag;
+
+   outSize = sizeof(UInt32);
+   err =  AudioDeviceGetProperty(info->output, 0, IS_OUTPUT,
+                                 kAudioDevicePropertyPlayThru,
+                                 &outSize, &flag);
+   if (err)
+      return 0.0;
+   if (flag)
+      return 1.0;
+   else
+      return 0.0;
+}
+
+void Px_SetPlaythrough( PxMixer *mixer, PxVolume volume )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   UInt32 flag = (volume > 0.01);
+   OSStatus err;
+
+   err =  AudioDeviceSetProperty(info->output, 0, 0, IS_OUTPUT,
+                                 kAudioDevicePropertyPlayThru,
+                                 sizeof(UInt32), &flag);
+}
+
+/*
+  unimplemented stubs
+*/
+
+int Px_SetMicrophoneBoost( PxMixer* mixer, int enable )
+{
+       return 1 ;
+}
+
+int Px_GetMicrophoneBoost( PxMixer* mixer )
+{
+       return -1 ;
+}
+
+int Px_SetCurrentInputSourceByName( PxMixer* mixer, const char* line_name )
+{
+       return 1 ;
+}
+
+
diff --git a/utils/iaxclient/lib/portmixer/px_none/px_none.c b/utils/iaxclient/lib/portmixer/px_none/px_none.c
new file mode 100755 (executable)
index 0000000..f2a48b0
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * PortMixer
+ * Empty implementation (as a placeholder on platforms where
+ * it hasn't been implemented yet)
+ *
+ * Copyright (c) 2002
+ *
+ * Written by Dominic Mazzoni
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <stdlib.h>
+
+#include "portaudio.h"
+#include "portmixer.h"
+
+typedef struct PxInfo
+{
+  int dummy;
+} PxInfo;
+
+int Px_GetNumMixers( void *pa_stream )
+{
+   return 0;
+}
+
+const char *Px_GetMixerName( void *pa_stream, int index )
+{
+   return NULL;
+}
+
+PxMixer *Px_OpenMixer( void *pa_stream, int index )
+{
+   return NULL;
+}
+
+/*
+ Px_CloseMixer() closes a mixer opened using Px_OpenMixer and frees any
+ memory associated with it. 
+*/
+
+void Px_CloseMixer(PxMixer *mixer)
+{
+}
+
+/*
+ Master (output) volume
+*/
+
+PxVolume Px_GetMasterVolume( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   return 0.0;
+}
+
+void Px_SetMasterVolume( PxMixer *mixer, PxVolume volume )
+{
+   PxInfo *info = (PxInfo *)mixer;
+}
+
+/*
+ PCM output volume
+*/
+
+PxVolume Px_GetPCMOutputVolume( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   return 0.0;
+}
+
+void Px_SetPCMOutputVolume( PxMixer *mixer, PxVolume volume )
+{
+   PxInfo *info = (PxInfo *)mixer;
+}
+
+/*
+ All output volumes
+*/
+
+int Px_GetNumOutputVolumes( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   return 0;
+}
+
+const char *Px_GetOutputVolumeName( PxMixer *mixer, int i )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   
+   return NULL;
+}
+
+PxVolume Px_GetOutputVolume( PxMixer *mixer, int i )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   return NULL;
+}
+
+void Px_SetOutputVolume( PxMixer *mixer, int i, PxVolume volume )
+{
+   PxInfo *info = (PxInfo *)mixer;
+}
+
+/*
+ Input sources
+*/
+
+int Px_GetNumInputSources( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   return 0;
+}
+
+const char *Px_GetInputSourceName( PxMixer *mixer, int i)
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   return NULL;
+}
+
+int Px_GetCurrentInputSource( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   return -1; /* none */
+}
+
+void Px_SetCurrentInputSource( PxMixer *mixer, int i )
+{
+   PxInfo *info = (PxInfo *)mixer;
+}
+
+/*
+ Input volume
+*/
+
+PxVolume Px_GetInputVolume( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   return 0.0;
+}
+
+void Px_SetInputVolume( PxMixer *mixer, PxVolume volume )
+{
+   PxInfo *info = (PxInfo *)mixer;
+}
+
+/*
+  Balance
+*/
+
+int Px_SupportsOutputBalance( PxMixer *mixer )
+{
+   return 0;
+}
+
+PxBalance Px_GetOutputBalance( PxMixer *mixer )
+{
+   return 0.0;
+}
+
+void Px_SetOutputBalance( PxMixer *mixer, PxBalance balance )
+{
+}
+
+/*
+  Playthrough
+*/
+
+int Px_SupportsPlaythrough( PxMixer *mixer )
+{
+   return 0;
+}
+
+PxBalance Px_GetPlaythrough( PxMixer *mixer )
+{
+   return 0.0;
+}
+
+void Px_SetPlaythrough( PxMixer *mixer, PxBalance balance )
+{
+}
+
diff --git a/utils/iaxclient/lib/portmixer/px_tests/px_test.c b/utils/iaxclient/lib/portmixer/px_tests/px_test.c
new file mode 100755 (executable)
index 0000000..ec391e9
--- /dev/null
@@ -0,0 +1,103 @@
+#include <stdio.h>
+
+#include "portmixer.h"
+#include "portaudio.h"
+
+static int DummyCallbackFunc(const void *inputBuffer, 
+                            void *outputBuffer,
+                             unsigned long framesPerBuffer,
+                            const PaStreamCallbackTimeInfo* timeInfo,
+                            PaStreamCallbackFlags statusFlags,
+                            void *userData )
+{
+   return 0;
+}
+#define NUM_CHANNELS    (2)
+#define PA_SAMPLE_TYPE  paFloat32
+#define SAMPLE_RATE         (44100)
+#define FRAMES_PER_BUFFER   (1024)
+
+int main(int argc, char **argv)
+{
+   int num_mixers;
+   int i;
+   PaError          error;
+   PaStream*       stream;
+   PaStreamParameters inputParameters;
+   PaStreamParameters outputParameters;
+
+   error = Pa_Initialize();
+   if ( error != paNoError ) {
+      printf("PortAudio error %d: %s\n", error, Pa_GetErrorText(error));
+      return -1;
+   }
+   inputParameters.device = Pa_GetDefaultInputDevice();
+   inputParameters.channelCount = NUM_CHANNELS;
+   inputParameters.sampleFormat = PA_SAMPLE_TYPE;
+   inputParameters.suggestedLatency = 
+       Pa_GetDeviceInfo(inputParameters.device )->defaultLowInputLatency;
+   inputParameters.hostApiSpecificStreamInfo = NULL;
+
+   outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */
+   outputParameters.channelCount = 2;       /* stereo output */
+   outputParameters.sampleFormat = paFloat32; /* 32 bit floating point output */
+   outputParameters.suggestedLatency = 
+       Pa_GetDeviceInfo( outputParameters.device )->defaultLowOutputLatency;
+   outputParameters.hostApiSpecificStreamInfo = NULL;
+
+
+
+   error = Pa_OpenStream(&stream, &inputParameters, &outputParameters, 
+                        SAMPLE_RATE,FRAMES_PER_BUFFER,
+                         paClipOff | paDitherOff,
+                         DummyCallbackFunc, NULL);
+
+   if (error) {
+      printf("PortAudio error %d: %s\n", error, Pa_GetErrorText(error));
+      return -1;
+   }
+   
+   num_mixers = Px_GetNumMixers(stream);
+   printf("Number of mixers: %d\n", num_mixers);
+   for(i=0; i<num_mixers; i++) {
+      PxMixer *mixer;
+      int num;
+      int j;
+
+      printf("Mixer %d: %s\n", i, Px_GetMixerName(stream, i));
+      mixer = Px_OpenMixer(stream, i);
+      if (!mixer) {
+         printf("  Could not open mixer!\n");
+         continue;
+      }
+      
+      printf("  Master volume: %.2f\n", Px_GetMasterVolume(mixer));
+      printf("  PCM output volume: %.2f\n", Px_GetPCMOutputVolume(mixer));
+
+      num = Px_GetNumOutputVolumes(mixer);
+      printf("  Num outputs: %d\n", num);
+      for(j=0; j<num; j++) {
+         printf("    Output %d (%s): %.2f\n",
+                j,
+                Px_GetOutputVolumeName(mixer, j),
+                Px_GetOutputVolume(mixer, j));
+      }
+
+      num = Px_GetNumInputSources(mixer);
+      printf("  Num input sources: %d\n", num);
+      for(j=0; j<num; j++) {
+         printf("    Input %d (%s) %s\n",
+                j,
+                Px_GetInputSourceName(mixer, j),
+                (Px_GetCurrentInputSource(mixer)==j?
+                 "SELECTED": ""));
+      }
+      printf("  Input volume: %.2f\n", Px_GetInputVolume(mixer));
+
+      Px_CloseMixer(mixer);
+   }
+
+   Pa_CloseStream(stream);
+
+   return 0;
+}
diff --git a/utils/iaxclient/lib/portmixer/px_unix_oss/px_unix_oss.c b/utils/iaxclient/lib/portmixer/px_unix_oss/px_unix_oss.c
new file mode 100755 (executable)
index 0000000..38ace3a
--- /dev/null
@@ -0,0 +1,404 @@
+/*
+ * PortMixer
+ * Unix OSS Implementation
+ *
+ * Copyright (c) 2002
+ *
+ * Written by Dominic Mazzoni
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#if defined(__linux__)
+#include <linux/soundcard.h>
+#elif defined(__FreeBSD__)
+#include <sys/soundcard.h>
+#else
+#include <machine/soundcard.h> /* JH20010905 */
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include "portaudio.h"
+#include "portmixer.h"
+
+typedef struct PxInfo
+{
+   int index;
+   int fd;
+
+   int num_out;
+   int outs[SOUND_MIXER_NRDEVICES];
+   int num_rec;
+   int recs[SOUND_MIXER_NRDEVICES];
+} PxInfo;
+
+char PxDevice[20] = "/dev/mixerX";
+
+int PxNumDevices = 0;
+int PxDevices[10];
+
+int Px_GetNumMixers( void *pa_stream )
+{
+   int i;
+   int fd;
+
+   PxNumDevices = 0;
+
+   for(i=0; i<11; i++) {
+      if (i==0)
+         PxDevice[10] = 0;
+      else
+         PxDevice[10] = '0'+(i-1);
+      fd = open(PxDevice, O_RDWR);
+      if (fd >= 0) {
+         PxDevices[PxNumDevices] = i;
+         PxNumDevices++;
+         close(fd);
+      }
+   }
+
+   return PxNumDevices;
+}
+
+const char *Px_GetMixerName( void *pa_stream, int index )
+{
+   if (PxNumDevices <= 0)
+      Px_GetNumMixers(pa_stream);
+
+   if (index < 0 || index >= PxNumDevices)
+      return NULL;
+
+   if (PxDevices[index]==0)
+      PxDevice[10] = 0;
+   else
+      PxDevice[10] = '0'+(PxDevices[index]-1);
+   return PxDevice;
+}
+
+PxMixer *Px_OpenMixer( void *pa_stream, int index )
+{
+   PxInfo *info;
+   int devmask, recmask, outmask;
+   int i;
+
+   if (PxNumDevices <= 0)
+      Px_GetNumMixers(pa_stream);
+
+   if (index < 0 || index >= PxNumDevices)
+      return NULL;
+
+   info = (PxInfo *)malloc(sizeof(PxInfo));
+   info->index = PxDevice[index];
+
+   if (PxDevices[index]==0)
+      PxDevice[10] = 0;
+   else
+      PxDevice[10] = '0'+(PxDevices[index]-1);
+   info->fd = open(PxDevice, O_RDWR);
+   if (info->fd < 0)
+      goto bad;
+
+   if (ioctl(info->fd, MIXER_READ(SOUND_MIXER_READ_DEVMASK),
+             &devmask) == -1)
+      goto bad;
+   if (ioctl(info->fd, MIXER_READ(SOUND_MIXER_READ_RECMASK),
+             &recmask) == -1)
+      goto bad;
+   outmask = devmask ^ recmask;
+
+   info->num_out = 0;
+   info->num_rec = 0;
+
+   for(i=0; i<SOUND_MIXER_NRDEVICES; i++)
+      if (recmask & (1<<i))
+         info->recs[info->num_rec++] = i;
+      else if (devmask & (1<<i))
+         info->outs[info->num_out++] = i;
+
+   return (PxMixer *)info;
+
+ bad:
+   free(info);
+   return NULL;
+}
+
+/*
+ Px_CloseMixer() closes a mixer opened using Px_OpenMixer and frees any
+ memory associated with it. 
+*/
+
+void Px_CloseMixer(PxMixer *mixer)
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   close(info->fd);
+
+   free(info);
+}
+
+PxVolume GetVolume(int fd, int channel)
+{
+   int vol;
+   int stereo;
+
+   if (ioctl(fd, SOUND_MIXER_READ_STEREODEVS, &stereo) == 0)
+      stereo = ((stereo & (1 << channel)) != 0);
+   else
+      stereo = 0;
+   
+   if (ioctl(fd, MIXER_READ(channel), &vol) == -1)
+      return 0.0;
+
+   if (stereo)
+      return ((vol & 0xFF)/200.0) + (((vol>>8) & 0xFF)/200.0);
+   else
+      return (vol & 0xFF)/100.0;
+}
+
+/*
+ Master (output) volume
+*/
+
+PxVolume Px_GetMasterVolume( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   return GetVolume(info->fd, SOUND_MIXER_VOLUME);
+}
+
+void Px_SetMasterVolume( PxMixer *mixer, PxVolume volume )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   int vol = (int)((volume * 100.0) + 0.5);
+   vol = (vol | (vol<<8));
+   ioctl(info->fd, MIXER_WRITE(SOUND_MIXER_VOLUME), &vol);
+}
+
+/*
+ PCM output volume
+*/
+
+int Px_SupportsPCMOutputVolume( PxMixer* mixer ) 
+{
+       return 1 ;
+}
+
+PxVolume Px_GetPCMOutputVolume( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   return GetVolume(info->fd, SOUND_MIXER_PCM);
+}
+
+void Px_SetPCMOutputVolume( PxMixer *mixer, PxVolume volume )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   int vol = (int)((volume * 100.0) + 0.5);
+   vol = (vol | (vol<<8));
+   ioctl(info->fd, MIXER_WRITE(SOUND_MIXER_PCM), &vol);
+}
+
+/*
+ All output volumes
+*/
+
+int Px_GetNumOutputVolumes( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   return info->num_out;
+}
+
+const char *Px_GetOutputVolumeName( PxMixer *mixer, int i )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   const char *labels[] = SOUND_DEVICE_LABELS;
+
+   return labels[info->outs[i]];
+}
+
+PxVolume Px_GetOutputVolume( PxMixer *mixer, int i )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   return GetVolume(info->fd, info->outs[i]);
+}
+
+void Px_SetOutputVolume( PxMixer *mixer, int i, PxVolume volume )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   int vol = (int)((volume * 100.0) + 0.5);
+   vol = (vol | (vol<<8));
+   ioctl(info->fd, MIXER_WRITE(info->outs[i]), &vol);
+}
+
+/*
+ Input sources
+*/
+
+int Px_GetNumInputSources( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   
+   return info->num_rec;
+}
+
+const char *Px_GetInputSourceName( PxMixer *mixer, int i)
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   const char *labels[] = SOUND_DEVICE_LABELS;
+   return labels[info->recs[i]];
+}
+
+int Px_GetCurrentInputSource( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   int recmask;
+   int i;
+
+   /* Note that there may be more than one in OSS; we pick
+      the first one */
+
+   if (ioctl(info->fd, MIXER_READ(SOUND_MIXER_READ_RECSRC),
+             &recmask) == -1)
+      return -1; /* none / error */
+
+   for(i=0; i<info->num_rec; i++)
+      if (recmask & (1 << (info->recs[i])))
+         return i;
+
+   return -1; /* none */
+}
+
+void Px_SetCurrentInputSource( PxMixer *mixer, int i )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   int newrecsrcmask = (1 << (info->recs[i]));
+
+   ioctl(info->fd, MIXER_WRITE(SOUND_MIXER_READ_RECSRC),
+         &newrecsrcmask);
+}
+
+/*
+ Input volume
+*/
+
+PxVolume Px_GetInputVolume( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   int i;
+   
+   i = Px_GetCurrentInputSource(mixer);
+   if (i < 0)
+      return 0.0;
+
+   return GetVolume(info->fd, info->recs[i]);
+}
+
+void Px_SetInputVolume( PxMixer *mixer, PxVolume volume )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   int vol;
+   int i;
+
+   i = Px_GetCurrentInputSource(mixer);
+   if (i < 0)
+      return;
+
+   vol = (int)((volume * 100.0) + 0.5);
+   vol = (vol | (vol<<8));
+   ioctl(info->fd, MIXER_WRITE(info->recs[i]), &vol);
+}
+
+/*
+  Balance
+*/
+
+int Px_SupportsOutputBalance( PxMixer *mixer )
+{
+   return 0;
+}
+
+PxBalance Px_GetOutputBalance( PxMixer *mixer )
+{
+   return 0.0;
+}
+
+void Px_SetOutputBalance( PxMixer *mixer, PxBalance balance )
+{
+}
+
+/*
+  Playthrough
+*/
+
+int Px_SupportsPlaythrough( PxMixer *mixer )
+{
+   return 0;
+}
+
+PxVolume Px_GetPlaythrough( PxMixer *mixer )
+{
+   return 0.0;
+}
+
+void Px_SetPlaythrough( PxMixer *mixer, PxVolume volume )
+{
+}
+
+
+/*
+  unimplemented stubs
+*/
+
+int Px_SetMicrophoneBoost( PxMixer* mixer, int enable )
+{
+       return 1 ;
+}
+
+int Px_GetMicrophoneBoost( PxMixer* mixer )
+{
+       return -1 ;
+}
+
+int Px_SetCurrentInputSourceByName( PxMixer* mixer, const char* line_name )
+{
+       return 1 ;
+}
diff --git a/utils/iaxclient/lib/portmixer/px_win_wmme/px_win_wmme.c b/utils/iaxclient/lib/portmixer/px_win_wmme/px_win_wmme.c
new file mode 100755 (executable)
index 0000000..4705476
--- /dev/null
@@ -0,0 +1,983 @@
+/*
+ * PortMixer
+ * Windows WMME Implementation
+ *
+ * Copyright (c) 2002
+ *
+ * Written by Dominic Mazzoni and Augustus Saunders
+ *
+ * PortMixer is intended to work side-by-side with PortAudio,
+ * the Portable Real-Time Audio Library by Ross Bencina and
+ * Phil Burk.
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * 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 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+ * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#if defined(WIN32) || defined(_WIN32_WCE)
+#include <stdlib.h>
+#define strcasecmp _stricmp
+#define strncasecmp _strnicmp
+#else
+#include <strings.h>
+#endif
+
+#include <windows.h>
+
+#include "portaudio.h"
+#include "portmixer.h"
+
+#include "pa_cpuload.h"
+#include "pa_process.h"
+#include "pa_stream.h"
+
+typedef struct
+{
+    HANDLE bufferEvent;
+    void *waveHandles;
+    unsigned int deviceCount;
+    /* unsigned int channelCount; */
+    WAVEHDR **waveHeaders;                  /* waveHeaders[device][buffer] */
+    unsigned int bufferCount;
+    unsigned int currentBufferIndex;
+    unsigned int framesPerBuffer;
+    unsigned int framesUsedInCurrentBuffer;
+}PaWinMmeSingleDirectionHandlesAndBuffers;
+
+/* PaWinMmeStream - a stream data structure specifically for this implementation */
+/* note that struct PaWinMmeStream is typedeffed to PaWinMmeStream above. */
+struct PaWinMmeStream
+{
+    PaUtilStreamRepresentation streamRepresentation;
+    PaUtilCpuLoadMeasurer cpuLoadMeasurer;
+    PaUtilBufferProcessor bufferProcessor;
+
+    int primeStreamUsingCallback;
+
+    PaWinMmeSingleDirectionHandlesAndBuffers input;
+    PaWinMmeSingleDirectionHandlesAndBuffers output;
+
+    /* Processing thread management -------------- */
+    HANDLE abortEvent;
+    HANDLE processingThread;
+    DWORD processingThreadId;
+
+    char throttleProcessingThreadOnOverload; /* 0 -> don't throtte, non-0 -> throttle */
+    int processingThreadPriority;
+    int highThreadPriority;
+    int throttledThreadPriority;
+    unsigned long throttledSleepMsecs;
+
+    int isStopped;
+    volatile int isActive;
+    volatile int stopProcessing; /* stop thread once existing buffers have been returned */
+    volatile int abortProcessing; /* stop thread immediately */
+
+    DWORD allBuffersDurationMs; /* used to calculate timeouts */
+};
+
+typedef struct PxSrcInfo
+{
+   char  name[256];
+   DWORD lineID;
+   DWORD controlID;
+} PxSrcInfo;
+
+typedef struct PxInfo
+{
+   HMIXEROBJ   hInputMixer;
+   HMIXEROBJ   hOutputMixer;
+   int         numInputs;
+   PxSrcInfo   src[32];
+   DWORD       muxID;
+   DWORD       speakerID;
+   DWORD       waveID;
+} PxInfo;
+
+int Px_GetNumMixers( void *pa_stream )
+{
+   return 1;
+}
+
+const char *Px_GetMixerName( void *pa_stream, int index )
+{
+   return "Mixer";
+}
+
+PxMixer *Px_OpenMixer( void *pa_stream, int index )
+{
+   struct PaWinMmeStream *past;
+   HWAVEIN hWaveIn;
+   HWAVEOUT hWaveOut;
+   PxInfo *mixer;
+   MMRESULT result;
+
+   if (!pa_stream)
+      return NULL;
+
+   mixer = (PxInfo *)malloc(sizeof(PxInfo));
+   mixer->hInputMixer = NULL;
+   mixer->hOutputMixer = NULL;
+
+   past = (struct PaWinMmeStream *) pa_stream;
+
+   hWaveIn = 0;
+   if (past->input.waveHandles) {
+      hWaveIn = ((HWAVEIN *)past->input.waveHandles)[0];
+   }
+
+   hWaveOut = 0;
+   if (past->output.waveHandles) {
+      hWaveOut = ((HWAVEOUT *)past->output.waveHandles)[0];
+   }
+
+   if (hWaveIn) {
+      result = mixerOpen((HMIXER *)&mixer->hInputMixer, (UINT)hWaveIn, 0, 0, MIXER_OBJECTF_HWAVEIN);
+      if (result != MMSYSERR_NOERROR) {
+         free(mixer);
+         return NULL;
+      }
+   }
+
+   if (hWaveOut) {
+      result = mixerOpen((HMIXER *)&mixer->hOutputMixer, (UINT)hWaveOut, 0, 0, MIXER_OBJECTF_HWAVEOUT);
+      if (result != MMSYSERR_NOERROR) {
+         free(mixer);
+         return NULL;
+      }
+   }
+
+   mixer->numInputs = 0;
+   mixer->muxID = -1;
+
+   if (mixer->hInputMixer)
+   {
+      MIXERLINE line;
+      line.cbStruct = sizeof(MIXERLINE);
+      line.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
+
+      result = mixerGetLineInfo(mixer->hInputMixer,
+                                &line,
+                                MIXER_GETLINEINFOF_COMPONENTTYPE);
+      if (result == MMSYSERR_NOERROR)
+      {
+         /* if the WaveInDestination has an InputSelectorControl (Mux or Mixer)
+          * get the names and IDs of all of the input sources
+          * make sure the name of the MicrophoneSource (if there is one)
+          * is "microphone" since pa_start() checks for it
+          */
+
+         MIXERLINECONTROLS controls;
+         MIXERCONTROL control;
+
+         controls.cbStruct = sizeof(MIXERLINECONTROLS);
+         controls.cbmxctrl = sizeof(MIXERCONTROL);
+         controls.pamxctrl = &control;
+
+         control.cbStruct = sizeof(MIXERCONTROL);
+
+         controls.dwLineID = line.dwLineID;
+         controls.dwControlType = MIXERCONTROL_CONTROLTYPE_MUX;
+         result = mixerGetLineControls(mixer->hInputMixer,
+                                       &controls,
+                                       MIXER_GETLINECONTROLSF_ONEBYTYPE);
+
+         if (result != MMSYSERR_NOERROR)
+         {
+            controls.dwControlType = MIXERCONTROL_CONTROLTYPE_MIXER;
+            result = mixerGetLineControls(mixer->hInputMixer,
+                                          &controls,
+                                          MIXER_GETLINECONTROLSF_ONEBYTYPE);
+         }
+
+         if (result == MMSYSERR_NOERROR)
+         {
+            int j;
+            int exactMic = -1;
+            int startMic = -1;
+            int firstMic = -1;
+            MIXERCONTROLDETAILS details;
+            MIXERCONTROLDETAILS_LISTTEXT mixList[32];
+
+            mixer->numInputs = control.cMultipleItems;
+            mixer->muxID = control.dwControlID;
+
+            details.cbStruct = sizeof(MIXERCONTROLDETAILS);
+            details.dwControlID = mixer->muxID;
+            details.cChannels = 1;
+            details.cbDetails = sizeof(MIXERCONTROLDETAILS_LISTTEXT);
+            details.paDetails = (LPMIXERCONTROLDETAILS_LISTTEXT)&mixList[0];
+            details.cMultipleItems = mixer->numInputs;
+
+            controls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
+            result = mixerGetControlDetails(mixer->hInputMixer,
+                                            (LPMIXERCONTROLDETAILS)&details,
+                                            MIXER_GETCONTROLDETAILSF_LISTTEXT);
+
+            if (result != MMSYSERR_NOERROR)
+               mixer->numInputs = 0;
+
+            for (j=0; j < mixer->numInputs; j++)
+            {
+               mixer->src[j].lineID = mixList[j].dwParam1;
+
+               controls.dwLineID = mixer->src[j].lineID;
+               result = mixerGetLineControls(mixer->hInputMixer,
+                     &controls,
+                     MIXER_GETLINECONTROLSF_ONEBYTYPE);
+               if (result == MMSYSERR_NOERROR)
+               {
+                  /* mark as volume control */
+                  mixer->src[j].controlID = control.dwControlID;
+               }
+               else
+               {
+                  /* mark as NOT volume control */
+                  mixer->src[j].controlID = 0;
+               }
+
+               line.dwLineID = mixer->src[j].lineID;
+
+               result = mixerGetLineInfo(mixer->hInputMixer, &line, MIXER_GETLINEINFOF_LINEID);
+               if (result == MMSYSERR_NOERROR &&
+                     line.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE)
+               {
+                  if (exactMic == -1)
+                  {
+                     if (strcasecmp(mixList[j].szName, "microphone") == 0)
+                     {
+                        exactMic = j;
+                     }
+                     else if (startMic == -1)
+                     {
+                        if (strncasecmp(mixList[j].szName, "microphone",
+                                 strlen("microphone")) == 0)
+                        {
+                           startMic = j;
+                        }
+                        else if (firstMic == -1)
+                        {
+                           firstMic = j;
+                        }
+                     }
+                  }
+               }
+               strcpy(mixer->src[j].name, mixList[j].szName);
+            }
+
+            if (exactMic == -1)
+            {
+               if (startMic != -1)
+               {
+                  strcpy(mixer->src[startMic].name, "microphone");
+               }
+               else if (firstMic != -1)
+               {
+                       strcpy(mixer->src[firstMic].name, "microphone");
+               }
+            }
+         }
+         else
+         {
+            /* if the WaveInDestination does not have an InputSelector
+             * see if the WaveInDestination SourceLine has a VolumeControl
+             */
+            controls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
+            result = mixerGetLineControls(mixer->hInputMixer,
+                                          &controls,
+                                          MIXER_GETLINECONTROLSF_ONEBYTYPE);
+            if (result == MMSYSERR_NOERROR)
+            {
+               mixer->src[0].lineID = line.dwLineID;
+               strcpy(mixer->src[0].name, line.szName);
+               mixer->src[0].controlID = control.dwControlID;
+               mixer->numInputs = 1;
+            }
+            else
+            {
+               line.dwSource = 0;
+               result = mixerGetLineInfo(mixer->hInputMixer,
+                                         &line,
+                                         MIXER_GETLINEINFOF_SOURCE);
+               if (result == MMSYSERR_NOERROR)
+               {
+                  mixer->src[0].lineID = line.dwLineID;
+                  strcpy(mixer->src[0].name, line.szName);
+
+                  controls.dwLineID = line.dwLineID;
+                  result = mixerGetLineControls(mixer->hInputMixer,
+                                                &controls,
+                                                MIXER_GETLINECONTROLSF_ONEBYTYPE);
+
+                  if (result == MMSYSERR_NOERROR)
+                  {
+                     mixer->src[0].controlID = control.dwControlID;
+                  }
+                  else
+                  {
+                     mixer->src[0].controlID = 0;
+                  }
+
+                  mixer->numInputs = 1;
+               }
+            }
+         }
+      }
+   }
+
+   // mixer->speakerID = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS/VolumeControl
+   // mixer->speakerID = MIXERLINE_COMPONENTTYPE_DST_HEADPHONES/VolumeControl
+   // mixer->speakerID = MIXERLINE_COMPONENTTYPE_DST_UNDEFINED/VolumeControl
+
+   mixer->speakerID = -1;
+   mixer->waveID = -1;
+
+   if (mixer->hOutputMixer) {
+
+      const DWORD componentTypes [] =
+      {
+         MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,
+         MIXERLINE_COMPONENTTYPE_DST_HEADPHONES,
+         MIXERLINE_COMPONENTTYPE_DST_UNDEFINED,
+      };
+      const size_t componentTypeLen = sizeof(componentTypes) / sizeof(DWORD);
+      DWORD j;
+
+      MIXERLINE line;
+      line.cbStruct = sizeof(MIXERLINE);
+
+      for (j = 0; j < componentTypeLen; j++)
+      {
+         line.dwComponentType = componentTypes[j];
+         result = mixerGetLineInfo(mixer->hOutputMixer,
+                                   &line,
+                                   MIXER_GETLINEINFOF_COMPONENTTYPE);
+
+         if (result == MMSYSERR_NOERROR)
+            break;
+      }
+
+      if (result == MMSYSERR_NOERROR)
+      {
+         MIXERLINECONTROLS controls;
+         MIXERCONTROL control;
+
+         controls.cbStruct = sizeof(MIXERLINECONTROLS);
+         controls.dwLineID = line.dwLineID;
+         controls.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
+         controls.cbmxctrl = sizeof(MIXERCONTROL);
+         controls.pamxctrl = &control;
+
+         control.cbStruct = sizeof(MIXERCONTROL);
+
+         result = mixerGetLineControls(mixer->hOutputMixer,
+                                       &controls,
+                                       MIXER_GETLINECONTROLSF_ONEBYTYPE);
+
+         if (result == MMSYSERR_NOERROR)
+            mixer->speakerID = control.dwControlID;
+
+         // mixer->waveID = MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT/VolumeControl
+
+         const DWORD numSources = line.cConnections;
+
+         for (j = 0; j < numSources; j++)
+         {
+             line.dwSource = j;
+             result = mixerGetLineInfo(mixer->hOutputMixer,
+                                       &line,
+                                       MIXER_GETLINEINFOF_SOURCE);
+             if (result == MMSYSERR_NOERROR &&
+                 line.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT)
+             {
+                controls.dwLineID = line.dwLineID;
+                result = mixerGetLineControls(mixer->hOutputMixer,
+                                              &controls,
+                                              MIXER_GETLINECONTROLSF_ONEBYTYPE);
+                if (result == MMSYSERR_NOERROR)
+                {
+                   mixer->waveID = control.dwControlID;
+                   break;
+                }
+             }
+         }
+      }
+   }
+
+   return (PxMixer *)mixer;
+}
+
+void VolumeFunction(HMIXEROBJ hMixer, DWORD controlID, PxVolume *volume)
+{
+   MIXERCONTROLDETAILS details;
+   MMRESULT result;
+   MIXERCONTROLDETAILS_UNSIGNED value;
+
+   memset(&value, 0, sizeof(MIXERCONTROLDETAILS_UNSIGNED));
+
+   details.cbStruct = sizeof(MIXERCONTROLDETAILS);
+   details.dwControlID = controlID;
+   details.cChannels = 1; /* all channels */
+   details.cMultipleItems = 0;
+   details.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
+   details.paDetails = &value;
+
+   result = mixerGetControlDetails(hMixer, &details,
+                                   MIXER_GETCONTROLDETAILSF_VALUE);
+
+   if (*volume < 0.0) {
+      *volume = (PxVolume)(value.dwValue / 65535.0);
+   }
+   else {
+      if (result != MMSYSERR_NOERROR)
+         return;
+      value.dwValue = (unsigned short)(*volume * 65535.0);
+      mixerSetControlDetails(hMixer, &details,
+                             MIXER_GETCONTROLDETAILSF_VALUE);
+   }
+}
+
+/*
+ Px_CloseMixer() closes a mixer opened using Px_OpenMixer and frees any
+ memory associated with it.
+*/
+
+void Px_CloseMixer(PxMixer *mixer)
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   if (info->hInputMixer)
+      mixerClose((HMIXER)info->hInputMixer);
+   if (info->hOutputMixer)
+      mixerClose((HMIXER)info->hOutputMixer);
+   free( mixer );
+}
+
+/*
+ Master (output) volume
+*/
+
+PxVolume Px_GetMasterVolume( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   PxVolume vol;
+
+   vol = -1.0;
+   VolumeFunction(info->hOutputMixer, info->speakerID, &vol);
+   return vol;
+}
+
+void Px_SetMasterVolume( PxMixer *mixer, PxVolume volume )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   VolumeFunction(info->hOutputMixer, info->speakerID, &volume);
+}
+
+/*
+ PCM output volume
+*/
+
+int Px_SupportsPCMOutputVolume( PxMixer* mixer )
+{
+   PxInfo* info = ( PxInfo* )( mixer ) ;
+   return ( info->waveID == -1 ) ? 0 : 1 ;
+}
+
+PxVolume Px_GetPCMOutputVolume( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   PxVolume vol;
+
+   vol = -1.0;
+   VolumeFunction(info->hOutputMixer, info->waveID, &vol);
+   return vol;
+}
+
+void Px_SetPCMOutputVolume( PxMixer *mixer, PxVolume volume )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   VolumeFunction(info->hOutputMixer, info->waveID, &volume);
+}
+
+
+/*
+ All output volumes
+*/
+
+int Px_GetNumOutputVolumes( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   return 2;
+}
+
+const char *Px_GetOutputVolumeName( PxMixer *mixer, int i )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   if (i==1)
+      return "Wave Out";
+   else
+      return "Master Volume";
+}
+
+PxVolume Px_GetOutputVolume( PxMixer *mixer, int i )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   if (i==1)
+      return Px_GetPCMOutputVolume(mixer);
+   else
+      return Px_GetMasterVolume(mixer);
+}
+
+void Px_SetOutputVolume( PxMixer *mixer, int i, PxVolume volume )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   if (i==1)
+      Px_SetPCMOutputVolume(mixer, volume);
+   else
+      Px_SetMasterVolume(mixer, volume);
+}
+
+/*
+ Input sources
+*/
+
+int Px_GetNumInputSources( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   return info->numInputs;
+}
+
+const char *Px_GetInputSourceName( PxMixer *mixer, int i)
+{
+   PxInfo *info = (PxInfo *)mixer;
+
+   return info->src[i].name;
+}
+
+int Px_GetCurrentInputSource( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   MIXERCONTROLDETAILS details;
+   MIXERCONTROLDETAILS_BOOLEAN flags[32];
+   MMRESULT result;
+   int i;
+
+   details.cbStruct = sizeof(MIXERCONTROLDETAILS);
+   details.dwControlID = info->muxID;
+   details.cMultipleItems = info->numInputs;
+   details.cChannels = 1;
+   details.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
+   details.paDetails = (LPMIXERCONTROLDETAILS_BOOLEAN)&flags[0];
+
+   result = mixerGetControlDetails(info->hInputMixer,
+                                   (LPMIXERCONTROLDETAILS)&details,
+                                   MIXER_GETCONTROLDETAILSF_VALUE);
+
+   if (result == MMSYSERR_NOERROR) {
+      for(i=0; i<info->numInputs; i++)
+         if (flags[i].fValue)
+            return i;
+   }
+
+   return 0;
+}
+
+void Px_SetCurrentInputSource( PxMixer *mixer, int i )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   MIXERCONTROLDETAILS details;
+   MIXERCONTROLDETAILS_BOOLEAN flags[32];
+   MMRESULT result;
+   int j;
+
+   details.cbStruct = sizeof(MIXERCONTROLDETAILS);
+   details.dwControlID = info->muxID;
+   details.cMultipleItems = info->numInputs;
+   details.cChannels = 1;
+   details.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
+   details.paDetails = (LPMIXERCONTROLDETAILS_BOOLEAN)&flags[0];
+
+   for(j=0; j<info->numInputs; j++)
+      flags[j].fValue = (i == j);
+
+   result = mixerSetControlDetails(info->hInputMixer,
+                                   (LPMIXERCONTROLDETAILS)&details,
+                                   MIXER_SETCONTROLDETAILSF_VALUE);
+}
+
+/*
+ Input volume
+*/
+
+PxVolume Px_GetInputVolume( PxMixer *mixer )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   PxVolume vol;
+   int src = Px_GetCurrentInputSource(mixer);
+
+   vol = -1.0;
+   VolumeFunction(info->hInputMixer, info->src[src].controlID, &vol);
+   return vol;
+}
+
+void Px_SetInputVolume( PxMixer *mixer, PxVolume volume )
+{
+   PxInfo *info = (PxInfo *)mixer;
+   int src = Px_GetCurrentInputSource(mixer);
+
+   VolumeFunction(info->hInputMixer, info->src[src].controlID, &volume);
+}
+
+/*
+  Balance
+*/
+
+int Px_SupportsOutputBalance( PxMixer *mixer )
+{
+   return 0;
+}
+
+PxBalance Px_GetOutputBalance( PxMixer *mixer )
+{
+   return 0.0;
+}
+
+void Px_SetOutputBalance( PxMixer *mixer, PxBalance balance )
+{
+}
+
+/*
+  Playthrough
+*/
+
+int Px_SupportsPlaythrough( PxMixer *mixer )
+{
+   return 0;
+}
+
+PxVolume Px_GetPlaythrough( PxMixer *mixer )
+{
+   return 0.0;
+}
+
+void Px_SetPlaythrough( PxMixer *mixer, PxVolume volume )
+{
+}
+
+int Px_SetMicrophoneBoost( PxMixer* mixer, int enable )
+{
+   MIXERLINE mixerLine ;
+   LPMIXERCONTROL mixerControl ;
+   MIXERLINECONTROLS mixerLineControls ;
+   MIXERCONTROLDETAILS mixerControlDetails ;
+   MIXERCONTROLDETAILS_BOOLEAN value ;
+   MMRESULT mmr = MMSYSERR_ERROR ;
+   DWORD boost_id = -1 ;
+   DWORD x ;
+
+   // cast void pointer
+   PxInfo* info = ( PxInfo* )( mixer ) ;
+
+   if ( info == NULL )
+      return MMSYSERR_ERROR ;
+
+   //
+   // get line info
+   //
+
+   mixerLine.cbStruct = sizeof( MIXERLINE ) ;
+   mixerLine.dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE ;
+
+   mmr = mixerGetLineInfo(
+         ( HMIXEROBJ )( info->hInputMixer ),
+         &mixerLine,
+         MIXER_GETLINEINFOF_COMPONENTTYPE
+         ) ;
+
+   if ( mmr != MMSYSERR_NOERROR )
+      return mmr ;
+
+   //
+   // get all controls
+   //
+
+   mixerControl = (MIXERCONTROL *)malloc( sizeof( MIXERCONTROL ) * mixerLine.cControls ) ;
+
+   mixerLineControls.cbStruct = sizeof( MIXERLINECONTROLS ) ;
+   mixerLineControls.dwLineID = mixerLine.dwLineID ;
+   mixerLineControls.cControls = mixerLine.cControls ;
+   mixerLineControls.cbmxctrl = sizeof( MIXERCONTROL ) ;
+   mixerLineControls.pamxctrl = ( LPMIXERCONTROL )( mixerControl ) ;
+
+   mmr = mixerGetLineControls(
+         ( HMIXEROBJ )( info->hInputMixer ),
+         &mixerLineControls,
+         MIXER_GETLINECONTROLSF_ALL
+         ) ;
+
+   if ( mmr != MMSYSERR_NOERROR )
+   {
+      free(mixerControl);
+
+      return mmr ;
+   }
+
+   //
+   // find boost control
+   //
+
+   for ( x = 0 ; x < mixerLineControls.cControls ; ++x )
+   {
+      // check control type
+      if ( mixerControl[x].dwControlType & MIXERCONTROL_CONTROLTYPE_BOOLEAN )
+      {
+         // normalize control name
+         char* name = _strupr( mixerControl[x].szName ) ;
+
+         // check for 'mic' and 'boost'
+         if (
+               ( strstr( name, "MIC" ) != NULL )
+               && ( strstr( name, "BOOST" ) != NULL )
+            )
+         {
+            boost_id = mixerControl[x].dwControlID ;
+            break ;
+         }
+      }
+   }
+
+   if ( boost_id == -1 )
+   {
+      free(mixerControl);
+
+      return MMSYSERR_ERROR ;
+   }
+
+   //
+   // get control details
+   //
+
+   mixerControlDetails.cbStruct = sizeof( MIXERCONTROLDETAILS ) ;
+   mixerControlDetails.dwControlID = boost_id ;
+   mixerControlDetails.cChannels = 1 ;
+   mixerControlDetails.cMultipleItems = 0 ;
+   mixerControlDetails.cbDetails = sizeof( MIXERCONTROLDETAILS_BOOLEAN ) ;
+   mixerControlDetails.paDetails = &value ;
+
+   mmr = mixerGetControlDetails(
+         ( HMIXEROBJ )( info->hInputMixer ),
+         &mixerControlDetails,
+         MIXER_GETCONTROLDETAILSF_VALUE
+         ) ;
+
+   if ( mmr != MMSYSERR_NOERROR )
+   {
+      free(mixerControl);
+
+      return mmr ;
+   }
+
+   //
+   // update value
+   //
+
+   value.fValue = ( enable == 0 ) ? 0L : 1L ;
+
+   //
+   // set control details
+   //
+
+   mmr = mixerSetControlDetails(
+         ( HMIXEROBJ )( info->hInputMixer ),
+         &mixerControlDetails,
+         MIXER_SETCONTROLDETAILSF_VALUE
+         ) ;
+
+   free(mixerControl);
+
+   if ( mmr != MMSYSERR_NOERROR )
+      return mmr ;
+
+   return mmr ;
+}
+
+int Px_GetMicrophoneBoost( PxMixer* mixer )
+{
+   MIXERLINE mixerLine ;
+   LPMIXERCONTROL mixerControl ;
+   MIXERLINECONTROLS mixerLineControls ;
+   MIXERCONTROLDETAILS mixerControlDetails ;
+   MIXERCONTROLDETAILS_BOOLEAN value ;
+   MMRESULT mmr = MMSYSERR_ERROR ;
+   DWORD boost_id = -1 ;
+   DWORD x ;
+
+   // cast void pointer
+   PxInfo* info = ( PxInfo* )( mixer ) ;
+
+   if ( info == NULL )
+      return -1 ;
+
+   //
+   // get line info
+   //
+
+   mixerLine.cbStruct = sizeof( MIXERLINE ) ;
+   mixerLine.dwComponentType = MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE ;
+
+   mmr = mixerGetLineInfo(
+         ( HMIXEROBJ )( info->hInputMixer ),
+         &mixerLine,
+         MIXER_GETLINEINFOF_COMPONENTTYPE
+         ) ;
+
+   if ( mmr != MMSYSERR_NOERROR )
+      return -1 ;
+
+   //
+   // get all controls
+   //
+
+   mixerControl = (MIXERCONTROL *)malloc( sizeof( MIXERCONTROL ) * mixerLine.cControls ) ;
+
+   mixerLineControls.cbStruct = sizeof( MIXERLINECONTROLS ) ;
+   mixerLineControls.dwLineID = mixerLine.dwLineID ;
+   mixerLineControls.cControls = mixerLine.cControls ;
+   mixerLineControls.cbmxctrl = sizeof( MIXERCONTROL ) ;
+   mixerLineControls.pamxctrl = ( LPMIXERCONTROL )( mixerControl ) ;
+
+   mmr = mixerGetLineControls(
+         ( HMIXEROBJ )( info->hInputMixer ),
+         &mixerLineControls,
+         MIXER_GETLINECONTROLSF_ALL
+         ) ;
+
+   if ( mmr != MMSYSERR_NOERROR )
+   {
+      free(mixerControl);
+
+      return -1 ;
+   }
+
+   //
+   // find boost control
+   //
+
+   for ( x = 0 ; x < mixerLineControls.cControls ; ++x )
+   {
+      // check control type
+      if ( mixerControl[x].dwControlType & MIXERCONTROL_CONTROLTYPE_BOOLEAN )
+      {
+         // normalize control name
+         char* name = _strupr( mixerControl[x].szName ) ;
+
+         // check for 'mic' and 'boost'
+         if (
+               ( strstr( name, "MIC" ) != NULL )
+               && ( strstr( name, "BOOST" ) != NULL )
+            )
+         {
+            boost_id = mixerControl[x].dwControlID ;
+            break ;
+         }
+      }
+   }
+
+   if ( boost_id == -1 )
+   {
+      free(mixerControl);
+
+      return -1 ;
+   }
+
+   //
+   // get control details
+   //
+
+   mixerControlDetails.cbStruct = sizeof( MIXERCONTROLDETAILS ) ;
+   mixerControlDetails.dwControlID = boost_id ;
+   mixerControlDetails.cChannels = 1 ;
+   mixerControlDetails.cMultipleItems = 0 ;
+   mixerControlDetails.cbDetails = sizeof( MIXERCONTROLDETAILS_BOOLEAN ) ;
+   mixerControlDetails.paDetails = &value ;
+
+   mmr = mixerGetControlDetails(
+         ( HMIXEROBJ )( info->hInputMixer ),
+         &mixerControlDetails,
+         MIXER_GETCONTROLDETAILSF_VALUE
+         ) ;
+
+   free(mixerControl);
+
+   if ( mmr != MMSYSERR_NOERROR )
+      return -1 ;
+
+   return ( int )( value.fValue ) ;
+}
+
+int Px_SetCurrentInputSourceByName( PxMixer* mixer, const char* name )
+{
+   int x ;
+
+   // cast void pointer
+   PxInfo* info = ( PxInfo* )( mixer ) ;
+
+   // make sure we have a mixer
+   if ( info == NULL )
+      return MMSYSERR_ERROR ;
+
+   // make sure we have a search name
+   if ( name == NULL )
+      return MMSYSERR_ERROR ;
+
+   //
+   // set input source
+   //
+
+   for ( x = 0 ; x < info->numInputs ; ++x )
+   {
+      // compare passed name with control name
+      if ( strcasecmp( info->src[x].name, name ) == 0 )
+      {
+         // set input source
+         Px_SetCurrentInputSource( mixer, x ) ;
+
+         // make sure set'ing worked
+         if ( Px_GetCurrentInputSource( mixer ) == x )
+            return MMSYSERR_NOERROR ;
+         else
+            return MMSYSERR_ERROR ;
+      }
+   }
+
+   return MMSYSERR_ERROR ;
+}
+
diff --git a/utils/iaxclient/lib/portmixer/winproj/portmixer.vcproj b/utils/iaxclient/lib/portmixer/winproj/portmixer.vcproj
new file mode 100644 (file)
index 0000000..6891189
--- /dev/null
@@ -0,0 +1,303 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+       ProjectType="Visual C++"
+       Version="8.00"
+       Name="portmixer"
+       ProjectGUID="{3A76129B-55AB-4D54-BAA7-08F63ED52569}"
+       RootNamespace="portmixer"
+       >
+       <Platforms>
+               <Platform
+                       Name="Win32"
+               />
+       </Platforms>
+       <ToolFiles>
+       </ToolFiles>
+       <Configurations>
+               <Configuration
+                       Name="Release|Win32"
+                       OutputDirectory=".\$(ConfigurationName)"
+                       IntermediateDirectory=".\$(ConfigurationName)"
+                       ConfigurationType="4"
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+                       UseOfMFC="0"
+                       ATLMinimizesCRunTimeLibraryUsage="false"
+                       CharacterSet="2"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               AdditionalOptions="/O2"
+                               Optimization="2"
+                               InlineFunctionExpansion="1"
+                               AdditionalIncludeDirectories="&quot;$(SolutionDir)&quot;;&quot;..\..\portaudio-v19\include&quot;;&quot;..\..\portaudio-v19\src\common&quot;;..\..\portaudio\pa_common;..\px_common;..\..\portaudio\include;..\..\portaudio\src\common"
+                               PreprocessorDefinitions="WIN32;NDEBUG;_LIB;strncasecmp=strnicmp"
+                               StringPooling="true"
+                               RuntimeLibrary="2"
+                               EnableFunctionLevelLinking="true"
+                               UsePrecompiledHeader="0"
+                               PrecompiledHeaderFile=".\$(ConfigurationName)/portmixer.pch"
+                               AssemblerListingLocation=".\$(ConfigurationName)/"
+                               ObjectFile=".\$(ConfigurationName)/"
+                               ProgramDataBaseFileName=".\$(ConfigurationName)/"
+                               WarningLevel="3"
+                               SuppressStartupBanner="true"
+                               CompileAs="0"
+                               DisableSpecificWarnings="4996"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                               PreprocessorDefinitions="NDEBUG"
+                               Culture="1033"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLibrarianTool"
+                               OutputFile=".\portmixer.lib"
+                               SuppressStartupBanner="true"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Debug|Win32"
+                       OutputDirectory=".\$(ConfigurationName)"
+                       IntermediateDirectory=".\$(ConfigurationName)"
+                       ConfigurationType="4"
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+                       UseOfMFC="0"
+                       ATLMinimizesCRunTimeLibraryUsage="false"
+                       CharacterSet="2"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories="&quot;$(SolutionDir)&quot;;&quot;..\..\portaudio-v19\include&quot;;&quot;..\..\portaudio-v19\src\common&quot;;..\..\portaudio\pa_common;..\px_common;..\..\portaudio\include;..\..\portaudio\src\common"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_LIB;strncasecmp=strnicmp"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="3"
+                               UsePrecompiledHeader="0"
+                               PrecompiledHeaderFile=".\$(ConfigurationName)/portmixer.pch"
+                               AssemblerListingLocation=".\$(ConfigurationName)/"
+                               ObjectFile=".\$(ConfigurationName)/"
+                               ProgramDataBaseFileName=".\$(ConfigurationName)/"
+                               WarningLevel="3"
+                               SuppressStartupBanner="true"
+                               DebugInformationFormat="4"
+                               CompileAs="2"
+                               DisableSpecificWarnings="4996"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                               PreprocessorDefinitions="_DEBUG"
+                               Culture="1033"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLibrarianTool"
+                               OutputFile=".\portmixerd.lib"
+                               SuppressStartupBanner="true"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+               <Configuration
+                       Name="Unicode_Debug|Win32"
+                       OutputDirectory="$(ConfigurationName)"
+                       IntermediateDirectory="$(ConfigurationName)"
+                       ConfigurationType="4"
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+                       UseOfMFC="0"
+                       ATLMinimizesCRunTimeLibraryUsage="false"
+                       CharacterSet="0"
+                       >
+                       <Tool
+                               Name="VCPreBuildEventTool"
+                       />
+                       <Tool
+                               Name="VCCustomBuildTool"
+                       />
+                       <Tool
+                               Name="VCXMLDataGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCWebServiceProxyGeneratorTool"
+                       />
+                       <Tool
+                               Name="VCMIDLTool"
+                       />
+                       <Tool
+                               Name="VCCLCompilerTool"
+                               Optimization="0"
+                               AdditionalIncludeDirectories="&quot;$(SolutionDir)&quot;;&quot;..\..\portaudio-v19\include&quot;;&quot;..\..\portaudio-v19\src\common&quot;;..\..\portaudio\pa_common;..\px_common"
+                               PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+                               BasicRuntimeChecks="3"
+                               RuntimeLibrary="1"
+                               UsePrecompiledHeader="0"
+                               PrecompiledHeaderFile=".\$(ConfigurationName)/portmixer.pch"
+                               AssemblerListingLocation=".\$(ConfigurationName)/"
+                               ObjectFile=".\$(ConfigurationName)/"
+                               ProgramDataBaseFileName=".\$(ConfigurationName)/"
+                               WarningLevel="3"
+                               SuppressStartupBanner="true"
+                               DebugInformationFormat="4"
+                               CompileAs="0"
+                               DisableSpecificWarnings="4996"
+                       />
+                       <Tool
+                               Name="VCManagedResourceCompilerTool"
+                       />
+                       <Tool
+                               Name="VCResourceCompilerTool"
+                               PreprocessorDefinitions="_DEBUG"
+                               Culture="1033"
+                       />
+                       <Tool
+                               Name="VCPreLinkEventTool"
+                       />
+                       <Tool
+                               Name="VCLibrarianTool"
+                               OutputFile=".\portmixerud.lib"
+                               SuppressStartupBanner="true"
+                       />
+                       <Tool
+                               Name="VCALinkTool"
+                       />
+                       <Tool
+                               Name="VCXDCMakeTool"
+                       />
+                       <Tool
+                               Name="VCBscMakeTool"
+                       />
+                       <Tool
+                               Name="VCFxCopTool"
+                       />
+                       <Tool
+                               Name="VCPostBuildEventTool"
+                       />
+               </Configuration>
+       </Configurations>
+       <References>
+       </References>
+       <Files>
+               <Filter
+                       Name="Source Files"
+                       Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+                       >
+                       <File
+                               RelativePath="..\px_win_wmme\px_win_wmme.c"
+                               >
+                               <FileConfiguration
+                                       Name="Release|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               Optimization="2"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                               CompileAs="2"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               Optimization="0"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                               BasicRuntimeChecks="3"
+                                               CompileAs="2"
+                                       />
+                               </FileConfiguration>
+                               <FileConfiguration
+                                       Name="Unicode_Debug|Win32"
+                                       >
+                                       <Tool
+                                               Name="VCCLCompilerTool"
+                                               Optimization="0"
+                                               AdditionalIncludeDirectories=""
+                                               PreprocessorDefinitions=""
+                                               BasicRuntimeChecks="3"
+                                       />
+                               </FileConfiguration>
+                       </File>
+               </Filter>
+               <Filter
+                       Name="Header Files"
+                       Filter="h;hpp;hxx;hm;inl"
+                       >
+                       <File
+                               RelativePath="..\px_common\portmixer.h"
+                               >
+                       </File>
+               </Filter>
+       </Files>
+       <Globals>
+       </Globals>
+</VisualStudioProject>
diff --git a/utils/iaxclient/lib/sound2c.pl b/utils/iaxclient/lib/sound2c.pl
new file mode 100755 (executable)
index 0000000..0ec00e0
--- /dev/null
@@ -0,0 +1,37 @@
+#!/usr/bin/perl
+
+$IN = $ARGV[0];
+$OUT = $ARGV[1];
+
+open (RAW, "sox $IN -t .sw -|");
+
+open (OUTF, ">$OUT");
+
+$var = $OUT;
+$var =~ s/\.c$//;
+
+print OUTF <<EOM;
+/* Converted sound file, from $IN
+ * sound is 16 bit signed samples, at 8khz.
+ */
+
+short $var \[\] \= \{ 
+EOM
+
+printf(OUTF "\t");     
+$n = 0;
+
+while(sysread(RAW,$word,2))
+{
+       #print "WORD is $word";
+       printf(OUTF "0x%04hx, ", unpack("s",$word));    
+       if((++$n) % 8 == 0) {
+               printf(OUTF "\n\t");    
+       }
+}
+
+printf(OUTF "0 \n};\n");
+
+close OUTF;
+
+
diff --git a/utils/iaxclient/lib/sox/README.sox b/utils/iaxclient/lib/sox/README.sox
new file mode 100644 (file)
index 0000000..450232a
--- /dev/null
@@ -0,0 +1,59 @@
+
+16Apr2003 Steve Kann <stevek@stevek.com>
+
+The code in resample.c/resample.h has been liberally yanked from the SoX
+distribution, and reworked just a tiny bit to allow compilation outside
+of SoX.
+
+Aside from some minor changes to the calling conventions (to use just
+the private resample data structure, not the larget sox structures), and
+generic code moves/defines that needed to be localized, the other
+notable changes are:
+
+1) st_sample_t is here defined as a 16 bit integer, and not a 32 bit
+integer, so this code will will be able to operate over 16 bit unsigned
+samples (the resample effect works with floating point internally
+anyway, so it was a small change in the code).
+
+2) The "getopts" call is not necessary (nor, at this point helpful,
+       since the options are set to their default now ad the beginning of
+       start).
+
+3) start now takes two additional parameters, "inrate" and "outrate"
+
+To use this, the basic idea is:
+
+
+st_resample_t resampler;
+
+st_resample_start(&resampler, inrate, outrate);
+
+while(you have input data)
+{
+       iNum = (number of Input samples we have);
+       oNum = (size of Output buffer available)
+       iBuf = input buffer;
+       oBuf = output buffer;
+       if(st_resample_flow(&resampler, ibuf, obuf, &iNum, &oNum) != ST_SUCCESS)
+       {
+               handle error.
+       }
+
+       (after calling, iNum, oNum will the the count of buffers
+       read/written)
+}
+
+finally, you call st_sample_drain, to get the "last" output;
+
+if(st_sample_drain(&resampler, obuf, &oNum) != ST_SUCCESS)
+{
+       error
+}
+
+Then, call st_sample_stop, to free resources:
+st_sample_stop(&resampler);
+
+For a discussion on this and other resampling algorithms, see this page for a
+great analysis by K. Bradley and Andreas Wilde at:
+       http://leute.server.de/wilde/resample.html
+
diff --git a/utils/iaxclient/lib/sox/compand.c b/utils/iaxclient/lib/sox/compand.c
new file mode 100644 (file)
index 0000000..6ecdd83
--- /dev/null
@@ -0,0 +1,397 @@
+/*
+ * Compander effect
+ *
+ * Written by Nick Bailey (nick@bailey-family.org.uk or
+ *                         n.bailey@elec.gla.ac.uk)
+ *
+ * Copyright 1999 Chris Bagwell And Nick Bailey
+ * This source code is freely redistributable and may be used for
+ * any purpose.  This copyright notice must be maintained. 
+ * Chris Bagwell And Nick Bailey are not responsible for 
+ * the consequences of using this software.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include "sox.h"
+
+/*
+ * Compressor/expander effect for dsp.
+ *
+ * Flow diagram for one channel:
+ *
+ *              ------------      ---------------
+ *             |            |    |               |     ---
+ * ibuff ---+---| integrator |--->| transfer func |--->|   |
+ *         |   |            |    |               |    |   |
+ *         |    ------------      ---------------     |   |  * gain
+ *         |                                          | * |----------->obuff
+ *         |       -------                            |   |
+ *         |      |       |                           |   |
+ *         +----->| delay |-------------------------->|   |
+ *                |       |                            ---
+ *                 -------
+ *
+ * Usage:
+ *   compand attack1,decay1[,attack2,decay2...]
+ *                  in-dB1,out-dB1[,in-dB2,out-dB2...]
+ *                 [ gain [ initial-volume [ delay ] ] ] 
+ *
+ * Note: clipping can occur if the transfer function pushes things too
+ * close to 0 dB.  In that case, use a negative gain, or reduce the
+ * output level of the transfer function.
+ */
+
+/*
+ * Process options
+ *
+ * Don't do initialization now.
+ * The 'info' fields are not yet filled in.
+ */
+int st_compand_getopts(compand_t l, int n, char **argv) 
+{
+
+    if (n < 2 || n > 5)
+    {
+      st_fail("Wrong number of arguments for the compander effect\n"
+          "Use: {<attack_time>,<decay_time>}+ {<dB_in>,<db_out>}+ "
+          "[<dB_postamp> [<initial-volume> [<delay_time]]]\n"
+          "where {}+ means `one or more in a comma-separated, "
+          "white-space-free list'\n"
+          "and [] indications possible omission.  dB values are floating\n"
+          "point or `-inf'; times are in seconds.");
+      return (ST_EOF);
+    }
+    else { /* Right no. of args, but are they well formed? */
+      char *s;
+      int rates, tfers, i, commas;
+
+      /* Start by checking the attack and decay rates */
+
+      for (s = argv[0], commas = 0; *s; ++s)
+       if (*s == ',') ++commas;
+
+      if (commas % 2 == 0) /* There must be an even number of
+                             attack/decay parameters */
+      {
+       st_fail("compander: Odd number of attack & decay rate parameters");
+       return (ST_EOF);
+      }
+
+      rates = 1 + commas/2;
+      if ((l->attackRate = malloc(sizeof(double) * rates)) == NULL ||
+         (l->decayRate  = malloc(sizeof(double) * rates)) == NULL ||
+         (l->volume     = malloc(sizeof(double) * rates)) == NULL)
+      {
+       st_fail("Out of memory");
+       return (ST_EOF);
+      }
+      l->expectedChannels = rates;
+      l->delay_buf = NULL;
+
+      /* Now tokenise the rates string and set up these arrays.  Keep
+        them in seconds at the moment: we don't know the sample rate yet. */
+
+      s = strtok(argv[0], ","); i = 0;
+      do {
+       l->attackRate[i] = atof(s); s = strtok(NULL, ",");
+       l->decayRate[i]  = atof(s); s = strtok(NULL, ",");
+       ++i;
+      } while (s != NULL);
+
+      /* Same business, but this time for the transfer function */
+
+      for (s = argv[1], commas = 0; *s; ++s)
+       if (*s == ',') ++commas;
+
+      if (commas % 2 == 0) /* There must be an even number of
+                             transfer parameters */
+      {
+       st_fail("compander: Odd number of transfer function parameters\n"
+            "Each input value in dB must have a corresponding output value");
+       return (ST_EOF);
+      }
+
+      tfers = 3 + commas/2; /* 0, 0 at start; 1, 1 at end */
+      if ((l->transferIns  = malloc(sizeof(double) * tfers)) == NULL ||
+         (l->transferOuts = malloc(sizeof(double) * tfers)) == NULL)
+      {
+       st_fail("Out of memory");
+       return (ST_EOF);
+      }
+      l->transferPoints = tfers;
+      l->transferIns[0] = 0.0; l->transferOuts[0] = 0.0;
+      l->transferIns[tfers-1] = 1.0; l->transferOuts[tfers-1] = 1.0;
+      s = strtok(argv[1], ","); i = 1;
+      do {
+       if (!strcmp(s, "-inf"))
+       {
+         st_fail("Input signals of zero level must always generate zero output");
+         return (ST_EOF);
+       }
+       l->transferIns[i]  = pow(10.0, atof(s)/20.0);
+       if (l->transferIns[i] > 1.0)
+       {
+         st_fail("dB values are relative to maximum input, and, ipso facto, "
+              "cannot exceed 0");
+         return (ST_EOF);
+       }
+       if (l->transferIns[i] == 1.0) /* Final point was explicit */
+         --(l->transferPoints);
+       if (i > 0 && l->transferIns[i] <= l->transferIns[i-1])
+       {
+         st_fail("Transfer function points don't have strictly ascending "
+              "input amplitude");
+         return (ST_EOF);
+       }
+       s = strtok(NULL, ",");
+       l->transferOuts[i] = strcmp(s, "-inf") ?
+                              pow(10.0, atof(s)/20.0) : 0;
+       s = strtok(NULL, ",");
+       ++i;
+      } while (s != NULL);
+      
+      /* If there is a postprocessor gain, store it */
+      if (n >= 3) l->outgain = pow(10.0, atof(argv[2])/20.0);
+      else l->outgain = 1.0;
+
+      /* Set the initial "volume" to be attibuted to the input channels.
+        Unless specified, choose 1.0 (maximum) otherwise clipping will
+        result if the user has seleced a long attack time */
+      for (i = 0; i < l->expectedChannels; ++i) {
+       double v = n>=4 ? pow(10.0, atof(argv[3])/20) : 1.0;
+       l->volume[i] = v;
+
+      /* If there is a delay, store it. */
+      if (n >= 5) l->delay = atof(argv[4]);
+      else l->delay = 0.0;
+      }
+    }
+    return (ST_SUCCESS);
+}
+
+
+/*
+ * Prepare processing.
+ * Do all initializations.
+ */
+int st_compand_start(compand_t *lH, char **opts, int nopts)
+{
+  int i;
+  compand_t l;
+
+  *lH = malloc(sizeof (struct compand));
+  l = *lH;
+
+  st_compand_getopts(l, nopts, opts);
+
+# ifdef DEBUG
+  {
+    fprintf(stderr, "Starting compand effect\n");
+    fprintf(stderr, "\nRate %ld, size %d, encoding %d, output gain %g.\n",
+          ST_SAMPLE_RATE, effp->outinfo.size, effp->outinfo.encoding,
+          l->outgain);
+    fprintf(stderr, "%d input channel(s) expected: actually %d\n",
+          l->expectedChannels, ST_CHANNELS);
+    fprintf(stderr, "\nAttack and decay rates\n"
+            "======================\n");
+    for (i = 0; i < l->expectedChannels; ++i)
+      fprintf(stderr, "Channel %d: attack = %-12g decay = %-12g\n",
+            i, l->attackRate[i], l->decayRate[i]);
+    fprintf(stderr, "\nTransfer function (linear values)\n"
+            "=================  =============\n");
+    for (i = 0; i < l->transferPoints; ++i)
+      fprintf(stderr, "%12g -> %-12g\n",
+            l->transferIns[i], l->transferOuts[i]);
+  }
+# endif
+  
+  /* Convert attack and decay rates using number of samples */
+
+  for (i = 0; i < l->expectedChannels; ++i) {
+    if (l->attackRate[i] > 1.0/ST_SAMPLE_RATE)
+      l->attackRate[i] = 1.0 -
+       exp(-1.0/(ST_SAMPLE_RATE * l->attackRate[i]));
+    else
+      l->attackRate[i] = 1.0;
+    if (l->decayRate[i] > 1.0/ST_SAMPLE_RATE)
+      l->decayRate[i] = 1.0 -
+       exp(-1.0/(ST_SAMPLE_RATE * l->decayRate[i]));
+    else
+      l->decayRate[i] = 1.0;
+  }
+
+  /* Allocate the delay buffer */
+  l->delay_buf_size = (int) (l->delay * ST_SAMPLE_RATE * ST_CHANNELS);
+  if (l->delay_buf_size > 0
+   && (l->delay_buf = malloc(sizeof(long) * l->delay_buf_size)) == NULL) {
+    st_fail("Out of memory");
+    return (ST_EOF);
+  }
+  for (i = 0;  i < l->delay_buf_size;  i++)
+    l->delay_buf[i] = 0;
+  l->delay_buf_ptr = 0;
+  l->delay_buf_cnt = 0;
+  l->delay_buf_full= 0;
+
+  return (ST_SUCCESS);
+}
+
+/*
+ * Update a volume value using the given sample
+ * value, the attack rate and decay rate
+ */
+
+static void doVolume(double *v, double samp, compand_t l, int chan)
+{
+  double s = samp/ST_SAMPLE_MAX;
+  double delta = s - *v;
+
+  if (delta > 0.0) /* increase volume according to attack rate */
+    *v += delta * l->attackRate[chan];
+  else             /* reduce volume according to decay rate */
+    *v += delta * l->decayRate[chan];
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+int st_compand_flow(compand_t l, st_sample_t *ibuf, st_sample_t *obuf, 
+                    st_size_t *isamp, st_size_t *osamp)
+{
+  int len =  (*isamp > *osamp) ? *osamp : *isamp;
+  int filechans = ST_CHANNELS;
+  int idone,odone;
+  long checkbuf; //if st_sample_t of type int32_t
+
+  for (idone = 0,odone = 0; idone < len; ibuf += filechans) {
+    int chan;
+
+    /* Maintain the volume fields by simulating a leaky pump circuit */
+
+    for (chan = 0; chan < filechans; ++chan) {
+      if (l->expectedChannels == 1 && filechans > 1) {
+       /* User is expecting same compander for all channels */
+       int i;
+       double maxsamp = 0.0;
+       for (i = 0; i < filechans; ++i) {
+         double rect = fabs(ibuf[i]);
+         if (rect > maxsamp) maxsamp = rect;
+       }
+       doVolume(&l->volume[0], maxsamp, l, 0);
+       break;
+      } else
+       doVolume(&l->volume[chan], fabs(ibuf[chan]), l, chan);
+    }
+
+    /* Volume memory is updated: perform compand */
+
+    for (chan = 0; chan < filechans; ++chan) {
+      double v = l->expectedChannels > 1 ?
+       l->volume[chan] : l->volume[0];
+      double outv;
+      int piece;
+
+      for (piece = 1 /* yes, 1 */;
+          piece < l->transferPoints;
+          ++piece)
+       if (v >= l->transferIns[piece - 1] &&
+           v < l->transferIns[piece])
+         break;
+
+      outv = l->transferOuts[piece-1] +
+       (l->transferOuts[piece] - l->transferOuts[piece-1]) *
+       (v - l->transferIns[piece-1]) /
+       (l->transferIns[piece] - l->transferIns[piece-1]);
+
+      if (l->delay_buf_size <= 0)
+      {
+        checkbuf = (long int) (ibuf[chan]*(outv/v)*l->outgain);
+        if(checkbuf > ST_SAMPLE_MAX)
+         obuf[odone] = ST_SAMPLE_MAX;
+        else if(checkbuf < ST_SAMPLE_MIN)
+         obuf[odone] = ST_SAMPLE_MIN;
+        else
+         obuf[odone] = (st_sample_t) checkbuf;
+
+        idone++;
+        odone++;
+      }
+      else
+      {
+       if (l->delay_buf_cnt >= l->delay_buf_size)
+        {
+            l->delay_buf_full=1; //delay buffer is now definetly full
+               checkbuf = (long int) (l->delay_buf[l->delay_buf_ptr]*(outv/v)*l->outgain);
+            if(checkbuf > ST_SAMPLE_MAX)
+             obuf[odone] = ST_SAMPLE_MAX;
+            else if(checkbuf < ST_SAMPLE_MIN)
+             obuf[odone] = ST_SAMPLE_MIN;
+            else
+             obuf[odone] = (st_sample_t) checkbuf;
+
+            odone++;
+            idone++;
+        }
+       else
+        {
+           l->delay_buf_cnt++;
+            idone++; //no "odone++" because we did not fill obuf[...]
+        }
+        l->delay_buf[l->delay_buf_ptr++] = ibuf[chan];
+        l->delay_buf_ptr %= l->delay_buf_size;
+      }
+    }
+  }
+
+  *isamp = idone; *osamp = odone;
+  return (ST_SUCCESS);
+}
+
+/*
+ * Drain out compander delay lines.
+ */
+int st_compand_drain(compand_t l, st_sample_t *obuf, st_size_t *osamp)
+{
+  int done;
+
+  /*
+   * Drain out delay samples.  Note that this loop does all channels.
+   */
+  if(l->delay_buf_full==0) l->delay_buf_ptr=0;
+  for (done = 0;  done < (int) *osamp  &&  l->delay_buf_cnt > 0;  done++) {
+    obuf[done] = l->delay_buf[l->delay_buf_ptr++];
+    l->delay_buf_ptr %= l->delay_buf_size;
+    l->delay_buf_cnt--;
+  }
+
+  /* tell caller number of samples played */
+  *osamp = done;
+  return (ST_SUCCESS);
+}
+
+
+/*
+ * Clean up compander effect.
+ */
+int st_compand_stop(compand_t l)
+{
+
+  free((char *) l->delay_buf);
+  free((char *) l->transferOuts);
+  free((char *) l->transferIns);
+  free((char *) l->volume);
+  free((char *) l->decayRate);
+  free((char *) l->attackRate);
+
+  l->delay_buf = NULL;
+  l->transferOuts = NULL;
+  l->transferIns = NULL;
+  l->volume = NULL;
+  l->decayRate = NULL;
+  l->attackRate = NULL;
+
+  return (ST_SUCCESS);
+}
diff --git a/utils/iaxclient/lib/sox/resample.c b/utils/iaxclient/lib/sox/resample.c
new file mode 100644 (file)
index 0000000..a20e826
--- /dev/null
@@ -0,0 +1,711 @@
+/*
+ * July 5, 1991
+ * Copyright 1991 Lance Norskog And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose.  This copyright notice must be maintained. 
+ * Lance Norskog And Sundry Contributors are not responsible for 
+ * the consequences of using this software.
+ */
+
+/*
+ * Sound Tools rate change effect file.
+ * Spiffy rate changer using Smith & Wesson Bandwidth-Limited Interpolation.
+ * The algorithm is described in "Bandlimited Interpolation -
+ * Introduction and Algorithm" by Julian O. Smith III.
+ * Available on ccrma-ftp.stanford.edu as
+ * pub/BandlimitedInterpolation.eps.Z or similar.
+ *
+ * The latest stand alone version of this algorithm can be found
+ * at ftp://ccrma-ftp.stanford.edu/pub/NeXT/
+ * under the name of resample-version.number.tar.Z
+ *
+ * NOTE: There is a newer version of the resample routine then what
+ * this file was originally based on.  Those adventurous might be
+ * interested in reviewing its improvesments and porting it to this
+ * version.
+ */
+
+/* Fixed bug: roll off frequency was wrong, too high by 2 when upsampling,
+ * too low by 2 when downsampling.
+ * Andreas Wilde, 12. Feb. 1999, andreas@eakaw2.et.tu-dresden.de
+*/
+
+/*
+ * October 29, 1999
+ * Various changes, bugfixes(?), increased precision, by Stan Brooks.
+ *
+ * This source code 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.
+ *
+ */
+/*
+ * SJB: [11/25/99]
+ * TODO: another idea for improvement...
+ * note that upsampling usually doesn't require interpolation,
+ * therefore is faster and more accurate than downsampling.
+ * Downsampling by an integer factor is also simple, since
+ * it just involves decimation if the input is already 
+ * lowpass-filtered to the output Nyquist freqency.
+ * Get the idea? :)
+ */
+
+/* Modified to compile outside of SoX by Steve Kann <stevek@stevek.com>
+ * 14Apr2003 */
+#define _USE_MATH_DEFINES
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+
+/* sox includes */
+#include "sox.h"
+#include "stdio.h"
+
+/* this Float MUST match that in filter.c */
+#define Float double/*float*/
+#define ISCALE 0x10000
+
+/* largest factor for which exact-coefficients upsampling will be used */
+#define NQMAX 511
+
+#define BUFFSIZE 8192 /*16384*/  /* Total I/O buffer size */
+
+
+static void LpFilter(double c[],
+                    long N,
+                    double frq,
+                    double Beta,
+                    long Num);
+
+/* makeFilter is used by filter.c */
+int makeFilter(Float Imp[],
+              long Nwing,
+              double Froll,
+              double Beta,
+              long Num,
+              int Normalize);
+
+static long SrcUD(resample_t r, long Nx);
+static long SrcEX(resample_t r, long Nx);
+
+/* define some functions/types for compatibility SK */
+/* TODO:
+       st_sample_t was int32! (we prefer int16!)
+       Make sure that MAX/MIN work right now.
+*/
+
+
+/*
+ * Process options
+ */
+int st_resample_getopts(resample_t r, int n, char **argv) 
+{
+
+       /* These defaults are conservative with respect to aliasing. */
+       r->rolloff = 0.80;
+       r->beta = 16; /* anything <=2 means Nutall window */
+       r->quadr = 0;
+       r->Nmult = 45;
+
+       /* This used to fail, but with sox-12.15 it works. AW */
+       if ((n >= 1)) {
+               if (!strcmp(argv[0], "-qs")) {
+                       r->quadr = 1;
+                       n--; argv++;
+               }
+               else if (!strcmp(argv[0], "-q")) {
+                       r->rolloff = 0.875;
+                       r->quadr = 1;
+                       r->Nmult = 75;
+                       n--; argv++;
+               }
+               else if (!strcmp(argv[0], "-ql")) {
+                       r->rolloff = 0.94;
+                       r->quadr = 1;
+                       r->Nmult = 149;
+                       n--; argv++;
+               }
+       }
+
+       if ((n >= 1) && (sscanf(argv[0], "%lf", &r->rolloff) != 1))
+       {
+         st_fail("Usage: resample [ rolloff [ beta ] ]");
+         return (ST_EOF);
+       }
+       else if ((r->rolloff <= 0.01) || (r->rolloff >= 1.0))
+       {
+         st_fail("resample: rolloff factor (%f) no good, should be 0.01<x<1.0", r->rolloff);
+         return(ST_EOF);
+       }
+
+       if ((n >= 2) && !sscanf(argv[1], "%lf", &r->beta))
+       {
+         st_fail("Usage: resample [ rolloff [ beta ] ]");
+         return (ST_EOF);
+       }
+       else if (r->beta <= 2.0) {
+         r->beta = 0;
+               st_report("resample opts: Nuttall window, cutoff %f\n", r->rolloff);
+       } else {
+               st_report("resample opts: Kaiser window, cutoff %f, beta %f\n", r->rolloff, r->beta);
+       }
+       return (ST_SUCCESS);
+}
+
+/*
+ * Prepare processing.
+ */
+int st_resample_start(resample_t *rH, int inrate, int outrate)
+{
+       long Xoff, gcdrate;
+       int i;
+       resample_t r;
+
+       *rH = malloc(sizeof (struct resamplestuff));
+       r=*rH;
+
+       if(!r)
+       {
+               st_fail("can't allocate memory");
+       }
+       
+       /* just set defaults */
+       st_resample_getopts(r,0,NULL);
+
+       if (inrate == outrate)
+       {
+           st_fail("Input and Output rates must be different to use resample effect");
+           return(ST_EOF);
+       }
+               
+       r->Factor = (double)outrate / (double)inrate;
+
+       gcdrate = st_gcd((long)inrate, (long)outrate);
+       r->a = inrate / gcdrate;
+       r->b = outrate / gcdrate;
+
+       if (r->a <= r->b && r->b <= NQMAX) {
+               r->quadr = -1; /* exact coeff's   */
+               r->Nq = r->b;  /* MAX(r->a,r->b);       */
+       } else {
+               r->Nq = Nc; /* for now */
+       }
+
+       /* Check for illegal constants */
+# if 0
+       if (Lp >= 16) st_fail("Error: Lp>=16");
+       if (Nb+Nhg+NLpScl >= 32) st_fail("Error: Nb+Nhg+NLpScl>=32");
+       if (Nh+Nb > 32) st_fail("Error: Nh+Nb>32");
+# endif
+
+       /* Nwing: # of filter coeffs in right wing */
+       r->Nwing = r->Nq * (r->Nmult/2+1) + 1;
+
+       r->Imp = (Float *)malloc(sizeof(Float) * (r->Nwing+2)) + 1;
+       /* need Imp[-1] and Imp[Nwing] for quadratic interpolation */
+       /* returns error # <=0, or adjusted wing-len > 0 */
+       i = makeFilter(r->Imp, r->Nwing, r->rolloff, r->beta, r->Nq, 1);
+       if (i <= 0)
+       {
+               st_fail("resample: Unable to make filter\n");
+               return (ST_EOF);
+       }
+
+       /*st_report("Nmult: %ld, Nwing: %ld, Nq: %ld\n",r->Nmult,r->Nwing,r->Nq);*/
+
+       if (r->quadr < 0) { /* exact coeff's method */
+               r->Xh = r->Nwing/r->b;
+         st_report("resample: rate ratio %ld:%ld, coeff interpolation not needed\n", r->a, r->b);
+       } else {
+         r->dhb = Np;  /* Fixed-point Filter sampling-time-increment */
+         if (r->Factor<1.0) r->dhb = r->Factor*Np + 0.5;
+         r->Xh = (r->Nwing<<La)/r->dhb;
+         /* (Xh * dhb)>>La is max index into Imp[] */
+       }
+
+       /* reach of LP filter wings + some creeping room */
+       Xoff = r->Xh + 10;
+       r->Xoff = Xoff;
+
+       /* Current "now"-sample pointer for input to filter */
+       r->Xp = Xoff;
+       /* Position in input array to read into */
+       r->Xread = Xoff;
+       /* Current-time pointer for converter */
+       r->Time = Xoff;
+       if (r->quadr < 0) { /* exact coeff's method */
+               r->t = Xoff*r->Nq;
+       }
+       i = BUFFSIZE - 2*Xoff;
+       if (i < r->Factor + 1.0/r->Factor)      /* Check input buffer size */
+       {
+               st_fail("Factor is too small or large for BUFFSIZE");
+               return (ST_EOF);
+       }
+       
+       r->Xsize = 2*Xoff + i/(1.0+r->Factor);
+       r->Ysize = BUFFSIZE - r->Xsize;
+       /* st_report("Xsize %d, Ysize %d, Xoff %d",r->Xsize,r->Ysize,r->Xoff); */
+
+       r->X = (Float *) malloc(sizeof(Float) * (BUFFSIZE));
+       r->Y = r->X + r->Xsize;
+
+       /* Need Xoff zeros at beginning of sample */
+       for (i=0; i<Xoff; i++)
+               r->X[i] = 0;
+       return (ST_SUCCESS);
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+int st_resample_flow(resample_t *rH, st_sample_t *ibuf, st_sample_t *obuf, 
+                     st_size_t *isamp, st_size_t *osamp)
+{
+       long i, last, Nout, Nx, Nproc;
+       resample_t r = *rH;
+
+       /* constrain amount we actually process */
+       /*fprintf(stderr,"Xp %d, Xread %d, isamp %d, ",r->Xp, r->Xread,*isamp);*/
+
+       Nproc = r->Xsize - r->Xp;
+
+       i = (r->Ysize < *osamp)? r->Ysize : *osamp;
+       if (Nproc * r->Factor >= i)
+         Nproc = i / r->Factor;
+
+       Nx = Nproc - r->Xread; /* space for right-wing future-data */
+       if (Nx <= 0)
+       {
+               st_fail("resample: Can not handle this sample rate change. Nx not positive: %d", Nx);
+               return (ST_EOF);
+       }
+       if (Nx > *isamp)
+               Nx = *isamp;
+       /*fprintf(stderr,"Nx %d\n",Nx);*/
+
+       if (ibuf == NULL) {
+               for(i = r->Xread; i < Nx + r->Xread  ; i++) 
+                       r->X[i] = 0;
+       } else {
+               for(i = r->Xread; i < Nx + r->Xread  ; i++) 
+                       r->X[i] = (Float)(*ibuf++)/ISCALE;
+       }
+       last = i;
+       Nproc = last - r->Xoff - r->Xp;
+
+       if (Nproc <= 0) {
+               /* fill in starting here next time */
+               r->Xread = last;
+               /* leave *isamp alone, we consumed it */
+               *osamp = 0;
+               return (ST_SUCCESS);
+       }
+       if (r->quadr < 0) { /* exact coeff's method */
+               long creep; 
+               Nout = SrcEX(r, Nproc);
+               /*fprintf(stderr,"Nproc %d --> %d\n",Nproc,Nout);*/
+               /* Move converter Nproc samples back in time */
+               r->t -= Nproc * r->b;
+               /* Advance by number of samples processed */
+               r->Xp += Nproc;
+               /* Calc time accumulation in Time */
+               creep = r->t/r->b - r->Xoff; 
+               if (creep)
+               {
+                 r->t -= creep * r->b;  /* Remove time accumulation   */
+                 r->Xp += creep;        /* and add it to read pointer */
+                 /*fprintf(stderr,"Nproc %ld, creep %ld\n",Nproc,creep);*/
+               }
+       } else { /* approx coeff's method */
+               long creep; 
+               Nout = SrcUD(r, Nproc);
+               /*fprintf(stderr,"Nproc %d --> %d\n",Nproc,Nout);*/
+               /* Move converter Nproc samples back in time */
+               r->Time -= Nproc;
+               /* Advance by number of samples processed */
+               r->Xp += Nproc;
+               /* Calc time accumulation in Time */
+               creep = r->Time - r->Xoff; 
+               if (creep)
+               {
+                 r->Time -= creep;   /* Remove time accumulation   */
+                 r->Xp += creep;     /* and add it to read pointer */
+                 /* fprintf(stderr,"Nproc %ld, creep %ld\n",Nproc,creep); */
+               }
+       }
+
+       {
+       long i,k;
+       /* Copy back portion of input signal that must be re-used */
+       k = r->Xp - r->Xoff;
+       /*fprintf(stderr,"k %d, last %d\n",k,last);*/
+       for (i=0; i<last - k; i++) 
+           r->X[i] = r->X[i+k];
+
+       /* Pos in input buff to read new data into */
+       r->Xread = i;                 
+       r->Xp = r->Xoff;
+
+       for(i=0; i < Nout; i++) { 
+               // orig: *obuf++ = r->Y[i] * ISCALE;
+               Float ftemp = r->Y[i] * ISCALE;
+
+               if (ftemp >= ST_SAMPLE_MAX)
+                       *obuf = ST_SAMPLE_MAX;
+               else if (ftemp <= ST_SAMPLE_MIN)
+                       *obuf = ST_SAMPLE_MIN;
+               else
+                       *obuf = ftemp;
+               obuf++;
+        }
+
+       *isamp = Nx;
+       *osamp = Nout;
+
+       }
+       return (ST_SUCCESS);
+}
+
+/*
+ * Process tail of input samples.
+ */
+int st_resample_drain(resample_t *rH, st_sample_t *obuf, st_size_t *osamp)
+{
+       long isamp_res, osamp_res;
+       st_sample_t *Obuf;
+       int rc;
+       resample_t r = *rH;
+
+       /* fprintf(stderr,"Xoff %d, Xt %d  <--- DRAIN\n",r->Xoff, r->Xt); */
+
+       /* stuff end with Xoff zeros */
+       isamp_res = r->Xoff;
+       osamp_res = *osamp;
+       Obuf = obuf;
+       while (isamp_res>0 && osamp_res>0) {
+               st_sample_t Isamp, Osamp;
+               Isamp = isamp_res;
+               Osamp = osamp_res;
+               rc = st_resample_flow(rH, NULL, Obuf, (st_size_t *)&Isamp, (st_size_t *)&Osamp);
+               if (rc)
+                   return rc;
+         /* fprintf(stderr,"DRAIN isamp,osamp  (%d,%d) -> (%d,%d)\n",
+                    isamp_res,osamp_res,Isamp,Osamp); */
+               Obuf += Osamp;
+               osamp_res -= Osamp;
+               isamp_res -= Isamp;
+       }
+       *osamp -= osamp_res;
+       /* fprintf(stderr,"DRAIN osamp %d\n", *osamp); */
+       if (isamp_res)
+               st_warn("drain overran obuf by %d\n", isamp_res); 
+       return (ST_SUCCESS);
+}
+
+/*
+ * Do anything required when you stop reading samples.  
+ * Don't close input file! 
+ */
+int st_resample_stop(resample_t *rH)
+{
+       resample_t r = *rH;     
+       
+       free(r->Imp - 1);
+       free(r->X);
+       free(r);
+       /* free(r->Y); Y is in same block starting at X */ 
+       return (ST_SUCCESS);
+}
+
+/* over 90% of CPU time spent in this iprodUD() function */
+/* quadratic interpolation */
+static double qprodUD(const Float Imp[], const Float *Xp, long Inc, double T0, 
+                     long dhb, long ct)
+{
+  const double f = 1.0/(1<<La);
+  double v;
+  long Ho;
+
+  Ho = T0 * dhb;
+  Ho += (ct-1)*dhb; /* so Float sum starts with smallest coef's */
+  Xp += (ct-1)*Inc;
+  v = 0;
+  do {
+    Float coef;
+    long Hoh;
+    Hoh = Ho>>La;
+    coef = Imp[Hoh];
+    {
+      Float dm,dp,t;
+      dm = coef - Imp[Hoh-1];
+      dp = Imp[Hoh+1] - coef;
+      t =(Ho & Amask) * f;
+      coef += ((dp-dm)*t + (dp+dm))*t*0.5;
+    }
+    /* filter coef, lower La bits by quadratic interpolation */
+    v += coef * *Xp;   /* sum coeff * input sample */
+    Xp -= Inc;     /* Input signal step. NO CHECK ON ARRAY BOUNDS */
+    Ho -= dhb;     /* IR step */
+  } while(--ct);
+  return v;
+}
+
+/* linear interpolation */
+static double iprodUD(const Float Imp[], const Float *Xp, long Inc, 
+                     double T0, long dhb, long ct)
+{
+  const double f = 1.0/(1<<La);
+  double v;
+  long Ho;
+
+  Ho = T0 * dhb;
+  Ho += (ct-1)*dhb; /* so Float sum starts with smallest coef's */
+  Xp += (ct-1)*Inc;
+  v = 0;
+  do {
+    Float coef;
+    long Hoh;
+    Hoh = Ho>>La;
+    /* if (Hoh >= End) break; */
+    coef = Imp[Hoh] + (Imp[Hoh+1]-Imp[Hoh]) * (Ho & Amask) * f;
+    /* filter coef, lower La bits by linear interpolation */
+    v += coef * *Xp;   /* sum coeff * input sample */
+    Xp -= Inc;     /* Input signal step. NO CHECK ON ARRAY BOUNDS */
+    Ho -= dhb;     /* IR step */
+  } while(--ct);
+  return v;
+}
+
+/* From resample:filters.c */
+/* Sampling rate conversion subroutine */
+
+static long SrcUD(resample_t r, long Nx)
+{
+   Float *Ystart, *Y;
+   double Factor;
+   double dt;                  /* Step through input signal */
+   double time;
+   double (*prodUD)();
+   int n;
+
+   prodUD = (r->quadr)? qprodUD:iprodUD; /* quadratic or linear interp */
+   Factor = r->Factor;
+   time = r->Time;
+   dt = 1.0/Factor;        /* Output sampling period */
+   /*fprintf(stderr,"Factor %f, dt %f, ",Factor,dt); */
+   /*fprintf(stderr,"Time %f, ",r->Time);*/
+   /* (Xh * dhb)>>La is max index into Imp[] */
+   /*fprintf(stderr,"ct=%d\n",ct);*/
+   /*fprintf(stderr,"ct=%.2f %d\n",(double)r->Nwing*Na/r->dhb, r->Xh);*/
+   /*fprintf(stderr,"ct=%ld, T=%.6f, dhb=%6f, dt=%.6f\n",
+                        r->Xh, time-floor(time),(double)r->dhb/Na,dt);*/
+   Ystart = Y = r->Y;
+   n = (int)ceil((double)Nx/dt);
+   while(n--)
+      {
+      Float *Xp;
+      double v;
+      double T;
+      T = time-floor(time);        /* fractional part of Time */
+      Xp = r->X + (long)time;      /* Ptr to current input sample */
+
+      /* Past  inner product: */
+      v = (*prodUD)(r->Imp, Xp, -1, T, r->dhb, r->Xh); /* needs Np*Nmult in 31 bits */
+      /* Future inner product: */
+      v += (*prodUD)(r->Imp, Xp+1, 1, (1.0-T), r->dhb, r->Xh); /* prefer even total */
+
+      if (Factor < 1) v *= Factor;
+      *Y++ = v;              /* Deposit output */
+      time += dt;            /* Move to next sample by time increment */
+      }
+   r->Time = time;
+   /*fprintf(stderr,"Time %f\n",r->Time);*/
+   return (Y - Ystart);        /* Return the number of output samples */
+}
+
+/* exact coeff's */
+static double prodEX(const Float Imp[], const Float *Xp, 
+                    long Inc, long T0, long dhb, long ct)
+{
+  double v;
+  const Float *Cp;
+
+  Cp  = Imp + (ct-1)*dhb + T0; /* so Float sum starts with smallest coef's */
+  Xp += (ct-1)*Inc;
+  v = 0;
+  do {
+    v += *Cp * *Xp;   /* sum coeff * input sample */
+    Cp -= dhb;     /* IR step */
+    Xp -= Inc;     /* Input signal step. */
+  } while(--ct);
+  return v;
+}
+
+static long SrcEX(resample_t r, long Nx)
+{
+   Float *Ystart, *Y;
+   double Factor;
+   long a,b;
+   long time;
+   int n;
+
+   Factor = r->Factor;
+   time = r->t;
+   a = r->a;
+   b = r->b;
+   Ystart = Y = r->Y;
+   n = (Nx*b + (a-1))/a;
+   while(n--)
+      {
+       Float *Xp;
+       double v;
+       long T;
+       T = time % b;              /* fractional part of Time */
+       Xp = r->X + (time/b);      /* Ptr to current input sample */
+
+       /* Past  inner product: */
+       v = prodEX(r->Imp, Xp, -1, T, b, r->Xh);
+       /* Future inner product: */
+       v += prodEX(r->Imp, Xp+1, 1, b-T, b, r->Xh);
+
+       if (Factor < 1) v *= Factor;
+       *Y++ = v;             /* Deposit output */
+       time += a;            /* Move to next sample by time increment */
+      }
+   r->t = time;
+   return (Y - Ystart);        /* Return the number of output samples */
+}
+
+int makeFilter(Float Imp[], long Nwing, double Froll, double Beta, 
+              long Num, int Normalize)
+{
+   double *ImpR;
+   long Mwing, i;
+
+   if (Nwing > MAXNWING)                      /* Check for valid parameters */
+      return(-1);
+   if ((Froll<=0) || (Froll>1))
+      return(-2);
+
+   /* it does help accuracy a bit to have the window stop at
+    * a zero-crossing of the sinc function */
+   Mwing = floor((double)Nwing/(Num/Froll))*(Num/Froll) +0.5;
+   if (Mwing==0)
+      return(-4);
+
+   ImpR = (double *) malloc(sizeof(double) * Mwing);
+
+   /* Design a Nuttall or Kaiser windowed Sinc low-pass filter */
+   LpFilter(ImpR, Mwing, Froll, Beta, Num);
+
+   if (Normalize) { /* 'correct' the DC gain of the lowpass filter */
+      long Dh;
+      double DCgain;
+      DCgain = 0;
+      Dh = Num;                  /* Filter sampling period for factors>=1 */
+      for (i=Dh; i<Mwing; i+=Dh)
+         DCgain += ImpR[i];
+      DCgain = 2*DCgain + ImpR[0];    /* DC gain of real coefficients */
+      /*st_report("DCgain err=%.12f",DCgain-1.0);*/
+  
+      DCgain = 1.0/DCgain;
+      for (i=0; i<Mwing; i++)
+         Imp[i] = ImpR[i]*DCgain;
+
+   } else {
+      for (i=0; i<Mwing; i++)
+         Imp[i] = ImpR[i];
+   }
+   free(ImpR);
+   for (i=Mwing; i<=Nwing; i++) Imp[i] = 0;
+   /* Imp[Mwing] and Imp[-1] needed for quadratic interpolation */
+   Imp[-1] = Imp[1];
+
+   return(Mwing);
+}
+
+/* LpFilter()
+ *
+ * reference: "Digital Filters, 2nd edition"
+ *            R.W. Hamming, pp. 178-179
+ *
+ * Izero() computes the 0th order modified bessel function of the first kind.
+ *    (Needed to compute Kaiser window).
+ *
+ * LpFilter() computes the coeffs of a Kaiser-windowed low pass filter with
+ *    the following characteristics:
+ *
+ *       c[]  = array in which to store computed coeffs
+ *       frq  = roll-off frequency of filter
+ *       N    = Half the window length in number of coeffs
+ *       Beta = parameter of Kaiser window
+ *       Num  = number of coeffs before 1/frq
+ *
+ * Beta trades the rejection of the lowpass filter against the transition
+ *    width from passband to stopband.  Larger Beta means a slower
+ *    transition and greater stopband rejection.  See Rabiner and Gold
+ *    (Theory and Application of DSP) under Kaiser windows for more about
+ *    Beta.  The following table from Rabiner and Gold gives some feel
+ *    for the effect of Beta:
+ *
+ * All ripples in dB, width of transition band = D*N where N = window length
+ *
+ *               BETA    D       PB RIP   SB RIP
+ *               2.120   1.50  +-0.27      -30
+ *               3.384   2.23    0.0864    -40
+ *               4.538   2.93    0.0274    -50
+ *               5.658   3.62    0.00868   -60
+ *               6.764   4.32    0.00275   -70
+ *               7.865   5.0     0.000868  -80
+ *               8.960   5.7     0.000275  -90
+ *               10.056  6.4     0.000087  -100
+ */
+
+
+#define IzeroEPSILON 1E-21               /* Max error acceptable in Izero */
+
+static double Izero(double x)
+{
+   double sum, u, halfx, temp;
+   long n;
+
+   sum = u = n = 1;
+   halfx = x/2.0;
+   do {
+      temp = halfx/(double)n;
+      n += 1;
+      temp *= temp;
+      u *= temp;
+      sum += u;
+   } while (u >= IzeroEPSILON*sum);
+   return(sum);
+}
+
+static void LpFilter(double *c, long N, double frq, double Beta, long Num)
+{
+   long i;
+
+   /* Calculate filter coeffs: */
+   c[0] = frq;
+   for (i=1; i<N; i++) {
+      double x = M_PI*(double)i/(double)(Num);
+      c[i] = sin(x*frq)/x;
+   }
+  
+   if (Beta>2) { /* Apply Kaiser window to filter coeffs: */
+      double IBeta = 1.0/Izero(Beta);
+      for (i=1; i<N; i++) {
+         double x = (double)i / (double)(N);
+         c[i] *= Izero(Beta*sqrt(1.0-x*x)) * IBeta;
+      }
+   } else { /* Apply Nuttall window: */
+      for(i = 0; i < N; i++) {
+         double x = M_PI*i / N;
+         c[i] *= 0.36335819 + 0.4891775*cos(x) + 0.1365995*cos(2*x) + 0.0106411*cos(3*x);
+      }
+   }
+}
diff --git a/utils/iaxclient/lib/sox/sox.h b/utils/iaxclient/lib/sox/sox.h
new file mode 100644 (file)
index 0000000..5776f34
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * FILE: resample.h
+ *   BY: Julius Smith (at CCRMA, Stanford U)
+ * C BY: translated from SAIL to C by Christopher Lee Fraley
+ *          (cf0v@andrew.cmu.edu)
+ * DATE: 7-JUN-88
+ * VERS: 2.0  (17-JUN-88, 3:00pm)
+ */
+
+/*
+ * October 29, 1999
+ * Various changes, bugfixes(?), increased precision, by Stan Brooks.
+ *
+ * This source code 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.
+ *
+ */
+
+/* Conversion constants */
+#define Lc        7
+#define Nc       (1<<Lc)
+#define La        16
+#define Na       (1<<La)
+#define Lp       (Lc+La)
+#define Np       (1<<Lp)
+#define Amask    (Na-1)
+#define Pmask    (Np-1)
+
+#define MAXNWING  (80<<Lc)
+/* Description of constants:
+ *
+ * Nc - is the number of look-up values available for the lowpass filter
+ *    between the beginning of its impulse response and the "cutoff time"
+ *    of the filter.  The cutoff time is defined as the reciprocal of the
+ *    lowpass-filter cut off frequence in Hz.  For example, if the
+ *    lowpass filter were a sinc function, Nc would be the index of the
+ *    impulse-response lookup-table corresponding to the first zero-
+ *    crossing of the sinc function.  (The inverse first zero-crossing
+ *    time of a sinc function equals its nominal cutoff frequency in Hz.)
+ *    Nc must be a power of 2 due to the details of the current
+ *    implementation. The default value of 128 is sufficiently high that
+ *    using linear interpolation to fill in between the table entries
+ *    gives approximately 16-bit precision, and quadratic interpolation
+ *    gives about 23-bit (float) precision in filter coefficients.
+ *
+ * Lc - is log base 2 of Nc.
+ *
+ * La - is the number of bits devoted to linear interpolation of the
+ *    filter coefficients.
+ *
+ * Lp - is La + Lc, the number of bits to the right of the binary point
+ *    in the integer "time" variable. To the left of the point, it indexes
+ *    the input array (X), and to the right, it is interpreted as a number
+ *    between 0 and 1 sample of the input X.  The default value of 23 is
+ *    about right.  There is a constraint that the filter window must be
+ *    "addressable" in a int32_t, more precisely, if Nmult is the number
+ *    of sinc zero-crossings in the right wing of the filter window, then
+ *    (Nwing<<Lp) must be expressible in 31 bits.
+ *
+ */
+
+/* this Float MUST match that in filter.c */
+#define Float double/*float*/
+#define ISCALE 0x10000
+
+/* largest factor for which exact-coefficients upsampling will be used
+ * */
+#define NQMAX 511
+
+#define BUFFSIZE 8192 /*16384*/  /* Total I/O buffer size */
+
+typedef short st_sample_t;
+typedef unsigned long st_size_t;
+typedef int st_ssize_t;
+
+#define ST_SAMPLE_MAX 0x7fff
+#define ST_SAMPLE_MIN (-ST_SAMPLE_MAX - 1)
+
+#define ST_SUCCESS 0
+#define ST_EOF 1
+
+#define ST_SAMPLE_RATE 8000
+#define ST_CHANNELS 1
+
+
+/* Private data for Lerp via LCM file */
+typedef struct resamplestuff {
+   double Factor;     /* Factor = Fout/Fin sample rates */
+   double rolloff;    /* roll-off frequency */
+   double beta;       /* passband/stopband tuning magic */
+   int quadr;         /* non-zero to use qprodUD quadratic interpolation */
+   long Nmult;        
+   long Nwing;
+   long Nq;
+   Float *Imp;        /* impulse [Nwing+1] Filter coefficients */
+   
+   double Time;       /* Current time/pos in input sample */
+   long dhb;
+   
+   long a,b;          /* gcd-reduced input,output rates   */
+   long t;            /* Current time/pos for exact-coeff's method */
+   
+   long Xh;           /* number of past/future samples needed by filter */
+   long Xoff;         /* Xh plus some room for creep  */
+   long Xread;        /* X[Xread] is start-position to enter new samples */
+   long Xp;           /* X[Xp] is position to start filter application */
+   long Xsize,Ysize;  /* size (Floats) of X[],Y[]         */
+   Float *X, *Y;      /* I/O buffers */
+} *resample_t;
+
+
+typedef struct compand {
+  int expectedChannels; /* Also flags that channels aren't to be treated
+                           individually when = 1 and input not mono */
+  int transferPoints;   /* Number of points specified on the transfer
+                           function */
+  double *attackRate;   /* An array of attack rates */
+  double *decayRate;    /*    ... and of decay rates */
+  double *transferIns;  /*    ... and points on the transfer function */
+  double *transferOuts;
+  double *volume;       /* Current "volume" of each channel */
+  double outgain;       /* Post processor gain */
+  double delay;         /* Delay to apply before companding */
+  st_sample_t *delay_buf;   /* Old samples, used for delay processing */
+  st_ssize_t delay_buf_size;/* Size of delay_buf in samples */
+  st_ssize_t delay_buf_ptr; /* Index into delay_buf */
+  st_ssize_t delay_buf_cnt; /* No. of active entries in delay_buf */
+  short int delay_buf_full; /* Shows buffer situation (important for st_compand_drain) */
+} *compand_t;
+
+
+int st_resample_start(resample_t *rH, int inrate, int outrate);
+int st_resample_flow(resample_t *rH, st_sample_t *ibuf, st_sample_t *obuf,
+                     st_size_t *isamp, st_size_t *osamp);
+int st_resample_drain(resample_t *rH, st_sample_t *obuf, st_size_t *osamp);
+int st_resample_stop(resample_t *rH);
+
+
+int st_compand_getopts(compand_t l, int n, char **argv); 
+int st_compand_start(compand_t *lH, char **opts, int nopts);
+int st_compand_flow(compand_t l, st_sample_t *ibuf, st_sample_t *obuf, 
+                     st_size_t *isamp, st_size_t *osamp);
+int st_compand_drain(compand_t l, st_sample_t *obuf, st_size_t *osamp);
+int st_compand_stop(compand_t l);
+
+void st_report(const char *fmt, ...);
+void st_fail(const char *fmt, ...);
+void st_warn(const char *fmt, ...);
+long st_gcd(long a, long b);
diff --git a/utils/iaxclient/lib/sox/soxcompat.c b/utils/iaxclient/lib/sox/soxcompat.c
new file mode 100644 (file)
index 0000000..c3135fc
--- /dev/null
@@ -0,0 +1,63 @@
+/* Sox-compatibility functions:  stuff to make sox dsp routines compile outside        of sox itself */
+#include "sox.h"
+#include <stdio.h>
+
+#if defined(__STDC__) || defined(_MSC_VER)
+#include <stdarg.h>
+#include <stdlib.h>
+#else
+#include <varargs.h>
+#endif
+
+static int verbose = 0;
+static char *myname="iaxclient-sox";
+
+void st_report(const char *fmt, ...)
+{
+        va_list args;
+
+        if (! verbose)
+                return;
+
+        fprintf(stderr, "%s: ", myname);
+        va_start(args, fmt);
+        vfprintf(stderr, fmt, args);
+        va_end(args);
+        fprintf(stderr, "\n");
+}
+
+void st_warn(const char *fmt, ...)
+{
+        va_list args;
+
+        fprintf(stderr, "%s: ", myname);
+        va_start(args, fmt);
+
+        vfprintf(stderr, fmt, args);
+        va_end(args);
+        fprintf(stderr, "\n");
+}
+
+void st_fail(const char *fmt, ...)
+{
+        va_list args;
+        extern void cleanup();
+
+        fprintf(stderr, "%s: ", myname);
+
+        va_start(args, fmt);
+        vfprintf(stderr, fmt, args);
+        va_end(args);
+        fprintf(stderr, "\n");
+        exit(2);
+}
+
+long st_gcd(long a, long b)
+{
+        if (b == 0)
+                return a;
+        else
+                return st_gcd(b, a % b);
+}
+
+
diff --git a/utils/iaxclient/lib/spandsp/plc.c b/utils/iaxclient/lib/spandsp/plc.c
new file mode 100644 (file)
index 0000000..4edbb2d
--- /dev/null
@@ -0,0 +1,267 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * plc.c
+ *
+ * Written by Steve Underwood <steveu@coppice.org>
+ *
+ * Copyright (C) 2004 Steve Underwood
+ *
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * This version may be optionally licenced under the GNU LGPL licence.
+ * This version is disclaimed to DIGIUM for inclusion in the Asterisk project.
+ */
+
+/*! \file */
+#ifdef HAVE_CONIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <limits.h>
+
+#include "plc.h"
+
+#if !defined(FALSE)
+#define FALSE 0
+#endif
+#if !defined(TRUE)
+#define TRUE (!FALSE)
+#endif
+
+#if !defined(INT16_MAX)
+#define INT16_MAX      (32767)
+#define INT16_MIN      (-32767-1)
+#endif
+
+/* msvc doesn't know rint() */
+#if defined(WIN32) && defined(_MSC_VER)
+#define rint(x) floor((x) + 0.5)
+#undef inline
+#define inline __inline
+#ifndef int16_t
+typedef short int16_t;
+#endif
+#endif
+
+/* We do a straight line fade to zero volume in 50ms when we are filling in for missing data. */
+#define ATTENUATION_INCREMENT       0.0025                              /* Attenuation per sample */
+
+#define ms_to_samples(t)            (((t)*SAMPLE_RATE)/1000)
+
+static inline int16_t fsaturate(double damp)
+{
+    if (damp > 32767.0)
+       return  INT16_MAX;
+    if (damp < -32768.0)
+       return  INT16_MIN;
+    return (int16_t) rint(damp);
+}
+
+static void save_history(plc_state_t *s, int16_t *buf, int len)
+{
+    if (len >= PLC_HISTORY_LEN)
+    {
+        /* Just keep the last part of the new data, starting at the beginning of the buffer */
+        memcpy(s->history, buf + len - PLC_HISTORY_LEN, sizeof(int16_t)*PLC_HISTORY_LEN);
+        s->buf_ptr = 0;
+        return;
+    }
+    if (s->buf_ptr + len > PLC_HISTORY_LEN)
+    {
+        /* Wraps around - must break into two sections */
+        memcpy(s->history + s->buf_ptr, buf, sizeof(int16_t)*(PLC_HISTORY_LEN - s->buf_ptr));
+        len -= (PLC_HISTORY_LEN - s->buf_ptr);
+        memcpy(s->history, buf + (PLC_HISTORY_LEN - s->buf_ptr), sizeof(int16_t)*len);
+        s->buf_ptr = len;
+        return;
+    }
+    /* Can use just one section */
+    memcpy(s->history + s->buf_ptr, buf, sizeof(int16_t)*len);
+    s->buf_ptr += len;
+}
+/*- End of function --------------------------------------------------------*/
+
+static void normalise_history(plc_state_t *s)
+{
+    int16_t tmp[PLC_HISTORY_LEN];
+
+    if (s->buf_ptr == 0)
+        return;
+    memcpy(tmp, s->history, sizeof(int16_t)*s->buf_ptr);
+    memcpy(s->history, s->history + s->buf_ptr, sizeof(int16_t)*(PLC_HISTORY_LEN - s->buf_ptr));
+    memcpy(s->history + PLC_HISTORY_LEN - s->buf_ptr, tmp, sizeof(int16_t)*s->buf_ptr);
+    s->buf_ptr = 0;
+}
+/*- End of function --------------------------------------------------------*/
+
+static int inline amdf_pitch(int min_pitch, int max_pitch, int16_t amp[], int len)
+{
+    int i;
+    int j;
+    int acc;
+    int min_acc;
+    int pitch;
+
+    pitch = min_pitch;
+    min_acc = INT_MAX;
+    for (i = max_pitch;  i <= min_pitch;  i++)
+    {
+        acc = 0;
+        for (j = 0;  j < len;  j++)
+            acc += abs(amp[i + j] - amp[j]);
+        if (acc < min_acc)
+        {
+            min_acc = acc;
+            pitch = i;
+        }
+    }
+    return pitch;
+}
+/*- End of function --------------------------------------------------------*/
+
+int plc_rx(plc_state_t *s, int16_t amp[], int len)
+{
+    int i;
+    int pitch_overlap;
+    float old_step;
+    float new_step;
+    float old_weight;
+    float new_weight;
+    float gain;
+    
+    if (s->missing_samples)
+    {
+        /* Although we have a real signal, we need to smooth it to fit well
+           with the synthetic signal we used for the previous block */
+
+        /* The start of the real data is overlapped with the next 1/4 cycle
+           of the synthetic data. */
+        pitch_overlap = s->pitch >> 2;
+        if (pitch_overlap > len)
+            pitch_overlap = len;
+        gain = 1.0 - s->missing_samples*ATTENUATION_INCREMENT;
+        if (gain < 0.0)
+            gain = 0.0;
+        new_step = 1.0/pitch_overlap;
+        old_step = new_step*gain;
+        new_weight = new_step;
+        old_weight = (1.0 - new_step)*gain;
+        for (i = 0;  i < pitch_overlap;  i++)
+        {
+            amp[i] = fsaturate(old_weight*s->pitchbuf[s->pitch_offset] + new_weight*amp[i]);
+            if (++s->pitch_offset >= s->pitch)
+                s->pitch_offset = 0;
+            new_weight += new_step;
+            old_weight -= old_step;
+            if (old_weight < 0.0)
+                old_weight = 0.0;
+        }
+        s->missing_samples = 0;
+    }
+    save_history(s, amp, len);
+    return len;
+}
+/*- End of function --------------------------------------------------------*/
+
+int plc_fillin(plc_state_t *s, int16_t amp[], int len)
+{
+    int i;
+    int pitch_overlap;
+    float old_step;
+    float new_step;
+    float old_weight;
+    float new_weight;
+    float gain;
+    //int16_t *orig_amp;
+    int orig_len;
+
+    //orig_amp = amp;
+    orig_len = len;
+    if (s->missing_samples == 0)
+    {
+        /* As the gap in real speech starts we need to assess the last known pitch,
+           and prepare the synthetic data we will use for fill-in */
+        normalise_history(s);
+        s->pitch = amdf_pitch(PLC_PITCH_MIN, PLC_PITCH_MAX, s->history + PLC_HISTORY_LEN - CORRELATION_SPAN - PLC_PITCH_MIN, CORRELATION_SPAN);
+        /* We overlap a 1/4 wavelength */
+        pitch_overlap = s->pitch >> 2;
+        /* Cook up a single cycle of pitch, using a single of the real signal with 1/4
+           cycle OLA'ed to make the ends join up nicely */
+        /* The first 3/4 of the cycle is a simple copy */
+        for (i = 0;  i < s->pitch - pitch_overlap;  i++)
+            s->pitchbuf[i] = s->history[PLC_HISTORY_LEN - s->pitch + i];
+        /* The last 1/4 of the cycle is overlapped with the end of the previous cycle */
+        new_step = 1.0/pitch_overlap;
+        new_weight = new_step;
+        for (  ;  i < s->pitch;  i++)
+        {
+            s->pitchbuf[i] = s->history[PLC_HISTORY_LEN - s->pitch + i]*(1.0 - new_weight) + s->history[PLC_HISTORY_LEN - 2*s->pitch + i]*new_weight;
+            new_weight += new_step;
+        }
+        /* We should now be ready to fill in the gap with repeated, decaying cycles
+           of what is in pitchbuf */
+
+        /* We need to OLA the first 1/4 wavelength of the synthetic data, to smooth
+           it into the previous real data. To avoid the need to introduce a delay
+           in the stream, reverse the last 1/4 wavelength, and OLA with that. */
+        gain = 1.0;
+        new_step = 1.0/pitch_overlap;
+        old_step = new_step;
+        new_weight = new_step;
+        old_weight = 1.0 - new_step;
+        for (i = 0;  i < pitch_overlap && i < len;  i++)
+        {
+            amp[i] = fsaturate(old_weight*s->history[PLC_HISTORY_LEN - 1 - i] + new_weight*s->pitchbuf[i]);
+            new_weight += new_step;
+            old_weight -= old_step;
+            if (old_weight < 0.0)
+                old_weight = 0.0;
+        }
+        s->pitch_offset = i;
+    }
+    else
+    {
+        gain = 1.0 - s->missing_samples*ATTENUATION_INCREMENT;
+        i = 0;
+    }
+    for (  ;  gain > 0.0  &&  i < len;  i++)
+    {
+        amp[i] = s->pitchbuf[s->pitch_offset]*gain;
+        gain -= ATTENUATION_INCREMENT;
+        if (++s->pitch_offset >= s->pitch)
+            s->pitch_offset = 0;
+    }
+    for (  ;  i < len;  i++)
+        amp[i] = 0;
+    s->missing_samples += orig_len;
+    save_history(s, amp, len);
+    return len;
+}
+/*- End of function --------------------------------------------------------*/
+
+plc_state_t *plc_init(plc_state_t *s)
+{
+    memset(s, 0, sizeof(*s));
+    return s;
+}
+/*- End of function --------------------------------------------------------*/
+/*- End of file ------------------------------------------------------------*/
diff --git a/utils/iaxclient/lib/spandsp/plc.h b/utils/iaxclient/lib/spandsp/plc.h
new file mode 100644 (file)
index 0000000..1f8b8aa
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * plc.h
+ *
+ * Written by Steve Underwood <steveu@coppice.org>
+ *
+ * Copyright (C) 2004 Steve Underwood
+ *
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * This version may be optionally licenced under the GNU LGPL licence.
+ * This version is disclaimed to DIGIUM for inclusion in the Asterisk project.
+ */
+
+/*! \file */
+
+#if !defined(_PLC_H_)
+#define _PLC_H_
+
+#ifdef SOLARIS
+#include <sys/int_types.h>
+#else
+#ifndef _MSC_VER
+#include <inttypes.h>
+#else
+typedef short int16_t;
+#endif
+#endif
+
+/*! \page plc_page Packet loss concealment
+\section plc_page_sec_1 What does it do?
+The packet loss concealment module provides a suitable synthetic fill-in signal,
+to minimise the audible effect of lost packets in VoIP applications. It is not
+tied to any particular codec, and could be used with almost any codec which does not
+specify its own procedure for packet loss concealment.
+
+Where a codec specific concealment procedure exists, the algorithm is usually built
+around knowledge of the characteristics of the particular codec. It will, therefore,
+generally give better results for that particular codec than this generic concealer will.
+
+\section plc_page_sec_2 How does it work?
+While good packets are being received, the plc_rx() routine keeps a record of the trailing
+section of the known speech signal. If a packet is missed, plc_fillin() is called to produce
+a synthetic replacement for the real speech signal. The average mean difference function
+(AMDF) is applied to the last known good signal, to determine its effective pitch.
+Based on this, the last pitch period of signal is saved. Essentially, this cycle of speech
+will be repeated over and over until the real speech resumes. However, several refinements
+are needed to obtain smooth pleasant sounding results.
+
+- The two ends of the stored cycle of speech will not always fit together smoothly. This can
+  cause roughness, or even clicks, at the joins between cycles. To soften this, the
+  1/4 pitch period of real speech preceeding the cycle to be repeated is blended with the last
+  1/4 pitch period of the cycle to be repeated, using an overlap-add (OLA) technique (i.e.
+  in total, the last 5/4 pitch periods of real speech are used).
+
+- The start of the synthetic speech will not always fit together smoothly with the tail of
+  real speech passed on before the erasure was identified. Ideally, we would like to modify
+  the last 1/4 pitch period of the real speech, to blend it into the synthetic speech. However,
+  it is too late for that. We could have delayed the real speech a little, but that would
+  require more buffer manipulation, and hurt the efficiency of the no-lost-packets case
+  (which we hope is the dominant case). Instead we use a degenerate form of OLA to modify
+  the start of the synthetic data. The last 1/4 pitch period of real speech is time reversed,
+  and OLA is used to blend it with the first 1/4 pitch period of synthetic speech. The result
+  seems quite acceptable.
+
+- As we progress into the erasure, the chances of the synthetic signal being anything like
+  correct steadily fall. Therefore, the volume of the synthesized signal is made to decay
+  linearly, such that after 50ms of missing audio it is reduced to silence.
+
+- When real speech resumes, an extra 1/4 pitch period of sythetic speech is blended with the
+  start of the real speech. If the erasure is small, this smoothes the transition. If the erasure
+  is long, and the synthetic signal has faded to zero, the blending softens the start up of the
+  real signal, avoiding a kind of "click" or "pop" effect that might occur with a sudden onset.
+
+\section plc_page_sec_3 How do I use it?
+Before audio is processed, call plc_init() to create an instance of the packet loss
+concealer. For each received audio packet that is acceptable (i.e. not including those being
+dropped for being too late) call plc_rx() to record the content of the packet. Note this may
+modify the packet a little after a period of packet loss, to blend real synthetic data smoothly.
+When a real packet is not available in time, call plc_fillin() to create a sythetic substitute.
+That's it!
+*/
+
+#define SAMPLE_RATE     8000
+
+/*! Minimum allowed pitch (66 Hz) */
+#define PLC_PITCH_MIN           120
+/*! Maximum allowed pitch (200 Hz) */
+#define PLC_PITCH_MAX           40
+/*! Maximum pitch OLA window */
+#define PLC_PITCH_OVERLAP_MAX   (PLC_PITCH_MIN >> 2)
+/*! The length over which the AMDF function looks for similarity (20 ms) */
+#define CORRELATION_SPAN        160
+/*! History buffer length. The buffer much also be at leat 1.25 times
+    PLC_PITCH_MIN, but that is much smaller than the buffer needs to be for
+    the pitch assessment. */
+#define PLC_HISTORY_LEN         (CORRELATION_SPAN + PLC_PITCH_MIN)
+
+typedef struct
+{
+    /*! Consecutive erased samples */
+    int missing_samples;
+    /*! Current offset into pitch period */
+    int pitch_offset;
+    /*! Pitch estimate */
+    int pitch;
+    /*! Buffer for a cycle of speech */
+    float pitchbuf[PLC_PITCH_MIN];
+    /*! History buffer */
+    int16_t history[PLC_HISTORY_LEN];
+    /*! Current pointer into the history buffer */
+    int buf_ptr;
+} plc_state_t;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*! Process a block of received audio samples.
+    \brief Process a block of received audio samples.
+    \param s The packet loss concealer context.
+    \param amp The audio sample buffer.
+    \param len The number of samples in the buffer.
+    \return The number of samples in the buffer. */
+int plc_rx(plc_state_t *s, int16_t amp[], int len);
+
+/*! Fill-in a block of missing audio samples.
+    \brief Fill-in a block of missing audio samples.
+    \param s The packet loss concealer context.
+    \param amp The audio sample buffer.
+    \param len The number of samples to be synthesised.
+    \return The number of samples synthesized. */
+int plc_fillin(plc_state_t *s, int16_t amp[], int len);
+
+/*! Process a block of received V.29 modem audio samples.
+    \brief Process a block of received V.29 modem audio samples.
+    \param s The packet loss concealer context.
+    \param amp The audio sample buffer.
+    \param len The number of samples in the buffer.
+    \return A pointer to the he packet loss concealer context. */
+plc_state_t *plc_init(plc_state_t *s);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/*- End of file ------------------------------------------------------------*/
diff --git a/utils/iaxclient/lib/unixfuncs.c b/utils/iaxclient/lib/unixfuncs.c
new file mode 100644 (file)
index 0000000..be8dc6e
--- /dev/null
@@ -0,0 +1,409 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003-2006, Horizon Wimba, Inc.
+ * Copyright (C) 2007, Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ */
+
+#define _BSD_SOURCE
+#include <unistd.h>
+#ifndef __USE_POSIX199309
+#define __USE_POSIX199309
+#endif
+#include <time.h>
+#include "iaxclient_lib.h"
+
+//#if (!defined(_MSC_VER) && !defined(HAVE_SYS_TIME_H))
+#define HAVE_SYS_TIME_H 1
+//#endif 
+
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+#else
+# if HAVE_SYS_TIME_H
+#  include <sys/time.h>
+# else
+#  include <time.h>
+# endif
+#endif
+
+#ifndef NULL
+#define NULL (0)
+#endif
+
+/* Unix-specific functions */
+
+void os_init(void)
+{
+}
+
+void iaxc_millisleep(long ms)
+{
+       struct timespec req;
+
+       req.tv_nsec = (ms%1000)*1000*1000;
+       req.tv_sec = ms/1000;
+
+        /* yes, it can return early.  We don't care */
+        nanosleep(&req,NULL);
+}
+
+
+/* TODO: Implement for X/MacOSX? */
+int iaxci_post_event_callback(iaxc_event ev)
+{
+#if 0
+       iaxc_event *e;
+       e = malloc(sizeof(ev));
+       *e = ev;
+
+       /* XXX Test return value? */
+       PostMessage(post_event_handle,post_event_id,(WPARAM) NULL, (LPARAM) e);
+#endif
+       return 0;
+}
+
+#ifdef MACOSX
+    /* Presently, OSX allows user-level processes to request RT
+     * priority.  The API is nice, but the scheduler presently ignores
+     * the parameters (but the API validates that you're not asking for
+     * too much).  See
+     * http://lists.apple.com/archives/darwin-development/2004/Feb/msg00079.html
+     */
+/* include mach stuff for declaration of thread_policy stuff */
+#include <mach/mach.h>
+
+int iaxci_prioboostbegin()
+{
+       struct thread_time_constraint_policy ttcpolicy;
+       int params [2] = {CTL_HW,HW_BUS_FREQ};
+       int hzms;
+       size_t sz;
+       int ret;
+
+       /* get hz */
+       sz = sizeof (hzms);
+       sysctl (params, 2, &hzms, &sz, NULL, 0);
+
+       /* make hzms actually hz per ms */
+       hzms /= 1000;
+
+       /* give us at least how much? 6-8ms every 10ms (we generally need less) */
+       ttcpolicy.period = 10 * hzms; /* 10 ms */
+       ttcpolicy.computation = 2 * hzms;
+       ttcpolicy.constraint = 3 * hzms;
+       ttcpolicy.preemptible = 1;
+
+       if ( (ret = thread_policy_set(mach_thread_self(),
+                       THREAD_TIME_CONSTRAINT_POLICY, (int *)&ttcpolicy,
+                       THREAD_TIME_CONSTRAINT_POLICY_COUNT)) != KERN_SUCCESS )
+       {
+               fprintf(stderr, "thread_policy_set failed: %d.\n", ret);
+       }
+       return 0;
+}
+
+int iaxci_prioboostend()
+{
+    /* TODO */
+    return 0;
+}
+
+#else
+
+
+/* Priority boosting/monitoring:  Adapted from portaudio/pa_unix.c ,
+ * which carries the following copyright notice:
+ * PortAudio Portable Real-Time Audio Library
+ * Latest Version at: http://www.portaudio.com
+ * Linux OSS Implementation by douglas repetto and Phil Burk
+ *
+ * Copyright (c) 1999-2000 Phil Burk
+ *
+ * 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.
+ *
+ * Any person wishing to distribute modifications to the Software is
+ * requested to send the modifications to the original developer so that
+ * they can be incorporated into the canonical version.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ */
+
+/* It has been clarified by the authors that the request to send modifications
+   is a request, and not a condition */
+
+/* Theory:
+ *  The main thread is boosted to a medium real-time priority.
+ *  Two additional threads are created:
+ *  Canary:  Runs as normal priority, updates a timevalue every second.
+ *  WatchDog:  Runs as a higher real-time priority.  Checks to see that
+ *           Canary is running.  If Canary isn't running, lowers
+ *           priority of calling thread, which has presumably run away
+ */
+
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sched.h>
+#include <pthread.h>
+#include <errno.h>
+
+//#define DBUG(...) fprintf(stderr, __VA_ARGS__)
+#define DBUG(...)
+#define ERR_RPT(...) fprintf(stderr, __VA_ARGS__)
+
+#define SCHEDULER_POLICY SCHED_RR
+#define WATCHDOG_INTERVAL_USEC 1000000
+#define WATCHDOG_MAX_SECONDS 3
+
+typedef void *(*pthread_function_t)(void *);
+
+typedef struct {
+       int priority;
+       pthread_t ThreadID;
+
+       struct timeval CanaryTime;
+       int CanaryRun;
+       pthread_t CanaryThread;
+       int IsCanaryThreadValid;
+
+       int WatchDogRun;
+       pthread_t WatchDogThread;
+       int IsWatchDogThreadValid;
+
+} prioboost;
+
+static prioboost *pb;
+
+static int CanaryProc( prioboost *b)
+{
+       int result = 0;
+       struct sched_param schat = { 0 };
+
+       /* set us up with normal priority, please */
+       if( pthread_setschedparam(pthread_self(), SCHED_OTHER, &schat) != 0)
+               return 1;
+
+       while( b->CanaryRun)
+       {
+               usleep( WATCHDOG_INTERVAL_USEC );
+               gettimeofday( &b->CanaryTime, NULL );
+       }
+
+       return result;
+}
+
+static int WatchDogProc( prioboost *b )
+{
+       struct sched_param    schp = { 0 };
+       int                   maxPri;
+
+       /* Run at a priority level above main thread so we can still run if it hangs. */
+       /* Rise more than 1 because of rumored off-by-one scheduler bugs. */
+       schp.sched_priority = b->priority + 4;
+       maxPri = sched_get_priority_max(SCHEDULER_POLICY);
+       if( schp.sched_priority > maxPri ) schp.sched_priority = maxPri;
+
+       if (pthread_setschedparam(pthread_self(), SCHEDULER_POLICY, &schp) != 0)
+       {
+               ERR_RPT("WatchDogProc: cannot set watch dog priority!\n");
+               goto killAudio;
+       }
+
+       DBUG("prioboost: WatchDog priority set to level %d!\n", schp.sched_priority);
+
+       /* Compare watchdog time with audio and canary thread times. */
+       /* Sleep for a while or until thread cancelled. */
+       while( b->WatchDogRun )
+       {
+
+               int              delta;
+               struct timeval   currentTime;
+
+               usleep( WATCHDOG_INTERVAL_USEC );
+               gettimeofday( &currentTime, NULL );
+
+#if 0
+               /* If audio thread is not advancing, then it must be hung so kill it. */
+               delta = currentTime.tv_sec - b->EntryTime.tv_sec;
+               DBUG(("WatchDogProc: audio delta = %d\n", delta ));
+               if( delta > WATCHDOG_MAX_SECONDS )
+               {
+                       goto killAudio;
+               }
+#endif
+
+               /* If canary died, then lower audio priority and halt canary. */
+               delta = currentTime.tv_sec - b->CanaryTime.tv_sec;
+               DBUG("WatchDogProc: dogging, delta = %ld, mysec=%d\n", delta, currentTime.tv_sec);
+               if( delta > WATCHDOG_MAX_SECONDS )
+               {
+                       ERR_RPT("WatchDogProc: canary died!\n");
+                       goto lowerAudio;
+               }
+       }
+
+       DBUG("WatchDogProc: exiting.\n");
+       return 0;
+
+lowerAudio:
+       {
+               struct sched_param    schat = { 0 };
+               if( pthread_setschedparam(b->ThreadID, SCHED_OTHER, &schat) != 0)
+               {
+                       ERR_RPT("WatchDogProc: failed to lower audio priority. errno = %d\n", errno );
+                       /* Fall through into killing audio thread. */
+               }
+               else
+               {
+                       ERR_RPT("WatchDogProc: lowered audio priority to prevent hogging of CPU.\n");
+                       goto cleanup;
+               }
+       }
+
+killAudio:
+       ERR_RPT("WatchDogProc: killing hung audio thread!\n");
+       //pthread_cancel( b->ThreadID);
+       //pthread_join( b->ThreadID);
+       exit(1);
+
+cleanup:
+       b->CanaryRun = 0;
+       DBUG("WatchDogProc: cancel Canary\n");
+       pthread_cancel( b->CanaryThread );
+       DBUG("WatchDogProc: join Canary\n");
+       pthread_join( b->CanaryThread, NULL );
+       DBUG("WatchDogProc: forget Canary\n");
+       b->IsCanaryThreadValid = 0;
+
+#ifdef GNUSTEP
+       GSUnregisterCurrentThread();  /* SB20010904 */
+#endif
+       return 0;
+}
+
+static void StopWatchDog( prioboost *b )
+{
+       /* Cancel WatchDog thread if there is one. */
+       if( b->IsWatchDogThreadValid )
+       {
+               b->WatchDogRun = 0;
+               DBUG("StopWatchDog: cancel WatchDog\n");
+               pthread_cancel( b->WatchDogThread );
+               pthread_join( b->WatchDogThread, NULL );
+               b->IsWatchDogThreadValid = 0;
+       }
+       /* Cancel Canary thread if there is one. */
+       if( b->IsCanaryThreadValid )
+       {
+               b->CanaryRun = 0;
+               DBUG("StopWatchDog: cancel Canary\n");
+               pthread_cancel( b->CanaryThread );
+               DBUG("StopWatchDog: join Canary\n");
+               pthread_join( b->CanaryThread, NULL );
+               b->IsCanaryThreadValid = 0;
+       }
+}
+
+
+static int StartWatchDog( prioboost *b)
+{
+       int  hres;
+       int  result = 0;
+
+       /* The watch dog watches for these timer updates */
+       gettimeofday( &b->CanaryTime, NULL );
+
+       /* Launch a canary thread to detect priority abuse. */
+       b->CanaryRun = 1;
+       hres = pthread_create(&(b->CanaryThread),
+                       NULL /*pthread_attr_t * attr*/,
+                       (pthread_function_t)CanaryProc, b);
+       if( hres != 0 )
+       {
+               b->IsCanaryThreadValid = 0;
+               result = 1;
+               goto error;
+       }
+       b->IsCanaryThreadValid = 1;
+
+       /* Launch a watchdog thread to prevent runaway audio thread. */
+       b->WatchDogRun = 1;
+       hres = pthread_create(&(b->WatchDogThread),
+                       NULL /*pthread_attr_t * attr*/,
+                       (pthread_function_t)WatchDogProc, b);
+       if( hres != 0 )     {
+               b->IsWatchDogThreadValid = 0;
+               result = 1;
+               goto error;
+       }
+       b->IsWatchDogThreadValid = 1;
+       return result;
+
+error:
+       StopWatchDog( b );
+       return result;
+}
+
+int iaxci_prioboostbegin()
+{
+       struct sched_param   schp = { 0 };
+       prioboost *b = calloc(sizeof(*b),1);
+
+       int result = 0;
+
+       b->priority = (sched_get_priority_max(SCHEDULER_POLICY) -
+                       sched_get_priority_min(SCHEDULER_POLICY)) / 2;
+       schp.sched_priority = b->priority;
+
+       b->ThreadID = pthread_self();
+
+       if (pthread_setschedparam(b->ThreadID, SCHEDULER_POLICY, &schp) != 0)
+       {
+               DBUG("prioboost: only superuser can use real-time priority.\n");
+       }
+       else
+       {
+               DBUG("prioboost: priority set to level %d!\n", schp.sched_priority);        /* We are running at high priority so we should have a watchdog in case audio goes wild. */
+               result = StartWatchDog( b );
+       }
+
+       if(result == 0)  {
+               pb = b;
+       } else {
+               pb = NULL;
+               schp.sched_priority = 0;
+               pthread_setschedparam(b->ThreadID, SCHED_OTHER, &schp);
+       }
+
+       return result;
+}
+
+int iaxci_prioboostend()
+{
+       if(pb) StopWatchDog(pb);
+       return 0;
+}
+
+#endif
+
diff --git a/utils/iaxclient/lib/video.c b/utils/iaxclient/lib/video.c
new file mode 100644 (file)
index 0000000..f209edd
--- /dev/null
@@ -0,0 +1,1852 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2005-2006, Horizon Wimba, inc.
+ * Copyright (C) 2007, Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ * Mihai Balea <mihai AT hates DOT ms>
+ * Peter Grayson <jpgrayson@gmail.com>
+ * Erik Bunce <kde@bunce.us>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include <vidcap/vidcap.h>
+#include <vidcap/converters.h>
+
+#include "video.h"
+#include "slice.h"
+#include "iaxclient_lib.h"
+#include "iax-client.h"
+#ifdef USE_FFMPEG
+#include "codec_ffmpeg.h"
+#endif
+#ifdef USE_THEORA
+#include "codec_theora.h"
+#endif
+
+#if defined(WIN32)
+#define strdup _strdup
+#endif
+
+struct video_info
+{
+       vidcap_state * vc;
+       vidcap_sapi * sapi;
+       vidcap_src * src;
+       struct vidcap_sapi_info sapi_info;
+       struct vidcap_fmt_info fmt_info;
+
+       /* these are the requested (post-scaling) dimensions */
+       int width;
+       int height;
+
+       MUTEX camera_lock;
+       int capturing;
+
+       char * converted_i420_buf;
+       int converted_i420_buf_size;
+       int (*convert_to_i420)(int, int, const char *, char *);
+
+       char * converted_rgb_buf;
+       int converted_rgb_buf_size;
+       int (*convert_to_rgb32)(int, int, const char *, char *);
+
+       char * scaled_buf;
+       int scaled_buf_size;
+       void (*scale_image)(const unsigned char *, int, int,
+                       unsigned char *, int, int);
+
+       int prefs;
+
+       struct slicer_context * sc;
+
+       /* these two struct arrays are correlated by index */
+       struct vidcap_src_info * vc_src_info;
+       struct iaxc_video_device * devices;
+       MUTEX dev_list_lock;
+
+       int device_count;
+       int selected_device_id;
+       int next_id;
+};
+
+struct video_format_info
+{
+       int width;
+       int height;
+       int framerate;
+       int bitrate;
+       int fragsize;
+
+       /* Note that here format really means codec (thoera, h264, etc) */
+       int format_preferred;
+       int format_allowed;
+};
+
+static struct video_info vinfo;
+
+/* TODO: This vfinfo instance is ... funny. The current semantic of
+ * iaxc_video_format_set() requires it to be called _prior_ to
+ * iaxc_initialize() which of course is where video initialize is called.
+ * This means that no code in this video.c module is called prior to
+ * iaxc_video_format_set(). This is silly, wrong, and bad.
+ *
+ * What would be better would be if iaxc_video_format_set() was called
+ * by clients _after_ iaxc_initialize(). The TODO here is to do the
+ * analysis and restructure things so that iaxc_video_format_set() and
+ * probably several other iaxc_*() calls do not happen until after
+ * iaxc_initialize().
+ *
+ * Once that happens, these members of video_format_info can be rolled
+ * back into video_info and we can initialize the members in
+ * video_initialize().
+ */
+static struct video_format_info vfinfo =
+{
+       320,    /* width */
+       240,    /* height */
+       15,     /* fps */
+       150000, /* bitrate */
+       1500,   /* fragsize */
+       0,      /* format preferred */
+       0,      /* format allowed */
+};
+
+extern int selected_call;
+extern int test_mode;
+extern struct iaxc_call * calls;
+
+/* to prevent clearing a call while in capture callback */
+extern __inline int try_iaxc_lock();
+extern __inline void put_iaxc_lock();
+
+EXPORT unsigned int iaxc_get_video_prefs(void)
+{
+       return vinfo.prefs;
+}
+
+static void reset_codec_stats(struct iaxc_video_codec *vcodec)
+{
+       if ( !vcodec )
+               return;
+
+       memset(&vcodec->video_stats, 0, sizeof(struct iaxc_video_stats));
+       vcodec->video_stats.start_time = iax_tvnow();
+}
+
+static void reset_video_stats(struct iaxc_call * call)
+{
+       if ( !call )
+               return;
+
+       reset_codec_stats(call->vdecoder);
+       reset_codec_stats(call->vencoder);
+}
+
+/* Collect and return video statistics. Also reset statistics if required.
+ * Returns a pointer to the data.
+ * Right now we use two different codecs for encoding and decoding. We need
+ * to collate information from both and wrap it into one nice struct.
+ */
+static int get_stats(struct iaxc_call *call, struct iaxc_video_stats *stats,
+               int reset)
+{
+       if ( !call || !stats )
+               return -1;
+
+       memset(stats, 0, sizeof(*stats));
+
+       if ( call->vencoder )
+       {
+               stats->sent_slices = call->vencoder->video_stats.sent_slices;
+               stats->acc_sent_size = call->vencoder->video_stats.acc_sent_size;
+               stats->outbound_frames = call->vencoder->video_stats.outbound_frames;
+               stats->avg_outbound_bps = call->vencoder->video_stats.avg_outbound_bps;
+               stats->avg_outbound_fps = call->vencoder->video_stats.avg_outbound_fps;
+       }
+
+       if ( call->vdecoder )
+       {
+               stats->received_slices = call->vdecoder->video_stats.received_slices;
+               stats->acc_recv_size = call->vdecoder->video_stats.acc_recv_size;
+               stats->inbound_frames = call->vdecoder->video_stats.inbound_frames;
+               stats->dropped_frames = call->vdecoder->video_stats.dropped_frames;
+               stats->avg_inbound_bps = call->vdecoder->video_stats.avg_inbound_bps;
+               stats->avg_inbound_fps = call->vdecoder->video_stats.avg_inbound_fps;
+       }
+
+       if ( reset )
+               reset_video_stats(call);
+
+       return 0;
+}
+
+static int maybe_send_stats(struct iaxc_call * call)
+{
+       const long video_stats_interval = 1000; /* milliseconds */
+       static struct timeval video_stats_start = {0, 0};
+       iaxc_event e;
+       struct timeval now;
+
+       if ( !call )
+               return -1;
+
+       if ( video_stats_start.tv_sec == 0 && video_stats_start.tv_usec == 0 )
+               video_stats_start = iax_tvnow();
+
+       now = iax_tvnow();
+
+       if ( iaxci_msecdiff(&now, &video_stats_start) > video_stats_interval )
+       {
+               get_stats(call, &e.ev.videostats.stats, 1);
+               e.type = IAXC_EVENT_VIDEOSTATS;
+               e.ev.videostats.callNo = selected_call;
+               iaxci_post_event(e);
+
+               video_stats_start = now;
+       }
+
+       return 0;
+}
+
+/* TODO: The encode parameter to this function is unused within this
+ * function. However, clients of this function still use this parameter.
+ * What ends up happening is we instantiate the codec encoder/decoder
+ * pairs multiple times. This seems not the best. For example, it is
+ * not clear that all codecs are idempotent to the extent that they can
+ * be initialized multiple times. Furthermore, within iaxclient itself,
+ * we have a nasty habit of using global statically allocated data.
+ * Multiple codec_video_*_new calls could easily result in race
+ * conditions or more blatantly bad problems.
+ *
+ * Splitting encoder and decoder creation has some merit.
+ *
+ *  - Avoid allocating encoder or decoder resources when not needed.
+ *  - Allows using different codecs for sending and receiving.
+ *  - Allows different codec parameters for sending and receiving.
+ *
+ */
+static struct iaxc_video_codec *create_codec(int format, int encode)
+{
+       struct iaxc_video_codec * vcodec = 0;
+
+       iaxci_usermsg(IAXC_TEXT_TYPE_NOTICE, "Creating codec format 0x%x",
+                       format);
+
+       switch ( format )
+       {
+       case IAXC_FORMAT_H261:
+       case IAXC_FORMAT_H263:
+       case IAXC_FORMAT_H263_PLUS:
+       case IAXC_FORMAT_MPEG4:
+       case IAXC_FORMAT_H264:
+#ifdef USE_FFMPEG
+               vcodec = codec_video_ffmpeg_new(format,
+                               vfinfo.width,
+                               vfinfo.height,
+                               vfinfo.framerate,
+                               vfinfo.bitrate,
+                               vfinfo.fragsize);
+#endif
+               break;
+
+       case IAXC_FORMAT_THEORA:
+#ifdef USE_THEORA
+               vcodec = codec_video_theora_new(format,
+                               vfinfo.width,
+                               vfinfo.height,
+                               vfinfo.framerate,
+                               vfinfo.bitrate,
+                               vfinfo.fragsize);
+#endif
+               break;
+       }
+
+       reset_codec_stats(vcodec);
+
+       return vcodec;
+}
+
+/*
+ * Returns video data to the main application using the callback mechanism.
+ * This function creates a dynamic copy of the video data. The memory is freed
+ * in iaxci_post_event. This is because the event we post may be queued and the
+ * frame data must live until after it is dequeued.
+
+ \todo For encoded data, set the event format to the calls video format.
+       For raw data, set the format to 0.
+
+ \todo For encoded data, set the event format to the calls video format. For raw data, set the format to 0.
+ */
+int show_video_frame(const char * in_buf, int in_buf_size,
+               int call_number, int source, int encoded,
+               unsigned int timestamp_ms)
+{
+       iaxc_event e;
+       char * buf = malloc(in_buf_size);
+
+       assert(buf);
+       assert(source == IAXC_SOURCE_REMOTE || source == IAXC_SOURCE_LOCAL);
+
+       memcpy(buf, in_buf, in_buf_size);
+
+       e.type = IAXC_EVENT_VIDEO;
+       e.ev.video.ts = timestamp_ms;
+       e.ev.video.data = buf;
+       e.ev.video.size = in_buf_size;
+       e.ev.video.format = vfinfo.format_preferred;
+       e.ev.video.width = vinfo.width;
+       e.ev.video.height = vinfo.height;
+       e.ev.video.callNo = call_number;
+       e.ev.video.encoded = encoded;
+       e.ev.video.source = source;
+
+       iaxci_post_event(e);
+
+       return 0;
+}
+
+// Resize the buffer to 25% (half resolution on both w and h )
+// No checks are made to ensure that the source dimensions are even numbers
+static void quarter_rgb32(const unsigned char *src, int src_w, int src_h,
+               unsigned char *dst)
+{
+       int i;
+       const unsigned char * src_even = src;
+       const unsigned char * src_odd = src + src_w * 4;
+
+       for ( i = 0 ; i < src_h / 2 ; i++ )
+       {
+               int j;
+               for ( j = 0 ; j < src_w / 2 ; j++ )
+               {
+                       short r, g, b;
+                       b = *src_even++;
+                       g = *src_even++;
+                       r = *src_even++;
+                       ++src_even;
+
+                       b += *src_even++;
+                       g += *src_even++;
+                       r += *src_even++;
+                       ++src_even;
+
+                       b += *src_odd++;
+                       g += *src_odd++;
+                       r += *src_odd++;
+                       ++src_odd;
+
+                       b += *src_odd++;
+                       g += *src_odd++;
+                       r += *src_odd++;
+                       ++src_odd;
+
+                       *dst++ = (unsigned char)(b >> 2);
+                       *dst++ = (unsigned char)(g >> 2);
+                       *dst++ = (unsigned char)(r >> 2);
+                       *dst++ = (unsigned char)0xff;
+               }
+               src_even = src_odd;
+               src_odd += src_w * 4;
+       }
+}
+
+// Resize the buffer to 25% (half resolution on both w and h )
+// No checks are made to ensure that the source dimensions are even numbers
+static void quarter_yuy2(const unsigned char *src, int src_w, int src_h,
+               unsigned char *dst)
+{
+       int i;
+       const unsigned char * src_even = src;
+       const unsigned char * src_odd = src + src_w * 2;
+
+       for ( i = 0 ; i < src_h / 2 ; i++ )
+       {
+               int j;
+               for ( j = 0 ; j < src_w / 4 ; j++ )
+               {
+                       short y1, u, y2, v;
+                       y1  = *src_even++;
+                       u   = *src_even++;
+                       y1 += *src_even++;
+                       v   = *src_even++;
+
+                       y1 += *src_odd++;
+                       u  += *src_odd++;
+                       y1 += *src_odd++;
+                       v  += *src_odd++;
+
+                       y2  = *src_even++;
+                       u  += *src_even++;
+                       y2 += *src_even++;
+                       v  += *src_even++;
+
+                       y2 += *src_odd++;
+                       u  += *src_odd++;
+                       y2 += *src_odd++;
+                       v  += *src_odd++;
+
+                       *dst++ = (unsigned char)(y1 >> 2);
+                       *dst++ = (unsigned char)(u  >> 2);
+                       *dst++ = (unsigned char)(y2 >> 2);
+                       *dst++ = (unsigned char)(v  >> 2);
+               }
+               src_even = src_odd;
+               src_odd += src_w * 2;
+       }
+}
+
+// Resize the channel to 25% (half resolution on both w and h )
+// No checks are made to ensure that the source dimensions are even numbers
+static void quarter_channel(const unsigned char *src, int src_w, int src_h,
+               unsigned char *dst)
+{
+       int i;
+       const unsigned char * evenl = src;
+       const unsigned char * oddl = src + src_w;
+
+       for ( i = 0 ; i < src_h / 2 ; i++ )
+       {
+               int j;
+               for ( j = 0 ; j < src_w / 2 ; j++ )
+               {
+                       int s = *(evenl++);
+                       s += *(evenl++);
+                       s += *(oddl++);
+                       s += *(oddl++);
+                       *(dst++) = (unsigned char)(s >> 2);
+               }
+               evenl = oddl;
+               oddl += src_w;
+       }
+}
+
+// Resize an I420 image by resizing each of the three channels.
+// Destination buffer must be sufficiently large to accommodate
+// the resulting image
+static void resize_i420(const unsigned char *src, int src_w, int src_h,
+               unsigned char *dst, int dst_w, int dst_h)
+{
+       const unsigned char *src_u = src + src_w * src_h;
+       const unsigned char *src_v = src_u + src_w * src_h / 4;
+       unsigned char *dst_u = dst + dst_w * dst_h;
+       unsigned char *dst_v = dst_u + dst_w * dst_h / 4;
+
+       // Resize each channel separately
+       if ( dst_w * 2 == src_w && dst_h * 2 == src_h )
+       {
+               quarter_channel(src, src_w, src_h, dst);
+               quarter_channel(src_u, src_w / 2, src_h / 2, dst_u);
+               quarter_channel(src_v, src_w / 2, src_h / 2, dst_v);
+       }
+/*
+       else if ( dst_w * 4 == src_w && dst_h * 4 == src_h )
+       {
+               double_quarter_channel(src, src_w, src_h, dst);
+               double_quarter_channel(src_u, src_w / 2, src_h / 2, dst_u);
+               double_quarter_channel(src_v, src_w / 2, src_h / 2, dst_v);
+       }
+       else
+       {
+               resize_channel(src, src_w, src_h, dst, dst_w, dst_h);
+               resize_channel(src_u, src_w / 2, src_h / 2,
+                               dst_u, dst_w / 2, dst_h / 2);
+               resize_channel(src_v, src_w / 2, src_h / 2,
+                               dst_v, dst_w / 2, dst_h / 2);
+       }
+*/
+}
+
+// Resize an rgb32 image
+// Destination buffer must be sufficiently large to accommodate
+// the resulting image
+static void resize_rgb32(const unsigned char *src, int src_w, int src_h,
+               unsigned char *dst, int dst_w, int dst_h)
+{
+       if ( dst_w * 2 == src_w && dst_h * 2 == src_h )
+       {
+               quarter_rgb32(src, src_w, src_h, dst);
+       }
+/*
+       else if ( dst_w * 4 == src_w && dst_h * 4 == src_h )
+       {
+               double_quarter_rgb32(src, src_w, src_h, dst);
+       }
+       else
+       {
+               resize_rgb32_buffer(src, src_w, src_h, dst, dst_w, dst_h);
+       }
+*/
+}
+
+// Resize a yuy2 image.
+// Destination buffer must be sufficiently large to accommodate
+// the resulting image
+static void resize_yuy2(const unsigned char *src, int src_w, int src_h,
+               unsigned char *dst, int dst_w, int dst_h)
+{
+       if ( dst_w * 2 == src_w && dst_h * 2 == src_h )
+       {
+               quarter_yuy2(src, src_w, src_h, dst);
+       }
+/*
+       else if ( dst_w * 4 == src_w && dst_h * 4 == src_h )
+       {
+               double_quarter_yuy2(src, src_w, src_h, dst);
+       }
+       else
+       {
+               resize_yuy2_buffer(src, src_w, src_h, dst, dst_w, dst_h);
+       }
+*/
+}
+
+static int video_device_notification_callback(vidcap_sapi *sapi,
+                       void * user_context)
+{
+       iaxc_event evt;
+
+       if ( sapi != vinfo.sapi )
+       {
+               fprintf(stderr, "ERROR: wrong sapi in device notification\n");
+               return -1;
+       }
+
+       /* notify application that device list has been updated */
+       evt.type = IAXC_EVENT_VIDCAP_DEVICE;
+       iaxci_post_event(evt);
+
+       return 0;
+}
+
+static int capture_callback(vidcap_src * src, void * user_data,
+               struct vidcap_capture_info * cap_info)
+{
+       static struct slice_set_t slice_set;
+
+       /* The prefs may change inbetween capture callbacks, so we cannot
+        * precompute any of this prior to starting capture.
+        */
+       const int send_encoded = !(vinfo.prefs & IAXC_VIDEO_PREF_SEND_DISABLE);
+       const int recv_local_enc = vinfo.prefs & IAXC_VIDEO_PREF_RECV_LOCAL_ENCODED;
+       const int recv_local_raw = vinfo.prefs & IAXC_VIDEO_PREF_RECV_LOCAL_RAW;
+       const int need_encode = send_encoded || recv_local_enc;
+       const int local_rgb = vinfo.prefs & IAXC_VIDEO_PREF_RECV_RGB32;
+
+       struct iaxc_call * call;
+       struct timeval now;
+       long time_delta;
+
+       const char * rgb_buf = 0;
+       int rgb_buf_size = 0;
+       const char * i420_buf = 0;
+       int i420_buf_size = 0;
+       const char * source_buf = 0;
+       int source_buf_size = 0;
+
+       iaxc_event evt;
+
+       int i;
+
+       if ( cap_info->error_status )
+       {
+               fprintf(stderr, "vidcap capture error %d\n",
+                               cap_info->error_status);
+               vinfo.capturing = 0;
+
+               /* NOTE:
+                * We want to release now, but we're in the capture callback thread.
+                * vidcap_src_release() fails during capture.
+                *
+                * We'll defer the release until the end-application's main thread
+                * requires the release - if either iaxc_set_video_prefs(),
+                * iaxc_video_device_set() or video_destroy() are called.
+                */
+
+               evt.type = IAXC_EVENT_VIDCAP_ERROR;
+               iaxci_post_event(evt);
+               return -1;
+       }
+
+       if ( cap_info->video_data_size < 1 )
+       {
+               fprintf(stderr, "FYI: callback with no data\n");
+               return 0;
+       }
+
+       if ( vinfo.prefs & IAXC_VIDEO_PREF_CAPTURE_DISABLE )
+               return 0;
+
+       if ( vinfo.width != vinfo.fmt_info.width )
+       {
+               vinfo.scale_image((const unsigned char *)cap_info->video_data,
+                               vinfo.fmt_info.width,
+                               vinfo.fmt_info.height,
+                               (unsigned char *)vinfo.scaled_buf,
+                               vinfo.width,
+                               vinfo.height);
+
+               source_buf = vinfo.scaled_buf;
+               source_buf_size = vinfo.scaled_buf_size;
+       }
+       else
+       {
+               source_buf = cap_info->video_data;
+               source_buf_size = cap_info->video_data_size;
+       }
+
+       if ( vinfo.convert_to_rgb32 && recv_local_raw && local_rgb )
+       {
+               vinfo.convert_to_rgb32(
+                               vinfo.width,
+                               vinfo.height,
+                               source_buf,
+                               vinfo.converted_rgb_buf);
+
+               rgb_buf = vinfo.converted_rgb_buf;
+               rgb_buf_size = vinfo.converted_rgb_buf_size;
+       }
+       else
+       {
+               rgb_buf = source_buf;
+               rgb_buf_size = source_buf_size;
+       }
+
+       if ( vinfo.convert_to_i420 && (need_encode ||
+                               (recv_local_raw && !local_rgb)) )
+       {
+               vinfo.convert_to_i420(
+                               vinfo.width,
+                               vinfo.height,
+                               source_buf,
+                               vinfo.converted_i420_buf);
+
+               i420_buf = vinfo.converted_i420_buf;
+               i420_buf_size = vinfo.converted_i420_buf_size;
+       }
+       else
+       {
+               i420_buf = source_buf;
+               i420_buf_size = source_buf_size;
+       }
+
+       if ( recv_local_raw )
+       {
+               show_video_frame(local_rgb ? rgb_buf : i420_buf,
+                               local_rgb ? rgb_buf_size : i420_buf_size,
+                               -1, /* local call number */
+                               IAXC_SOURCE_LOCAL,
+                               0,  /* not encoded */
+                               0); /* timestamp (ms) */
+       }
+
+       /* Don't block waiting for this lock. If the main thread has the lock
+        * for the purpose of dumping the call, it may request that video
+        * capture stop - which would block until this callback returned.
+        */
+       if ( try_iaxc_lock() )
+       {
+               /* give it a second try */
+               iaxc_millisleep(5);
+               if ( try_iaxc_lock() )
+               {
+                       fprintf(stderr, "skipping processing of a video frame\n");
+                       return 0;
+               }
+       }
+
+       if ( selected_call < 0 )
+               goto callback_done;
+
+       call = &calls[selected_call];
+
+       if ( !call || !(call->state & (IAXC_CALL_STATE_COMPLETE |
+                                       IAXC_CALL_STATE_OUTGOING)) )
+       {
+               goto callback_done;
+       }
+
+       if ( call->vformat == 0 )
+       {
+               goto callback_failed;
+       }
+
+       if ( !need_encode )
+       {
+               /* Since we are neither sending out encoded video on the
+                * network nor to the application, we no longer need the
+                * codec instance.
+                */
+               if ( call->vencoder )
+               {
+                       fprintf(stderr, "destroying codec %s\n",
+                                       call->vencoder->name);
+                       call->vencoder->destroy(call->vencoder);
+                       call->vencoder = 0;
+               }
+
+               goto callback_done;
+       }
+       else
+       {
+               if ( call->vencoder &&
+                               (call->vencoder->format != call->vformat ||
+                                call->vencoder->params_changed) )
+               {
+                       call->vencoder->destroy(call->vencoder);
+                       call->vencoder = 0;
+               }
+
+               if ( !call->vencoder )
+               {
+                       if ( !(call->vencoder = create_codec(call->vformat, 1)) )
+                       {
+                               fprintf(stderr, "ERROR: failed to create codec "
+                                               "for format 0x%08x\n",
+                                               call->vformat);
+
+                               goto callback_failed;
+                       }
+
+                       fprintf(stderr, "created encoder codec %s\n",
+                                       call->vencoder->name);
+               }
+
+               if ( call->vencoder->encode(call->vencoder,
+                                       i420_buf_size, i420_buf,
+                                       &slice_set) )
+               {
+                       fprintf(stderr, "failed to encode captured video\n");
+                       goto callback_failed;
+               }
+       }
+
+       /* Gather statistics */
+       call->vencoder->video_stats.outbound_frames++;
+
+       now = iax_tvnow();
+       time_delta =
+               iaxci_msecdiff(&now, &call->vencoder->video_stats.start_time);
+
+       if ( time_delta > 0 )
+               call->vencoder->video_stats.avg_outbound_fps =
+                       (float)call->vencoder->video_stats.outbound_frames *
+                       1000.0f / (float)time_delta;
+
+       if ( !call->session )
+       {
+               fprintf(stderr, "not sending video to sessionless call\n");
+               goto callback_failed;
+       }
+
+       for ( i = 0; i < slice_set.num_slices; ++i )
+       {
+               //Pass the encoded frame to the main app
+               // \todo Fix the call number
+               if ( vinfo.prefs & IAXC_VIDEO_PREF_RECV_LOCAL_ENCODED )
+               {
+                       show_video_frame(slice_set.data[i],
+                                       slice_set.size[i],
+                                       -1, /* local call number */
+                                       IAXC_SOURCE_LOCAL,
+                                       1,  /* encoded */
+                                       0); /* timestamp */
+               }
+
+               if ( !(vinfo.prefs & IAXC_VIDEO_PREF_SEND_DISABLE) )
+               {
+                       if ( iax_send_video_trunk(call->session, call->vformat,
+                                               slice_set.data[i],
+                                               slice_set.size[i],
+                                               0, /* not fullframe */
+                                               i) == -1)
+                       {
+                               fprintf(stderr, "failed sending slice call %d "
+                                               "size %d\n", selected_call,
+                                               slice_set.size[i]);
+                               goto callback_failed;
+                       }
+
+                       /* More statistics */
+                       call->vencoder->video_stats.sent_slices++;
+                       call->vencoder->video_stats.acc_sent_size +=
+                               slice_set.size[i];
+                       if ( time_delta > 0 )
+                               call->vencoder->video_stats.avg_outbound_bps =
+                                       call->vencoder->video_stats.acc_sent_size *
+                                       8000 / time_delta;
+               }
+       }
+
+       maybe_send_stats(call);
+
+callback_done:
+       put_iaxc_lock();
+       return 0;
+
+callback_failed:
+       put_iaxc_lock();
+       return -1;
+}
+
+static int prepare_for_capture()
+{
+       static const int fourcc_list[] =
+       {
+               VIDCAP_FOURCC_I420,
+               VIDCAP_FOURCC_YUY2,
+               VIDCAP_FOURCC_RGB32
+       };
+
+       static const int fourcc_list_len = sizeof(fourcc_list) / sizeof(int);
+       static const int max_factor = 2;
+       int scale_factor;
+       int i;
+
+       vinfo.width = vfinfo.width;
+       vinfo.height = vfinfo.height;
+       vinfo.fmt_info.fps_numerator = vfinfo.framerate;
+       vinfo.fmt_info.fps_denominator = 1;
+
+       for ( scale_factor = 1; scale_factor <= max_factor; scale_factor *= 2 )
+       {
+               vinfo.fmt_info.width = vfinfo.width * scale_factor;
+               vinfo.fmt_info.height = vfinfo.height * scale_factor;
+
+               for ( i = 0; i < fourcc_list_len; ++i )
+               {
+                       vinfo.fmt_info.fourcc = fourcc_list[i];
+
+                       if ( !vidcap_format_bind(vinfo.src, &vinfo.fmt_info) )
+                               break;
+               }
+
+               if ( i != fourcc_list_len )
+                       break;
+       }
+
+       if ( i == fourcc_list_len )
+       {
+               fprintf(stderr, "failed to bind format %dx%d %f fps\n",
+                               vinfo.fmt_info.width,
+                               vinfo.fmt_info.height,
+                               (float)vinfo.fmt_info.fps_numerator /
+                               (float)vinfo.fmt_info.fps_denominator);
+               return -1;
+       }
+
+       /* Prepare various conversion buffers */
+
+       if ( vinfo.converted_i420_buf )
+       {
+               free(vinfo.converted_i420_buf);
+               vinfo.converted_i420_buf = 0;
+       }
+
+       if ( vinfo.converted_rgb_buf )
+       {
+               free(vinfo.converted_rgb_buf);
+               vinfo.converted_rgb_buf = 0;
+       }
+
+       vinfo.converted_i420_buf_size =
+               vinfo.width * vinfo.height * 3 / 2;
+
+       vinfo.converted_rgb_buf_size =
+               vinfo.width * vinfo.height * 4;
+
+       if ( vinfo.fmt_info.fourcc != VIDCAP_FOURCC_RGB32 )
+               vinfo.converted_rgb_buf = malloc(vinfo.converted_rgb_buf_size);
+
+       if ( vinfo.fmt_info.fourcc != VIDCAP_FOURCC_I420 )
+               vinfo.converted_i420_buf = malloc(vinfo.converted_i420_buf_size);
+
+       switch ( vinfo.fmt_info.fourcc )
+       {
+       case VIDCAP_FOURCC_RGB32:
+               vinfo.convert_to_i420 = vidcap_rgb32_to_i420;
+               vinfo.convert_to_rgb32 = 0;
+               vinfo.scale_image = 0;
+               vinfo.scaled_buf = 0;
+               if ( vinfo.width != vinfo.fmt_info.width )
+               {
+                       vinfo.scale_image = resize_rgb32;
+                       vinfo.scaled_buf_size = vinfo.converted_rgb_buf_size;
+                       vinfo.scaled_buf = malloc(vinfo.scaled_buf_size);
+                       fprintf(stderr, "scaling rgb32 images by 1/%d\n",
+                                       scale_factor);
+               }
+               if ( !vinfo.converted_i420_buf )
+                       return -1;
+               break;
+       case VIDCAP_FOURCC_I420:
+               vinfo.convert_to_i420 = 0;
+               vinfo.convert_to_rgb32 = vidcap_i420_to_rgb32;
+               vinfo.scale_image = 0;
+               vinfo.scaled_buf = 0;
+               if ( vinfo.width != vinfo.fmt_info.width )
+               {
+                       vinfo.scale_image = resize_i420;
+                       vinfo.scaled_buf_size = vinfo.converted_i420_buf_size;
+                       vinfo.scaled_buf = malloc(vinfo.scaled_buf_size);
+                       fprintf(stderr, "scaling i420 images by 1/%d\n",
+                                       scale_factor);
+               }
+               if ( !vinfo.converted_rgb_buf )
+                       return -1;
+               break;
+       case VIDCAP_FOURCC_YUY2:
+               vinfo.convert_to_i420 = vidcap_yuy2_to_i420;
+               vinfo.convert_to_rgb32 = vidcap_yuy2_to_rgb32;
+               vinfo.scale_image = 0;
+               vinfo.scaled_buf = 0;
+               if ( vinfo.width != vinfo.fmt_info.width )
+               {
+                       vinfo.scale_image = resize_yuy2;
+                       vinfo.scaled_buf_size = vinfo.width *
+                                       vinfo.height * 2;
+                       vinfo.scaled_buf = malloc(vinfo.scaled_buf_size);
+                       fprintf(stderr, "scaling yuy2 images by 1/%d\n",
+                                       scale_factor);
+               }
+               if ( !vinfo.converted_rgb_buf || !vinfo.converted_i420_buf )
+                       return -1;
+               break;
+       default:
+               fprintf(stderr, "do not know how to deal with vidcap "
+                               "fourcc '%s'\n",
+                               vidcap_fourcc_string_get(vinfo.fmt_info.fourcc));
+               return -1;
+       }
+
+       if ( vinfo.scale_image && !vinfo.scaled_buf )
+               return -1;
+
+       return 0;
+}
+
+static int ensure_acquired(int dev_id)
+{
+       int dev_num;
+
+       if ( !vinfo.src )
+       {
+               MUTEXLOCK(&vinfo.dev_list_lock);
+
+               for ( dev_num = 0; dev_num < vinfo.device_count; dev_num++ )
+               {
+                       if ( vinfo.devices[dev_num].id == dev_id )
+                               break;
+               }
+
+               if ( dev_num == vinfo.device_count )
+               {
+                       MUTEXUNLOCK(&vinfo.dev_list_lock);
+                       fprintf(stderr, "invalid vidcap dev id: %d\n", dev_id);
+                       return -1;
+               }
+
+               if ( !(vinfo.src = vidcap_src_acquire(vinfo.sapi,
+                                       &vinfo.vc_src_info[dev_num])) )
+               {
+                       vinfo.src = 0;
+                       MUTEXUNLOCK(&vinfo.dev_list_lock);
+                       fprintf(stderr, "failed to acquire video source\n");
+                       return -1;
+               }
+
+               fprintf(stderr, "acquired vidcap source %s (%s)\n",
+                               vinfo.vc_src_info[dev_num].description,
+                               vinfo.vc_src_info[dev_num].identifier);
+
+               MUTEXUNLOCK(&vinfo.dev_list_lock);
+       }
+
+       return 0;
+}
+
+EXPORT int iaxc_set_video_prefs(unsigned int prefs)
+{
+       const unsigned int prefs_mask =
+               IAXC_VIDEO_PREF_RECV_LOCAL_RAW      |
+               IAXC_VIDEO_PREF_RECV_LOCAL_ENCODED  |
+               IAXC_VIDEO_PREF_RECV_REMOTE_RAW     |
+               IAXC_VIDEO_PREF_RECV_REMOTE_ENCODED |
+               IAXC_VIDEO_PREF_SEND_DISABLE        |
+               IAXC_VIDEO_PREF_RECV_RGB32          |
+               IAXC_VIDEO_PREF_CAPTURE_DISABLE;
+       int ret;
+
+       if ( prefs & ~prefs_mask )
+       {
+               fprintf(stderr, "ERROR: unexpected video preference: 0x%0x\n",
+                               prefs);
+               return -1;
+       }
+
+       vinfo.prefs = prefs;
+
+       if ( test_mode )
+               return 0;
+
+       /* Not sending any video and not needing any form of
+        * local video implies that we do not need to capture
+        * video.
+        */
+       if ( prefs & IAXC_VIDEO_PREF_CAPTURE_DISABLE ||
+                       ((prefs & IAXC_VIDEO_PREF_SEND_DISABLE) &&
+                        !(prefs & IAXC_VIDEO_PREF_RECV_LOCAL_RAW) &&
+                        !(prefs & IAXC_VIDEO_PREF_RECV_LOCAL_ENCODED)) )
+       {
+               MUTEXLOCK(&vinfo.camera_lock);
+               if ( vinfo.capturing && vinfo.src &&
+                               vidcap_src_capture_stop(vinfo.src) )
+               {
+                       fprintf(stderr, "failed vidcap_src_capture_stop\n");
+               }
+
+               if ( vinfo.src && vidcap_src_release(vinfo.src) )
+               {
+                       fprintf(stderr, "failed to release a video source\n");
+               }
+
+               vinfo.src = 0;
+               vinfo.capturing = 0;
+               MUTEXUNLOCK(&vinfo.camera_lock);
+       }
+       else
+       {
+               MUTEXLOCK(&vinfo.camera_lock);
+               if ( !vinfo.capturing )
+               {
+                       if ( vinfo.selected_device_id < 0 )
+                       {
+                               MUTEXUNLOCK(&vinfo.camera_lock);
+                               return -1;
+                       }
+
+                       if ( ensure_acquired(vinfo.selected_device_id) )
+                       {
+                               MUTEXUNLOCK(&vinfo.camera_lock);
+                               return -1;
+                       }
+
+                       if ( prepare_for_capture() )
+                       {
+                               MUTEXUNLOCK(&vinfo.camera_lock);
+                               return -1;
+                       }
+
+                       if ( (ret = vidcap_src_capture_start(vinfo.src,
+                                               capture_callback, 0)) )
+                       {
+                               MUTEXUNLOCK(&vinfo.camera_lock);
+                               fprintf(stderr, "failed to start video capture: %d\n",
+                                               ret);
+                               return -1;
+                       }
+
+                       vinfo.capturing = 1;
+               }
+               MUTEXUNLOCK(&vinfo.camera_lock);
+       }
+
+       return 0;
+}
+
+EXPORT void iaxc_video_format_set_cap(int preferred, int allowed)
+{
+       vfinfo.format_preferred = preferred;
+       vfinfo.format_allowed = allowed;
+}
+
+EXPORT void iaxc_video_format_get_cap(int *preferred, int *allowed)
+{
+       *preferred = vfinfo.format_preferred;
+       *allowed = vfinfo.format_allowed;
+}
+
+EXPORT void iaxc_video_format_set(int preferred, int allowed, int framerate,
+               int bitrate, int width, int height, int fs)
+{
+       int real_pref = 0;
+       int real_allowed = 0;
+#ifdef USE_FFMPEG
+       int tmp_allowed;
+       int i;
+#endif
+
+       // Make sure resolution is in range
+       if ( width < IAXC_VIDEO_MIN_WIDTH )
+               width = IAXC_VIDEO_MIN_WIDTH;
+       else if ( width > IAXC_VIDEO_MAX_WIDTH )
+               width = IAXC_VIDEO_MAX_WIDTH;
+
+       if ( height < IAXC_VIDEO_MIN_HEIGHT )
+               height = IAXC_VIDEO_MIN_HEIGHT;
+       else if ( height > IAXC_VIDEO_MAX_HEIGHT )
+               height = IAXC_VIDEO_MAX_HEIGHT;
+
+       vfinfo.framerate = framerate;
+       vfinfo.bitrate = bitrate;
+       vfinfo.width = width;
+       vfinfo.height = height;
+       vfinfo.fragsize = fs;
+
+       vfinfo.format_allowed = 0;
+       vfinfo.format_preferred = 0;
+
+       if ( preferred && (preferred & ~IAXC_VIDEO_FORMAT_MASK) )
+       {
+               fprintf(stderr, "ERROR: Preferred video format invalid.\n");
+               preferred = 0;
+       }
+
+       /* This check:
+        * 1. Check if preferred is a supported and compiled in codec. If
+        *    not, switch to the default preferred format.
+        * 2. Check if allowed contains a list of all supported and compiled
+        *    in codec. If there are some unavailable codec, remove it from
+        *    this list.
+        */
+
+       if ( preferred & IAXC_FORMAT_THEORA )
+               real_pref = IAXC_FORMAT_THEORA;
+
+#ifdef USE_FFMPEG
+       if ( codec_video_ffmpeg_check_codec(preferred) )
+               real_pref = preferred;
+#endif
+
+       if ( !real_pref )
+       {
+               /* If preferred codec is not available switch to the
+                * supported default codec.
+                */
+               fprintf(stderr, "Preferred codec (0x%08x) is not available. "
+                               "Switching to default\n", preferred);
+               real_pref = IAXC_FORMAT_THEORA;
+       }
+
+       /* Check on allowed codecs availability */
+
+       if ( allowed & IAXC_FORMAT_THEORA )
+               real_allowed |= IAXC_FORMAT_THEORA;
+
+#ifdef USE_FFMPEG
+       /* TODO: This codec_video_ffmpeg_check_codec stuff is bogus. We
+        * need a standard interface in our codec wrappers that allows us to
+        * (1) test if a selected codec is valid and/or (2) return the set of
+        * available valid codecs. With that, we should be able to come up
+        * with a more elegant algorithm here for determining the video codec.
+        */
+       for ( i = 0; i <= 24; i++)
+       {
+               tmp_allowed = 1 << i;
+               if ( (allowed & tmp_allowed)  &&
+                                codec_video_ffmpeg_check_codec(tmp_allowed) )
+                       real_allowed |= tmp_allowed;
+       }
+#endif
+
+       if ( !real_pref )
+       {
+               fprintf(stderr, "Audio-only client!\n");
+       } else
+       {
+               vfinfo.format_preferred = real_pref;
+
+               /*
+                * When a client use a 'preferred' format, it can force to
+                * use allowed formats using a non-zero value for 'allowed'
+                * parameter. If it is left 0, the client will use all
+                * capabilities set by default in this code.
+                */
+               if ( real_allowed )
+               {
+                       vfinfo.format_allowed = real_allowed;
+               }
+               else
+               {
+#ifdef USE_FFMPEG
+                       vfinfo.format_allowed |= IAXC_FORMAT_H263_PLUS
+                               | IAXC_FORMAT_H263
+                               | IAXC_FORMAT_MPEG4
+                               | IAXC_FORMAT_H264;
+#endif
+                       vfinfo.format_allowed |= IAXC_FORMAT_THEORA;
+               }
+       }
+}
+
+void iaxc_video_params_change(int framerate, int bitrate, int width,
+               int height, int fs)
+{
+       struct iaxc_call *call;
+
+       /* set default video params */
+       if ( framerate > 0 )
+               vfinfo.framerate = framerate;
+       if ( bitrate > 0 )
+               vfinfo.bitrate = bitrate;
+       if ( width > 0 )
+               vfinfo.width = width;
+       if ( height > 0 )
+               vfinfo.height = height;
+       if ( fs > 0 )
+               vfinfo.fragsize = fs;
+
+       if ( selected_call < 0 )
+               return;
+
+       call = &calls[selected_call];
+
+       if ( !call || !call->vencoder )
+               return;
+
+       call->vencoder->params_changed = 1;
+
+       if ( framerate > 0 )
+               call->vencoder->framerate = framerate;
+       if ( bitrate > 0 )
+               call->vencoder->bitrate = bitrate;
+       if ( width > 0 )
+               call->vencoder->width = width;
+       if ( height > 0 )
+               call->vencoder->height = height;
+       if ( fs > 0 )
+               call->vencoder->fragsize = fs;
+}
+
+/* process an incoming video frame */
+int video_recv_video(struct iaxc_call *call, int sel_call,
+               void *encoded_video, int encoded_video_len,
+               unsigned int ts, int format)
+{
+       enum
+       {
+               max_pixels = IAXC_VIDEO_MAX_WIDTH * IAXC_VIDEO_MAX_HEIGHT,
+               max_yuv_buf_size = max_pixels * 3 / 2,
+               max_rgb_buf_size = max_pixels * 4
+       };
+
+       static char yuv_buf[max_yuv_buf_size];
+       static char rgb_buf[max_rgb_buf_size];
+
+       const int pixels = vfinfo.width * vfinfo.height;
+       const int yuv_size = pixels * 3 / 2;
+       const int rgb_size = pixels * 4;
+
+       int out_size = max_yuv_buf_size;
+       int ret;
+       struct timeval now;
+       long time;
+
+       if ( !call )
+               return 0;
+
+       if ( format == 0 )
+       {
+               fprintf(stderr, "video_recv_video: Format is zero (should't happen)!\n");
+               return -1;
+       }
+
+       // Send the encoded frame to the main app if necessary
+       if ( vinfo.prefs & IAXC_VIDEO_PREF_RECV_REMOTE_ENCODED )
+       {
+               show_video_frame((char *)encoded_video,
+                               encoded_video_len,
+                               -1,  /* TODO: why is the callnumber -1? */
+                               IAXC_SOURCE_REMOTE,
+                               1,   /* encoded */
+                               ts);
+       }
+
+       /* destroy vdecoder if it is incorrect type */
+       if ( call->vdecoder && call->vdecoder->format != format )
+       {
+               call->vdecoder->destroy(call->vdecoder);
+               call->vdecoder = NULL;
+       }
+
+       /* If the user does not need decoded video, then do not decode. */
+       if ( !(vinfo.prefs & IAXC_VIDEO_PREF_RECV_REMOTE_RAW) )
+               return 0;
+
+       /* create decoder if necessary */
+       if ( !call->vdecoder )
+       {
+               call->vdecoder = create_codec(format, 0);
+               fprintf(stderr,"**** Created decoder codec %s\n",call->vdecoder->name);
+       }
+
+       if ( !call->vdecoder )
+       {
+               fprintf(stderr, "ERROR: Video codec could not be created: %d\n",
+                               format);
+               return -1;
+       }
+
+       /* Statistics */
+       now = iax_tvnow();
+       time = iaxci_msecdiff(&now, &call->vdecoder->video_stats.start_time);
+       call->vdecoder->video_stats.received_slices++;
+       call->vdecoder->video_stats.acc_recv_size += encoded_video_len;
+       if ( time > 0 )
+               call->vdecoder->video_stats.avg_inbound_bps =
+                       call->vdecoder->video_stats.acc_recv_size * 8000 / time;
+
+       ret = call->vdecoder->decode(call->vdecoder, encoded_video_len,
+                       (char *)encoded_video, &out_size, yuv_buf);
+
+       if ( ret < 0 )
+       {
+               fprintf(stderr, "ERROR: decode error\n");
+               return -1;
+       }
+       else if ( ret > 0 )
+       {
+               /* This indicates that a complete frame cannot yet
+                * be decoded. This is okay.
+                */
+               return 0;
+       }
+       else if ( out_size != yuv_size )
+       {
+               fprintf(stderr, "ERROR: decoder returned unexpected sized "
+                               "frame (expected %d got %d)\n",
+                               yuv_size, out_size);
+               return -1;
+       }
+
+       /* Statistics */
+       call->vdecoder->video_stats.inbound_frames++;
+       if ( time > 0 )
+               call->vdecoder->video_stats.avg_inbound_fps =
+                       call->vdecoder->video_stats.inbound_frames *
+                       1000.0F / time;
+
+       if ( vinfo.prefs & IAXC_VIDEO_PREF_RECV_RGB32 )
+       {
+               vidcap_i420_to_rgb32(vfinfo.width, vfinfo.height,
+                               yuv_buf, rgb_buf);
+
+               show_video_frame(rgb_buf, rgb_size, sel_call,
+                               IAXC_SOURCE_REMOTE, 0, ts);
+       }
+       else
+       {
+               show_video_frame(yuv_buf, yuv_size, sel_call,
+                               IAXC_SOURCE_REMOTE, 0, ts);
+       }
+
+       return 0;
+}
+
+EXPORT int iaxc_video_devices_get(struct iaxc_video_device **devs,
+                       int *num_devs, int *id_selected)
+{
+       int new_device_count;
+       int old_device_count;
+       struct vidcap_src_info *new_src_list;
+       struct vidcap_src_info *old_src_list;
+       struct iaxc_video_device  *new_iaxc_dev_list;
+       struct iaxc_video_device  *old_iaxc_dev_list;
+       int found_selected_device = 0;
+       int list_changed;
+       int i, n;
+
+       if ( !vinfo.sapi )
+               return -1;
+
+       /* update libvidcap's device list */
+       new_device_count = vidcap_src_list_update(vinfo.sapi);
+       list_changed = new_device_count != vinfo.device_count;
+
+       if ( new_device_count < 0 )
+       {
+               fprintf(stderr, "ERROR: failed getting updated vidcap device list: %d\n",
+                               new_device_count);
+               return -1;
+       }
+
+       new_src_list = calloc(new_device_count, sizeof(struct vidcap_src_info));
+
+       if ( !new_src_list )
+       {
+               fprintf(stderr, "ERROR: failed updated source allocation\n");
+               return -1;
+       }
+
+       new_iaxc_dev_list = calloc(new_device_count,
+                       sizeof(struct iaxc_video_device));
+
+       if ( !new_iaxc_dev_list )
+       {
+               free(new_src_list);
+               fprintf(stderr, "ERROR: failed source allocation update\n");
+               return -1;
+       }
+
+       /* get an updated libvidcap device list */
+       if ( vidcap_src_list_get(vinfo.sapi, new_device_count, new_src_list) )
+       {
+               fprintf(stderr, "ERROR: failed vidcap_srcList_get().\n");
+
+               free(new_src_list);
+               free(new_iaxc_dev_list);
+               return -1;
+       }
+
+       /* build a new iaxclient video source list */
+       for ( n = 0; n < new_device_count; n++ )
+       {
+               new_iaxc_dev_list[n].name = strdup(new_src_list[n].description);
+               new_iaxc_dev_list[n].id_string = strdup(new_src_list[n].identifier);
+
+               /* This device may have been here all along.
+                * If it has, re-assign that device id
+                * else assign a new id
+                */
+               for ( i = 0; i < vinfo.device_count; i++ )
+               {
+                       /* check both the device name and its unique identifier */
+                       if ( !strcmp(new_iaxc_dev_list[n].name, vinfo.devices[i].name) &&
+                                       !strcmp(new_iaxc_dev_list[n].id_string,
+                                                       vinfo.devices[i].id_string) )
+                       {
+                               new_iaxc_dev_list[n].id = vinfo.devices[i].id;
+
+                               if ( vinfo.selected_device_id == new_iaxc_dev_list[n].id )
+                                       found_selected_device = 1;
+                               break;
+                       }
+               }
+               if ( i == vinfo.device_count )
+               {
+                       new_iaxc_dev_list[n].id = vinfo.next_id++;
+
+                       list_changed = 1;
+               }
+       }
+
+       if ( !list_changed )
+       {
+               /* Free new lists. Nothing's really changed */
+               free(new_src_list);
+               for ( i = 0; i < new_device_count; i++ )
+               {
+                       free((void *)new_iaxc_dev_list[i].name);
+                       free((void *)new_iaxc_dev_list[i].id_string);
+               }
+               free(new_iaxc_dev_list);
+       }
+       else
+       {
+               old_device_count = vinfo.device_count;
+               old_src_list = vinfo.vc_src_info;
+               old_iaxc_dev_list = vinfo.devices;
+
+               /* Update iaxclient's device list info               */
+               /* Lock since other iaxclient funcs use these fields */
+               MUTEXLOCK(&vinfo.dev_list_lock);
+
+               vinfo.device_count = new_device_count;
+               vinfo.vc_src_info = new_src_list;
+               vinfo.devices = new_iaxc_dev_list;
+
+               MUTEXUNLOCK(&vinfo.dev_list_lock);
+
+               /* free old lists */
+               free(old_src_list);
+               for ( i = 0; i < old_device_count; i++ )
+               {
+                       free((void *)old_iaxc_dev_list[i].name);
+                       free((void *)old_iaxc_dev_list[i].id_string);
+               }
+               free(old_iaxc_dev_list);
+       }
+
+       /* If we can't find the selected device, defer releasing it.
+        * It'll happen when we set a new device, or shutdown
+        */
+
+       if ( !found_selected_device )
+               vinfo.selected_device_id = -1;
+
+       *devs = vinfo.devices;
+       *num_devs = vinfo.device_count;
+       *id_selected = vinfo.selected_device_id;
+
+       return list_changed;
+}
+
+EXPORT int iaxc_video_device_set(int capture_dev_id)
+{
+       int ret = 0;
+       int dev_num = 0;
+
+       MUTEXLOCK(&vinfo.camera_lock);
+
+       if ( capture_dev_id == vinfo.selected_device_id )
+       {
+               MUTEXUNLOCK(&vinfo.camera_lock);
+               return 0;
+       }
+
+       if ( capture_dev_id < 0 )
+       {
+               MUTEXUNLOCK(&vinfo.camera_lock);
+               fprintf(stderr, "invalid video device id ( < 0 )\n");
+               return -1;
+       }
+
+       MUTEXLOCK(&vinfo.dev_list_lock);
+
+       for ( dev_num = 0; dev_num < vinfo.device_count; dev_num++ )
+       {
+               if ( vinfo.devices[dev_num].id == capture_dev_id )
+                       break;
+       }
+
+       if ( dev_num == vinfo.device_count )
+       {
+               MUTEXUNLOCK(&vinfo.dev_list_lock);
+               MUTEXUNLOCK(&vinfo.camera_lock);
+               fprintf(stderr, "invalid video device id: %d\n",
+                               capture_dev_id);
+               return -1;
+       }
+
+       vinfo.selected_device_id = capture_dev_id;
+
+       if ( vinfo.capturing && vinfo.src &&
+                       vidcap_src_capture_stop(vinfo.src) )
+       {
+               fprintf(stderr, "failed to stop video capture\n");
+       }
+
+       if ( vinfo.src && vidcap_src_release(vinfo.src) )
+       {
+               fprintf(stderr, "failed to release video source\n");
+       }
+
+       vinfo.src = 0;
+
+       MUTEXUNLOCK(&vinfo.dev_list_lock);
+
+       if ( vinfo.capturing )
+       {
+               if ( ensure_acquired(capture_dev_id) )
+               {
+                       MUTEXUNLOCK(&vinfo.camera_lock);
+                       return -1;
+               }
+
+               if ( prepare_for_capture() )
+               {
+                       MUTEXUNLOCK(&vinfo.camera_lock);
+                       return -1;
+               }
+
+               if ( (ret = vidcap_src_capture_start(vinfo.src,
+                                               capture_callback, 0)) )
+               {
+                       MUTEXUNLOCK(&vinfo.camera_lock);
+                       fprintf(stderr, "failed to restart video capture: %d\n", ret);
+                       return -1;
+               }
+       }
+
+       MUTEXUNLOCK(&vinfo.camera_lock);
+
+       return 0;
+}
+
+int video_initialize(void)
+{
+       int i;
+       const int starting_id = 50;
+
+       memset(&vinfo, 0, sizeof(vinfo));
+
+       vinfo.width = vfinfo.width;
+       vinfo.height = vfinfo.height;
+       vinfo.selected_device_id = -1;
+       vinfo.next_id = starting_id;
+
+       MUTEXINIT(&vinfo.camera_lock);
+       MUTEXINIT(&vinfo.dev_list_lock);
+
+       if ( !(vinfo.vc = vidcap_initialize()) )
+       {
+               fprintf(stderr, "ERROR: failed vidcap_initialize\n");
+               return -1;
+       }
+
+       if ( !(vinfo.sapi = vidcap_sapi_acquire(vinfo.vc, 0)) )
+       {
+               fprintf(stderr, "ERROR: failed vidcap_sapi_acquire\n");
+               goto bail;
+       }
+
+       if ( vidcap_sapi_info_get(vinfo.sapi, &vinfo.sapi_info) )
+       {
+               fprintf(stderr, "ERROR: failed vidcap_sapi_info_get\n");
+               goto bail;
+       }
+
+       fprintf(stderr, "using vidcap sapi %s (%s)\n",
+                       vinfo.sapi_info.description,
+                       vinfo.sapi_info.identifier);
+
+       vinfo.device_count = vidcap_src_list_update(vinfo.sapi);
+       if ( vinfo.device_count < 0 )
+       {
+               fprintf(stderr,
+                               "ERROR: failed updating video capture devices list\n");
+               goto bail;
+       }
+
+       vinfo.vc_src_info = calloc(vinfo.device_count,
+                       sizeof(struct vidcap_src_info));
+
+       if ( !vinfo.vc_src_info )
+       {
+               fprintf(stderr, "ERROR: failed vinfo field allocations\n");
+               goto bail;
+       }
+
+       vinfo.devices = calloc(vinfo.device_count,
+                       sizeof(struct iaxc_video_device));
+
+       if ( !vinfo.devices )
+       {
+               fprintf(stderr, "ERROR: failed vinfo field allocation\n");
+               free(vinfo.vc_src_info);
+               goto bail;
+       }
+
+       if ( vidcap_src_list_get(vinfo.sapi, vinfo.device_count,
+                               vinfo.vc_src_info) )
+       {
+               fprintf(stderr, "ERROR: failed vidcap_src_list_get()\n");
+               free(vinfo.vc_src_info);
+               free(vinfo.devices);
+               goto bail;
+       }
+
+       /* build initial iaxclient video source list */
+       for ( i = 0; i < vinfo.device_count; i++ )
+       {
+               vinfo.devices[i].name = strdup(vinfo.vc_src_info[i].description);
+               vinfo.devices[i].id_string = strdup(vinfo.vc_src_info[i].identifier);
+               /* Let's be clear that the device id is not some
+                * base-zero index. Once plug-n-play is implemented,
+                * these ids may diverge as devices are added
+                * and removed.
+                */
+               vinfo.devices[i].id = vinfo.next_id++;
+       }
+
+       if ( vinfo.device_count )
+       {
+               /* set default source - the first device */
+               iaxc_video_device_set(vinfo.devices[0].id);
+       }
+
+       /* setup device notification callback
+        * for device insertion and removal
+        */
+       if ( vidcap_srcs_notify(vinfo.sapi, &video_device_notification_callback, 0) )
+       {
+               fprintf(stderr, "ERROR: failed vidcap_srcs_notify()\n");
+               goto late_bail;
+       }
+
+       vinfo.prefs =
+               IAXC_VIDEO_PREF_RECV_LOCAL_RAW |
+               IAXC_VIDEO_PREF_RECV_REMOTE_RAW |
+               IAXC_VIDEO_PREF_CAPTURE_DISABLE;
+
+       return 0;
+
+late_bail:
+       free(vinfo.vc_src_info);
+
+       for ( i = 0; i < vinfo.device_count; i++ )
+       {
+               free((void *)vinfo.devices[i].name);
+               free((void *)vinfo.devices[i].id_string);
+       }
+
+       free(vinfo.devices);
+
+bail:
+       if ( vinfo.sapi )
+       {
+               vidcap_sapi_release(vinfo.sapi);
+               vinfo.sapi = 0;
+       }
+       vidcap_destroy(vinfo.vc);
+       vinfo.vc = 0;
+       return -1;
+}
+
+int video_destroy(void)
+{
+       int i;
+
+       if ( !vinfo.vc )
+               return -1;
+
+       free(vinfo.vc_src_info);
+       for ( i = 0; i < vinfo.device_count; i++ )
+       {
+               free((void *)vinfo.devices[i].name);
+               free((void *)vinfo.devices[i].id_string);
+       }
+       free(vinfo.devices);
+
+       if ( vinfo.capturing && vinfo.src )
+               vidcap_src_capture_stop(vinfo.src);
+
+       if ( vinfo.src )
+               vidcap_src_release(vinfo.src);
+
+       vidcap_destroy(vinfo.vc);
+       vinfo.vc = 0;
+
+       MUTEXDESTROY(&vinfo.camera_lock);
+       MUTEXDESTROY(&vinfo.dev_list_lock);
+
+       if ( vinfo.converted_i420_buf )
+       {
+               free(vinfo.converted_i420_buf);
+               vinfo.converted_i420_buf = 0;
+       }
+
+       if ( vinfo.converted_rgb_buf )
+       {
+               free(vinfo.converted_rgb_buf);
+               vinfo.converted_rgb_buf = 0;
+       }
+
+       if ( vinfo.scaled_buf )
+       {
+               free(vinfo.scaled_buf);
+               vinfo.scaled_buf = 0;
+       }
+
+       return 0;
+}
+
+void iaxc_YUV420_to_RGB32(int width, int height, const char * src, char * dst)
+{
+       if ( vidcap_i420_to_rgb32(width, height, src, dst) )
+               iaxci_usermsg(IAXC_TEXT_TYPE_ERROR,
+                               "failed iaxc_YUV420_to_RGB32()");
+}
+
+int iaxc_is_camera_working()
+{
+       /* This tells us how many video sources are available, so
+        * we are saying that the "camera is working" if there exists
+        * more than zero cameras.
+        */
+       return vinfo.sapi && vidcap_src_list_update(vinfo.sapi) > 0;
+}
+
+int video_send_stats(struct iaxc_call * call)
+{
+       const long video_stats_interval = 1000; /* milliseconds */
+       static struct timeval video_stats_start = {0, 0};
+       iaxc_event e;
+       struct timeval now;
+
+       if ( !call )
+               return -1;
+
+       if ( video_stats_start.tv_sec == 0 && video_stats_start.tv_usec == 0 )
+               video_stats_start = iax_tvnow();
+
+       now = iax_tvnow();
+
+       if ( iaxci_msecdiff(&now, &video_stats_start) > video_stats_interval )
+       {
+               get_stats(call, &e.ev.videostats.stats, 1);
+               e.type = IAXC_EVENT_VIDEOSTATS;
+               e.ev.videostats.callNo = selected_call;
+               iaxci_post_event(e);
+
+               video_stats_start = now;
+       }
+
+       return 0;
+}
+
+EXPORT int iaxc_push_video(void *data, unsigned int size, int fragment)
+{
+       struct iaxc_call *call;
+
+       if (selected_call < 0)
+               return -1;
+
+       call = &calls[selected_call];
+
+       if ( vinfo.prefs & IAXC_VIDEO_PREF_SEND_DISABLE )
+               return 0;
+
+       //fprintf(stderr, "iaxc_push_video: sending video size %d\n", size);
+
+       // Fragment if needed
+       if ( fragment )
+       {
+               static struct slice_set_t slice_set;
+               int i;
+
+               if ( !vinfo.sc )
+                       vinfo.sc = create_slicer_context((unsigned short)rand(),
+                                       vfinfo.fragsize);
+
+               slice(data, size, &slice_set, vinfo.sc);
+               for ( i = 0 ; i < slice_set.num_slices ; i++ )
+               {
+                       if ( iax_send_video_trunk(call->session,
+                                                 call->vformat,
+                                                 slice_set.data[i],
+                                                 slice_set.size[i],
+                                                 0,
+                                                 i
+                                                ) == -1
+                          )
+                       {
+                               fprintf(stderr, "Failed to send a slice, call %d, size %d: %s\n",
+                                                               selected_call, slice_set.size[i], iax_errstr);
+                               return -1;
+                       }
+
+               }
+       } else
+       {
+               if ( iax_send_video_trunk(call->session, call->vformat, data,
+                                       size, 0, 0) == -1 )
+               {
+                       fprintf(stderr, "iaxc_push_video: failed to send "
+                                       "video frame of size %d on call %d: %s\n",
+                                       size, selected_call, iax_errstr);
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
diff --git a/utils/iaxclient/lib/video_portvideo.cpp b/utils/iaxclient/lib/video_portvideo.cpp
new file mode 100644 (file)
index 0000000..d67a2a3
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003 HorizonLive.com, (c) 2004, Horizon Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License
+ *
+ * Module: video_portvideo
+ * Purpose: Video code to provide portvideo driver support for IAX library
+ * Developed by: Steve Kann
+ * Creation Date: April 7, 2005
+ *
+ *
+ */
+
+#include "iaxclient_lib.h"
+#include "PortVideoSDL/common/cameraEngine.h"
+#include "PortVideoSDL/common/cameraTool.h"
+
+static cameraEngine *engine;
+int running;
+
+
+int pv_start (struct iaxc_video_driver *d ) {
+    if(!running) {  
+       if(!engine->startCamera()) {
+         fprintf(stderr, "pv: couldn't start camera\n");
+         return -1;
+       }
+       running = 1;
+    }
+   return 0;
+}
+
+int pv_stop (struct iaxc_video_driver *d ) {
+    return 0;
+}
+
+void pv_shutdown() {
+}
+
+int pv_input(struct iaxc_video_driver *d, unsigned char **in) {
+    unsigned char *data = NULL;
+    data = engine->getFrame();
+    if(!data) {
+       if(!engine->stillRunning()) {
+           fprintf(stderr, "camera disconnected\n");
+           running = 0;
+       }
+       fprintf(stderr, "pv_input: no frame\n");
+       return 0;
+    }
+    *in = data;
+    return 0;
+}
+
+int pv_output(struct iaxc_video_driver *d, unsigned char *data) {
+       return 0;
+}
+
+int pv_select_devices (struct iaxc_video_driver *d, int input, int output) {
+    return 0;
+}
+
+int pv_selected_devices (struct iaxc_video_driver *d, int *input, int *output) {
+    return 0;
+}
+
+int pv_destroy (struct iaxc_video_driver *d ) {
+    //implementme
+    return 0;
+}
+
+
+
+/* initialize video driver */
+int pv_initialize (struct iaxc_video_driver *d, int w, int h, int framerate) {
+    /* setup methods */
+    d->initialize = pv_initialize;
+    d->destroy = pv_destroy;
+    d->select_devices = pv_select_devices;
+    d->selected_devices = pv_selected_devices;
+    d->start = pv_start;
+    d->stop = pv_stop;
+    d->output = pv_output;
+    d->input = pv_input;
+
+    engine = cameraTool::findCamera();
+    if(!engine) {
+       fprintf(stderr, "video_portvideo: can't find camera\n");
+       return -1;
+    }
+
+    if(!engine->initCamera(w,h,true)) {
+       fprintf(stderr, "can't initialize camera");
+       return -1;
+    }
+       
+
+    return 0;
+}
diff --git a/utils/iaxclient/lib/video_portvideo.h b/utils/iaxclient/lib/video_portvideo.h
new file mode 100644 (file)
index 0000000..8dbd05c
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003 HorizonLive.com, (c) 2004, Horizon Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License
+ */
+#ifndef _VIDEO_PORTVIDEO_H
+#define _VIDEO_PORTVIDEO_H
+
+#include "iaxclient_lib.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+int pv_initialize (struct iaxc_video_driver *d, int w, int h, int framerate);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/utils/iaxclient/lib/win/devcpp/iaxclient.dev b/utils/iaxclient/lib/win/devcpp/iaxclient.dev
new file mode 100644 (file)
index 0000000..d57cfdf
--- /dev/null
@@ -0,0 +1,1369 @@
+[Project]\r
+FileName=iaxclient.dev\r
+Name=iaxclient\r
+UnitCount=132\r
+Type=2\r
+Ver=1\r
+ObjFiles=\r
+Includes=.;../../portaudio/include;../../portaudio/src/common;../../portaudio/pablio;../../portmixer/px_common;../../libspeex/include;../../gsm/inc;../../libiax2/src\r
+Libs=\r
+PrivateResource=\r
+ResourceIncludes=\r
+MakeIncludes=\r
+Compiler=-DSPEEX_PREPROCESS=1_@@_-DSPEEX_EC=1_@@_-DHAVE_NOT_RESTRICT_KEYWORD_@@_-DNEWJB_@@_-DLIBIAX_@@_-DLIBVER=\"SVN-20061010\"_@@_-DPA_NO_DS_@@_-DPA_NO_ASIO_@@_\r
+CppCompiler=\r
+Linker=\r
+IsCpp=0\r
+Icon=\r
+ExeOutput=\r
+ObjectOutput=\r
+OverrideOutput=1\r
+OverrideOutputName=libiaxclient.a\r
+HostApplication=\r
+Folders=codecs,gsm,iax2,iaxclient,portaudio,sox,speex,win32\r
+CommandLine=\r
+UseCustomMakefile=0\r
+CustomMakefile=\r
+IncludeVersionInfo=0\r
+SupportXPThemes=0\r
+CompilerSet=0\r
+CompilerSettings=0000000000000000000000\r
+\r
+[VersionInfo]\r
+Major=0\r
+Minor=1\r
+Release=1\r
+Build=1\r
+LanguageID=1033\r
+CharsetID=1252\r
+CompanyName=\r
+FileVersion=\r
+FileDescription=Developed using the Dev-C++ IDE\r
+InternalName=\r
+LegalCopyright=\r
+LegalTrademarks=\r
+OriginalFilename=\r
+ProductName=\r
+ProductVersion=\r
+AutoIncBuildNr=0\r
+\r
+[Unit1]\r
+FileName=..\..\gsm\src\table.c\r
+CompileCpp=0\r
+Folder=gsm\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit2]\r
+FileName=..\..\gsm\src\add.c\r
+CompileCpp=0\r
+Folder=gsm\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit3]\r
+FileName=..\..\gsm\src\code.c\r
+CompileCpp=0\r
+Folder=gsm\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit4]\r
+FileName=..\..\gsm\src\debug.c\r
+CompileCpp=0\r
+Folder=gsm\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit5]\r
+FileName=..\..\gsm\src\decode.c\r
+CompileCpp=0\r
+Folder=gsm\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit6]\r
+FileName=..\..\gsm\src\gsm_create.c\r
+CompileCpp=0\r
+Folder=gsm\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit7]\r
+FileName=..\..\gsm\src\gsm_decode.c\r
+CompileCpp=0\r
+Folder=gsm\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit8]\r
+FileName=..\..\gsm\src\gsm_destroy.c\r
+CompileCpp=0\r
+Folder=gsm\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit9]\r
+FileName=..\..\gsm\src\gsm_encode.c\r
+CompileCpp=0\r
+Folder=gsm\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit10]\r
+FileName=..\..\gsm\src\gsm_explode.c\r
+CompileCpp=0\r
+Folder=gsm\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit11]\r
+FileName=..\..\gsm\src\gsm_implode.c\r
+CompileCpp=0\r
+Folder=gsm\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit12]\r
+FileName=..\..\gsm\src\gsm_option.c\r
+CompileCpp=0\r
+Folder=gsm\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit13]\r
+FileName=..\..\gsm\src\gsm_print.c\r
+CompileCpp=0\r
+Folder=gsm\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit14]\r
+FileName=..\..\gsm\src\long_term.c\r
+CompileCpp=0\r
+Folder=gsm\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit15]\r
+FileName=..\..\gsm\src\lpc.c\r
+CompileCpp=0\r
+Folder=gsm\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit16]\r
+FileName=..\..\gsm\src\preprocess.c\r
+CompileCpp=0\r
+Folder=gsm\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit17]\r
+FileName=..\..\gsm\src\rpe.c\r
+CompileCpp=0\r
+Folder=gsm\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit18]\r
+FileName=..\..\gsm\src\short_term.c\r
+CompileCpp=0\r
+Folder=gsm\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit20]\r
+FileName=..\..\libspeex\misc.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit22]\r
+FileName=..\..\libspeex\modes.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit23]\r
+FileName=..\..\libspeex\modes.h\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit24]\r
+FileName=..\..\libspeex\nb_celp.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit25]\r
+FileName=..\..\libspeex\nb_celp.h\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit26]\r
+FileName=..\..\libspeex\preprocess.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit27]\r
+FileName=..\..\libspeex\quant_lsp.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit28]\r
+FileName=..\..\libspeex\quant_lsp.h\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit29]\r
+FileName=..\..\libspeex\sb_celp.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit30]\r
+FileName=..\..\libspeex\sb_celp.h\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit31]\r
+FileName=..\..\libspeex\smallft.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit32]\r
+FileName=..\..\libspeex\smallft.h\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit33]\r
+FileName=..\..\libspeex\speex.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit34]\r
+FileName=..\..\libspeex\speex_callbacks.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit35]\r
+FileName=..\..\libspeex\speex_header.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit36]\r
+FileName=..\..\libspeex\stereo.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit37]\r
+FileName=..\..\libspeex\vbr.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit38]\r
+FileName=..\..\libspeex\vbr.h\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit39]\r
+FileName=..\..\libspeex\vq.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit40]\r
+FileName=..\..\libspeex\vq.h\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit41]\r
+FileName=..\..\libspeex\bits.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit42]\r
+FileName=..\..\libspeex\cb_search.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit43]\r
+FileName=..\..\libspeex\cb_search.h\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit44]\r
+FileName=..\..\libspeex\exc_5_64_table.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit45]\r
+FileName=..\..\libspeex\exc_5_256_table.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit46]\r
+FileName=..\..\libspeex\exc_8_128_table.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit47]\r
+FileName=..\..\libspeex\exc_10_16_table.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit48]\r
+FileName=..\..\libspeex\exc_10_32_table.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit49]\r
+FileName=..\..\libspeex\exc_20_32_table.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit50]\r
+FileName=..\..\libspeex\filters.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit51]\r
+FileName=..\..\libspeex\filters.h\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit52]\r
+FileName=..\..\libspeex\gain_table.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit53]\r
+FileName=..\..\libspeex\gain_table_lbr.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit54]\r
+FileName=..\..\libspeex\hexc_10_32_table.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit55]\r
+FileName=..\..\libspeex\hexc_table.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit56]\r
+FileName=..\..\libspeex\high_lsp_tables.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit57]\r
+FileName=..\..\libspeex\jitter.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit58]\r
+FileName=..\..\libspeex\lbr_48k_tables.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit59]\r
+FileName=..\..\libspeex\lpc.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit60]\r
+FileName=..\..\libspeex\lpc.h\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit61]\r
+FileName=..\..\libspeex\lsp.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit62]\r
+FileName=..\..\libspeex\lsp.h\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit63]\r
+FileName=..\..\libspeex\lsp_tables_nb.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit64]\r
+FileName=..\..\libspeex\ltp.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit65]\r
+FileName=..\..\libspeex\ltp.h\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit66]\r
+FileName=..\..\libspeex\math_approx.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit67]\r
+FileName=..\..\libspeex\math_approx.h\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit68]\r
+FileName=..\..\winfuncs.c\r
+CompileCpp=0\r
+Folder=win32\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit70]\r
+FileName=..\..\spandsp\plc.c\r
+CompileCpp=0\r
+Folder=iaxclient\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit71]\r
+FileName=..\..\audio_file.h\r
+CompileCpp=0\r
+Folder=iaxclient\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit72]\r
+FileName=..\..\audio_portaudio.c\r
+CompileCpp=0\r
+Folder=iaxclient\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit73]\r
+FileName=..\..\audio_portaudio.h\r
+CompileCpp=0\r
+Folder=iaxclient\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit74]\r
+FileName=..\..\audio_encode.c\r
+CompileCpp=0\r
+Folder=iaxclient\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit75]\r
+FileName=..\..\audio_encode.h\r
+CompileCpp=0\r
+Folder=iaxclient\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit76]\r
+FileName=..\..\audio_file.c\r
+CompileCpp=0\r
+Folder=iaxclient\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit77]\r
+FileName=..\..\codec_speex.h\r
+CompileCpp=0\r
+Folder=codecs\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit78]\r
+FileName=..\..\codec_ulaw.c\r
+CompileCpp=0\r
+Folder=codecs\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit79]\r
+FileName=..\..\codec_ulaw.h\r
+CompileCpp=0\r
+Folder=codecs\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit80]\r
+FileName=..\..\codec_alaw.c\r
+CompileCpp=0\r
+Folder=codecs\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit81]\r
+FileName=..\..\codec_alaw.h\r
+CompileCpp=0\r
+Folder=codecs\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit82]\r
+FileName=..\..\codec_gsm.c\r
+CompileCpp=0\r
+Folder=codecs\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit83]\r
+FileName=..\..\codec_gsm.h\r
+CompileCpp=0\r
+Folder=codecs\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit84]\r
+FileName=..\..\codec_speex.c\r
+CompileCpp=0\r
+Folder=codecs\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit85]\r
+FileName=..\..\libiax2\src\iax2-parser.h\r
+CompileCpp=0\r
+Folder=iax2\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit86]\r
+FileName=..\..\libiax2\src\iax.c\r
+CompileCpp=0\r
+Folder=iax2\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit87]\r
+FileName=..\..\libiax2\src\md5.c\r
+CompileCpp=0\r
+Folder=iax2\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit88]\r
+FileName=..\..\libiax2\src\md5.h\r
+CompileCpp=0\r
+Folder=iax2\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit89]\r
+FileName=..\..\libiax2\src\iax2-parser.c\r
+CompileCpp=0\r
+Folder=iax2\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit90]\r
+FileName=..\..\sox\soxcompat.c\r
+CompileCpp=0\r
+Folder=sox\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit91]\r
+FileName=..\..\sox\compand.c\r
+CompileCpp=0\r
+Folder=sox\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit93]\r
+FileName=..\..\sox\sox.h\r
+CompileCpp=0\r
+Folder=sox\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit94]\r
+FileName=..\..\libiax2\src\winpoop.h\r
+CompileCpp=0\r
+Folder=win32\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit95]\r
+FileName=..\..\iaxclient_lib.c\r
+CompileCpp=0\r
+Folder=iaxclient\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit96]\r
+FileName=..\..\iaxclient_lib.h\r
+CompileCpp=0\r
+Folder=iaxclient\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit97]\r
+FileName=..\..\gsm\inc\config.h\r
+CompileCpp=0\r
+Folder=gsm\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit98]\r
+FileName=..\..\gsm\inc\unproto.h\r
+CompileCpp=0\r
+Folder=gsm\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit99]\r
+FileName=..\..\gsm\inc\gsm.h\r
+CompileCpp=0\r
+Folder=gsm\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit101]\r
+FileName=..\..\gsm\inc\proto.h\r
+CompileCpp=0\r
+Folder=gsm\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit102]\r
+FileName=..\..\libiax2\src\iax2.h\r
+CompileCpp=0\r
+Folder=iax2\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit103]\r
+FileName=..\..\libiax2\src\iax-client.h\r
+CompileCpp=0\r
+Folder=iax2\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit104]\r
+FileName=..\..\libiax2\src\jitterbuf.h\r
+CompileCpp=0\r
+Folder=iax2\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit105]\r
+FileName=..\..\libiax2\src\jitterbuf.c\r
+CompileCpp=0\r
+Folder=iax2\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit106]\r
+FileName=..\..\iaxclient.h\r
+CompileCpp=0\r
+Folder=iaxclient\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit107]\r
+FileName=..\..\portaudio\src\common\pa_stream.c\r
+CompileCpp=0\r
+Folder=portaudio\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit108]\r
+FileName=..\..\portaudio\src\common\pa_stream.h\r
+CompileCpp=0\r
+Folder=portaudio\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit92]\r
+FileName=..\..\sox\resample.c\r
+CompileCpp=0\r
+Folder=sox\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit109]\r
+FileName=..\..\portaudio\src\common\pa_trace.c\r
+CompileCpp=0\r
+Folder=portaudio\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit110]\r
+FileName=..\..\portaudio\src\common\pa_trace.h\r
+CompileCpp=0\r
+Folder=portaudio\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit111]\r
+FileName=..\..\portaudio\src\common\pa_types.h\r
+CompileCpp=0\r
+Folder=portaudio\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit100]\r
+FileName=..\..\gsm\inc\private.h\r
+CompileCpp=0\r
+Folder=gsm\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit19]\r
+FileName=..\..\libspeex\mdf.c\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit21]\r
+FileName=..\..\libspeex\misc.h\r
+CompileCpp=0\r
+Folder=speex\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit112]\r
+FileName=..\..\portaudio\src\common\pa_util.h\r
+CompileCpp=0\r
+Folder=portaudio\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit113]\r
+FileName=..\..\portaudio\src\common\pa_allocation.c\r
+CompileCpp=0\r
+Folder=portaudio\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit114]\r
+FileName=..\..\portaudio\src\common\pa_allocation.h\r
+CompileCpp=0\r
+Folder=portaudio\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit115]\r
+FileName=..\..\portaudio\src\common\pa_converters.c\r
+CompileCpp=0\r
+Folder=portaudio\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit116]\r
+FileName=..\..\portaudio\src\common\pa_converters.h\r
+CompileCpp=0\r
+Folder=portaudio\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit117]\r
+FileName=..\..\portaudio\src\common\pa_cpuload.c\r
+CompileCpp=0\r
+Folder=portaudio\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit118]\r
+FileName=..\..\portaudio\src\common\pa_cpuload.h\r
+CompileCpp=0\r
+Folder=portaudio\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit119]\r
+FileName=..\..\portaudio\src\common\pa_dither.c\r
+CompileCpp=0\r
+Folder=portaudio\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit120]\r
+FileName=..\..\portaudio\src\common\pa_dither.h\r
+CompileCpp=0\r
+Folder=portaudio\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit121]\r
+FileName=..\..\portaudio\src\common\pa_endianness.h\r
+CompileCpp=0\r
+Folder=portaudio\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit122]\r
+FileName=..\..\portaudio\src\common\pa_front.c\r
+CompileCpp=0\r
+Folder=portaudio\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit123]\r
+FileName=..\..\portaudio\src\common\pa_hostapi.h\r
+CompileCpp=0\r
+Folder=portaudio\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit124]\r
+FileName=..\..\portaudio\src\common\pa_process.c\r
+CompileCpp=0\r
+Folder=portaudio\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit125]\r
+FileName=..\..\portaudio\src\common\pa_process.h\r
+CompileCpp=0\r
+Folder=portaudio\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit126]\r
+FileName=..\..\portaudio\src\common\pa_skeleton.c\r
+CompileCpp=0\r
+Folder=portaudio\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit127]\r
+FileName=..\..\portaudio\src\hostapi\wmme\pa_win_wmme.c\r
+CompileCpp=0\r
+Folder=win32\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit69]\r
+FileName=..\..\spandsp\plc.h\r
+CompileCpp=0\r
+Folder=iaxclient\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit128]\r
+FileName=..\..\portaudio\src\os\win\pa_win_hostapis.c\r
+CompileCpp=0\r
+Folder=win32\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit129]\r
+FileName=..\..\portaudio\src\os\win\pa_win_util.c\r
+CompileCpp=0\r
+Folder=win32\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit130]\r
+FileName=..\..\portaudio\pablio\ringbuffer.h\r
+CompileCpp=0\r
+Folder=win32\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit131]\r
+FileName=..\..\portaudio\pablio\ringbuffer.c\r
+CompileCpp=0\r
+Folder=win32\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
+[Unit132]\r
+FileName=..\..\portmixer\px_win_wmme\px_win_wmme.c\r
+CompileCpp=0\r
+Folder=win32\r
+Compile=1\r
+Link=1\r
+Priority=1000\r
+OverrideBuildCmd=0\r
+BuildCmd=\r
+\r
diff --git a/utils/iaxclient/lib/win/iaxclient.def b/utils/iaxclient/lib/win/iaxclient.def
new file mode 100644 (file)
index 0000000..bac4049
--- /dev/null
@@ -0,0 +1,107 @@
+EXPORTS
+    iaxc_answer_call = iaxc_answer_call@4 @1
+    iaxc_answer_call@4 @2
+    iaxc_audio_devices_get = iaxc_audio_devices_get@20 @3
+    iaxc_audio_devices_get@20 @4
+    iaxc_audio_devices_set = iaxc_audio_devices_set@12 @5
+    iaxc_audio_devices_set@12 @6
+    iaxc_blind_transfer_call = iaxc_blind_transfer_call@8 @7
+    iaxc_blind_transfer_call@8 @8
+    iaxc_call = iaxc_call@4 @9
+    iaxc_call@4 @10
+    iaxc_dump_all_calls = iaxc_dump_all_calls@0 @11
+    iaxc_dump_all_calls@0 @12
+    iaxc_dump_call = iaxc_dump_call@0 @13
+    iaxc_dump_call@0 @14
+    iaxc_first_free_call = iaxc_first_free_call@0 @15
+    iaxc_first_free_call@0 @16
+    iaxc_free_event = iaxc_free_event@4 @17
+    iaxc_free_event@4 @18
+    iaxc_get_event_levels = iaxc_get_event_levels@4 @19
+    iaxc_get_event_levels@4 @20
+    iaxc_get_event_state = iaxc_get_event_state@4 @21
+    iaxc_get_event_state@4 @22
+    iaxc_get_event_text = iaxc_get_event_text@4 @23
+    iaxc_get_event_text@4 @24
+    iaxc_get_filters = iaxc_get_filters@0 @25
+    iaxc_get_filters@0 @26
+    iaxc_get_netstats = iaxc_get_netstats@16 @27
+    iaxc_get_netstats@16 @28
+    iaxc_initialize = iaxc_initialize@8 @29
+    iaxc_initialize@8 @30
+    iaxc_input_level_get = iaxc_input_level_get@0 @31
+    iaxc_input_level_get@0 @32
+    iaxc_input_level_set = iaxc_input_level_set@8 @33
+    iaxc_input_level_set@8 @34
+    iaxc_mic_boost_get = iaxc_mic_boost_get@0 @35
+    iaxc_mic_boost_get@0 @36
+    iaxc_mic_boost_set = iaxc_mic_boost_set@4 @37
+    iaxc_mic_boost_set@4 @38
+    iaxc_millisleep = iaxc_millisleep@4 @39
+    iaxc_millisleep@4 @40
+    iaxc_output_level_get = iaxc_output_level_get@0 @41
+    iaxc_output_level_get@0 @42
+    iaxc_output_level_set = iaxc_output_level_set@8 @43
+    iaxc_output_level_set@8 @44
+    iaxc_play_sound = iaxc_play_sound@8 @45
+    iaxc_play_sound@8 @46
+    iaxc_process_calls = iaxc_process_calls@0 @47
+    iaxc_process_calls@0 @48
+    iaxc_quelch = iaxc_quelch@8 @49
+    iaxc_quelch@8 @50
+    iaxc_register = iaxc_register@12 @51
+    iaxc_register@12 @52
+    iaxc_reject_call = iaxc_reject_call@0 @53
+    iaxc_reject_call@0 @54
+    iaxc_reject_call_number = iaxc_reject_call_number@4 @55
+    iaxc_reject_call_number@4 @56
+    iaxc_select_call = iaxc_select_call@4 @57
+    iaxc_select_call@4 @58
+    iaxc_selected_call = iaxc_selected_call@0 @59
+    iaxc_selected_call@0 @60
+    iaxc_send_busy_on_incoming_call = iaxc_send_busy_on_incoming_call@4 @61
+    iaxc_send_busy_on_incoming_call@4 @62
+    iaxc_send_dtmf = iaxc_send_dtmf@4 @63
+    iaxc_send_dtmf@4 @64
+    iaxc_send_text = iaxc_send_text@4 @65
+    iaxc_send_text@4 @66
+    iaxc_send_url = iaxc_send_url@8 @67
+    iaxc_send_url@8 @68
+    iaxc_set_audio_output = iaxc_set_audio_output@4 @69
+    iaxc_set_audio_output@4 @70
+    iaxc_set_callerid = iaxc_set_callerid@8 @71
+    iaxc_set_callerid@8 @72
+    iaxc_set_event_callback = iaxc_set_event_callback@4 @73
+    iaxc_set_event_callback@4 @74
+    iaxc_set_event_callpost = iaxc_set_event_callpost@8 @75
+    iaxc_set_event_callpost@8 @76
+    iaxc_set_files = iaxc_set_files@8 @77
+    iaxc_set_files@8 @78
+    iaxc_set_filters = iaxc_set_filters@4 @79
+    iaxc_set_filters@4 @80
+    iaxc_set_formats = iaxc_set_formats@8 @81
+    iaxc_set_formats@8 @82
+    iaxc_set_min_outgoing_framesize = iaxc_set_min_outgoing_framesize@4 @83
+    iaxc_set_min_outgoing_framesize@4 @84
+    iaxc_set_networking = iaxc_set_networking@8 @85
+    iaxc_set_networking@8 @86
+    iaxc_set_preferred_source_udp_port = iaxc_set_preferred_source_udp_port@4 @87
+    iaxc_set_preferred_source_udp_port@4 @88
+    iaxc_set_silence_threshold = iaxc_set_silence_threshold@8 @89
+    iaxc_set_silence_threshold@8 @90
+    iaxc_set_speex_settings = iaxc_set_speex_settings@24 @91
+    iaxc_set_speex_settings@24 @92
+    iaxc_shutdown = iaxc_shutdown@0 @93
+    iaxc_shutdown@0 @94
+    iaxc_start_processing_thread = iaxc_start_processing_thread@0 @95
+    iaxc_start_processing_thread@0 @96
+    iaxc_stop_processing_thread = iaxc_stop_processing_thread@0 @97
+    iaxc_stop_processing_thread@0 @98
+    iaxc_stop_sound = iaxc_stop_sound@4 @99
+    iaxc_stop_sound@4 @100
+    iaxc_unquelch = iaxc_unquelch@4 @101
+    iaxc_unquelch@4 @102
+    iaxc_unregister = iaxc_unregister@4 @103
+    iaxc_unregister@4 @104
+    iaxc_version = iaxc_version@4 @105
+    iaxc_version@4 @106
diff --git a/utils/iaxclient/lib/win/iaxclient_dll.c b/utils/iaxclient/lib/win/iaxclient_dll.c
new file mode 100644 (file)
index 0000000..4823dfe
--- /dev/null
@@ -0,0 +1,27 @@
+/*\r
+ * Copyrights:\r
+ * Copyright (C) 2006 Gatherworks.com\r
+ *\r
+ * Contributors:\r
+ * Frik Strecker <frik@gatherworks.com>\r
+ * Bill Welch <bill@gatherworks.com>\r
+ *\r
+ *\r
+ * This program is free software, distributed under the terms of\r
+ * the GNU Lesser (Library) General Public License\r
+ */\r
+\r
+//#define INITGUID\r
+//#include <initguid.h>\r
+#include <windows.h>\r
+\r
+BOOL APIENTRY DllMain(\r
+       HANDLE                  hModule, \r
+    DWORD                      ul_reason_for_call, \r
+    LPVOID                     lpReserved)\r
+{\r
+    return TRUE;\r
+}\r
+\r
+/* #EOF# */\r
+\r
diff --git a/utils/iaxclient/lib/win/iaxclient_dll.def b/utils/iaxclient/lib/win/iaxclient_dll.def
new file mode 100644 (file)
index 0000000..80a715d
--- /dev/null
@@ -0,0 +1,57 @@
+EXPORTS\r
+       iaxc_answer_call\r
+       iaxc_audio_devices_get\r
+       iaxc_audio_devices_set\r
+;      iaxc_auto_call\r
+       iaxc_blind_transfer_call\r
+       iaxc_call\r
+       iaxc_dump_all_calls\r
+       iaxc_dump_call\r
+       iaxc_first_free_call\r
+       iaxc_free_event\r
+       iaxc_get_event_levels\r
+       iaxc_get_event_state\r
+       iaxc_get_event_text\r
+       iaxc_get_filters\r
+       iaxc_get_netstats\r
+       iaxc_initialize\r
+;      iaxc_initialize_sock\r
+       iaxc_input_level_get\r
+       iaxc_input_level_set\r
+       iaxc_mic_boost_get\r
+       iaxc_mic_boost_set\r
+       iaxc_millisleep\r
+       iaxc_output_level_get\r
+       iaxc_output_level_set\r
+       iaxc_play_sound\r
+       iaxc_process_calls\r
+       iaxc_quelch\r
+       iaxc_register\r
+       iaxc_reject_call\r
+       iaxc_reject_call_number\r
+       iaxc_select_call\r
+       iaxc_selected_call\r
+       iaxc_send_busy_on_incoming_call\r
+       iaxc_send_dtmf\r
+       iaxc_send_text\r
+       iaxc_send_url\r
+       iaxc_set_audio_output\r
+       iaxc_set_callerid\r
+       iaxc_set_event_callback\r
+       iaxc_set_event_callpost\r
+       iaxc_set_files\r
+       iaxc_set_filters\r
+       iaxc_set_formats\r
+       iaxc_set_min_outgoing_framesize\r
+       iaxc_set_networking\r
+       iaxc_set_preferred_source_udp_port\r
+       iaxc_set_silence_threshold\r
+       iaxc_set_speex_settings\r
+       iaxc_shutdown\r
+       iaxc_start_processing_thread\r
+       iaxc_stop_processing_thread\r
+       iaxc_stop_sound\r
+       iaxc_unquelch\r
+       iaxc_unregister\r
+       iaxc_version\r
+;      setup_jb_output\r
diff --git a/utils/iaxclient/lib/win/vc6/all.dsp b/utils/iaxclient/lib/win/vc6/all.dsp
new file mode 100644 (file)
index 0000000..2358823
--- /dev/null
@@ -0,0 +1,63 @@
+# Microsoft Developer Studio Project File - Name="all" - Package Owner=<4>\r
+# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
+# ** DO NOT EDIT **\r
+\r
+# TARGTYPE "Win32 (x86) Generic Project" 0x010a\r
+\r
+CFG=all - Win32 Debug\r
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
+!MESSAGE use the Export Makefile command and run\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "all.mak".\r
+!MESSAGE \r
+!MESSAGE You can specify a configuration when running NMAKE\r
+!MESSAGE by defining the macro CFG on the command line. For example:\r
+!MESSAGE \r
+!MESSAGE NMAKE /f "all.mak" CFG="all - Win32 Debug"\r
+!MESSAGE \r
+!MESSAGE Possible choices for configuration are:\r
+!MESSAGE \r
+!MESSAGE "all - Win32 Release" (based on "Win32 (x86) Generic Project")\r
+!MESSAGE "all - Win32 Debug" (based on "Win32 (x86) Generic Project")\r
+!MESSAGE \r
+\r
+# Begin Project\r
+# PROP AllowPerConfigDependencies 0\r
+# PROP Scc_ProjName ""\r
+# PROP Scc_LocalPath ""\r
+MTL=midl.exe\r
+\r
+!IF  "$(CFG)" == "all - Win32 Release"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 0\r
+# PROP BASE Output_Dir "Release"\r
+# PROP BASE Intermediate_Dir "Release"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 0\r
+# PROP Output_Dir "Release"\r
+# PROP Intermediate_Dir "Release"\r
+# PROP Target_Dir ""\r
+\r
+!ELSEIF  "$(CFG)" == "all - Win32 Debug"\r
+\r
+# PROP BASE Use_MFC 0\r
+# PROP BASE Use_Debug_Libraries 1\r
+# PROP BASE Output_Dir "Debug"\r
+# PROP BASE Intermediate_Dir "Debug"\r
+# PROP BASE Target_Dir ""\r
+# PROP Use_MFC 0\r
+# PROP Use_Debug_Libraries 1\r
+# PROP Output_Dir "Debug"\r
+# PROP Intermediate_Dir "Debug"\r
+# PROP Target_Dir ""\r
+\r
+!ENDIF \r
+\r
+# Begin Target\r
+\r
+# Name "all - Win32 Release"\r
+# Name "all - Win32 Debug"\r
+# End Target\r
+# End Project\r
diff --git a/utils/iaxclient/lib/win/vc6/iaxclient_lib.dsw b/utils/iaxclient/lib/win/vc6/iaxclient_lib.dsw
new file mode 100644 (file)
index 0000000..6a94f6f
--- /dev/null
@@ -0,0 +1,59 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00\r
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\r
+\r
+###############################################################################\r
+\r
+Project: "all"=.\all.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+    Begin Project Dependency\r
+    Project_Dep_Name iaxclient_dll\r
+    End Project Dependency\r
+    Begin Project Dependency\r
+    Project_Dep_Name iaxclient_lib\r
+    End Project Dependency\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Project: "iaxclient_dll"=.\iaxclient_dll.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Project: "iaxclient_lib"=.\iaxclient_lib.dsp - Package Owner=<4>\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<4>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
+Global:\r
+\r
+Package=<5>\r
+{{{\r
+}}}\r
+\r
+Package=<3>\r
+{{{\r
+}}}\r
+\r
+###############################################################################\r
+\r
diff --git a/utils/iaxclient/lib/win/vs2003/iaxclient_dll.vcproj b/utils/iaxclient/lib/win/vs2003/iaxclient_dll.vcproj
new file mode 100644 (file)
index 0000000..7e4eb3c
--- /dev/null
@@ -0,0 +1,678 @@
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="7.10"\r
+       Name="iaxclient_dll"\r
+       SccProjectName=""\r
+       SccLocalPath="">\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"/>\r
+       </Platforms>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory=".\DebugDLL"\r
+                       IntermediateDirectory=".\DebugDLL"\r
+                       ConfigurationType="2"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE"\r
+                       CharacterSet="2">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..,..\..\gsm\inc,..\..\portaudio\include,..\..\portaudio\src\common,..\..\portaudio\pablio,..\..\portmixer\px_common,..\..\libspeex\include,..\..\libiax2\src,..\..\wince"\r
+                               PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_WINDLL;_USRDLL;BUILDING_DLL;PA_NO_DS;PA_NO_ASIO;SPEEX_PREPROCESS=1;NEWJB;LIBIAX;SPEEX_EC=1;_CRT_SECURE_NO_DEPRECATE;inline=__inline;strncasecmp=_strnicmp;vsnprintf=_vsnprintf"\r
+                               MinimalRebuild="FALSE"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="3"\r
+                               BufferSecurityCheck="TRUE"\r
+                               RuntimeTypeInfo="FALSE"\r
+                               PrecompiledHeaderFile=""\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(IntDir)\vc80.pdb"\r
+                               BrowseInformation="0"\r
+                               BrowseInformationFile="$(TargetDir)$(TargetName).bsc"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               Detect64BitPortabilityProblems="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CallingConvention="2"\r
+                               CompileAs="1"\r
+                               DisableSpecificWarnings="4244;4100;4201;4305;4189;4127;4131"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="msvcrt.lib wsock32.lib winmm.lib odbc32.lib odbccp32.lib"\r
+                               OutputFile="$(IntDir)\iaxclient.dll"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               ModuleDefinitionFile="..\iaxclient_dll.def"\r
+                               GenerateDebugInformation="TRUE"\r
+                               ProgramDatabaseFile="$(IntDir)/iaxclient.pdb"\r
+                               GenerateMapFile="TRUE"\r
+                               MapFileName="$(IntDir)/iaxclient.map"\r
+                               ImportLibrary="$(IntDir)/iaxclient.lib"\r
+                               TargetMachine="1"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               MkTypLibCompatible="TRUE"\r
+                               SuppressStartupBanner="TRUE"\r
+                               TargetEnvironment="1"\r
+                               TypeLibraryName="$(IntDir)/iaxclient.tlb"\r
+                               HeaderFileName=""/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+                       <Tool\r
+                               Name="VCManagedWrapperGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory=".\ReleaseDLL"\r
+                       IntermediateDirectory=".\ReleaseDLL"\r
+                       ConfigurationType="2"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="2"\r
+                               InlineFunctionExpansion="1"\r
+                               FavorSizeOrSpeed="2"\r
+                               OmitFramePointers="TRUE"\r
+                               AdditionalIncludeDirectories="..\..,..\..\gsm\inc,..\..\portaudio\include,..\..\portaudio\src\common,..\..\portaudio\pablio,..\..\portmixer\px_common,..\..\libspeex\include,..\..\libiax2\src,..\..\wince"\r
+                               PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_WINDLL;_USRDLL;BUILDING_DLL;PA_NO_DS;PA_NO_ASIO;SPEEX_PREPROCESS=1;NEWJB;LIBIAX;SPEEX_EC=1;inline=__inline;strncasecmp=strnicmp;vsnprintf=_vsnprintf"\r
+                               StringPooling="TRUE"\r
+                               RuntimeLibrary="2"\r
+                               RuntimeTypeInfo="FALSE"\r
+                               PrecompiledHeaderFile=""\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(IntDir)\vc80.pdb"\r
+                               BrowseInformation="0"\r
+                               BrowseInformationFile="$(TargetDir)$(TargetName).bsc"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CallingConvention="2"\r
+                               CompileAs="1"\r
+                               DisableSpecificWarnings="4244;4100;4201;4305;4189;4127;4131"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="wsock32.lib winmm.lib odbc32.lib odbccp32.lib"\r
+                               OutputFile="$(IntDir)/iaxclient.dll"\r
+                               LinkIncremental="1"\r
+                               SuppressStartupBanner="TRUE"\r
+                               ProgramDatabaseFile="$(IntDir)/iaxclient.pdb"\r
+                               GenerateMapFile="TRUE"\r
+                               MapFileName="$(IntDir)/iaxclient.map"\r
+                               ImportLibrary="$(IntDir)/iaxclient.lib"\r
+                               TargetMachine="1"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               MkTypLibCompatible="TRUE"\r
+                               SuppressStartupBanner="TRUE"\r
+                               TargetEnvironment="1"\r
+                               TypeLibraryName="$(IntDir)/iaxclient.tlb"\r
+                               HeaderFileName=""/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"/>\r
+                       <Tool\r
+                               Name="VCManagedWrapperGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+               </Configuration>\r
+       </Configurations>\r
+       <References>\r
+       </References>\r
+       <Files>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">\r
+                       <File\r
+                               RelativePath="..\..\audio_encode.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\audio_file.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\audio_portaudio.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_alaw.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_gsm.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_speex.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_ulaw.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\iax.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\iax2-parser.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\iaxclient_dll.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\iaxclient_dll.def">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\iaxclient_lib.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\jitterbuf.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\md5.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\winfuncs.c">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl">\r
+                       <File\r
+                               RelativePath="..\..\audio_encode.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\audio_file.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\audio_portaudio.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_alaw.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_gsm.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_speex.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_ulaw.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\iax.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\iax2-parser.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\iax2.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\iaxclient.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\iaxclient_lib.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\jitterbuf.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\md5.h">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="DSP"\r
+                       Filter="c;h">\r
+                       <File\r
+                               RelativePath="..\..\sox\compand.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\spandsp\plc.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\spandsp\plc.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\sox\resample.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\sox\soxcompat.c">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="GSM"\r
+                       Filter="c;h">\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\add.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\code.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\inc\config.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\debug.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\decode.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\inc\gsm.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_create.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_decode.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_destroy.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_encode.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_explode.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_implode.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_option.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_print.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\k6opt.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\long_term.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\lpc.c">\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32">\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               ObjectFile="$(IntDir)\gsm\"\r
+                                               ProgramDataBaseFileName="$(IntDir)\gsm\"/>\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32">\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               ObjectFile="$(IntDir)\gsm\"\r
+                                               ProgramDataBaseFileName="$(IntDir)\gsm\"/>\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\preprocess.c">\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32">\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               ObjectFile="$(IntDir)\gsm\"\r
+                                               ProgramDataBaseFileName="$(IntDir)\gsm\"/>\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32">\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               ObjectFile="$(IntDir)\gsm\"\r
+                                               ProgramDataBaseFileName="$(IntDir)\gsm\"/>\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\inc\private.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\inc\proto.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\rpe.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\short_term.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\inc\unproto.h">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="PortAudio"\r
+                       Filter="c;h">\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_allocation.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_allocation.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_converters.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_converters.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_cpuload.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_cpuload.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_dither.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_dither.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_endianness.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_front.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_hostapi.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_process.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_process.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_skeleton.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_stream.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_stream.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_trace.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_trace.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_types.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_util.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\hostapi\dsound\pa_win_ds_dynlink.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\hostapi\dsound\pa_win_ds_dynlink.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\os\win\pa_win_hostapis.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\os\win\pa_win_util.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\hostapi\wmme\pa_win_wmme.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\os\win\pa_x86_plain_converters.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\os\win\pa_x86_plain_converters.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\pablio\ringbuffer.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\pablio\ringbuffer.h">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="PortMixer"\r
+                       Filter="cpp;h">\r
+                       <File\r
+                               RelativePath="..\..\portmixer\px_win_wmme\px_win_wmme.c">\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32">\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               CompileAs="2"/>\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32">\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               CompileAs="2"/>\r
+                               </FileConfiguration>\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Speex"\r
+                       Filter="c;h">\r
+                       <File\r
+                               RelativePath="..\..\libspeex\arch.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\bits.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\cb_search.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\cb_search.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\cb_search_sse.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\exc_10_16_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\exc_10_32_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\exc_20_32_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\exc_5_256_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\exc_5_64_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\exc_8_128_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\filters.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\filters.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\filters_sse.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\fixed_debug.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\fixed_generic.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\gain_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\gain_table_lbr.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\hexc_10_32_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\hexc_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\high_lsp_tables.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\jitter.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\lbr_48k_tables.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\lpc.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\lpc.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\lsp.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\lsp.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\lsp_tables_nb.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\ltp.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\ltp.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\ltp_sse.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\math_approx.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\math_approx.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\mdf.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\medfilter.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\medfilter.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\misc.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\misc.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\modes.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\modes.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\nb_celp.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\nb_celp.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\preprocess.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\quant_lsp.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\quant_lsp.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\sb_celp.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\sb_celp.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\smallft.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\smallft.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\sox\sox.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\speex.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\speex_callbacks.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\speex_header.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\stack_alloc.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\stereo.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\vbr.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\vbr.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\vq.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\vq.h">\r
+                       </File>\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/utils/iaxclient/lib/win/vs2003/iaxclient_lib.sln b/utils/iaxclient/lib/win/vs2003/iaxclient_lib.sln
new file mode 100644 (file)
index 0000000..028446c
--- /dev/null
@@ -0,0 +1,29 @@
+Microsoft Visual Studio Solution File, Format Version 8.00\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iaxclient_dll", "iaxclient_dll.vcproj", "{00920B8E-2080-45AB-8742-6499B262FB7E}"\r
+       ProjectSection(ProjectDependencies) = postProject\r
+       EndProjectSection\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iaxclient_lib", "iaxclient_lib.vcproj", "{EA324E13-9C5F-4AF3-9DE8-9360628DB3B0}"\r
+       ProjectSection(ProjectDependencies) = postProject\r
+       EndProjectSection\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfiguration) = preSolution\r
+               Debug = Debug\r
+               Release = Release\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfiguration) = postSolution\r
+               {00920B8E-2080-45AB-8742-6499B262FB7E}.Debug.ActiveCfg = Debug|Win32\r
+               {00920B8E-2080-45AB-8742-6499B262FB7E}.Debug.Build.0 = Debug|Win32\r
+               {00920B8E-2080-45AB-8742-6499B262FB7E}.Release.ActiveCfg = Release|Win32\r
+               {00920B8E-2080-45AB-8742-6499B262FB7E}.Release.Build.0 = Release|Win32\r
+               {EA324E13-9C5F-4AF3-9DE8-9360628DB3B0}.Debug.ActiveCfg = Debug|Win32\r
+               {EA324E13-9C5F-4AF3-9DE8-9360628DB3B0}.Debug.Build.0 = Debug|Win32\r
+               {EA324E13-9C5F-4AF3-9DE8-9360628DB3B0}.Release.ActiveCfg = Release|Win32\r
+               {EA324E13-9C5F-4AF3-9DE8-9360628DB3B0}.Release.Build.0 = Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(ExtensibilityGlobals) = postSolution\r
+       EndGlobalSection\r
+       GlobalSection(ExtensibilityAddIns) = postSolution\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/utils/iaxclient/lib/win/vs2003/iaxclient_lib.vcproj b/utils/iaxclient/lib/win/vs2003/iaxclient_lib.vcproj
new file mode 100644 (file)
index 0000000..4ff881f
--- /dev/null
@@ -0,0 +1,528 @@
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="7.10"\r
+       Name="iaxclient_lib"\r
+       ProjectGUID="{90081FBB-8988-40ED-A5FD-7EA2B24B6337}"\r
+       SccProjectName=""\r
+       SccLocalPath="">\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"/>\r
+       </Platforms>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory=".\DebugLIB"\r
+                       IntermediateDirectory=".\DebugLIB"\r
+                       ConfigurationType="4"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..,..\..\gsm\inc,..\..\portaudio\include,..\..\portaudio\src\common,..\..\portaudio\pablio,..\..\portmixer\px_common,..\..\libspeex\include,..\..\libiax2\src,..\..\wince;..\..\..\..\..\3rdparty\include"\r
+                               PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_LIB;PA_NO_DS;PA_NO_ASIO;SPEEX_PREPROCESS=1;NEWJB;LIBIAX;SPEEX_EC=1;inline=__inline;strncasecmp=strnicmp;vsnprintf=_vsnprintf"\r
+                               MinimalRebuild="FALSE"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="3"\r
+                               BufferSecurityCheck="TRUE"\r
+                               RuntimeTypeInfo="FALSE"\r
+                               PrecompiledHeaderFile=""\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(IntDir)\vc80.pdb"\r
+                               BrowseInformation="0"\r
+                               BrowseInformationFile="$(TargetDir)$(TargetName).bsc"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               Detect64BitPortabilityProblems="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CallingConvention="2"\r
+                               CompileAs="1"\r
+                               DisableSpecificWarnings="4244;4100;4201;4305;4189;4127;4131"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLibrarianTool"\r
+                               OutputFile="$(IntDir)\iaxclient1.lib"\r
+                               SuppressStartupBanner="TRUE"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCManagedWrapperGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory=".\ReleaseLIB"\r
+                       IntermediateDirectory=".\ReleaseLIB"\r
+                       ConfigurationType="4"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="FALSE">\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="2"\r
+                               InlineFunctionExpansion="1"\r
+                               FavorSizeOrSpeed="2"\r
+                               OmitFramePointers="TRUE"\r
+                               AdditionalIncludeDirectories="..\..,..\..\gsm\inc,..\..\portaudio\include,..\..\portaudio\src\common,..\..\portaudio\pablio,..\..\portmixer\px_common,..\..\libspeex\include,..\..\libiax2\src,..\..\wince;..\..\..\..\..\3rdparty\include"\r
+                               PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_LIB;PA_NO_DS;PA_NO_ASIO;SPEEX_PREPROCESS=1;NEWJB;LIBIAX;SPEEX_EC=1;inline=__inline;strncasecmp=strnicmp;vsnprintf=_vsnprintf;AUDIO_OPENAL=1"\r
+                               StringPooling="TRUE"\r
+                               RuntimeLibrary="2"\r
+                               RuntimeTypeInfo="FALSE"\r
+                               PrecompiledHeaderFile=""\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(IntDir)\vc80.pdb"\r
+                               BrowseInformation="0"\r
+                               BrowseInformationFile="$(TargetDir)$(TargetName).bsc"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="TRUE"\r
+                               DebugInformationFormat="3"\r
+                               CallingConvention="0"\r
+                               CompileAs="1"\r
+                               DisableSpecificWarnings="4244;4100;4201;4305;4189;4127;4131"/>\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"/>\r
+                       <Tool\r
+                               Name="VCLibrarianTool"\r
+                               OutputFile="$(IntDir)\iaxclient1.lib"\r
+                               SuppressStartupBanner="TRUE"/>\r
+                       <Tool\r
+                               Name="VCMIDLTool"/>\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"/>\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"/>\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="1033"/>\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCManagedWrapperGeneratorTool"/>\r
+                       <Tool\r
+                               Name="VCAuxiliaryManagedWrapperGeneratorTool"/>\r
+               </Configuration>\r
+       </Configurations>\r
+       <References>\r
+       </References>\r
+       <Files>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">\r
+                       <File\r
+                               RelativePath="..\..\audio_encode.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\audio_file.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\audio_openal.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_alaw.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_gsm.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_speex.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_ulaw.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\iax.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\iax2-parser.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\iaxclient_lib.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\jitterbuf.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\md5.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\winfuncs.c">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl">\r
+                       <File\r
+                               RelativePath="..\..\audio_encode.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\audio_file.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\audio_portaudio.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_alaw.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_gsm.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_speex.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_ulaw.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\iax.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\iax2-parser.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\iax2.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\iaxclient.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\iaxclient_lib.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\jitterbuf.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\md5.h">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="DSP"\r
+                       Filter="c;h">\r
+                       <File\r
+                               RelativePath="..\..\sox\compand.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\spandsp\plc.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\spandsp\plc.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\sox\resample.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\sox\soxcompat.c">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="GSM"\r
+                       Filter="c;h">\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\add.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\code.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\inc\config.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\debug.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\decode.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\inc\gsm.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_create.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_decode.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_destroy.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_encode.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_explode.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_implode.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_option.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_print.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\k6opt.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\long_term.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\lpc.c">\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32">\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               ObjectFile="$(IntDir)\gsm\"\r
+                                               ProgramDataBaseFileName="$(IntDir)\gsm\"/>\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32">\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               ObjectFile="$(IntDir)\gsm\"\r
+                                               ProgramDataBaseFileName="$(IntDir)\gsm\"/>\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\preprocess.c">\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32">\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               ObjectFile="$(IntDir)\gsm\"\r
+                                               ProgramDataBaseFileName="$(IntDir)\gsm\"/>\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32">\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               ObjectFile="$(IntDir)\gsm\"\r
+                                               ProgramDataBaseFileName="$(IntDir)\gsm\"/>\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\inc\private.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\inc\proto.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\rpe.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\short_term.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\inc\unproto.h">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Speex"\r
+                       Filter="c;h">\r
+                       <File\r
+                               RelativePath="..\..\libspeex\arch.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\bits.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\cb_search.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\cb_search.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\cb_search_sse.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\exc_10_16_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\exc_10_32_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\exc_20_32_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\exc_5_256_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\exc_5_64_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\exc_8_128_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\filters.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\filters.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\filters_sse.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\fixed_debug.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\fixed_generic.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\gain_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\gain_table_lbr.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\hexc_10_32_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\hexc_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\high_lsp_tables.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\jitter.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\lbr_48k_tables.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\lpc.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\lpc.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\lsp.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\lsp.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\lsp_tables_nb.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\ltp.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\ltp.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\ltp_sse.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\math_approx.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\math_approx.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\mdf.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\medfilter.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\medfilter.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\misc.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\misc.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\modes.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\modes.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\nb_celp.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\nb_celp.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\preprocess.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\quant_lsp.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\quant_lsp.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\sb_celp.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\sb_celp.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\smallft.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\smallft.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\sox\sox.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\speex.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\speex_callbacks.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\speex_header.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\stack_alloc.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\stereo.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\vbr.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\vbr.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\vq.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\vq.h">\r
+                       </File>\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/utils/iaxclient/lib/win/vs2005/iaxclient_dll.vcproj b/utils/iaxclient/lib/win/vs2005/iaxclient_dll.vcproj
new file mode 100644 (file)
index 0000000..74e0df5
--- /dev/null
@@ -0,0 +1,744 @@
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="8.00"\r
+       Name="iaxclient_dll"\r
+       ProjectGUID="{334F0D70-5086-4180-8325-2B77FA845C13}"\r
+       RootNamespace="iaxclient_dll"\r
+       >\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"\r
+               />\r
+       </Platforms>\r
+       <ToolFiles>\r
+       </ToolFiles>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory=".\DebugDLL"\r
+                       IntermediateDirectory=".\DebugDLL"\r
+                       ConfigurationType="2"\r
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..,..\..\gsm\inc,..\..\portaudio\include,..\..\portaudio\src\common,..\..\portaudio\pablio,..\..\portmixer\px_common,..\..\libspeex\include,..\..\libiax2\src,..\..\wince"\r
+                               PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_WINDLL;_USRDLL;BUILDING_DLL;PA_NO_DS;PA_NO_ASIO;SPEEX_PREPROCESS=1;NEWJB;LIBIAX;SPEEX_EC=1;_CRT_SECURE_NO_DEPRECATE;inline=__inline;strncasecmp=_strnicmp;vsnprintf=_vsnprintf"\r
+                               MinimalRebuild="false"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="3"\r
+                               BufferSecurityCheck="true"\r
+                               RuntimeTypeInfo="false"\r
+                               PrecompiledHeaderFile=""\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(IntDir)\vc80.pdb"\r
+                               BrowseInformation="0"\r
+                               BrowseInformationFile="$(TargetDir)$(TargetName).bsc"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                               CallingConvention="2"\r
+                               CompileAs="1"\r
+                               DisableSpecificWarnings="4244;4100;4201;4305;4189;4127;4131"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1033"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="wsock32.lib winmm.lib Kernel32.lib dsound.lib"\r
+                               OutputFile="$(OutDir)\iaxclient.dll"\r
+                               LinkIncremental="1"\r
+                               ManifestFile="$(IntDir)\$(TargetFileName).intermediate.manifest"\r
+                               IgnoreDefaultLibraryNames=""\r
+                               ModuleDefinitionFile="..\iaxclient_dll.def"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb"\r
+                               GenerateMapFile="true"\r
+                               MapFileName="$(TargetDir)$(TargetName).map"\r
+                               MapExports="true"\r
+                               SubSystem="2"\r
+                               ImportLibrary="$(TargetDir)$(TargetName).lib"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                               SuppressStartupBanner="true"\r
+                               OutputFile="$(TargetDir)$(TargetName).bsc"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory=".\ReleaseDLL"\r
+                       IntermediateDirectory=".\ReleaseDLL"\r
+                       ConfigurationType="2"\r
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="2"\r
+                               InlineFunctionExpansion="1"\r
+                               FavorSizeOrSpeed="2"\r
+                               OmitFramePointers="true"\r
+                               AdditionalIncludeDirectories="..\..,..\..\gsm\inc,..\..\portaudio\include,..\..\portaudio\src\common,..\..\portaudio\pablio,..\..\portmixer\px_common,..\..\libspeex\include,..\..\libiax2\src,..\..\wince"\r
+                               PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_WINDLL;_USRDLL;BUILDING_DLL;PA_NO_DS;PA_NO_ASIO;SPEEX_PREPROCESS=1;NEWJB;LIBIAX;SPEEX_EC=1;_CRT_SECURE_NO_DEPRECATE;inline=__inline;strncasecmp=_strnicmp;vsnprintf=_vsnprintf"\r
+                               StringPooling="true"\r
+                               RuntimeLibrary="2"\r
+                               RuntimeTypeInfo="false"\r
+                               PrecompiledHeaderFile=""\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(IntDir)\vc80.pdb"\r
+                               BrowseInformation="0"\r
+                               BrowseInformationFile="$(TargetDir)$(TargetName).bsc"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                               DebugInformationFormat="3"\r
+                               CallingConvention="2"\r
+                               CompileAs="1"\r
+                               DisableSpecificWarnings="4244;4100;4201;4305;4189;4127;4131"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="1033"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="wsock32.lib winmm.lib Kernel32.lib dsound.lib"\r
+                               OutputFile="$(OutDir)\iaxclient.dll"\r
+                               LinkIncremental="1"\r
+                               ManifestFile="$(IntDir)\$(TargetFileName).intermediate.manifest"\r
+                               ModuleDefinitionFile="..\iaxclient_dll.def"\r
+                               GenerateDebugInformation="true"\r
+                               ProgramDatabaseFile="$(TargetDir)$(TargetName).pdb"\r
+                               GenerateMapFile="true"\r
+                               MapFileName="$(TargetDir)$(TargetName).map"\r
+                               MapExports="true"\r
+                               SubSystem="2"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               ImportLibrary="$(TargetDir)$(TargetName).lib"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                               SuppressStartupBanner="true"\r
+                               OutputFile="$(TargetDir)$(TargetName).bsc"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebDeploymentTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+       </Configurations>\r
+       <References>\r
+       </References>\r
+       <Files>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">\r
+                       <File\r
+                               RelativePath="..\..\audio_encode.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\audio_file.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\audio_portaudio.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_alaw.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_gsm.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_speex.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_ulaw.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\iax.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\iax2-parser.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\iaxclient_dll.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\iaxclient_dll.def">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\iaxclient_lib.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\jitterbuf.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\md5.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\winfuncs.c">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl">\r
+                       <File\r
+                               RelativePath="..\..\audio_encode.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\audio_file.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\audio_portaudio.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_alaw.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_gsm.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_speex.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_ulaw.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\iax.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\iax2-parser.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\iax2.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\iaxclient.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\iaxclient_lib.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\jitterbuf.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\md5.h">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="DSP"\r
+                       Filter="c;h">\r
+                       <File\r
+                               RelativePath="..\..\sox\compand.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\spandsp\plc.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\spandsp\plc.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\sox\resample.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\sox\soxcompat.c">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="GSM"\r
+                       Filter="c;h">\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\add.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\code.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\inc\config.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\debug.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\decode.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\inc\gsm.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_create.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_decode.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_destroy.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_encode.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_explode.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_implode.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_option.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_print.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\k6opt.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\long_term.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\lpc.c">\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32">\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               ObjectFile="$(IntDir)\gsm\"\r
+                                               XMLDocumentationFileName="$(IntDir)\gsm\"/>\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32">\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               ObjectFile="$(IntDir)\gsm\"\r
+                                               XMLDocumentationFileName="$(IntDir)\gsm\"/>\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\preprocess.c">\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32">\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               ObjectFile="$(IntDir)\gsm\"\r
+                                               XMLDocumentationFileName="$(IntDir)\gsm\"/>\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32">\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               ObjectFile="$(IntDir)\gsm\"\r
+                                               XMLDocumentationFileName="$(IntDir)\gsm\"/>\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\inc\private.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\inc\proto.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\rpe.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\short_term.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\inc\unproto.h">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="PortAudio"\r
+                       Filter="c;h">\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_allocation.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_allocation.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_converters.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_converters.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_cpuload.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_cpuload.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_dither.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_dither.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_endianness.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_front.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_hostapi.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_process.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_process.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_skeleton.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_stream.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_stream.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_trace.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_trace.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_types.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_util.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\hostapi\dsound\pa_win_ds_dynlink.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\hostapi\dsound\pa_win_ds_dynlink.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\os\win\pa_win_hostapis.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\os\win\pa_win_util.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\hostapi\wmme\pa_win_wmme.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\os\win\pa_x86_plain_converters.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\os\win\pa_x86_plain_converters.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\pablio\ringbuffer.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\pablio\ringbuffer.h">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="PortMixer"\r
+                       Filter="cpp;h">\r
+                       <File\r
+                               RelativePath="..\..\portmixer\px_win_wmme\px_win_wmme.c">\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32">\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               CompileAs="2"/>\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32">\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               CompileAs="2"/>\r
+                               </FileConfiguration>\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Speex"\r
+                       Filter="c;h">\r
+                       <File\r
+                               RelativePath="..\..\libspeex\arch.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\bits.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\cb_search.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\cb_search.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\cb_search_sse.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\exc_10_16_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\exc_10_32_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\exc_20_32_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\exc_5_256_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\exc_5_64_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\exc_8_128_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\filters.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\filters.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\filters_sse.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\fixed_debug.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\fixed_generic.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\gain_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\gain_table_lbr.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\hexc_10_32_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\hexc_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\high_lsp_tables.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\jitter.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\lbr_48k_tables.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\lpc.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\lpc.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\lsp.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\lsp.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\lsp_tables_nb.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\ltp.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\ltp.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\ltp_sse.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\math_approx.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\math_approx.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\mdf.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\medfilter.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\medfilter.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\misc.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\misc.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\modes.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\modes.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\nb_celp.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\nb_celp.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\preprocess.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\quant_lsp.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\quant_lsp.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\sb_celp.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\sb_celp.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\smallft.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\smallft.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\sox\sox.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\speex.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\speex_callbacks.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\speex_header.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\stack_alloc.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\stereo.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\vbr.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\vbr.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\vq.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\vq.h">\r
+                       </File>\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/utils/iaxclient/lib/win/vs2005/iaxclient_lib.sln b/utils/iaxclient/lib/win/vs2005/iaxclient_lib.sln
new file mode 100644 (file)
index 0000000..1d271e1
--- /dev/null
@@ -0,0 +1,26 @@
+\r
+Microsoft Visual Studio Solution File, Format Version 9.00\r
+# Visual Studio 2005\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iaxclient_lib", "iaxclient_lib.vcproj", "{4AF56BD0-9FB7-435B-99F2-8582FEAC8137}"\r
+EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iaxclient_dll", "iaxclient_dll.vcproj", "{334F0D70-5086-4180-8325-2B77FA845C13}"\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+               Debug|Win32 = Debug|Win32\r
+               Release|Win32 = Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+               {4AF56BD0-9FB7-435B-99F2-8582FEAC8137}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {4AF56BD0-9FB7-435B-99F2-8582FEAC8137}.Debug|Win32.Build.0 = Debug|Win32\r
+               {4AF56BD0-9FB7-435B-99F2-8582FEAC8137}.Release|Win32.ActiveCfg = Release|Win32\r
+               {4AF56BD0-9FB7-435B-99F2-8582FEAC8137}.Release|Win32.Build.0 = Release|Win32\r
+               {334F0D70-5086-4180-8325-2B77FA845C13}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {334F0D70-5086-4180-8325-2B77FA845C13}.Debug|Win32.Build.0 = Debug|Win32\r
+               {334F0D70-5086-4180-8325-2B77FA845C13}.Release|Win32.ActiveCfg = Release|Win32\r
+               {334F0D70-5086-4180-8325-2B77FA845C13}.Release|Win32.Build.0 = Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(SolutionProperties) = preSolution\r
+               HideSolutionNode = FALSE\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/utils/iaxclient/lib/win/vs2005/iaxclient_lib.vcproj b/utils/iaxclient/lib/win/vs2005/iaxclient_lib.vcproj
new file mode 100644 (file)
index 0000000..579cdb8
--- /dev/null
@@ -0,0 +1,701 @@
+<?xml version="1.0" encoding="Windows-1252"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="8.00"\r
+       Name="iaxclient_lib"\r
+       ProjectGUID="{4AF56BD0-9FB7-435B-99F2-8582FEAC8137}"\r
+       RootNamespace="iaxclient_lib"\r
+       >\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"\r
+               />\r
+       </Platforms>\r
+       <ToolFiles>\r
+       </ToolFiles>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory=".\DebugLIB"\r
+                       IntermediateDirectory=".\DebugLIB"\r
+                       ConfigurationType="4"\r
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
+                               AdditionalIncludeDirectories="..\..,..\..\gsm\inc,..\..\portaudio\include,..\..\portaudio\src\common,..\..\portaudio\pablio,..\..\portmixer\px_common,..\..\libspeex\include,..\..\libiax2\src,..\..\wince"\r
+                               PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_LIB;PA_NO_DS;PA_NO_ASIO;SPEEX_PREPROCESS=1;NEWJB;LIBIAX;SPEEX_EC=1;_CRT_SECURE_NO_DEPRECATE;inline=__inline;strncasecmp=_strnicmp;vsnprintf=_vsnprintf"\r
+                               MinimalRebuild="false"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="3"\r
+                               BufferSecurityCheck="true"\r
+                               RuntimeTypeInfo="false"\r
+                               PrecompiledHeaderFile=""\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(IntDir)\vc80.pdb"\r
+                               BrowseInformation="0"\r
+                               BrowseInformationFile="$(TargetDir)$(TargetName).bsc"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                               Detect64BitPortabilityProblems="true"\r
+                               DebugInformationFormat="3"\r
+                               CallingConvention="2"\r
+                               CompileAs="1"\r
+                               DisableSpecificWarnings="4244;4100;4201;4305;4189;4127;4131"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
+                               Culture="1033"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLibrarianTool"\r
+                               OutputFile="$(IntDir)\iaxclient1.lib"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                               SuppressStartupBanner="true"\r
+                               OutputFile="$(IntDir)/iaxclient.bsc"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory=".\ReleaseLIB"\r
+                       IntermediateDirectory=".\ReleaseLIB"\r
+                       ConfigurationType="4"\r
+                       InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"\r
+                       UseOfMFC="0"\r
+                       ATLMinimizesCRunTimeLibraryUsage="false"\r
+                       CharacterSet="2"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               Optimization="2"\r
+                               InlineFunctionExpansion="1"\r
+                               FavorSizeOrSpeed="2"\r
+                               OmitFramePointers="true"\r
+                               AdditionalIncludeDirectories="..\..,..\..\gsm\inc,..\..\portaudio\include,..\..\portaudio\src\common,..\..\portaudio\pablio,..\..\portmixer\px_common,..\..\libspeex\include,..\..\libiax2\src,..\..\wince"\r
+                               PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_LIB;PA_NO_DS;PA_NO_ASIO;SPEEX_PREPROCESS=1;NEWJB;LIBIAX;SPEEX_EC=1;_CRT_SECURE_NO_DEPRECATE;inline=__inline;strncasecmp=_strnicmp;vsnprintf=_vsnprintf"\r
+                               StringPooling="true"\r
+                               RuntimeLibrary="2"\r
+                               RuntimeTypeInfo="false"\r
+                               PrecompiledHeaderFile=""\r
+                               AssemblerListingLocation="$(IntDir)\"\r
+                               ObjectFile="$(IntDir)\"\r
+                               ProgramDataBaseFileName="$(IntDir)\vc80.pdb"\r
+                               BrowseInformation="0"\r
+                               BrowseInformationFile="$(TargetDir)$(TargetName).bsc"\r
+                               WarningLevel="3"\r
+                               SuppressStartupBanner="true"\r
+                               DebugInformationFormat="3"\r
+                               CallingConvention="2"\r
+                               CompileAs="1"\r
+                               DisableSpecificWarnings="4244;4100;4201;4305;4189;4127;4131"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="NDEBUG"\r
+                               Culture="1033"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLibrarianTool"\r
+                               OutputFile="$(IntDir)\iaxclient1.lib"\r
+                               SuppressStartupBanner="true"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                               SuppressStartupBanner="true"\r
+                               OutputFile="$(IntDir)/iaxclient.bsc"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+       </Configurations>\r
+       <References>\r
+       </References>\r
+       <Files>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">\r
+                       <File\r
+                               RelativePath="..\..\audio_encode.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\audio_file.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\audio_portaudio.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_alaw.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_gsm.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_speex.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_ulaw.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\iax.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\iax2-parser.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\iaxclient_dll.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\iaxclient_dll.def">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\iaxclient_lib.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\jitterbuf.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\md5.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\winfuncs.c">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl">\r
+                       <File\r
+                               RelativePath="..\..\audio_encode.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\audio_file.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\audio_portaudio.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_alaw.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_gsm.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_speex.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\codec_ulaw.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\iax.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\iax2-parser.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\iax2.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\iaxclient.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\iaxclient_lib.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\jitterbuf.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libiax2\src\md5.h">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="DSP"\r
+                       Filter="c;h">\r
+                       <File\r
+                               RelativePath="..\..\sox\compand.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\spandsp\plc.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\spandsp\plc.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\sox\resample.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\sox\soxcompat.c">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="GSM"\r
+                       Filter="c;h">\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\add.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\code.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\inc\config.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\debug.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\decode.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\inc\gsm.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_create.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_decode.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_destroy.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_encode.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_explode.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_implode.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_option.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\gsm_print.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\k6opt.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\long_term.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\lpc.c">\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32">\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               ObjectFile="$(IntDir)\gsm\"\r
+                                               XMLDocumentationFileName="$(IntDir)\gsm\"/>\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32">\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               ObjectFile="$(IntDir)\gsm\"\r
+                                               XMLDocumentationFileName="$(IntDir)\gsm\"/>\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\preprocess.c">\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32">\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               ObjectFile="$(IntDir)\gsm\"\r
+                                               XMLDocumentationFileName="$(IntDir)\gsm\"/>\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32">\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               ObjectFile="$(IntDir)\gsm\"\r
+                                               XMLDocumentationFileName="$(IntDir)\gsm\"/>\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\inc\private.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\inc\proto.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\rpe.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\short_term.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\src\table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\gsm\inc\unproto.h">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="PortAudio"\r
+                       Filter="c;h">\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_allocation.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_allocation.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_converters.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_converters.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_cpuload.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_cpuload.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_dither.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_dither.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_endianness.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_front.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_hostapi.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_process.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_process.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_skeleton.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_stream.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_stream.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_trace.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_trace.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_types.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\common\pa_util.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\hostapi\dsound\pa_win_ds_dynlink.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\hostapi\dsound\pa_win_ds_dynlink.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\os\win\pa_win_hostapis.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\os\win\pa_win_util.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\hostapi\wmme\pa_win_wmme.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\os\win\pa_x86_plain_converters.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\src\os\win\pa_x86_plain_converters.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\pablio\ringbuffer.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\portaudio\pablio\ringbuffer.h">\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="PortMixer"\r
+                       Filter="cpp;h">\r
+                       <File\r
+                               RelativePath="..\..\portmixer\px_win_wmme\px_win_wmme.c">\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32">\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               CompileAs="2"/>\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32">\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               CompileAs="2"/>\r
+                               </FileConfiguration>\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Speex"\r
+                       Filter="c;h">\r
+                       <File\r
+                               RelativePath="..\..\libspeex\arch.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\bits.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\cb_search.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\cb_search.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\cb_search_sse.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\exc_10_16_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\exc_10_32_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\exc_20_32_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\exc_5_256_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\exc_5_64_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\exc_8_128_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\filters.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\filters.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\filters_sse.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\fixed_debug.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\fixed_generic.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\gain_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\gain_table_lbr.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\hexc_10_32_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\hexc_table.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\high_lsp_tables.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\jitter.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\lbr_48k_tables.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\lpc.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\lpc.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\lsp.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\lsp.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\lsp_tables_nb.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\ltp.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\ltp.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\ltp_sse.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\math_approx.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\math_approx.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\mdf.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\medfilter.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\medfilter.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\misc.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\misc.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\modes.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\modes.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\nb_celp.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\nb_celp.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\preprocess.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\quant_lsp.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\quant_lsp.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\sb_celp.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\sb_celp.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\smallft.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\smallft.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\sox\sox.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\speex.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\speex_callbacks.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\speex_header.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\stack_alloc.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\stereo.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\vbr.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\vbr.h">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\vq.c">\r
+                       </File>\r
+                       <File\r
+                               RelativePath="..\..\libspeex\vq.h">\r
+                       </File>\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/utils/iaxclient/lib/wince/inttypes.h b/utils/iaxclient/lib/wince/inttypes.h
new file mode 100644 (file)
index 0000000..1aea1c0
--- /dev/null
@@ -0,0 +1,208 @@
+/* A basic inttypes.h, for platforms which lack their own. Take care that it
+   suits the integer lengths of the tools with which it is used. */
+
+#ifndef _INTTYPES_H
+#define _INTTYPES_H
+
+/*
+ *    ISO C99: 7.18 Integer types <stdint.h/inttypes.h>
+ */
+#ifndef __int8_t_defined
+#define __int8_t_defined
+typedef signed char                                 int8_t;
+typedef short int                                   int16_t;
+typedef long int                                    int32_t;
+#if defined(__GNUC__)  
+__extension__ typedef long long int                 int64_t;
+#endif
+
+typedef unsigned char                               uint8_t;
+typedef unsigned short int                          uint16_t;
+typedef unsigned long int                           uint32_t;
+#if defined(__GNUC__)  
+__extension__ typedef unsigned long long int        uint64_t;
+#endif
+#endif
+
+/* Small types.  */
+
+/* Signed.  */
+typedef signed char                                 int_least8_t;
+typedef short int                                   int_least16_t;
+typedef long int                                    int_least32_t;
+#if defined(__GNUC__)  
+__extension__ typedef long long int                 int_least64_t;
+#endif
+
+/* Unsigned.  */
+typedef unsigned char                               uint_least8_t;
+typedef unsigned short int                          uint_least16_t;
+typedef unsigned long int                           uint_least32_t;
+#if defined(__GNUC__)  
+__extension__ typedef unsigned long long int        uint_least64_t;
+#endif
+
+
+/* Fast types.  */
+
+/* Signed.  */
+typedef signed char                                 int_fast8_t;
+typedef short int                                   int_fast16_t;
+typedef long int                                    int_fast32_t;
+#if defined(__GNUC__)  
+__extension__ typedef long long int                 int_fast64_t;
+#endif
+
+/* Unsigned.  */
+typedef unsigned char                               uint_fast8_t;
+typedef unsigned int                                uint_fast16_t;
+typedef unsigned long int                           uint_fast32_t;
+#if defined(__GNUC__)  
+__extension__ typedef unsigned long long int        uint_fast64_t;
+#endif
+
+
+/* Types for `void *' pointers.  */
+#ifndef __intptr_t_defined
+#define __intptr_t_defined
+typedef int                                         intptr_t;
+typedef unsigned int                                uintptr_t;
+#endif
+
+
+/* Largest integral types.  */
+#if defined(__GNUC__)  
+__extension__ typedef long long int                 intmax_t;
+__extension__ typedef unsigned long long int        uintmax_t;
+#endif
+
+
+/* The ISO C99 standard specifies that in C++ implementations these
+   macros should only be defined if explicitly requested.  */
+#if !defined __cplusplus || defined __STDC_LIMIT_MACROS
+
+#define __INT64_C(c)        c ## LL
+#define __UINT64_C(c)       c ## ULL
+
+/* Limits of integral types.  */
+
+/* Minimum of signed integral types.  */
+#define INT8_MIN            (-128)
+#define INT16_MIN           (-32767-1)
+#define INT32_MIN           (-2147483647-1)
+#define INT64_MIN           (-__INT64_C(9223372036854775807)-1)
+/* Maximum of signed integral types.  */
+#define INT8_MAX            (127)
+#define INT16_MAX           (32767)
+#define INT32_MAX           (2147483647)
+#define INT64_MAX           (__INT64_C(9223372036854775807))
+
+/* Maximum of unsigned integral types.  */
+#define UINT8_MAX           (255)
+#define UINT16_MAX          (65535)
+#define UINT32_MAX          (4294967295U)
+#define UINT64_MAX          (__UINT64_C(18446744073709551615))
+
+
+/* Minimum of signed integral types having a minimum size.  */
+#define INT_LEAST8_MIN      (-128)
+#define INT_LEAST16_MIN     (-32767-1)
+#define INT_LEAST32_MIN     (-2147483647-1)
+#define INT_LEAST64_MIN     (-__INT64_C(9223372036854775807)-1)
+/* Maximum of signed integral types having a minimum size.  */
+#define INT_LEAST8_MAX      (127)
+#define INT_LEAST16_MAX     (32767)
+#define INT_LEAST32_MAX     (2147483647)
+#define INT_LEAST64_MAX     (__INT64_C(9223372036854775807))
+
+/* Maximum of unsigned integral types having a minimum size.  */
+#define UINT_LEAST8_MAX     (255)
+#define UINT_LEAST16_MAX    (65535)
+#define UINT_LEAST32_MAX    (4294967295U)
+#define UINT_LEAST64_MAX    (__UINT64_C(18446744073709551615))
+
+
+/* Minimum of fast signed integral types having a minimum size.  */
+#define INT_FAST8_MIN       (-128)
+#define INT_FAST16_MIN      (-32768)
+#define INT_FAST32_MIN      (-2147483647-1)
+#define INT_FAST64_MIN      (-__INT64_C(9223372036854775807)-1)
+/* Maximum of fast signed integral types having a minimum size.  */
+#define INT_FAST8_MAX       (127)
+#define INT_FAST16_MAX      (32767)
+#define INT_FAST32_MAX      (2147483647)
+#define INT_FAST64_MAX      (__INT64_C(9223372036854775807))
+
+/* Maximum of fast unsigned integral types having a minimum size.  */
+#define UINT_FAST8_MAX      (255U)
+#define UINT_FAST16_MAX     (65535U)
+#define UINT_FAST32_MAX     (4294967295UL)
+#define UINT_FAST64_MAX     (__UINT64_C(18446744073709551615))
+
+
+/* Values to test for integral types holding `void *' pointer.  */
+#define INTPTR_MIN          (-32768)
+#define INTPTR_MAX          (32767)
+#define UINTPTR_MAX         (65535U)
+
+
+/* Minimum for largest signed integral type.  */
+#define INTMAX_MIN          (-__INT64_C(9223372036854775807)-1)
+/* Maximum for largest signed integral type.  */
+#define INTMAX_MAX          (__INT64_C(9223372036854775807))
+
+/* Maximum for largest unsigned integral type.  */
+#define UINTMAX_MAX         (__UINT64_C(18446744073709551615))
+
+
+/* Limits of other integer types.  */
+
+/* Limits of `ptrdiff_t' type.  */
+#define PTRDIFF_MIN         (-32768)
+#define PTRDIFF_MAX         (32767)
+
+/* Limits of `sig_atomic_t'.  */
+#define SIG_ATOMIC_MIN      (-32768)
+#define SIG_ATOMIC_MAX      (32767)
+
+/* Limit of `size_t' type.  */
+#ifndef SIZE_MAX
+#define SIZE_MAX            (65535U)
+#endif
+
+/* Limits of `wchar_t'.  */
+#ifndef WCHAR_MIN
+/* These constants might also be defined in <wchar.h>.  */
+#define WCHAR_MIN           __WCHAR_MIN
+#define WCHAR_MAX           __WCHAR_MAX
+#endif
+
+/* Limits of `wint_t'.  */
+#define WINT_MIN            (0U)
+#define WINT_MAX            (65535U)
+
+#endif    /* C++ && limit macros */
+
+
+/* The ISO C99 standard specifies that in C++ implementations these
+   should only be defined if explicitly requested.  */
+#if !defined __cplusplus || defined __STDC_CONSTANT_MACROS
+
+/* Signed.  */
+#define INT8_C(c)           c
+#define INT16_C(c)          c
+#define INT32_C(c)          c
+#define INT64_C(c)          c ## LL
+
+/* Unsigned.  */
+#define UINT8_C(c)          c ## U
+#define UINT16_C(c)         c ## U
+#define UINT32_C(c)         c ## U
+#define UINT64_C(c)         c ## ULL
+
+/* Maximal type.  */
+#define INTMAX_C(c)         c ## LL
+#define UINTMAX_C(c)        c ## ULL
+
+#endif    /* C++ && constant macros */
+#endif
diff --git a/utils/iaxclient/lib/winfuncs.c b/utils/iaxclient/lib/winfuncs.c
new file mode 100644 (file)
index 0000000..af15af7
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * iaxclient: a cross-platform IAX softphone library
+ *
+ * Copyrights:
+ * Copyright (C) 2003-2006, Horizon Wimba, Inc.
+ * Copyright (C) 2007, Wimba, Inc.
+ *
+ * Contributors:
+ * Steve Kann <stevek@stevek.com>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU Lesser (Library) General Public License.
+ */
+
+#include "winpoop.h"    // include winsock2.h, windows.h, stdio.h, io.h
+#include "iaxclient_lib.h"
+
+void os_init(void)
+{
+       WSADATA wsd;
+
+       if(WSAStartup(0x0101,&wsd))
+       {   // Error message?
+           exit(1);
+       }
+}
+
+/* yes, it could have just been a #define, but that makes linking trickier */
+EXPORT void iaxc_millisleep(long ms)
+{
+       Sleep(ms);
+}
+
+int iaxci_post_event_callback(iaxc_event ev) {
+       iaxc_event *e;
+       e = (iaxc_event *)malloc(sizeof(ev));
+       *e = ev;
+
+       if (!PostMessage((HWND)post_event_handle,post_event_id,(WPARAM) NULL, (LPARAM) e))
+               free(e);
+       return 0;
+}
+
+/* Increasing the Thread Priority.  See
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/scheduling_priorities.asp
+ * for discussion on Win32 scheduling priorities.
+ */
+
+int iaxci_prioboostbegin() {
+    if ( !SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL)  ) {
+        fprintf(stderr, "SetThreadPriority failed: %ld.\n", GetLastError());
+    }
+    return 0;
+}
+
+int iaxci_prioboostend() {
+    /* TODO */
+    return 0;
+}
+