summaryrefslogtreecommitdiffstats
path: root/flow
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-05 00:01:18 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-05 00:01:18 +0000
commit42995d7bf396933ee60c5f89c354ea89cf13df0d (patch)
treecfdcea0ac57420e7baf570bfe435e107bb842541 /flow
downloadarts-42995d7bf396933ee60c5f89c354ea89cf13df0d.tar.gz
arts-42995d7bf396933ee60c5f89c354ea89cf13df0d.zip
Copy of aRts for Trinity modifications
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/dependencies/arts@1070145 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'flow')
-rw-r--r--flow/Makefile.am49
-rw-r--r--flow/artsflow.idl566
-rw-r--r--flow/asyncschedule.cc553
-rw-r--r--flow/asyncschedule.h134
-rw-r--r--flow/audioio.cc165
-rw-r--r--flow/audioio.h145
-rw-r--r--flow/audioioaix.cc390
-rw-r--r--flow/audioioalsa.cc561
-rw-r--r--flow/audioioalsa9.cc590
-rw-r--r--flow/audioiocsl.cc640
-rw-r--r--flow/audioioesd.cc231
-rw-r--r--flow/audioiojack.cc346
-rw-r--r--flow/audioiolibaudioio.cc236
-rw-r--r--flow/audioiomas.cc619
-rw-r--r--flow/audioionas.cc260
-rw-r--r--flow/audioionull.cc184
-rw-r--r--flow/audioiooss.cc485
-rw-r--r--flow/audioioossthreaded.cc681
-rw-r--r--flow/audioiosgi.cc274
-rw-r--r--flow/audioiosun.cc442
-rw-r--r--flow/audiomanager_impl.cc325
-rw-r--r--flow/audiosubsys.cc645
-rw-r--r--flow/audiosubsys.h236
-rw-r--r--flow/audiotobytestream_impl.cc223
-rw-r--r--flow/bufferqueue.h148
-rw-r--r--flow/bus.cc367
-rw-r--r--flow/bus.h76
-rw-r--r--flow/bytestreamtoaudio_impl.cc119
-rw-r--r--flow/cache.cc274
-rw-r--r--flow/cache.h92
-rw-r--r--flow/cachedwav.h81
-rw-r--r--flow/convert.cc418
-rw-r--r--flow/convert.h164
-rw-r--r--flow/cpuinfo.cc232
-rw-r--r--flow/cpuinfo.h72
-rw-r--r--flow/datahandle_impl.cc499
-rw-r--r--flow/fft.c32
-rw-r--r--flow/fft.h32
-rw-r--r--flow/gsl/Makefile.am24
-rw-r--r--flow/gsl/arts-patches73
-rw-r--r--flow/gsl/configure.in.in224
-rw-r--r--flow/gsl/dummy.cc3
-rw-r--r--flow/gsl/gbsearcharray.h292
-rwxr-xr-xflow/gsl/gsl-fftconf.sh468
-rwxr-xr-xflow/gsl/gsl-fftgen.pl810
-rw-r--r--flow/gsl/gsl-iplan.txt57
-rw-r--r--flow/gsl/gsl-mplan.txt226
-rw-r--r--flow/gsl/gsl.3822
-rw-r--r--flow/gsl/gsl.gnuplot5
-rw-r--r--flow/gsl/gslarrows30
-rw-r--r--flow/gsl/gslartsthreads.cc205
-rw-r--r--flow/gsl/gslartsthreads.h102
-rw-r--r--flow/gsl/gslcommon.c1651
-rw-r--r--flow/gsl/gslcommon.h293
-rw-r--r--flow/gsl/gslconfig.h.in11
-rw-r--r--flow/gsl/gslconvert.c57
-rw-r--r--flow/gsl/gslconvert.h43
-rw-r--r--flow/gsl/gsldatacache.c633
-rw-r--r--flow/gsl/gsldatacache.h87
-rw-r--r--flow/gsl/gsldatahandle-lbuffer.c11
-rw-r--r--flow/gsl/gsldatahandle-mad.c711
-rw-r--r--flow/gsl/gsldatahandle-mad.h42
-rw-r--r--flow/gsl/gsldatahandle-vorbis.c376
-rw-r--r--flow/gsl/gsldatahandle-vorbis.h41
-rw-r--r--flow/gsl/gsldatahandle.c1241
-rw-r--r--flow/gsl/gsldatahandle.h143
-rw-r--r--flow/gsl/gsldatautils.c462
-rw-r--r--flow/gsl/gsldatautils.h909
-rw-r--r--flow/gsl/gsldefs.h136
-rw-r--r--flow/gsl/gslengine.c753
-rw-r--r--flow/gsl/gslengine.h206
-rw-r--r--flow/gsl/gslfft.c9052
-rw-r--r--flow/gsl/gslfft.h126
-rw-r--r--flow/gsl/gslffttest.c435
-rw-r--r--flow/gsl/gslfilehash.c464
-rw-r--r--flow/gsl/gslfilehash.h77
-rw-r--r--flow/gsl/gslfilter.c1379
-rw-r--r--flow/gsl/gslfilter.h281
-rw-r--r--flow/gsl/gslglib.c2400
-rw-r--r--flow/gsl/gslglib.h858
-rw-r--r--flow/gsl/gslglibhash.cc151
-rw-r--r--flow/gsl/gslglibhashtest.cc123
-rw-r--r--flow/gsl/gslieee754.h246
-rw-r--r--flow/gsl/gslincluder.c13420
-rw-r--r--flow/gsl/gslloader-gslwave.c701
-rw-r--r--flow/gsl/gslloader-mad.c210
-rw-r--r--flow/gsl/gslloader-oggvorbis.c178
-rw-r--r--flow/gsl/gslloader-wav.c442
-rw-r--r--flow/gsl/gslloader.c335
-rw-r--r--flow/gsl/gslloader.h136
-rw-r--r--flow/gsl/gslmagic.c711
-rw-r--r--flow/gsl/gslmagic.h72
-rw-r--r--flow/gsl/gslmakefile.inc87
-rw-r--r--flow/gsl/gslmath.c1085
-rw-r--r--flow/gsl/gslmath.h518
-rw-r--r--flow/gsl/gslmathtest.c334
-rw-r--r--flow/gsl/gslopmaster.c783
-rw-r--r--flow/gsl/gslopmaster.h42
-rw-r--r--flow/gsl/gslopnode.h247
-rw-r--r--flow/gsl/gslopschedule.c582
-rw-r--r--flow/gsl/gslopschedule.h79
-rw-r--r--flow/gsl/gsloputil.c721
-rw-r--r--flow/gsl/gsloputil.h86
-rw-r--r--flow/gsl/gsloscillator-aux.c214
-rw-r--r--flow/gsl/gsloscillator.c219
-rw-r--r--flow/gsl/gsloscillator.h84
-rw-r--r--flow/gsl/gslosctable.c626
-rw-r--r--flow/gsl/gslosctable.h104
-rw-r--r--flow/gsl/gslsignal.c258
-rw-r--r--flow/gsl/gslsignal.h343
-rw-r--r--flow/gsl/gsltests.c650
-rw-r--r--flow/gsl/gslwave.headerbin0 -> 3342 bytes
-rw-r--r--flow/gsl/gslwavechunk.c812
-rw-r--r--flow/gsl/gslwavechunk.h129
-rw-r--r--flow/gsl/gslwaveloader.c2
-rw-r--r--flow/gsl/gslwaveloader.h6
-rw-r--r--flow/gsl/gslwaveosc-aux.c249
-rw-r--r--flow/gsl/gslwaveosc.c376
-rw-r--r--flow/gsl/gslwaveosc.h96
-rw-r--r--flow/gsl/gslwchunk.c279
-rw-r--r--flow/gslpp/Makefile.am7
-rw-r--r--flow/gslpp/datahandle.cpp412
-rw-r--r--flow/gslpp/datahandle.h220
-rw-r--r--flow/gslschedule.cc1195
-rw-r--r--flow/gslschedule.h262
-rw-r--r--flow/mcopclass/DataHandlePlay.mcopclass2
-rw-r--r--flow/mcopclass/Makefile.am15
-rw-r--r--flow/mcopclass/Synth_ADD.mcopclass3
-rw-r--r--flow/mcopclass/Synth_AMAN_PLAY.mcopclass3
-rw-r--r--flow/mcopclass/Synth_AMAN_RECORD.mcopclass3
-rw-r--r--flow/mcopclass/Synth_BUS_DOWNLINK.mcopclass3
-rw-r--r--flow/mcopclass/Synth_BUS_UPLINK.mcopclass3
-rw-r--r--flow/mcopclass/Synth_FREQUENCY.mcopclass3
-rw-r--r--flow/mcopclass/Synth_MUL.mcopclass3
-rw-r--r--flow/mcopclass/Synth_MULTI_ADD.mcopclass3
-rw-r--r--flow/mcopclass/Synth_PLAY.mcopclass3
-rw-r--r--flow/mcopclass/Synth_PLAY_WAV.mcopclass3
-rw-r--r--flow/mcopclass/Synth_RECORD.mcopclass3
-rw-r--r--flow/mcopclass/Synth_WAVE_SIN.mcopclass3
-rw-r--r--flow/mcopclass/WaveDataHandle.mcopclass2
-rw-r--r--flow/pipebuffer.cc166
-rw-r--r--flow/pipebuffer.h75
-rw-r--r--flow/resample.cc305
-rw-r--r--flow/resample.h167
-rw-r--r--flow/stdsynthmodule.cc92
-rw-r--r--flow/stdsynthmodule.h65
-rw-r--r--flow/stereoeffectstack_impl.cc179
-rw-r--r--flow/stereofftscope_impl.cc131
-rw-r--r--flow/stereovolumecontrol_impl.cc197
-rw-r--r--flow/synth_add_impl.cc44
-rw-r--r--flow/synth_frequency_impl.cc70
-rw-r--r--flow/synth_mul_impl.cc44
-rw-r--r--flow/synth_multi_add_impl.cc64
-rw-r--r--flow/synth_play_impl.cc285
-rw-r--r--flow/synth_play_wav_impl.cc579
-rw-r--r--flow/synth_record_impl.cc184
-rw-r--r--flow/synth_wave_sin_impl.cc44
-rw-r--r--flow/synthschedule.h36
-rw-r--r--flow/virtualports.cc491
-rw-r--r--flow/virtualports.h87
160 files changed, 68997 insertions, 0 deletions
diff --git a/flow/Makefile.am b/flow/Makefile.am
new file mode 100644
index 0000000..720ca47
--- /dev/null
+++ b/flow/Makefile.am
@@ -0,0 +1,49 @@
+
+SUBDIRS = mcopclass gsl gslpp
+INCLUDES = -I$(top_srcdir)/mcop -I$(top_builddir)/mcop $(all_includes)
+AM_CXXFLAGS = $(MAS_CFLAGS) $(JACK_CFLAGS) -DQT_CLEAN_NAMESPACE
+
+####### Files
+
+lib_LTLIBRARIES = libartsflow_idl.la libartsflow.la
+
+libartsflow_idl_la_SOURCES = artsflow.cc
+libartsflow_idl_la_LDFLAGS = -no-undefined -version-info 1:0 $(all_libraries)
+libartsflow_idl_la_LIBADD = $(top_builddir)/mcop/libmcop.la $(LIBPOSIX4)
+
+libartsflow_la_LIBADD = $(top_builddir)/mcop/libmcop.la libartsflow_idl.la $(top_builddir)/flow/gslpp/libgslpp.la $(LIBAUDIOFILE) $(LIBASOUND) $(LIBAUDIOIO) $(LIBOSSAUDIO) $(LIBAUDIONAS) $(LIBCSL) $(SGILIBAUDIO) $(LIBESD) $(LIBMAS) $(JACK_LIBADD) -lm \
+ $(top_builddir)/flow/gsl/libgsl.la
+libartsflow_la_LDFLAGS = $(MAS_LDFLAGS) $(JACK_LDFLAGS) $(LIBAUDIOFILE_LDFLAGS) $(LIBAUDIONAS_LDFLAGS) $(LIBESD_LDFLAGS) -no-undefined -version-info 1:0
+libartsflow_la_COMPILE_FIRST = artsflow.h
+libartsflow_la_SOURCES = synth_play_impl.cc \
+ gslschedule.cc audiosubsys.cc \
+ pipebuffer.cc convert.cc synth_wave_sin_impl.cc synth_frequency_impl.cc \
+ synth_multi_add_impl.cc synth_add_impl.cc synth_mul_impl.cc \
+ synth_play_wav_impl.cc stdsynthmodule.cc cache.cc asyncschedule.cc \
+ bytestreamtoaudio_impl.cc stereovolumecontrol_impl.cc \
+ stereoeffectstack_impl.cc fft.c stereofftscope_impl.cc virtualports.cc \
+ bus.cc audiomanager_impl.cc synth_record_impl.cc resample.cc \
+ audioio.cc audioiooss.cc audioioalsa.cc audioioalsa9.cc \
+ audioionull.cc audioiolibaudioio.cc audioioesd.cc audioiojack.cc \
+ audioiosun.cc audioioaix.cc audioionas.cc cpuinfo.cc \
+ audioioossthreaded.cc audiotobytestream_impl.cc audioiosgi.cc \
+ audioiocsl.cc audioiomas.cc datahandle_impl.cc
+
+artsincludedir = $(includedir)/arts
+artsinclude_HEADERS = artsflow.h audiosubsys.h cache.h \
+ cachedwav.h convert.h pipebuffer.h stdsynthmodule.h \
+ synthschedule.h fft.h artsflow.idl audioio.h resample.h \
+ cpuinfo.h bufferqueue.h gslschedule.h
+
+DISTCLEANFILES = artsflow.cc artsflow.h artsflow.mcoptype artsflow.mcopclass
+
+artsflow.cc artsflow.h: $(top_srcdir)/flow/artsflow.idl $(MCOPIDL)
+ $(MCOPIDL) -t $(top_srcdir)/flow/artsflow.idl
+
+artsflow.mcoptype: artsflow.h
+artsflow.mcopclass: artsflow.h
+
+######## install idl typeinfo files
+
+mcoptypedir = $(libdir)/mcop
+mcoptype_DATA = artsflow.mcoptype artsflow.mcopclass
diff --git a/flow/artsflow.idl b/flow/artsflow.idl
new file mode 100644
index 0000000..44424e0
--- /dev/null
+++ b/flow/artsflow.idl
@@ -0,0 +1,566 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+/*
+ * arts.idl - MCOP port. What's missing currently in MCOP?
+ *
+ * - namespaces (module)
+ */
+
+module Arts { // analog real time synthesizer
+
+enum AutoSuspendState { asNoSuspend, asSuspend, asSuspendStop, asSuspendMask = 0x3,
+ asProducer = 0x10, asConsumer = 0x20, asDirectionMask = 0x30 };
+
+/**
+ * The SynthModule interface is the base for all modules containing streams.
+ *
+ * There are two goals achieved by this interface. On one side, there is
+ * functionality which users of stream carrying modules want to use (which
+ * is: start streaming, stop streaming).
+ *
+ * On the other hand, there is functionality which the flow system will use
+ * to achieve these goals.
+ */
+interface SynthModule {
+ // interface for users of this module
+
+ /**
+ * This function starts the streaming (e.g. the module will start
+ * producing samples) - if you write a module, do not reimplement this,
+ * instead reimplement streamInit/streamStart
+ */
+ void start();
+
+ /**
+ * This function stops the streaming - if you write a plugin, do not
+ * reimplement this, instead reimplement streamEnd
+ */
+ void stop();
+
+ // interface for people implementing modules
+
+ /**
+ * this is supposed to be the initialization every module passes after
+ * all attributes have been set up (e.g. you can see which file to open,
+ * how to initialize your filter coefficients or whatever)
+ */
+ void streamInit();
+
+ /**
+ * starts the I/O of the module
+ */
+ void streamStart();
+
+ /**
+ * stop the thing again, and free data possibly allocated in streamInit
+ */
+ void streamEnd();
+
+ /**
+ * If you run a mixer desk (without anything connected), no calculations
+ * need to be done - since the output is silent anyway. For this reason,
+ * there exists this autosuspend attribute. It allows the flow system
+ * to detect the idle condition, and start suspending the calculations,
+ * until something "important" happens again.
+ *
+ * There are three possible values:
+ *
+ * @li asNoSuspend - this one is appropriate when you have a module that
+ * is active by itself
+ * @li asSuspend - this one is appropriate for modules that "do nothing"
+ * by themselves
+ * @li asSuspendStop - this one is for modules that should be stopped, when
+ * the system gets suspended, and restarted when the
+ * system will start again - an example for this is
+ * soundcard output
+ *
+ * A module should choose asSuspend (or asSuspendStop) only if the
+ * following conditions are true:
+ *
+ * @li given constant inputs (like 3.0 on all ports), the module will
+ * give constant output after some time
+ * @li given only 0.0 inputs, the module will give only 0.0 outputs
+ * after some time
+ * @li the module does not synchronize itself through signal flow (i.e.
+ * a midi sequence which "knows" when a second has passed through
+ * the signal flow breaks when suspension happens)
+ * @li the module can't be brought to do something with a method
+ * invocation (i.e. a module which starts generating noise for
+ * a second whenever the noise() method is called is not suspendable)
+ * @li the module has no internal state that changes over time when only
+ * constant inputs are given
+ *
+ * Typical examples for suspendable modules are arithmetic operations,
+ * filters, delay/hall/reverb.
+ *
+ * Typical examples for non-suspendable modules are sequences, midi stuff,
+ * oscillators, sample players,...
+ *
+ * To deal with modules which either input data from some external source
+ * (i.e. soundcard input) or output data to some external destination,
+ * (i.e. soundcard output) the following flags are available:
+ *
+ * @li asProducer - set this flag for modules which fulfill the conditions
+ * for a suspendable module, but produce non-zero output
+ * even when left alone
+ * @li asConsumer - set this flag for modules which write the data to
+ * some external destination - that is - definitely
+ * require constant input to be suspended
+ *
+ * The suspension algorithm will first divide the graph of modules into
+ * subgraphs of interconnected modules. A subgraph is suspendable if
+ * all of its modules are suspendable and the subgraph does not contain
+ * producer(s) and consumer(s) at the same time.
+ *
+ * Finally, our module graph is suspendable if all its subgraphs are.
+ */
+ readonly attribute AutoSuspendState autoSuspend;
+};
+
+/**
+ * Plays a stream of audio data to the soundcard
+ */
+interface Synth_PLAY : SynthModule {
+ // attribute string channels;
+ default in audio stream invalue_left,invalue_right;
+};
+
+/**
+ * Records a stream of audio data from the soundcard
+ */
+interface Synth_RECORD : SynthModule {
+ // attribute string channels;
+ default out audio stream left,right;
+};
+
+/**
+ * A frequency generator
+ *
+ * This kind of object is used to create frequencies. Oscillators are connected
+ * at the output of this object
+ */
+interface Synth_FREQUENCY : SynthModule {
+ in audio stream frequency;
+ out audio stream pos;
+};
+
+/**
+ * A sine wave
+ */
+interface Synth_WAVE_SIN : SynthModule {
+ in audio stream pos;
+ out audio stream outvalue;
+};
+
+/**
+ * A module which mixes an arbitary number of audio streams
+ */
+interface Synth_MULTI_ADD : SynthModule {
+ in multi audio stream invalue;
+ out audio stream outvalue;
+};
+
+/**
+ * A module which adds two audio streams
+ */
+interface Synth_ADD : SynthModule {
+ default in audio stream invalue1,invalue2;
+ out audio stream outvalue;
+};
+
+/**
+ * Multiplies two audio streams
+ */
+interface Synth_MUL : SynthModule {
+ in audio stream invalue1,invalue2;
+ out audio stream outvalue;
+ default invalue1, invalue2;
+};
+
+/**
+ * This plays a wave file
+ */
+interface Synth_PLAY_WAV : SynthModule {
+ /**
+ * How fast should it be played? 1.0 = normal speed
+ */
+ attribute float speed;
+ /**
+ * Which file should be played
+ */
+ attribute string filename;
+ /**
+ * Is true as soon as the file is finished
+ */
+ readonly attribute boolean finished;
+
+ out audio stream left, right;
+ default left, right;
+};
+
+/**
+ * sends data to a bus - busses are dynamic N:M connections - all signals
+ * from all uplinks are mixed together, and sent to all downlinks
+ */
+interface Synth_BUS_UPLINK : SynthModule {
+ /**
+ * the name of the bus to use
+ */
+ attribute string busname;
+
+ default in audio stream left,right;
+};
+
+/**
+ * receives data from a bus - busses are dynamic N:M connections - all signals
+ * from all uplinks are mixed together, and sent to all downlinks
+ */
+interface Synth_BUS_DOWNLINK : SynthModule {
+ /**
+ * the name of the bus to use
+ */
+ attribute string busname;
+
+ default out audio stream left,right;
+};
+
+
+/**
+ * Byte stream to audio conversion object
+ *
+ * Converts an asynchronous byte stream to a synchronous audio stream
+ */
+interface ByteStreamToAudio : SynthModule {
+ attribute long samplingRate;
+ attribute long channels;
+ attribute long bits;
+
+ /**
+ * is conversion currently running, or is it stalled due to the fact
+ * that there is not enough input input?
+ */
+ readonly attribute boolean running;
+
+ async in byte stream indata;
+
+ out audio stream left,right;
+ default left;
+ default right;
+};
+
+/**
+ * Audio to Byte stream conversion object
+ *
+ * Converts a synchronous audio stream to an asynchronous byte stream
+ */
+interface AudioToByteStream : SynthModule {
+ attribute long samplingRate;
+ attribute long channels;
+ attribute long bits;
+
+ async out byte stream outdata;
+
+ in audio stream left,right;
+ default left;
+ default right;
+};
+
+/**
+ * Base interface for all stereo effects
+ */
+interface StereoEffect : SynthModule {
+ default in audio stream inleft, inright;
+ default out audio stream outleft, outright;
+};
+
+/**
+ * this is a simple clipping stereo volume control
+ */
+interface StereoVolumeControl : StereoEffect {
+ attribute float scaleFactor;
+ readonly attribute float currentVolumeLeft;
+ readonly attribute float currentVolumeRight;
+};
+
+/**
+ * A funny FFT scope
+ */
+interface StereoFFTScope : StereoEffect {
+ readonly attribute sequence<float> scope;
+};
+
+/**
+ * A stack of stereo effects
+ */
+interface StereoEffectStack : StereoEffect {
+ /**
+ * inserts an effect at the top side (= directly after the input)
+ *
+ * @returns an ID which can be used to remove the effect again
+ */
+ long insertTop(StereoEffect effect, string name);
+
+ /**
+ * inserts an effect at the bottom (= close to the output) side
+ *
+ * @returns an ID which can be used to remove the effect again
+ */
+ long insertBottom(StereoEffect effect, string name);
+
+ /**
+ * removes an effect again
+ */
+ void remove(long ID);
+};
+
+/*
+ * Audio Manager stuff
+ */
+
+enum AudioManagerDirection { amPlay, amRecord };
+
+/**
+ * Information structure for audio manager clients
+ */
+struct AudioManagerInfo {
+ long ID;
+ string destination;
+
+ AudioManagerDirection direction;
+ string title, autoRestoreID;
+};
+
+/**
+ * an audio manager client
+ */
+interface AudioManagerClient {
+ readonly attribute long ID;
+ attribute AudioManagerDirection direction;
+ attribute string title, autoRestoreID;
+
+ void constructor(AudioManagerDirection direction, string title,
+ string autoRestoreID);
+};
+
+/**
+ * The audio manager interface
+ */
+interface AudioManager {
+ /**
+ * a list of destinations, where you can play/record data to/from
+ */
+ readonly attribute sequence<string> destinations;
+
+ /**
+ * a list of clients
+ */
+ readonly attribute sequence<AudioManagerInfo> clients;
+
+ /**
+ * this is incremented each time a change is made (i.e. new client attached)
+ * TODO: SHOULD GO AWAY WITH ATTRIBUTE WATCHING
+ */
+ readonly attribute long changes;
+
+ /**
+ * this is used to route a client to another destination
+ */
+ void setDestination(long ID, string destination);
+};
+/**
+ * This is a virtual output port, which you use to play data. Where exactly
+ * this data gets played is managed by the audiomanager.
+ *
+ * Creation: there are two ways to initialize a Synth_AMAN_PLAY - one is
+ * to set title and autoRestoreID to sensible (non empty) values. The other
+ * is to pass an already initialized AudioManagerClient on the constructor.
+ */
+interface Synth_AMAN_PLAY : SynthModule {
+ attribute string title, autoRestoreID;
+ void constructor(AudioManagerClient client);
+
+ default in audio stream left, right;
+};
+
+/**
+ * This is a virtual input port, which you use to record data. Where this
+ * data comes from is in turn managed by the audiomanager.
+ *
+ * Creation: there are two ways to initialize a Synth_AMAN_RECORD - one is
+ * to set title and autoRestoreID to sensible (non empty) values. The other
+ * is to pass an already initialized AudioManagerClient on the constructor.
+ */
+interface Synth_AMAN_RECORD : SynthModule {
+ attribute string title, autoRestoreID;
+ void constructor(AudioManagerClient client);
+
+ default out audio stream left, right;
+};
+
+/* --------------------------------------------------------------------- */
+
+/**
+ * Wraps a datahandle. That is an abstraction for a float value array
+ * which can be directly loaded data from a file or have some
+ * processing stages in between (caching, reversing, cropping...)
+ * which are hidden to this interface.
+ * In contrast to the underlying C++ API, this datahandle is already
+ * open()ed after creation, so you can access its information (like
+ * channelCount) without further action.
+ * A datahandle normally has one more important function: read() which
+ * is not wrapped in MCOP because of the overhead of the data
+ * transfer. (If there is need for sth. like that in the future,
+ * one could maybe find a solution.)
+ */
+interface DataHandle {
+ readonly attribute long bitDepth;
+ readonly attribute long channelCount;
+ readonly attribute long valueCount;
+ /**
+ * error code open() returned
+ */
+ readonly attribute long errorNo;
+};
+
+/**
+ * Represents a datahandle which delivers the data from the underlying
+ * sourceDatahandle in reverse order.
+ */
+interface ReversedDataHandle : DataHandle {
+ void init(DataHandle sourceHandle);
+};
+
+/**
+ * Represents a datahandle which delivers an "inner" part of the data
+ * from the underlying sourceDatahandle. You can cut away parts at the
+ * start and/or the end with this.
+ */
+interface CroppedDataHandle : DataHandle {
+ void init(DataHandle sourceHandle,
+ long headCutValueCount,
+ long tailCutValueCount);
+};
+
+/**
+ * Represents a datahandle which delivers the data from the underlying
+ * sourceDatahandle without the "inner" part containing the values
+ * [cutOffset..cutOffset+cutValueCount-1], which will be cut away.
+ */
+interface CutDataHandle : DataHandle {
+ void init(DataHandle sourceHandle,
+ long cutOffset,
+ long cutValueCount);
+};
+
+/**
+ * DataHandlePlay uses a gsl_wave_osc to play back data from a
+ * DataHandle using sophisticated anti-aliasing filtering and caching
+ * techniques. (Though not implemented at the time of writing this, it
+ * will be optimized for cases where the anti-aliasing is not needed
+ * because the mixerFrequency equals the current soundserver's.)
+ */
+interface DataHandlePlay : SynthModule {
+ /**
+ * Which data should be played?
+ */
+ attribute DataHandle handle;
+ /**
+ * What is the normal mixer frequency the data from the handle
+ * should be played back at? (default: current mixing frequency
+ * of the soundserver, e.g. 44100)
+ */
+ attribute float mixerFrequency;
+ /**
+ * Which channel of the datahandle should by played?
+ * (defaults to 0 = the first channel)
+ */
+ attribute long channelIndex;
+ /**
+ * How fast should the data be played?
+ * (defaults to 1.0 = normal speed, see mixerFrequency)
+ */
+ attribute float speed;
+ /**
+ * Current position while playing, in fact it's the index in the
+ * datahandle, so 0 <= pos < handle.valueCount
+ */
+ attribute long pos;
+ /**
+ * Is true as soon as the file is finished
+ */
+ readonly attribute boolean finished;
+ /**
+ * Can be used to pause and/or continue playing
+ */
+ attribute boolean paused;
+
+ default out audio stream outvalue;
+
+ DataHandlePlay clone();
+};
+
+/**
+ * DataHandle which represents sample data loaded from a file. Note
+ * that the samples from all channels are interleaved, that is, the
+ * samples of the first channel in a stereo file are found at offsets
+ * 0,2,4,6,.. etc.
+ */
+interface WaveDataHandle : DataHandle {
+ /**
+ * Properties of the loaded sample data. Note that those
+ * properties are only available from a WaveDataHandle, but may be
+ * available from a DataHandle in the future.
+ */
+ readonly attribute float mixerFrequency;
+ readonly attribute float oscillatorFrequency;
+
+ /**
+ * Load the first wavechunk from a file and return true on
+ * success. A more specific error code is not available at the
+ * moment.
+ */
+ boolean load(string filename);
+
+ /**
+ * Load a specific wavechunk from a file and return true on
+ * success. A more specific error code is not available at the
+ * moment.
+ */
+ boolean load(string filename,
+ long waveIndex, long chunkIndex);
+
+ /**
+ * Return true if and only if a wavechunk was successfully loaded
+ * from a file.
+ */
+ readonly attribute boolean isLoaded;
+
+ /**
+ * Creates a DataHandlePlay object with the important attributes
+ * handle, mixerFrequency and channelCount already set to play
+ * this WaveDataHandle.
+ */
+ DataHandlePlay createPlayer();
+};
+
+};
diff --git a/flow/asyncschedule.cc b/flow/asyncschedule.cc
new file mode 100644
index 0000000..b3251a7
--- /dev/null
+++ b/flow/asyncschedule.cc
@@ -0,0 +1,553 @@
+ /*
+
+ Copyright (C) 2000,2001 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include <iostream>
+#include "asyncschedule.h"
+
+using namespace std;
+using namespace Arts;
+
+#include "debug.h"
+#include <stdio.h>
+
+/* Since this file is a tad bit more complex, here is some basic documentation:
+
+1) ASyncPort: There are asynchronous ports which are parts of the standard-
+ flowsystem schedule nodes. Their lifetime starts whenever an asynchronous
+ stream gets created by the flow system, and ends when the schedule node
+ gets destroyed. Basically, an ASyncPort has two functions:
+
+ * it is a "Port", which means that it gets connect(), disconnect() and
+ other calls from the flowsystem
+
+ * it is a "GenericDataChannel", which means that DataPackets can interact
+ with it
+
+ Although there will be ASyncPorts which only send data and ASyncPorts which
+ only receive data (there are none that do both), there are no distinct
+ classes for this.
+
+2) Standard case: a DataPacket that gets transported over a datachannel locally:
+
+ 1. the user allocates himself a datapacket "packet"
+ 2. the user calls "packet->send()", which in turn calls
+ ASyncPort::sendPacket(packet)
+ 3. the ASyncPort sends the DataPacket to every subscriber (incrementing the
+ useCount) over the NotificationManager
+ 4. the NotificationManager delivers the DataPackets to the receiver
+ 5. eventually, the receiver confirms using "packet->processed()"
+ 6. the packet informs the ASyncPort::processedPacket()
+ 7. the packet is freed
+
+variant (pulling):
+
+ 1. the user gets told by the ASyncPort: produce some data, here is a "packet"
+ 2. the user calls "packet->send()", which in turn calls
+ ASyncPort::sendPacket(packet)
+ 3. the ASyncPort sends the DataPacket to every subscriber (incrementing the
+ useCount) over the NotificationManager
+ 4. the NotificationManager delivers the DataPackets to the receiver
+ 5. eventually, the receiver confirms using "packet->processed()"
+ 6. the packet informs the ASyncPort::processedPacket()
+ 7. the ASyncPort restarts with 1.
+
+3) Remote case: the remote case follows from the local case by adding two extra
+things: one object that converts packets from their packet form to a message
+(ASyncNetSend), and one object that converts packets from the message form
+to a packet again. Effectively, the sending of a single packet looks like
+this, then:
+
+ 1-S. the user allocates himself a datapacket "packet"
+ 2-S. the user calls "packet->send()", which in turn calls
+ ASyncPort::sendPacket(packet)
+ 3-S. the ASyncPort sends the DataPacket to every subscriber (incrementing the
+ useCount) over the NotificationManager
+ 4-S. the NotificationManager delivers the DataPackets to the ASyncNetSend
+ 5-S. the ASyncNetSend::notify method gets called, which in turn converts
+ the packet to a network message
+
+ ... network transfer ...
+
+ 6-R. the ASyncNetReceive::receive method gets called - the method creates
+ a new data packet, and sends it using the NotificationManager again
+ 7-R. the NotificationManager delivers the DataPacket to the receiver
+ 8-R. eventually, the receiver confirms using "packet->processed()"
+ 9-R. the packet informs the ASyncNetReceive::processedPacket() which
+ frees the packet and tells the (remote) sender that it went all right
+
+ ... network transfer ...
+
+ 10-S. eventually, ASyncNetSend::processed() gets called, and confirms
+ the packet using "packet->processed()"
+ 11-S. the packet informs the ASyncPort::processedPacket()
+ 12-S. the packet is freed
+
+variant(pulling):
+
+ works the same as in the local case by exchanging steps 1-S and 12-S
+
+4) ownership:
+
+ * ASyncPort: is owned by the Object which it is a part of, if the object
+ dies, ASyncPort dies unconditionally
+
+ * DataPacket: is owned by the GenericDataChannel they are propagated over,
+ that is, the ASyncPort normally - however if the DataPacket is still in
+ use (i.e. in state 5 of the local case), it will take responsibility to
+ free itself once all processed() calls have been collected
+
+ * ASyncNetSend, ASyncNetReceive: own each other, so that if the sender dies,
+ the connection will die as well, and if the receiver dies, the same happens
+
+*/
+
+#undef DEBUG_ASYNC_TRANSFER
+
+ASyncPort::ASyncPort(const std::string& name, void *ptr, long flags,
+ StdScheduleNode* parent) : Port(name, ptr, flags, parent), pull(false)
+{
+ stream = (GenericAsyncStream *)ptr;
+ stream->channel = this;
+ stream->_notifyID = notifyID = parent->object()->_mkNotifyID();
+}
+
+ASyncPort::~ASyncPort()
+{
+ /*
+ * tell all outstanding packets that we don't exist any longer, so that
+ * if they feel like they need to confirm they have been processed now,
+ * they don't talk to an no longer existing object about it
+ */
+ while(!sent.empty())
+ {
+ sent.front()->channel = 0;
+ sent.pop_front();
+ }
+
+ /* disconnect remote connections (if present): the following things will
+ * need to be ensured here, since we are being deleted:
+ *
+ * - the senders should not talk to us after our destructor
+ * - all of our connections need to be disconnected
+ * - every connection needs to be closed exactly once
+ *
+ * (closing a connection can cause reentrancy due to mcop communication)
+ */
+ while(!netSenders.empty())
+ netSenders.front()->disconnect();
+
+ FlowSystemReceiver receiver = netReceiver;
+ if(!receiver.isNull())
+ receiver.disconnect();
+}
+
+//-------------------- GenericDataChannel interface -------------------------
+
+void ASyncPort::setPull(int packets, int capacity)
+{
+ pullNotification.receiver = parent->object();
+ pullNotification.ID = notifyID;
+ pullNotification.internal = 0;
+ pull = true;
+
+ for(int i=0;i<packets;i++)
+ {
+ GenericDataPacket *packet = stream->createPacket(capacity);
+ packet->useCount = 0;
+ pullNotification.data = packet;
+ NotificationManager::the()->send(pullNotification);
+ }
+}
+
+void ASyncPort::endPull()
+{
+ pull = false;
+ // TODO: maybe remove all pending pull packets here
+}
+
+void ASyncPort::processedPacket(GenericDataPacket *packet)
+{
+ int count = 0;
+ list<GenericDataPacket *>::iterator i = sent.begin();
+ while(i != sent.end())
+ {
+ if(*i == packet)
+ {
+ count++;
+ i = sent.erase(i);
+ }
+ else i++;
+ }
+ assert(count == 1);
+
+#ifdef DEBUG_ASYNC_TRANSFER
+ cout << "port::processedPacket" << endl;
+#endif
+ assert(packet->useCount == 0);
+ if(pull)
+ {
+ pullNotification.data = packet;
+ NotificationManager::the()->send(pullNotification);
+ }
+ else
+ {
+ stream->freePacket(packet);
+ }
+}
+
+void ASyncPort::sendPacket(GenericDataPacket *packet)
+{
+ bool sendOk = false;
+
+#ifdef DEBUG_ASYNC_TRANSFER
+ cout << "port::sendPacket" << endl;
+#endif
+
+ if(packet->size > 0)
+ {
+ vector<Notification>::iterator i;
+ for(i=subscribers.begin(); i != subscribers.end(); i++)
+ {
+ Notification n = *i;
+ n.data = packet;
+ packet->useCount++;
+#ifdef DEBUG_ASYNC_TRANSFER
+ cout << "sending notification " << n.ID << endl;
+#endif
+ NotificationManager::the()->send(n);
+ sendOk = true;
+ }
+ }
+
+ if(sendOk)
+ sent.push_back(packet);
+ else
+ stream->freePacket(packet);
+}
+
+//----------------------- Port interface ------------------------------------
+
+void ASyncPort::connect(Port *xsource)
+{
+ arts_debug("port(%s)::connect",_name.c_str());
+
+ ASyncPort *source = xsource->asyncPort();
+ assert(source);
+ addAutoDisconnect(xsource);
+
+ Notification n;
+ n.receiver = parent->object();
+ n.ID = notifyID;
+ n.internal = 0;
+ source->subscribers.push_back(n);
+}
+
+void ASyncPort::disconnect(Port *xsource)
+{
+ arts_debug("port::disconnect");
+
+ ASyncPort *source = xsource->asyncPort();
+ assert(source);
+ removeAutoDisconnect(xsource);
+
+ // remove our subscription from the source object
+ vector<Notification>::iterator si;
+ for(si = source->subscribers.begin(); si != source->subscribers.end(); si++)
+ {
+ if(si->receiver == parent->object())
+ {
+ source->subscribers.erase(si);
+ return;
+ }
+ }
+
+ // there should have been exactly one, so this shouldn't be reached
+ assert(false);
+}
+
+ASyncPort *ASyncPort::asyncPort()
+{
+ return this;
+}
+
+GenericAsyncStream *ASyncPort::receiveNetCreateStream()
+{
+ return stream->createNewStream();
+}
+
+NotificationClient *ASyncPort::receiveNetObject()
+{
+ return parent->object();
+}
+
+long ASyncPort::receiveNetNotifyID()
+{
+ return notifyID;
+}
+
+// Network transparency
+void ASyncPort::addSendNet(ASyncNetSend *netsend)
+{
+ Notification n;
+ n.receiver = netsend;
+ n.ID = netsend->notifyID();
+ n.internal = 0;
+ subscribers.push_back(n);
+ netSenders.push_back(netsend);
+}
+
+void ASyncPort::removeSendNet(ASyncNetSend *netsend)
+{
+ arts_return_if_fail(netsend != 0);
+ netSenders.remove(netsend);
+
+ vector<Notification>::iterator si;
+ for(si = subscribers.begin(); si != subscribers.end(); si++)
+ {
+ if(si->receiver == netsend)
+ {
+ subscribers.erase(si);
+ return;
+ }
+ }
+ arts_warning("Failed to remove ASyncNetSend (%p) from ASyncPort", netsend);
+}
+
+void ASyncPort::setNetReceiver(ASyncNetReceive *receiver)
+{
+ arts_return_if_fail(receiver != 0);
+
+ FlowSystemReceiver r = FlowSystemReceiver::_from_base(receiver->_copy());
+ netReceiver = r;
+}
+
+void ASyncPort::disconnectRemote(const string& dest)
+{
+ list<ASyncNetSend *>::iterator i;
+
+ for(i = netSenders.begin(); i != netSenders.end(); i++)
+ {
+ if((*i)->dest() == dest)
+ {
+ (*i)->disconnect();
+ return;
+ }
+ }
+ arts_warning("failed to disconnect %s in ASyncPort", dest.c_str());
+}
+
+ASyncNetSend::ASyncNetSend(ASyncPort *ap, const std::string& dest) : ap(ap)
+{
+ _dest = dest;
+ ap->addSendNet(this);
+}
+
+ASyncNetSend::~ASyncNetSend()
+{
+ while(!pqueue.empty())
+ {
+ pqueue.front()->processed();
+ pqueue.pop();
+ }
+ if(ap)
+ {
+ ap->removeSendNet(this);
+ ap = 0;
+ }
+}
+
+long ASyncNetSend::notifyID()
+{
+ return 1;
+}
+
+void ASyncNetSend::notify(const Notification& notification)
+{
+ // got a packet?
+ assert(notification.ID == notifyID());
+ GenericDataPacket *dp = (GenericDataPacket *)notification.data;
+ pqueue.push(dp);
+
+ /*
+ * since packets are delivered asynchronously, and since disconnection
+ * involves communication, it might happen that we get a packet without
+ * actually being connected any longer - in that case, silently forget it
+ */
+ if(!receiver.isNull())
+ {
+ // put it into a custom data message and send it to the receiver
+ Buffer *buffer = receiver._allocCustomMessage(receiveHandlerID);
+ dp->write(*buffer);
+ receiver._sendCustomMessage(buffer);
+ }
+}
+
+void ASyncNetSend::processed()
+{
+ assert(!pqueue.empty());
+ pqueue.front()->processed();
+ pqueue.pop();
+}
+
+void ASyncNetSend::setReceiver(FlowSystemReceiver newReceiver)
+{
+ receiver = newReceiver;
+ receiveHandlerID = newReceiver.receiveHandlerID();
+}
+
+void ASyncNetSend::disconnect()
+{
+ /* since disconnection will cause destruction (most likely immediate),
+ * we'll reference ourselves ... */
+ _copy();
+
+ if(!receiver.isNull())
+ {
+ FlowSystemReceiver r = receiver;
+ receiver = FlowSystemReceiver::null();
+ r.disconnect();
+ }
+ if(ap)
+ {
+ ap->removeSendNet(this);
+ ap = 0;
+ }
+
+ _release();
+}
+
+string ASyncNetSend::dest()
+{
+ return _dest;
+}
+
+/* dispatching function for custom message */
+
+static void _dispatch_ASyncNetReceive_receive(void *object, Buffer *buffer)
+{
+ ((ASyncNetReceive *)object)->receive(buffer);
+}
+
+ASyncNetReceive::ASyncNetReceive(ASyncPort *port, FlowSystemSender sender)
+{
+ port->setNetReceiver(this);
+ stream = port->receiveNetCreateStream();
+ stream->channel = this;
+ this->sender = sender;
+ /* stream->_notifyID = _mkNotifyID(); */
+
+ gotPacketNotification.ID = port->receiveNetNotifyID();
+ gotPacketNotification.receiver = port->receiveNetObject();
+ gotPacketNotification.internal = 0;
+ _receiveHandlerID =
+ _addCustomMessageHandler(_dispatch_ASyncNetReceive_receive,this);
+}
+
+ASyncNetReceive::~ASyncNetReceive()
+{
+ /* tell outstanding packets that we don't exist any longer */
+ while(!sent.empty())
+ {
+ sent.front()->channel = 0;
+ sent.pop_front();
+ }
+ delete stream;
+}
+
+long ASyncNetReceive::receiveHandlerID()
+{
+ return _receiveHandlerID;
+}
+
+void ASyncNetReceive::receive(Buffer *buffer)
+{
+ GenericDataPacket *dp = stream->createPacket(512);
+ dp->read(*buffer);
+ dp->useCount = 1;
+ gotPacketNotification.data = dp;
+ NotificationManager::the()->send(gotPacketNotification);
+ sent.push_back(dp);
+}
+
+/*
+ * It will happen that this routine is called in time critical situations,
+ * such as: while audio calculation is running, and must be finished in
+ * time. The routine is mostly harmless, because sender->processed() is
+ * a oneway function, which just queues the buffer for sending and returns
+ * back, so it should return at once.
+ *
+ * However there is an exception upon first call: when sender->processed()
+ * is called for the first time, the method processed has still to be looked
+ * up. Thus, a synchronous call to _lookupMethod is made. That means, upon
+ * first call, the method will send out an MCOP request and block until the
+ * remote process tells that id.
+ */
+void ASyncNetReceive::processedPacket(GenericDataPacket *packet)
+{
+ /*
+ * HACK! Upon disconnect, strange things will happen. One of them is
+ * that we might, for the reason of not being referenced any longer,
+ * cease to exist without warning. Another is that our nice "sender"
+ * reference will get a null reference without warning, see disconnect
+ * code (which will cause the attached stub to also disappear). As
+ * those objects (especially the stub) are not prepared for not
+ * being there any more in the middle of whatever they do, we here
+ * explicitly reference us, and them, *again*, so that no evil things
+ * will happen. A general solution for this would be garbage collection
+ * in a timer, but until this is implemented (if it ever will become
+ * implemented), we'll live with this hack.
+ */
+ _copy();
+ sent.remove(packet);
+ stream->freePacket(packet);
+ if(!sender.isNull())
+ {
+ FlowSystemSender xsender = sender;
+ xsender.processed();
+ }
+ _release();
+}
+
+void ASyncNetReceive::disconnect()
+{
+ if(!sender.isNull())
+ {
+ FlowSystemSender s = sender;
+ sender = FlowSystemSender::null();
+ s.disconnect();
+ }
+}
+
+void ASyncNetReceive::sendPacket(GenericDataPacket *)
+{
+ assert(false);
+}
+
+void ASyncNetReceive::setPull(int, int)
+{
+ assert(false);
+}
+
+void ASyncNetReceive::endPull()
+{
+ assert(false);
+}
diff --git a/flow/asyncschedule.h b/flow/asyncschedule.h
new file mode 100644
index 0000000..0477c9a
--- /dev/null
+++ b/flow/asyncschedule.h
@@ -0,0 +1,134 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef ASYNCSCHEDULE_H
+#define ASYNCSCHEDULE_H
+
+#include "gslschedule.h"
+#include "datapacket.h"
+#include "weakreference.h"
+
+#include <queue>
+
+/*
+ * BC - Status (2002-03-08): ASyncNetSend, ASyncNetReceive, ASyncPort.
+ *
+ * None of these classes is considered part of the public API. Do NOT use it
+ * in your apps. These are part of the implementation of libartsflow's
+ * StdFlowSystem, and subject to change with the needs of it.
+ */
+
+namespace Arts {
+
+class ASyncPort;
+class ASyncNetSend : public FlowSystemSender_skel
+{
+protected:
+ ASyncPort *ap;
+ std::queue<GenericDataPacket *> pqueue;
+ FlowSystemReceiver receiver;
+ long receiveHandlerID;
+ std::string _dest;
+
+public:
+ ASyncNetSend(ASyncPort *ap, const std::string& dest);
+ ~ASyncNetSend();
+ long notifyID();
+ std::string dest();
+
+ /* this overwrites the Object::notify function */
+ void notify(const Notification& notification);
+ void processed();
+ void setReceiver(FlowSystemReceiver receiver);
+ void disconnect();
+};
+
+class ASyncNetReceive : public FlowSystemReceiver_skel,
+ public GenericDataChannel
+{
+protected:
+ GenericAsyncStream *stream;
+ FlowSystemSender sender;
+ Notification gotPacketNotification;
+ std::list<GenericDataPacket *> sent;
+ long _receiveHandlerID;
+
+public:
+ ASyncNetReceive(ASyncPort *port, FlowSystemSender sender);
+ ~ASyncNetReceive();
+
+ // GenericDataChannel interface
+ void processedPacket(GenericDataPacket *packet);
+ void sendPacket(GenericDataPacket *packet);
+ void setPull(int packets, int capacity);
+ void endPull();
+
+ // FlowSystemReceiver interface
+
+ long receiveHandlerID();
+ void disconnect();
+ void receive(Buffer *buffer); // custom data receiver
+};
+
+class ASyncPort :public Port, public GenericDataChannel {
+protected:
+ long notifyID;
+ std::vector<Notification> subscribers;
+ std::list<GenericDataPacket *> sent;
+ std::list<ASyncNetSend *> netSenders;
+ WeakReference<FlowSystemReceiver> netReceiver;
+
+ GenericAsyncStream *stream;
+
+ bool pull;
+ Notification pullNotification;
+
+public:
+ // GenericDataChannel interface
+ void processedPacket(GenericDataPacket *packet);
+ void sendPacket(GenericDataPacket *packet);
+ void setPull(int packets, int capacity);
+ void endPull();
+
+ // Port interface
+ ASyncPort(const std::string& name, void *ptr, long flags,
+ StdScheduleNode* parent);
+ ~ASyncPort();
+
+ void connect(Port *port);
+ void disconnect(Port *port);
+ ASyncPort *asyncPort();
+
+ // Network transparency
+ void addSendNet(ASyncNetSend *netsend); // send
+ void removeSendNet(ASyncNetSend *netsend);
+ void disconnectRemote(const std::string& dest);
+
+ long receiveNetNotifyID(); // receive
+ GenericAsyncStream *receiveNetCreateStream();
+ NotificationClient *receiveNetObject();
+ void setNetReceiver(ASyncNetReceive *receiver);
+};
+
+}
+
+#endif /* ASYNCSCHEDULE_H */
diff --git a/flow/audioio.cc b/flow/audioio.cc
new file mode 100644
index 0000000..e5924ab
--- /dev/null
+++ b/flow/audioio.cc
@@ -0,0 +1,165 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include "audioio.h"
+#include <map>
+#include <list>
+#include <assert.h>
+#include <cstring>
+
+using namespace Arts;
+using namespace std;
+
+class Arts::AudioIOPrivate {
+public:
+ map<AudioIO::AudioParam, int> paramMap;
+ map<AudioIO::AudioParam, string> paramStrMap;
+};
+
+AudioIO::AudioIO() :d(new AudioIOPrivate)
+{
+}
+
+AudioIO::~AudioIO()
+{
+ delete d;
+}
+
+int& AudioIO::param(AudioParam param)
+{
+ /*
+ * returns d->paramMap[param], initializes new elements with -1 (for those
+ * parameters not handled explicitly by the derived AudioIO* class).
+ */
+
+ map<AudioIO::AudioParam, int>::iterator pi = d->paramMap.find(param);
+ if(pi == d->paramMap.end())
+ {
+ int& result = d->paramMap[param];
+ result = -1;
+ return result;
+ }
+ else return pi->second;
+}
+
+string& AudioIO::paramStr(AudioParam param)
+{
+ return d->paramStrMap[param];
+}
+
+void AudioIO::setParamStr(AudioParam p, const char *value)
+{
+ paramStr(p) = value;
+}
+
+void AudioIO::setParam(AudioParam p, int& value)
+{
+ param(p) = value;
+}
+
+int AudioIO::getParam(AudioParam p)
+{
+ return param(p);
+}
+
+const char *AudioIO::getParamStr(AudioParam p)
+{
+ return paramStr(p).c_str();
+}
+
+/* ---- factories ---- */
+
+static list<AudioIOFactory *> *audioIOFactories = 0;
+
+AudioIO *AudioIO::createAudioIO(const char *name)
+{
+ if(audioIOFactories)
+ {
+ list<AudioIOFactory *>::iterator i;
+ for(i = audioIOFactories->begin(); i != audioIOFactories->end(); i++)
+ {
+ AudioIOFactory *factory = *i;
+
+ if(strcmp(factory->name(),name) == 0)
+ return factory->createAudioIO();
+ }
+ }
+ return 0;
+}
+
+int AudioIO::queryAudioIOCount()
+{
+ return audioIOFactories->size();
+}
+
+int AudioIO::queryAudioIOParam(int /*audioIO*/, AudioParam /*p*/)
+{
+ return 0;
+}
+
+const char *AudioIO::queryAudioIOParamStr(int audioIO, AudioParam p)
+{
+ list<AudioIOFactory *>::iterator i = audioIOFactories->begin();
+
+ while(audioIO && i != audioIOFactories->end()) { i++; audioIO--; }
+ if(i == audioIOFactories->end()) return 0;
+
+ switch(p)
+ {
+ case name:
+ return (*i)->name();
+ case fullName:
+ return (*i)->fullName();
+ default:
+ return 0;
+ }
+}
+
+void AudioIO::addFactory(AudioIOFactory *factory)
+{
+ if(!audioIOFactories)
+ audioIOFactories = new list<AudioIOFactory *>;
+
+ audioIOFactories->push_back(factory);
+}
+
+void AudioIO::removeFactory(AudioIOFactory *factory)
+{
+ assert(audioIOFactories);
+
+ audioIOFactories->remove(factory);
+ if(audioIOFactories->empty())
+ {
+ delete audioIOFactories;
+ audioIOFactories = 0;
+ }
+}
+
+void AudioIOFactory::startup()
+{
+ AudioIO::addFactory(this);
+}
+
+void AudioIOFactory::shutdown()
+{
+ AudioIO::removeFactory(this);
+}
diff --git a/flow/audioio.h b/flow/audioio.h
new file mode 100644
index 0000000..ade96e2
--- /dev/null
+++ b/flow/audioio.h
@@ -0,0 +1,145 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef ARTS_AUDIOIO_H
+#define ARTS_AUDIOIO_H
+
+#include <startupmanager.h>
+#include <string>
+#include "arts_export.h"
+/*
+ * BC - Status (2002-03-08): AudioIO, AudioIOFactory
+ *
+ * Right now, these classes are considered an implementation detail. No binary
+ * compatibility guaranteed, its safe to add virtual methods when required.
+ */
+
+/*
+ * The AudioIO class - it is used as follows:
+ *
+ * 1. check the settings with getParam, modify what you don't like
+ * 2. call open -> print getInfo(lastError) if it failed (returned false)
+ * 3. check whether the settings are still what you expected them to
+ * be (as the AudioIO class will maybe only know after open if the
+ * requested parameters can be achieved)
+ */
+
+namespace Arts {
+
+class AudioIOPrivate;
+class AudioIOFactory;
+
+class ARTS_EXPORT AudioIO {
+private:
+ class AudioIOPrivate *d;
+
+public:
+ enum AudioParam {
+/* the following has to be supported */
+ samplingRate = 1, /* usually 4000..48000 (Hz) */
+ channels = 2, /* usually 1 (mono) or 2 (stereo) */
+ format = 3, /* 8 = 8bit unsigned
+ * 16 = 16bit signed little endian
+ * 17 = 16bit signed big endian
+ * 32 = 32bit float */
+
+/* the following -can- be supported (value=-1 if they are not) */
+ direction = 101, /* 1 = read, 2 = write, 3 = read|write */
+ fragmentCount = 102,/* usually 3..16 (to control latency) */
+ fragmentSize = 103, /* usually 256,512,...8192 (a 2^N value) */
+ canRead = 104, /* the amount of bytes that can be read */
+ canWrite = 105, /* the amount of bytes that can be written */
+ selectReadFD = 106, /* filedescriptor to be select()ed on for reading */
+ selectWriteFD = 107,/* filedescriptor to be select()ed on for writing */
+ autoDetect = 108, /* 0 = don't use this as default
+ * 1 or higher = preference of using this as default
+ *
+ * if nothing else is specified, aRts asks all
+ * available AudioIO classes for the autoDetect
+ * value and chooses the one which returned the
+ * highest number */
+
+/* string parameters that have to be supported */
+ lastError = 201, /* the last error message as human readable text */
+
+/* string parameters that -can- be supported */
+ deviceName = 301, /* name of the device to open */
+
+/* class parameters: same semantics as above */
+ name = 1201, /* name of the driver (i.e. oss) */
+ fullName = 1202 /* full name (i.e. Open Sound System) */
+ };
+
+ enum {
+ directionRead = 1,
+ directionWrite = 2,
+ directionReadWrite = 3
+ };
+
+ AudioIO();
+ virtual ~AudioIO();
+
+ virtual void setParamStr(AudioParam param, const char *value);
+ virtual void setParam(AudioParam param, int& value);
+ virtual int getParam(AudioParam param);
+ virtual const char *getParamStr(AudioParam param);
+
+ virtual bool open() = 0;
+ virtual void close() = 0;
+ virtual int read(void *buffer, int size) = 0;
+ virtual int write(void *buffer, int size) = 0;
+
+/* ---- factory querying stuff ---- */
+ static int queryAudioIOCount();
+ static int queryAudioIOParam(int audioIO, AudioParam param);
+ static const char *queryAudioIOParamStr(int audioIO, AudioParam param);
+
+/* ---- factory stuff ---- */
+ static AudioIO *createAudioIO(const char *name);
+ static void addFactory(AudioIOFactory *factory);
+ static void removeFactory(AudioIOFactory *factory);
+
+protected:
+ int& param(AudioParam param);
+ std::string& paramStr(AudioParam param);
+};
+
+class ARTS_EXPORT AudioIOFactory : public StartupClass {
+public:
+ void startup();
+ void shutdown();
+ virtual AudioIO *createAudioIO() = 0;
+ virtual const char *name() = 0;
+ virtual const char *fullName() = 0;
+};
+
+}
+
+#define REGISTER_AUDIO_IO(impl,implName,implFullName) \
+ static class AudioIOFactory ## impl : public AudioIOFactory { \
+ public: \
+ AudioIO *createAudioIO() { return new impl(); } \
+ virtual const char *name() { return implName; } \
+ virtual const char *fullName() { return implFullName; } \
+ } The_ ## impl ## _Factory /* <- add semicolon when calling this macro */
+
+#endif /* ARTS_AUDIOIO_H */
diff --git a/flow/audioioaix.cc b/flow/audioioaix.cc
new file mode 100644
index 0000000..f36e9db
--- /dev/null
+++ b/flow/audioioaix.cc
@@ -0,0 +1,390 @@
+/*
+
+ Copyright (C) 2001 Carsten Griwodz
+ griff@ifi.uio.no
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef _AIX
+
+/*
+ * The audio header files exist even if there is not soundcard the
+ * the AIX machine. You won't be able to compile this code on AIX3
+ * which had ACPA support, so /dev/acpa is not checked here.
+ * I have no idea whether the Ultimedia Audio Adapter is actually
+ * working or what it is right now.
+ * For PCI machines including PowerSeries 850, baud or paud should
+ * work. The DSP (MWave?) of the 850 laptops may need microcode
+ * download. This is not implemented.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/machine.h>
+#undef BIG_ENDIAN
+#include <sys/audio.h>
+
+#ifndef AUDIO_BIG_ENDIAN
+#define AUDIO_BIG_ENDIAN BIG_ENDIAN
+#endif
+
+#include "debug.h"
+#include "audioio.h"
+
+namespace Arts {
+
+class AudioIOAIX : public AudioIO {
+ int openDevice();
+
+protected:
+ int audio_fd;
+
+public:
+ AudioIOAIX();
+
+ void setParam(AudioParam param, int& value);
+ int getParam(AudioParam param);
+
+ bool open();
+ void close();
+ int read(void *buffer, int size);
+ int write(void *buffer, int size);
+};
+
+REGISTER_AUDIO_IO(AudioIOAIX,"paud","Personal Audio Device");
+};
+
+using namespace std;
+using namespace Arts;
+
+int AudioIOAIX::openDevice()
+{
+ char devname[14];
+ int fd;
+ for ( int dev=0; dev<4; dev++ )
+ {
+ for ( int chan=1; chan<8; chan++ )
+ {
+ sprintf(devname,"/dev/paud%d/%d",dev,chan);
+ fd = ::open (devname, O_WRONLY, 0);
+ if ( fd >= 0 )
+ {
+ paramStr(deviceName) = devname;
+ return fd;
+ }
+ sprintf(devname,"/dev/baud%d/%d",dev,chan);
+ fd = ::open (devname, O_WRONLY, 0);
+ if ( fd >= 0 )
+ {
+ paramStr(deviceName) = devname;
+ return fd;
+ }
+ }
+ }
+ return -1;
+}
+
+AudioIOAIX::AudioIOAIX()
+{
+ int fd = openDevice();
+ if( fd >= 0 )
+ {
+ audio_status audioStatus;
+ memset( &audioStatus, 0, sizeof(audio_status) );
+ ioctl(fd, AUDIO_STATUS, &audioStatus);
+
+ audio_buffer audioBuffer;
+ memset( &audioBuffer, 0, sizeof(audio_buffer) );
+ ioctl(fd, AUDIO_BUFFER, &audioBuffer);
+
+ ::close( fd );
+
+ /*
+ * default parameters
+ */
+ param(samplingRate) = audioStatus.srate;
+ param(fragmentSize) = audioStatus.bsize;
+ param(fragmentCount) = audioBuffer.write_buf_cap / audioStatus.bsize;
+ param(channels) = audioStatus.channels;
+ param(direction) = 2;
+
+ param(format) = ( audioStatus.bits_per_sample==8 ) ? 8
+ : ( ( audioStatus.flags & AUDIO_BIG_ENDIAN ) ? 17 : 16 );
+ }
+}
+
+bool AudioIOAIX::open()
+{
+ string& _error = paramStr(lastError);
+ string& _deviceName = paramStr(deviceName);
+ int& _channels = param(channels);
+ int& _fragmentSize = param(fragmentSize);
+ int& _fragmentCount = param(fragmentCount);
+ int& _samplingRate = param(samplingRate);
+ int& _format = param(format);
+
+ int mode;
+
+ switch( param(direction) )
+ {
+ case 1 : mode = O_RDONLY | O_NDELAY; break;
+ case 2 : mode = O_WRONLY | O_NDELAY; break;
+ case 3 :
+ _error = "open device twice to RDWR";
+ return false;
+ default :
+ _error = "invalid direction";
+ return false;
+ }
+
+ audio_fd = ::open(_deviceName.c_str(), mode, 0);
+
+ if(audio_fd == -1)
+ {
+ _error = "device ";
+ _error += _deviceName.c_str();
+ _error += " can't be opened (";
+ _error += strerror(errno);
+ _error += ")";
+ return false;
+ }
+
+ if( (_channels!=1) && (_channels!=2) )
+ {
+ _error = "internal error; set channels to 1 (mono) or 2 (stereo)";
+
+ close();
+ return false;
+ }
+
+ // int requeststereo = stereo;
+
+ // int speed = _samplingRate;
+
+ audio_init audioInit;
+ memset( &audioInit, 0, sizeof(audio_init) );
+ audioInit.srate = _samplingRate;
+ audioInit.bits_per_sample = ((_format==8)?8:16);
+ audioInit.bsize = _fragmentSize;
+ audioInit.mode = PCM;
+ audioInit.channels = _channels;
+ audioInit.flags = 0;
+ audioInit.flags |= (_format==17) ? AUDIO_BIG_ENDIAN : 0;
+ audioInit.flags |= (_format==8) ? 0 : SIGNED;
+ audioInit.operation = (param(direction)==1) ? RECORD : PLAY;
+
+ if ( ioctl(audio_fd, AUDIO_INIT, &audioInit) < 0 )
+ {
+ _error = "AUDIO_INIT failed - ";
+ _error += strerror(errno);
+ switch ( audioInit.rc )
+ {
+ case 1 :
+ _error += "Couldn't set audio format: DSP can't do play requests";
+ break;
+ case 2 :
+ _error += "Couldn't set audio format: DSP can't do record requests";
+ break;
+ case 4 :
+ _error += "Couldn't set audio format: request was invalid";
+ break;
+ case 5 :
+ _error += "Couldn't set audio format: conflict with open's flags";
+ break;
+ case 6 :
+ _error += "Couldn't set audio format: out of DSP MIPS or memory";
+ break;
+ default :
+ _error += "Couldn't set audio format: not documented in sys/audio.h";
+ break;
+ }
+
+ close();
+ return false;
+ }
+
+ if (audioInit.channels != _channels)
+ {
+ _error = "audio device doesn't support number of requested channels";
+ close();
+ return false;
+ }
+
+ switch( _format )
+ {
+ case 8 :
+ if (audioInit.flags&AUDIO_BIG_ENDIAN==1)
+ {
+ _error = "setting little endian format failed";
+ close();
+ return false;
+ }
+ if (audioInit.flags&SIGNED==1)
+ {
+ _error = "setting unsigned format failed";
+ close();
+ return false;
+ }
+ break;
+ case 16 :
+ if (audioInit.flags&AUDIO_BIG_ENDIAN==1)
+ {
+ _error = "setting little endian format failed";
+ close();
+ return false;
+ }
+ if (audioInit.flags&SIGNED==0)
+ {
+ _error = "setting signed format failed";
+ close();
+ return false;
+ }
+ break;
+ case 17 :
+ if (audioInit.flags&AUDIO_BIG_ENDIAN==0)
+ {
+ _error = "setting big endian format failed";
+ close();
+ return false;
+ }
+ if (audioInit.flags&SIGNED==0)
+ {
+ _error = "setting signed format failed";
+ close();
+ return false;
+ }
+ break;
+ default :
+ break;
+ }
+
+ /*
+ * Some soundcards seem to be able to only supply "nearly" the requested
+ * sampling rate, especially PAS 16 cards seem to quite radical supplying
+ * something different than the requested sampling rate ;)
+ *
+ * So we have a quite large tolerance here (when requesting 44100 Hz, it
+ * will accept anything between 38690 Hz and 49510 Hz). Most parts of the
+ * aRts code will do resampling where appropriate, so it shouldn't affect
+ * sound quality.
+ */
+ int tolerance = _samplingRate/10+1000;
+
+ if (abs(audioInit.srate - _samplingRate) > tolerance)
+ {
+ _error = "can't set requested samplingrate";
+
+ char details[80];
+ sprintf(details," (requested rate %d, got rate %ld)",
+ _samplingRate, audioInit.srate);
+ _error += details;
+
+ close();
+ return false;
+ }
+ _samplingRate = audioInit.srate;
+
+ _fragmentSize = audioInit.bsize;
+ _fragmentCount = audioInit.bsize / audioInit.bits_per_sample;
+
+ audio_buffer buffer_info;
+ ioctl(audio_fd, AUDIO_BUFFER, &buffer_info);
+ _fragmentCount = buffer_info.write_buf_cap / audioInit.bsize;
+
+
+ artsdebug("buffering: %d fragments with %d bytes "
+ "(audio latency is %1.1f ms)", _fragmentCount, _fragmentSize,
+ (float)(_fragmentSize*_fragmentCount) /
+ (float)(2.0 * _samplingRate * _channels)*1000.0);
+
+ return true;
+}
+
+void AudioIOAIX::close()
+{
+ ::close(audio_fd);
+}
+
+void AudioIOAIX::setParam(AudioParam p, int& value)
+{
+ param(p) = value;
+}
+
+int AudioIOAIX::getParam(AudioParam p)
+{
+ audio_buffer info;
+ switch(p)
+ {
+ case canRead:
+ ioctl(audio_fd, AUDIO_BUFFER, &info);
+ return (info.read_buf_cap - info.read_buf_size);
+ break;
+
+ case canWrite:
+ ioctl(audio_fd, AUDIO_BUFFER, &info);
+ return (info.write_buf_cap - info.write_buf_size);
+ break;
+
+ case selectReadFD:
+ return (param(direction) & directionRead)?audio_fd:-1;
+ break;
+
+ case selectWriteFD:
+ return (param(direction) & directionWrite)?audio_fd:-1;
+ break;
+
+ case autoDetect:
+ /* You may prefer OSS if it works, e.g. on 43P 240
+ * or you may prefer UMS, if anyone bothers to write
+ * a module for it.
+ */
+ return 2;
+ break;
+
+ default:
+ return param(p);
+ break;
+ }
+}
+
+int AudioIOAIX::read(void *buffer, int size)
+{
+ arts_assert(audio_fd != 0);
+ return ::read(audio_fd,buffer,size);
+}
+
+int AudioIOAIX::write(void *buffer, int size)
+{
+ arts_assert(audio_fd != 0);
+ return ::write(audio_fd,buffer,size);
+}
+
+#endif
+
diff --git a/flow/audioioalsa.cc b/flow/audioioalsa.cc
new file mode 100644
index 0000000..303db16
--- /dev/null
+++ b/flow/audioioalsa.cc
@@ -0,0 +1,561 @@
+ /*
+
+ Copyright (C) 2000,2001 Jozef Kosoru
+ jozef.kosoru@pobox.sk
+ (C) 2000,2001 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/**
+ * only compile 'alsa' AudioIO class if configure thinks it is a good idea
+ */
+#ifdef HAVE_LIBASOUND
+
+#ifdef HAVE_ALSA_ASOUNDLIB_H
+#include <alsa/asoundlib.h>
+#elif defined(HAVE_SYS_ASOUNDLIB_H)
+#include <sys/asoundlib.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h> // Needed on some systems.
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <iostream>
+#include <algorithm>
+
+#include "debug.h"
+#include "audioio.h"
+
+namespace Arts {
+
+class AudioIOALSA : public AudioIO {
+protected:
+ int audio_read_fd;
+ int audio_write_fd;
+ int requestedFragmentSize;
+ int requestedFragmentCount;
+
+ enum BufferMode{block, stream};
+ int m_card;
+ int m_device;
+ int m_format;
+ BufferMode m_bufferMode;
+
+ snd_pcm_t *m_pcm_handle;
+ snd_pcm_channel_info_t m_cinfo;
+ snd_pcm_format_t m_cformat;
+ snd_pcm_channel_params_t m_params;
+ snd_pcm_channel_setup_t m_setup;
+
+ int setPcmParams(const int channel);
+ void checkCapabilities();
+
+public:
+ AudioIOALSA();
+
+ void setParam(AudioParam param, int& value);
+ int getParam(AudioParam param);
+
+ bool open();
+ void close();
+ int read(void *buffer, int size);
+ int write(void *buffer, int size);
+};
+
+REGISTER_AUDIO_IO(AudioIOALSA,"alsa","Advanced Linux Sound Architecture");
+};
+
+using namespace std;
+using namespace Arts;
+
+AudioIOALSA::AudioIOALSA()
+{
+ param(samplingRate) = 44100;
+ paramStr(deviceName) = "/dev/dsp"; //!! alsa doesn't need this
+ requestedFragmentSize = param(fragmentSize) = 1024;
+ requestedFragmentCount = param(fragmentCount) = 7;
+ param(channels) = 2;
+ param(direction) = directionWrite;
+
+ /*
+ * default parameters
+ */
+ m_card = snd_defaults_pcm_card(); //!! need interface !!
+ m_device = snd_defaults_pcm_device(); //!!
+#ifdef WORDS_BIGENDIAN
+ m_format = SND_PCM_SFMT_S16_BE;
+#else
+ m_format = SND_PCM_SFMT_S16_LE;
+#endif
+ m_bufferMode = block; //block/stream (stream mode doesn't work yet)
+
+ if(m_card >= 0) {
+ char* cardname = 0;
+
+ if(snd_card_get_name(m_card, &cardname) == 0 && cardname != 0)
+ {
+ //!! thats not what devicename is intended to do
+ //!! devicename is an input information into
+ //!! the "driver", to select which card to use
+ //!! not an output information
+ paramStr(deviceName) = cardname;
+ free(cardname);
+ }
+ }
+}
+
+bool AudioIOALSA::open()
+{
+ string& _error = paramStr(lastError);
+ string& _deviceName = paramStr(deviceName);
+ int& _channels = param(channels);
+ int& _fragmentSize = param(fragmentSize);
+ int& _fragmentCount = param(fragmentCount);
+ int& _samplingRate = param(samplingRate);
+ int& _direction = param(direction);
+ int& _format = param(format);
+
+ /*
+ * initialize format - TODO: implement fallback (i.e. if no format given,
+ * it should try 16bit first, then fall back to 8bit)
+ */
+ switch(_format)
+ {
+ default: _format = 16;
+
+ case 16: // 16bit, signed little endian
+ m_format = SND_PCM_SFMT_S16_LE;
+ break;
+
+ case 17: // 16bit, signed big endian
+ m_format = SND_PCM_SFMT_S16_BE;
+ break;
+
+ case 8: // 8bit, unsigned
+ m_format = SND_PCM_SFMT_U8;
+ break;
+ }
+
+ /* open pcm device */
+ int mode = SND_PCM_OPEN_NONBLOCK;
+
+ if(_direction == directionReadWrite)
+ mode |= SND_PCM_OPEN_DUPLEX;
+ else if(_direction == directionWrite)
+ mode |= SND_PCM_OPEN_PLAYBACK;
+ else
+ {
+ _error = "invalid direction";
+ return false;
+ }
+
+ int err;
+ if((err = snd_pcm_open(&m_pcm_handle, m_card, m_device, mode)) < 0) {
+ _error = "device: ";
+ _error += _deviceName.c_str();
+ _error += " can't be opened (";
+ _error += snd_strerror(err);
+ _error += ")";
+ return false;
+ }
+ else {
+ artsdebug("ALSA driver: %s", _deviceName.c_str());
+ }
+
+ snd_pcm_nonblock_mode(m_pcm_handle, 0);
+
+ /* flush buffers */
+ (void)snd_pcm_capture_flush(m_pcm_handle);
+ if(_direction & directionRead)
+ (void)snd_pcm_channel_flush(m_pcm_handle, SND_PCM_CHANNEL_CAPTURE);
+ if(_direction & directionWrite)
+ (void)snd_pcm_channel_flush(m_pcm_handle, SND_PCM_CHANNEL_PLAYBACK);
+
+ /* check device capabilities */
+ checkCapabilities();
+
+ /* set the fragment settings to what the user requested */
+ _fragmentSize = requestedFragmentSize;
+ _fragmentCount = requestedFragmentCount;
+
+ /* set PCM communication parameters */
+ if((_direction & directionRead) && setPcmParams(SND_PCM_CHANNEL_CAPTURE))
+ return false;
+ if((_direction & directionWrite) && setPcmParams(SND_PCM_CHANNEL_PLAYBACK))
+ return false;
+
+ /* prepare channel */
+ if((_direction & directionRead) &&
+ snd_pcm_channel_prepare(m_pcm_handle, SND_PCM_CHANNEL_CAPTURE) < 0)
+ {
+ _error = "Unable to prepare capture channel!";
+ return false;
+ }
+ if((_direction & directionWrite) &&
+ snd_pcm_channel_prepare(m_pcm_handle, SND_PCM_CHANNEL_PLAYBACK) < 0)
+ {
+ _error = "Unable to prepare playback channel!";
+ return false;
+ }
+
+ /* obtain current PCM setup (may differ from requested one) */
+ (void)memset(&m_setup, 0, sizeof(m_setup));
+
+ m_setup.channel = SND_PCM_CHANNEL_PLAYBACK;
+ if(snd_pcm_channel_setup(m_pcm_handle, &m_setup) < 0) {
+ _error = "Unable to obtain channel setup!";
+ return false;
+ }
+
+ /* check samplerate */
+ const int tolerance = _samplingRate/10+1000;
+ if(abs(m_setup.format.rate-_samplingRate) > tolerance)
+ {
+ _error = "Can't set requested sampling rate!";
+ char details[80];
+ sprintf(details," (requested rate %d, got rate %d)",
+ _samplingRate, m_setup.format.rate);
+ _error += details;
+ return false;
+ }
+ _samplingRate = m_setup.format.rate;
+
+ /* check format */
+ if(m_setup.format.format != m_format) {
+ _error = "Can't set requested format:";
+ _error += snd_pcm_get_format_name(m_format);
+ return false;
+ }
+
+ /* check voices */
+ if(m_setup.format.voices != _channels) {
+ _error = "Audio device doesn't support number of requested channels!";
+ return false;
+ }
+
+ /* update fragment settings with what we got */
+ switch(m_bufferMode) {
+ case block:
+ _fragmentSize = m_setup.buf.block.frag_size;
+ _fragmentCount = m_setup.buf.block.frags_max-1;
+ break;
+ case stream:
+ _fragmentSize = m_setup.buf.stream.queue_size;
+ _fragmentCount = 1;
+ break;
+ }
+
+ artsdebug("buffering: %d fragments with %d bytes "
+ "(audio latency is %1.1f ms)", _fragmentCount, _fragmentSize,
+ (float)(_fragmentSize*_fragmentCount) /
+ (float)(2.0 * _samplingRate * _channels)*1000.0);
+
+ /* obtain PCM file descriptor(s) */
+ audio_read_fd = audio_write_fd = -1;
+
+ if(_direction & directionRead)
+ audio_read_fd = snd_pcm_file_descriptor(m_pcm_handle,
+ SND_PCM_CHANNEL_CAPTURE);
+ if(_direction & directionWrite)
+ audio_write_fd = snd_pcm_file_descriptor(m_pcm_handle,
+ SND_PCM_CHANNEL_PLAYBACK);
+
+ /* start recording */
+ if((_direction & directionRead) && snd_pcm_capture_go(m_pcm_handle)) {
+ _error = "Can't start recording!";
+ return false;
+ }
+
+ return true;
+}
+
+void AudioIOALSA::close()
+{
+ int& _direction = param(direction);
+ if(_direction & directionRead)
+ (void)snd_pcm_channel_flush(m_pcm_handle, SND_PCM_CHANNEL_CAPTURE);
+ if(_direction & directionWrite)
+ (void)snd_pcm_channel_flush(m_pcm_handle, SND_PCM_CHANNEL_PLAYBACK);
+ (void)snd_pcm_close(m_pcm_handle);
+}
+
+void AudioIOALSA::setParam(AudioParam p, int& value)
+{
+ switch(p)
+ {
+ case fragmentSize:
+ param(p) = requestedFragmentSize = value;
+ break;
+ case fragmentCount:
+ param(p) = requestedFragmentCount = value;
+ break;
+ default:
+ param(p) = value;
+ break;
+ }
+}
+
+int AudioIOALSA::getParam(AudioParam p)
+{
+ snd_pcm_channel_status_t status;
+ (void)memset(&status, 0, sizeof(status));
+
+ switch(p)
+ {
+ case canRead:
+ status.channel = SND_PCM_CHANNEL_CAPTURE;
+ if(snd_pcm_channel_status(m_pcm_handle, &status) < 0) {
+ arts_warning("Capture channel status error!");
+ return -1;
+ }
+ return status.free;
+ break;
+
+ case canWrite:
+ status.channel = SND_PCM_CHANNEL_PLAYBACK;
+ if(snd_pcm_channel_status(m_pcm_handle, &status) < 0) {
+ arts_warning("Playback channel status error!");
+ return -1;
+ }
+ return status.free;
+ break;
+
+ case selectReadFD:
+ return audio_read_fd;
+ break;
+
+ case selectWriteFD:
+ return audio_write_fd;
+ break;
+
+ case autoDetect:
+ /*
+ * that the ALSA driver could be compiled doesn't say anything
+ * about whether it will work (the user might be using an OSS
+ * kernel driver) so we'll use a value less than the OSS one
+ * here, because OSS will most certainly work (ALSA's OSS emu)
+ */
+ return 5;
+ break;
+
+ default:
+ return param(p);
+ break;
+ }
+}
+
+int AudioIOALSA::read(void *buffer, int size)
+{
+ int length;
+ do {
+ length = snd_pcm_read(m_pcm_handle, buffer, size);
+ } while (length == -EINTR);
+ if(length == -EPIPE) {
+ snd_pcm_channel_status_t status;
+ (void)memset(&status, 0, sizeof(status));
+ status.channel = SND_PCM_CHANNEL_CAPTURE;
+ if(snd_pcm_channel_status(m_pcm_handle, &status) < 0) {
+ arts_info("Capture channel status error!");
+ return -1;
+ }
+ else if(status.status == SND_PCM_STATUS_RUNNING) {
+ length = 0;
+ }
+ else if(status.status == SND_PCM_STATUS_OVERRUN) {
+ artsdebug("Overrun at position: %d" ,status.scount);
+ if(snd_pcm_channel_prepare(m_pcm_handle, SND_PCM_CHANNEL_CAPTURE)<0)
+ {
+ arts_info("Overrun: capture prepare error!");
+ return -1;
+ }
+ length = 0;
+ }
+ else {
+ arts_info("Unknown capture error!");
+ return -1;
+ }
+ }
+ else if(length < 0) {
+ arts_info("Capture error: %s", snd_strerror(length));
+ return -1;
+ }
+ return length;
+}
+
+int AudioIOALSA::write(void *buffer, int size)
+{
+ int length;
+ while((length = snd_pcm_write(m_pcm_handle, buffer, size)) != size) {
+ if (length == -EINTR)
+ continue; // Try again
+ snd_pcm_channel_status_t status;
+ (void)memset(&status, 0, sizeof(status));
+ status.channel = SND_PCM_CHANNEL_PLAYBACK;
+
+ if(snd_pcm_channel_status(m_pcm_handle, &status) < 0) {
+ arts_warning("Playback channel status error!");
+ return -1;
+ }
+ else if(status.status == SND_PCM_STATUS_UNDERRUN) {
+ artsdebug("Underrun at position: %d", status.scount);
+ if(snd_pcm_channel_prepare(m_pcm_handle, SND_PCM_CHANNEL_PLAYBACK)
+ < 0) {
+ arts_warning("Underrun: playback prepare error!");
+ return -1;
+ }
+ }
+ else {
+ arts_warning("Unknown playback error!");
+ return -1;
+ }
+ }
+ return size;
+}
+
+int AudioIOALSA::setPcmParams(const int channel)
+{
+ int &_samplingRate = param(samplingRate);
+ int &_channels = param(channels);
+ int &_fragmentSize = param(fragmentSize);
+ int &_fragmentCount = param(fragmentCount);
+
+ (void)memset(&m_cformat, 0, sizeof(m_cformat));
+ m_cformat.interleave = 1;
+ m_cformat.format = m_format;
+ m_cformat.rate = _samplingRate;
+ m_cformat.voices = _channels;
+
+ (void)memset(&m_params, 0, sizeof(m_params));
+ switch(m_bufferMode){
+ case stream:
+ m_params.mode=SND_PCM_MODE_STREAM;
+ break;
+ case block:
+ m_params.mode=SND_PCM_MODE_BLOCK;
+ break;
+ }
+ m_params.channel=channel;
+ (void)memcpy(&m_params.format, &m_cformat, sizeof(m_cformat));
+ if(channel==SND_PCM_CHANNEL_CAPTURE){
+ m_params.start_mode=SND_PCM_START_GO;
+ m_params.stop_mode=SND_PCM_STOP_ROLLOVER;
+ }
+ else{ //SND_PCM_CHANNEL_PLAYBACK
+ m_params.start_mode= (m_bufferMode==block) ? SND_PCM_START_FULL : SND_PCM_START_DATA;
+ m_params.stop_mode=SND_PCM_STOP_ROLLOVER; // SND_PCM_STOP_STOP
+ //use this ^^^ if you want to track underruns
+ }
+
+ switch(m_bufferMode){
+ case stream:
+ m_params.buf.stream.queue_size=1024*1024; //_fragmentSize*_fragmentCount;
+ m_params.buf.stream.fill=SND_PCM_FILL_SILENCE_WHOLE;
+ m_params.buf.stream.max_fill=1024;
+ break;
+ case block:
+ m_params.buf.block.frag_size=_fragmentSize;
+ if(channel==SND_PCM_CHANNEL_CAPTURE){
+ m_params.buf.block.frags_max=1;
+ m_params.buf.block.frags_min=1;
+ }
+ else{ //SND_PCM_CHANNEL_PLAYBACK
+ m_params.buf.block.frags_max=_fragmentCount+1;
+ m_params.buf.block.frags_min=1;
+ }
+ }
+ if(snd_pcm_channel_params(m_pcm_handle, &m_params)<0){
+ paramStr(lastError) = "Unable to set channel params!";
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
+void AudioIOALSA::checkCapabilities()
+{
+ snd_pcm_info_t info;
+ (void)memset(&info, 0, sizeof(info));
+ if(!snd_pcm_info(m_pcm_handle, &info)) {
+ string flags = "";
+ if(info.flags & SND_PCM_INFO_PLAYBACK) flags += "playback ";
+ if(info.flags & SND_PCM_INFO_CAPTURE) flags += "capture ";
+ if(info.flags & SND_PCM_INFO_DUPLEX) flags += "duplex ";
+ if(info.flags & SND_PCM_INFO_DUPLEX_RATE) flags += "duplex_rate ";
+ artsdebug(" type:%d id:%s\n"
+ " flags:%s\n"
+ " playback_subdevices:%d capture_subdevices:%d",
+ info.type, info.id,
+ flags.c_str(),
+ info.playback+1, info.capture+1);
+ }
+ else {
+ arts_warning("Can't get device info!"); //not fatal error
+ }
+
+ (void)memset(&m_cinfo, 0, sizeof(m_cinfo));
+ m_cinfo.channel = SND_PCM_CHANNEL_PLAYBACK;
+ if(!snd_pcm_channel_info(m_pcm_handle, &m_cinfo)) {
+ string flags = "";
+ if(m_cinfo.flags & SND_PCM_CHNINFO_MMAP) flags += "mmap ";
+ if(m_cinfo.flags & SND_PCM_CHNINFO_STREAM) flags += "stream ";
+ if(m_cinfo.flags & SND_PCM_CHNINFO_BLOCK) flags += "block ";
+ if(m_cinfo.flags & SND_PCM_CHNINFO_BATCH) flags += "batch ";
+ if(m_cinfo.flags & SND_PCM_CHNINFO_INTERLEAVE) flags += "interleave ";
+ if(m_cinfo.flags & SND_PCM_CHNINFO_NONINTERLEAVE) flags += "noninterleave ";
+ if(m_cinfo.flags & SND_PCM_CHNINFO_BLOCK_TRANSFER) flags += "block_transfer ";
+ if(m_cinfo.flags & SND_PCM_CHNINFO_OVERRANGE) flags += "overrange ";
+ if(m_cinfo.flags & SND_PCM_CHNINFO_MMAP_VALID) flags += "mmap_valid ";
+ if(m_cinfo.flags & SND_PCM_CHNINFO_PAUSE) flags += "pause ";
+
+ artsdebug(" subdevice:%d\n"
+ " flags:%s\n"
+ " min_rate:%d max_rate:%d\n"
+ " buffer_size:%d min_fragment_size:%d max_fragment_size:%d\n"
+ " fragment_align:%d fifo_size:%d transfer_block_size:%d\n"
+ " mmap_size:%d",
+ m_cinfo.subdevice,
+ flags.c_str(),
+ m_cinfo.min_rate, m_cinfo.max_rate,
+ m_cinfo.buffer_size, m_cinfo.min_fragment_size, m_cinfo.max_fragment_size,
+ m_cinfo.fragment_align, m_cinfo.fifo_size, m_cinfo.transfer_block_size,
+ m_cinfo.mmap_size);
+ }
+ else {
+ arts_warning("Can't get channel info!"); //not fatal error
+ }
+}
+
+#endif /* HAVE_LIBASOUND */
diff --git a/flow/audioioalsa9.cc b/flow/audioioalsa9.cc
new file mode 100644
index 0000000..8367da6
--- /dev/null
+++ b/flow/audioioalsa9.cc
@@ -0,0 +1,590 @@
+ /*
+
+ Copyright (C) 2001 Takashi Iwai <tiwai@suse.de>
+ Copyright (C) 2004 Allan Sandfeld Jensen <kde@carewolf.com>
+
+ based on audioalsa.cc:
+ Copyright (C) 2000,2001 Jozef Kosoru
+ jozef.kosoru@pobox.sk
+ (C) 2000,2001 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/**
+ * only compile 'alsa' AudioIO class if configure thinks it is a good idea
+ */
+#ifdef HAVE_LIBASOUND2
+
+#ifdef HAVE_ALSA_ASOUNDLIB_H
+#include <alsa/asoundlib.h>
+#elif defined(HAVE_SYS_ASOUNDLIB_H)
+#include <sys/asoundlib.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <iostream>
+#include <algorithm>
+
+#include "debug.h"
+#include "audioio.h"
+#include "audiosubsys.h"
+#include "dispatcher.h"
+#include "iomanager.h"
+
+namespace Arts {
+
+class AudioIOALSA : public AudioIO, public IONotify {
+protected:
+ // List of file descriptors
+ struct poll_descriptors {
+ poll_descriptors() : nfds(0), pfds(0) {};
+ int nfds;
+ struct pollfd *pfds;
+ } audio_write_pds, audio_read_pds;
+
+ snd_pcm_t *m_pcm_playback;
+ snd_pcm_t *m_pcm_capture;
+ snd_pcm_format_t m_format;
+ int m_period_size, m_periods;
+
+ void startIO();
+ int setPcmParams(snd_pcm_t *pcm);
+ static int poll2iomanager(int pollTypes);
+ static int iomanager2poll(int ioTypes);
+ void getDescriptors(snd_pcm_t *pcm, poll_descriptors *pds);
+ void watchDescriptors(poll_descriptors *pds);
+
+ void notifyIO(int fd, int types);
+
+ int xrun(snd_pcm_t *pcm);
+#ifdef HAVE_SND_PCM_RESUME
+ int resume(snd_pcm_t *pcm);
+#endif
+
+public:
+ AudioIOALSA();
+
+ void setParam(AudioParam param, int& value);
+ int getParam(AudioParam param);
+
+ bool open();
+ void close();
+ int read(void *buffer, int size);
+ int write(void *buffer, int size);
+};
+
+REGISTER_AUDIO_IO(AudioIOALSA,"alsa","Advanced Linux Sound Architecture");
+}
+
+using namespace std;
+using namespace Arts;
+
+AudioIOALSA::AudioIOALSA()
+{
+ param(samplingRate) = 44100;
+ paramStr(deviceName) = "default"; // ALSA pcm device name - not file name
+ param(fragmentSize) = 1024;
+ param(fragmentCount) = 7;
+ param(channels) = 2;
+ param(direction) = directionWrite;
+ param(format) = 16;
+ /*
+ * default parameters
+ */
+ m_format = SND_PCM_FORMAT_S16_LE;
+ m_pcm_playback = NULL;
+ m_pcm_capture = NULL;
+}
+
+bool AudioIOALSA::open()
+{
+ string& _error = paramStr(lastError);
+ string& _deviceName = paramStr(deviceName);
+ int& _channels = param(channels);
+ int& _fragmentSize = param(fragmentSize);
+ int& _fragmentCount = param(fragmentCount);
+ int& _samplingRate = param(samplingRate);
+ int& _direction = param(direction);
+ int& _format = param(format);
+
+ m_pcm_playback = NULL;
+ m_pcm_capture = NULL;
+
+ /* initialize format */
+ switch(_format) {
+ case 16: // 16bit, signed little endian
+ m_format = SND_PCM_FORMAT_S16_LE;
+ break;
+ case 17: // 16bit, signed big endian
+ m_format = SND_PCM_FORMAT_S16_BE;
+ break;
+ case 8: // 8bit, unsigned
+ m_format = SND_PCM_FORMAT_U8;
+ break;
+ default: // test later
+ m_format = SND_PCM_FORMAT_UNKNOWN;
+ break;
+ }
+
+ /* open pcm device */
+ int err;
+ if (_direction & directionWrite) {
+ if ((err = snd_pcm_open(&m_pcm_playback, _deviceName.c_str(),
+ SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK)) < 0) {
+ _error = "device: ";
+ _error += _deviceName.c_str();
+ _error += " can't be opened for playback (";
+ _error += snd_strerror(err);
+ _error += ")";
+ return false;
+ }
+ snd_pcm_nonblock(m_pcm_playback, 0);
+ }
+ if (_direction & directionRead) {
+ if ((err = snd_pcm_open(&m_pcm_capture, _deviceName.c_str(),
+ SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK)) < 0) {
+ _error = "device: ";
+ _error += _deviceName.c_str();
+ _error += " can't be opened for capture (";
+ _error += snd_strerror(err);
+ _error += ")";
+ snd_pcm_close(m_pcm_playback);
+ return false;
+ }
+ snd_pcm_nonblock(m_pcm_capture, 0);
+ }
+
+ artsdebug("ALSA driver: %s", _deviceName.c_str());
+
+ /* check device capabilities */
+ // checkCapabilities();
+
+ /* set PCM communication parameters */
+ if (((_direction & directionWrite) && setPcmParams(m_pcm_playback)) ||
+ ((_direction & directionRead) && setPcmParams(m_pcm_capture))) {
+ snd_pcm_close(m_pcm_playback);
+ snd_pcm_close(m_pcm_capture);
+ return false;
+ }
+
+ artsdebug("buffering: %d fragments with %d bytes "
+ "(audio latency is %1.1f ms)", _fragmentCount, _fragmentSize,
+ (float)(_fragmentSize*_fragmentCount) /
+ (float)(2.0 * _samplingRate * _channels)*1000.0);
+
+
+ startIO();
+ /* restore the format value */
+ switch (m_format) {
+ case SND_PCM_FORMAT_S16_LE:
+ _format = 16;
+ break;
+ case SND_PCM_FORMAT_S16_BE:
+ _format = 17;
+ break;
+ case SND_PCM_FORMAT_U8:
+ _format = 8;
+ break;
+ default:
+ _error = "Unknown PCM format";
+ return false;
+ }
+
+ /* start recording */
+ if (_direction & directionRead)
+ snd_pcm_start(m_pcm_capture);
+
+ return true;
+}
+
+void AudioIOALSA::close()
+{
+ arts_debug("Closing ALSA-driver");
+ int& _direction = param(direction);
+ if ((_direction & directionRead) && m_pcm_capture) {
+ (void)snd_pcm_drop(m_pcm_capture);
+ (void)snd_pcm_close(m_pcm_capture);
+ m_pcm_capture = NULL;
+ }
+ if ((_direction & directionWrite) && m_pcm_playback) {
+ (void)snd_pcm_drop(m_pcm_playback);
+ (void)snd_pcm_close(m_pcm_playback);
+ m_pcm_playback = NULL;
+ }
+ Dispatcher::the()->ioManager()->remove(this, IOType::all);
+
+ delete[] audio_read_pds.pfds;
+ delete[] audio_write_pds.pfds;
+ audio_read_pds.pfds = NULL; audio_write_pds.pfds = NULL;
+ audio_read_pds.nfds = 0; audio_write_pds.nfds = 0;
+}
+
+void AudioIOALSA::setParam(AudioParam p, int& value)
+{
+ param(p) = value;
+ if (m_pcm_playback != NULL) {
+ setPcmParams(m_pcm_playback);
+ }
+ if (m_pcm_capture != NULL) {
+ setPcmParams(m_pcm_capture);
+ }
+}
+
+int AudioIOALSA::getParam(AudioParam p)
+{
+ snd_pcm_sframes_t avail;
+ switch(p) {
+
+ case canRead:
+ if (! m_pcm_capture) return -1;
+ while ((avail = snd_pcm_avail_update(m_pcm_capture)) < 0) {
+ if (avail == -EPIPE)
+ avail = xrun(m_pcm_capture);
+#ifdef HAVE_SND_PCM_RESUME
+ else if (avail == -ESTRPIPE)
+ avail = resume(m_pcm_capture);
+#endif
+ if (avail < 0) {
+ arts_info("Capture error: %s", snd_strerror(avail));
+ return -1;
+ }
+ }
+ return snd_pcm_frames_to_bytes(m_pcm_capture, avail);
+
+ case canWrite:
+ if (! m_pcm_playback) return -1;
+ while ((avail = snd_pcm_avail_update(m_pcm_playback)) < 0) {
+ if (avail == -EPIPE)
+ avail = xrun(m_pcm_playback);
+#ifdef HAVE_SND_PCM_RESUME
+ else if (avail == -ESTRPIPE)
+ avail = resume(m_pcm_playback);
+#endif
+ if (avail < 0) {
+ arts_info("Playback error: %s", snd_strerror(avail));
+ return -1;
+ }
+ }
+ return snd_pcm_frames_to_bytes(m_pcm_playback, avail);
+
+ case selectReadFD:
+ return -1;
+
+ case selectWriteFD:
+ return -1;
+
+ case autoDetect:
+ {
+ /*
+ * that the ALSA driver could be compiled doesn't say anything
+ * about whether it will work (the user might be using an OSS
+ * kernel driver).
+ * If we can open the device, it'll work - and we'll have to use
+ * a higher number than OSS to avoid buggy OSS emulation being used.
+ */
+ int card = -1;
+ if (snd_card_next(&card) < 0 || card < 0) {
+ // No ALSA drivers in use...
+ return 0;
+ }
+ return 15;
+ }
+
+ default:
+ return param(p);
+ }
+}
+
+void AudioIOALSA::startIO()
+{
+ /* get & watch PCM file descriptor(s) */
+ if (m_pcm_playback) {
+ getDescriptors(m_pcm_playback, &audio_write_pds);
+ watchDescriptors(&audio_write_pds);
+ }
+ if (m_pcm_capture) {
+ getDescriptors(m_pcm_capture, &audio_read_pds);
+ watchDescriptors(&audio_read_pds);
+ }
+
+}
+
+int AudioIOALSA::poll2iomanager(int pollTypes)
+{
+ int types = 0;
+
+ if(pollTypes & POLLIN)
+ types |= IOType::read;
+ if(pollTypes & POLLOUT)
+ types |= IOType::write;
+ if(pollTypes & POLLERR)
+ types |= IOType::except;
+
+ return types;
+}
+
+int AudioIOALSA::iomanager2poll(int ioTypes)
+{
+ int types = 0;
+
+ if(ioTypes & IOType::read)
+ types |= POLLIN;
+ if(ioTypes & IOType::write)
+ types |= POLLOUT;
+ if(ioTypes & IOType::except)
+ types |= POLLERR;
+
+ return types;
+}
+
+void AudioIOALSA::getDescriptors(snd_pcm_t *pcm, poll_descriptors *pds)
+{
+ pds->nfds = snd_pcm_poll_descriptors_count(pcm);
+ pds->pfds = new struct pollfd[pds->nfds];
+
+ if (snd_pcm_poll_descriptors(pcm, pds->pfds, pds->nfds) != pds->nfds) {
+ arts_info("Cannot get poll descriptor(s)\n");
+ }
+
+}
+
+void AudioIOALSA::watchDescriptors(poll_descriptors *pds)
+{
+ for(int i=0; i<pds->nfds; i++) {
+ // Check in which direction this handle is supposed to be watched
+ int types = poll2iomanager(pds->pfds[i].events);
+ Dispatcher::the()->ioManager()->watchFD(pds->pfds[i].fd, types, this);
+ }
+}
+
+int AudioIOALSA::xrun(snd_pcm_t *pcm)
+{
+ int err;
+ artsdebug("xrun!!\n");
+ if ((err = snd_pcm_prepare(pcm)) < 0)
+ return err;
+ if (pcm == m_pcm_capture)
+ snd_pcm_start(pcm); // ignore error here..
+ return 0;
+}
+
+#ifdef HAVE_SND_PCM_RESUME
+int AudioIOALSA::resume(snd_pcm_t *pcm)
+{
+ int err;
+ artsdebug("resume!\n");
+ while ((err = snd_pcm_resume(pcm)) == -EAGAIN)
+ sleep(1); /* wait until suspend flag is not released */
+ if (err < 0) {
+ if ((err = snd_pcm_prepare(pcm)) < 0)
+ return err;
+ if (pcm == m_pcm_capture)
+ snd_pcm_start(pcm); // ignore error here..
+ }
+ return 0;
+}
+#endif
+
+int AudioIOALSA::read(void *buffer, int size)
+{
+ int frames = snd_pcm_bytes_to_frames(m_pcm_capture, size);
+ int length;
+ while ((length = snd_pcm_readi(m_pcm_capture, buffer, frames)) < 0) {
+ if (length == -EINTR)
+ continue; // Try again
+ else if (length == -EPIPE)
+ length = xrun(m_pcm_capture);
+#ifdef HAVE_SND_PCM_RESUME
+ else if (length == -ESTRPIPE)
+ length = resume(m_pcm_capture);
+#endif
+ if (length < 0) {
+ arts_info("Capture error: %s", snd_strerror(length));
+ return -1;
+ }
+ }
+ return snd_pcm_frames_to_bytes(m_pcm_capture, length);
+}
+
+int AudioIOALSA::write(void *buffer, int size)
+{
+ int frames = snd_pcm_bytes_to_frames(m_pcm_playback, size);
+ int length;
+ while ((length = snd_pcm_writei(m_pcm_playback, buffer, frames)) < 0) {
+ if (length == -EINTR)
+ continue; // Try again
+ else if (length == -EPIPE)
+ length = xrun(m_pcm_playback);
+#ifdef HAVE_SND_PCM_RESUME
+ else if (length == -ESTRPIPE)
+ length = resume(m_pcm_playback);
+#endif
+ if (length < 0) {
+ arts_info("Playback error: %s", snd_strerror(length));
+ return -1;
+ }
+ }
+
+ // Start the sink if it needs it
+ if (snd_pcm_state( m_pcm_playback ) == SND_PCM_STATE_PREPARED)
+ snd_pcm_start(m_pcm_playback);
+
+ if (length == frames) // Sometimes the fragments are "odd" in alsa
+ return size;
+ else
+ return snd_pcm_frames_to_bytes(m_pcm_playback, length);
+}
+
+void AudioIOALSA::notifyIO(int fd, int type)
+{
+ int todo = 0;
+
+ // Translate from iomanager-types to poll-types,
+ // inorder to fake a snd_pcm_poll_descriptors_revents call.
+ if(m_pcm_playback) {
+ for(int i=0; i < audio_write_pds.nfds; i++) {
+ if(fd == audio_write_pds.pfds[i].fd) {
+ audio_write_pds.pfds[i].revents = iomanager2poll(type);
+ todo |= AudioSubSystem::ioWrite;
+ }
+ }
+ if (todo & AudioSubSystem::ioWrite) {
+ unsigned short revents;
+ snd_pcm_poll_descriptors_revents(m_pcm_playback,
+ audio_write_pds.pfds,
+ audio_write_pds.nfds,
+ &revents);
+ if (! (revents & POLLOUT)) todo &= ~AudioSubSystem::ioWrite;
+ }
+ }
+ if(m_pcm_capture) {
+ for(int i=0; i < audio_read_pds.nfds; i++) {
+ if(fd == audio_read_pds.pfds[i].fd) {
+ audio_read_pds.pfds[i].revents = iomanager2poll(type);
+ todo |= AudioSubSystem::ioRead;
+ }
+ }
+ if (todo & AudioSubSystem::ioRead) {
+ unsigned short revents;
+ snd_pcm_poll_descriptors_revents(m_pcm_capture,
+ audio_read_pds.pfds,
+ audio_read_pds.nfds,
+ &revents);
+ if (! (revents & POLLIN)) todo &= ~AudioSubSystem::ioRead;
+ }
+ }
+
+ if (type & IOType::except) todo |= AudioSubSystem::ioExcept;
+
+ if (todo != 0) AudioSubSystem::the()->handleIO(todo);
+}
+
+int AudioIOALSA::setPcmParams(snd_pcm_t *pcm)
+{
+ int &_samplingRate = param(samplingRate);
+ int &_channels = param(channels);
+ int &_fragmentSize = param(fragmentSize);
+ int &_fragmentCount = param(fragmentCount);
+ string& _error = paramStr(lastError);
+
+ snd_pcm_hw_params_t *hw;
+ snd_pcm_hw_params_alloca(&hw);
+ snd_pcm_hw_params_any(pcm, hw);
+
+ if (snd_pcm_hw_params_set_access(pcm, hw, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
+ _error = "Unable to set interleaved!";
+ return 1;
+ }
+ if (m_format == SND_PCM_FORMAT_UNKNOWN) {
+ // test the available formats
+ // try 16bit first, then fall back to 8bit
+ if (! snd_pcm_hw_params_test_format(pcm, hw, SND_PCM_FORMAT_S16_LE))
+ m_format = SND_PCM_FORMAT_S16_LE;
+ else if (! snd_pcm_hw_params_test_format(pcm, hw, SND_PCM_FORMAT_S16_BE))
+ m_format = SND_PCM_FORMAT_S16_BE;
+ else if (! snd_pcm_hw_params_test_format(pcm, hw, SND_PCM_FORMAT_U8))
+ m_format = SND_PCM_FORMAT_U8;
+ else
+ m_format = SND_PCM_FORMAT_UNKNOWN;
+ }
+ if (snd_pcm_hw_params_set_format(pcm, hw, m_format) < 0) {
+ _error = "Unable to set format!";
+ return 1;
+ }
+
+ unsigned int rate = snd_pcm_hw_params_set_rate_near(pcm, hw, _samplingRate, 0);
+ const unsigned int tolerance = _samplingRate/10+1000;
+ if (abs((int)rate - (int)_samplingRate) > (int)tolerance) {
+ _error = "Can't set requested sampling rate!";
+ char details[80];
+ sprintf(details," (requested rate %d, got rate %d)",
+ _samplingRate, rate);
+ _error += details;
+ return 1;
+ }
+ _samplingRate = rate;
+
+ if (snd_pcm_hw_params_set_channels(pcm, hw, _channels) < 0) {
+ _error = "Unable to set channels!";
+ return 1;
+ }
+
+ m_period_size = _fragmentSize;
+ if (m_format != SND_PCM_FORMAT_U8)
+ m_period_size <<= 1;
+ if (_channels > 1)
+ m_period_size /= _channels;
+ if ((m_period_size = snd_pcm_hw_params_set_period_size_near(pcm, hw, m_period_size, 0)) < 0) {
+ _error = "Unable to set period size!";
+ return 1;
+ }
+ m_periods = _fragmentCount;
+ if ((m_periods = snd_pcm_hw_params_set_periods_near(pcm, hw, m_periods, 0)) < 0) {
+ _error = "Unable to set periods!";
+ return 1;
+ }
+
+ if (snd_pcm_hw_params(pcm, hw) < 0) {
+ _error = "Unable to set hw params!";
+ return 1;
+ }
+
+ _fragmentSize = m_period_size;
+ _fragmentCount = m_periods;
+ if (m_format != SND_PCM_FORMAT_U8)
+ _fragmentSize >>= 1;
+ if (_channels > 1)
+ _fragmentSize *= _channels;
+
+ return 0; // ok, we're ready..
+}
+
+#endif /* HAVE_LIBASOUND2 */
diff --git a/flow/audioiocsl.cc b/flow/audioiocsl.cc
new file mode 100644
index 0000000..9a9b44e
--- /dev/null
+++ b/flow/audioiocsl.cc
@@ -0,0 +1,640 @@
+ /*
+
+ Copyright (C) 2000-2002 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/**
+ * only compile 'csl' AudioIO class if libcsl is present
+ */
+#ifdef HAVE_LIBCSL
+#include <csl/csl.h>
+
+/* g_newa */
+#include <gsl/gsldefs.h>
+
+#include <vector>
+
+#include "audioio.h"
+#include "audiosubsys.h"
+#include "debug.h"
+#include "dispatcher.h"
+#include "iomanager.h"
+
+namespace Arts {
+
+class AudioIOCSL : public AudioIO,
+ public IONotify
+{
+protected:
+ CslPcmStream *inputStream, *outputStream;
+ CslDriver *cslDriver;
+ int requestedFragmentSize;
+ int requestedFragmentCount;
+ const char *cslDriverName;
+
+ std::vector<CslPollFD> cslFds, cslOldFds;
+ int csl2iomanager(int cslTypes);
+ void updateFds();
+
+ void notifyIO(int fd, int types);
+ static void handleRead(void *user_data, CslPcmStream *stream);
+ static void handleWrite(void *user_data, CslPcmStream *stream);
+
+public:
+ AudioIOCSL(const char *driverName = 0);
+
+ void setParam(AudioParam param, int& value);
+ int getParam(AudioParam param);
+
+ bool open();
+ void close();
+ int read(void *buffer, int size);
+ int write(void *buffer, int size);
+};
+
+REGISTER_AUDIO_IO(AudioIOCSL,"csl","Common Sound Layer");
+
+class AudioIOCSLFactory : public AudioIOFactory {
+protected:
+ const char *driverName;
+ std::string _name;
+ std::string _fullName;
+
+public:
+ AudioIOCSLFactory(const char *driverName)
+ : driverName(driverName)
+ {
+ _name = "csl-";
+ _name += driverName;
+
+ _fullName = "Common Sound Layer (";
+ _fullName += driverName;
+ _fullName += ")";
+ }
+ virtual ~AudioIOCSLFactory()
+ {
+ }
+ AudioIO *createAudioIO() { return new AudioIOCSL(driverName); }
+ virtual const char *name() { return _name.c_str(); }
+ virtual const char *fullName() { return _fullName.c_str(); }
+};
+
+static class AudioIOCSLInit {
+protected:
+ std::list<AudioIOCSLFactory *> factories;
+
+public:
+ AudioIOCSLInit()
+ {
+ unsigned int i,n;
+ const char **drivers = csl_list_drivers(&n);
+
+ for(i = 0; i < n; i++)
+ factories.push_back(new AudioIOCSLFactory(drivers[i]));
+ }
+ ~AudioIOCSLInit()
+ {
+ std::list<AudioIOCSLFactory *>::iterator i;
+ for(i = factories.begin(); i != factories.end(); i++)
+ delete (*i);
+
+ factories.clear();
+ }
+} aci;
+
+};
+
+using namespace std;
+using namespace Arts;
+
+AudioIOCSL::AudioIOCSL(const char *driverName)
+ : cslDriverName(driverName)
+{
+ /*
+ * default parameters
+ */
+ param(samplingRate) = 44100;
+ paramStr(deviceName) = "todo";
+ requestedFragmentSize = param(fragmentSize) = 1024;
+ requestedFragmentCount = param(fragmentCount) = 7;
+ param(channels) = 2;
+ param(direction) = 2;
+
+#ifdef WORDS_BIGENDIAN
+ param(format) = 17;
+#else
+ param(format) = 16;
+#endif
+}
+
+bool AudioIOCSL::open()
+{
+ string& errorMsg = paramStr(lastError);
+ string& _deviceName = paramStr(deviceName);
+ int& _channels = param(channels);
+ int& _fragmentSize = param(fragmentSize);
+ int& _fragmentCount = param(fragmentCount);
+ int& _samplingRate = param(samplingRate);
+ int& _format = param(format);
+ int fmt = 0;
+ char *env = 0;
+
+ if(cslDriverName && strcmp(cslDriverName, "arts") == 0)
+ env = arts_strdup_printf("ARTS_SERVER=%s",_deviceName.c_str());
+
+ if(env)
+ {
+ putenv(env);
+ arts_debug("AudioIOCsl: set %s\n",env);
+ }
+
+ CslErrorType error;
+ error = csl_driver_init(cslDriverName, &cslDriver); /* choose backend */
+
+ if(env)
+ {
+ putenv("ARTS_SERVER");
+ free(env);
+ }
+
+ if (error)
+ {
+ errorMsg = "unable to initialize CSL driver: ";
+ errorMsg += csl_strerror(error);
+ return false;
+ }
+
+ if(_format == 8)
+ fmt = CSL_PCM_FORMAT_U8;
+ else if(_format == 16)
+ fmt = CSL_PCM_FORMAT_S16_LE;
+ else if(_format == 17)
+ fmt = CSL_PCM_FORMAT_S16_BE;
+
+ inputStream = outputStream = 0;
+ if(param(direction) & directionRead)
+ {
+ /* open PCM output stream */
+ error = csl_pcm_open_output(cslDriver,
+ "artsd output",
+ _samplingRate,
+ _channels,
+ fmt, &inputStream);
+ if (error)
+ {
+ errorMsg = "failed to open CSL input stream: ";
+ errorMsg += csl_strerror(error);
+ return false;
+ }
+ csl_pcm_set_callback(inputStream, handleRead, 0, 0);
+ }
+ if(param(direction) & directionWrite)
+ {
+ /* open PCM output stream */
+ error = csl_pcm_open_output(cslDriver,
+ "artsd output",
+ _samplingRate,
+ _channels,
+ fmt, &outputStream);
+ if (error)
+ {
+ close();
+
+ errorMsg = "failed to open CSL output stream: ";
+ errorMsg += csl_strerror(error);
+ return false;
+ }
+ csl_pcm_set_callback(outputStream, handleWrite, 0, 0);
+ }
+#if 0
+ if (_format && (ossBits(gotFormat) != ossBits(requestedFormat)))
+ {
+ char details[80];
+ sprintf(details," (_format = %d, asked driver to give %d, got %d)",
+ _format, requestedFormat, gotFormat);
+
+ _error = "Can't set playback format";
+ _error += details;
+
+ close();
+ return false;
+ }
+
+ if(gotFormat == AFMT_U8)
+ _format = 8;
+ else if(gotFormat == AFMT_S16_LE)
+ _format = 16;
+ else if(gotFormat == AFMT_S16_BE)
+ _format = 17;
+ else
+ {
+ char details[80];
+ sprintf(details," (_format = %d, asked driver to give %d, got %d)",
+ _format, requestedFormat, gotFormat);
+
+ _error = "unknown format given by driver";
+ _error += details;
+
+ close();
+ return false;
+ }
+
+
+ int stereo=-1; /* 0=mono, 1=stereo */
+
+ if(_channels == 1)
+ {
+ stereo = 0;
+ }
+ if(_channels == 2)
+ {
+ stereo = 1;
+ }
+
+ if(stereo == -1)
+ {
+ _error = "internal error; set channels to 1 (mono) or 2 (stereo)";
+
+ close();
+ return false;
+ }
+
+ int requeststereo = stereo;
+
+ if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo)==-1)
+ {
+ _error = "SNDCTL_DSP_STEREO failed - ";
+ _error += strerror(errno);
+
+ close();
+ return false;
+ }
+
+ if (requeststereo != stereo)
+ {
+ _error = "audio device doesn't support number of requested channels";
+
+ close();
+ return false;
+ }
+
+ int speed = _samplingRate;
+
+ if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &speed)==-1)
+ {
+ _error = "SNDCTL_DSP_SPEED failed - ";
+ _error += strerror(errno);
+
+ close();
+ return false;
+ }
+
+ /*
+ * Some soundcards seem to be able to only supply "nearly" the requested
+ * sampling rate, especially PAS 16 cards seem to quite radical supplying
+ * something different than the requested sampling rate ;)
+ *
+ * So we have a quite large tolerance here (when requesting 44100 Hz, it
+ * will accept anything between 38690 Hz and 49510 Hz). Most parts of the
+ * aRts code will do resampling where appropriate, so it shouldn't affect
+ * sound quality.
+ */
+ int tolerance = _samplingRate/10+1000;
+
+ if (abs(speed-_samplingRate) > tolerance)
+ {
+ _error = "can't set requested samplingrate";
+
+ char details[80];
+ sprintf(details," (requested rate %d, got rate %d)",
+ _samplingRate, speed);
+ _error += details;
+
+ close();
+ return false;
+ }
+ _samplingRate = speed;
+
+ /*
+ * set the fragment settings to what the user requested
+ */
+
+ _fragmentSize = requestedFragmentSize;
+ _fragmentCount = requestedFragmentCount;
+
+ /*
+ * lower 16 bits are the fragment size (as 2^S)
+ * higher 16 bits are the number of fragments
+ */
+ int frag_arg = 0;
+
+ int size = _fragmentSize;
+ while(size > 1) { size /= 2; frag_arg++; }
+ frag_arg += (_fragmentCount << 16);
+ if(ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag_arg) == -1)
+ {
+ char buffer[1024];
+ _error = "can't set requested fragments settings";
+ sprintf(buffer,"size%d:count%d\n",_fragmentSize,_fragmentCount);
+ close();
+ return false;
+ }
+
+ /*
+ * now see what we really got as cards aren't required to supply what
+ * we asked for
+ */
+ audio_buf_info info;
+ if(ioctl(audio_fd,SNDCTL_DSP_GETOSPACE, &info) == -1)
+ {
+ _error = "can't retrieve fragment settings";
+ close();
+ return false;
+ }
+
+ // update fragment settings with what we got
+ _fragmentSize = info.fragsize;
+ _fragmentCount = info.fragstotal;
+
+ artsdebug("buffering: %d fragments with %d bytes "
+ "(audio latency is %1.1f ms)", _fragmentCount, _fragmentSize,
+ (float)(_fragmentSize*_fragmentCount) /
+ (float)(2.0 * _samplingRate * _channels)*1000.0);
+
+ /*
+ * Workaround for broken kernel drivers: usually filling up the audio
+ * buffer is _only_ required if _fullDuplex is true. However, there
+ * are kernel drivers around (especially everything related to ES1370/1371)
+ * which will not trigger select()ing the file descriptor unless we have
+ * written something first.
+ */
+ char *zbuffer = (char *)calloc(sizeof(char), _fragmentSize);
+ if(_format == 8)
+ for(int zpos = 0; zpos < _fragmentSize; zpos++)
+ zbuffer[zpos] |= 0x80;
+
+ for(int fill = 0; fill < _fragmentCount; fill++)
+ {
+ int len = ::write(audio_fd,zbuffer,_fragmentSize);
+ if(len != _fragmentSize)
+ {
+ arts_debug("AudioIOCSL: failed prefilling audio buffer (might cause synchronization problems in conjunction with full duplex)");
+ fill = _fragmentCount+1;
+ }
+ }
+ free(zbuffer);
+
+ /*
+ * Triggering - the original aRts code did this for full duplex:
+ *
+ * - stop audio i/o using SETTRIGGER(~(PCM_ENABLE_INPUT|PCM_ENABLE_OUTPUT))
+ * - fill buffer (see zbuffer code two lines above)
+ * - start audio i/o using SETTRIGGER(PCM_ENABLE_INPUT|PCM_ENABLE_OUTPUT)
+ *
+ * this should guarantee synchronous start of input/output. Today, it
+ * seems there are too many broken drivers around for this.
+ */
+
+ if(device_caps & DSP_CAP_TRIGGER)
+ {
+ int enable_bits = 0;
+
+ if(param(direction) & 1) enable_bits |= PCM_ENABLE_INPUT;
+ if(param(direction) & 2) enable_bits |= PCM_ENABLE_OUTPUT;
+
+ if(ioctl(audio_fd,SNDCTL_DSP_SETTRIGGER, &enable_bits) == -1)
+ {
+ _error = "can't start sound i/o";
+
+ close();
+ return false;
+ }
+ }
+#endif
+ updateFds();
+ return true;
+}
+
+void AudioIOCSL::close()
+{
+ if(inputStream)
+ {
+ csl_pcm_close(inputStream);
+ inputStream = 0;
+ }
+ if(outputStream)
+ {
+ csl_pcm_close(outputStream);
+ outputStream = 0;
+ }
+ updateFds();
+}
+
+void AudioIOCSL::setParam(AudioParam p, int& value)
+{
+ switch(p)
+ {
+ case fragmentSize:
+ param(p) = requestedFragmentSize = value;
+ break;
+ case fragmentCount:
+ param(p) = requestedFragmentCount = value;
+ break;
+ default:
+ param(p) = value;
+ break;
+ }
+}
+
+int AudioIOCSL::getParam(AudioParam p)
+{
+ CslErrorType error;
+ CslPcmStatus status;
+
+ switch(p)
+ {
+ case canRead:
+ error = csl_pcm_get_status (inputStream, &status);
+ if (error) /* FIXME */
+ arts_fatal("unable to obtain csl stream status: %s",
+ csl_strerror (error));
+
+ updateFds();
+ return status.n_bytes_available;
+ break;
+
+ case canWrite:
+ error = csl_pcm_get_status(outputStream, &status);
+ if (error) /* FIXME */
+ arts_fatal("unable to obtain csl stream status: %s",
+ csl_strerror (error));
+
+ updateFds();
+ return status.n_bytes_available;
+ break;
+
+ case autoDetect:
+ /* CSL is pretty experimental currently */
+ return 1;
+ break;
+
+ default:
+ return param(p);
+ break;
+ }
+}
+
+int AudioIOCSL::read(void *buffer, int size)
+{
+ arts_assert(inputStream != 0);
+
+ int result = csl_pcm_read(inputStream, size, buffer);
+ updateFds();
+
+ return result;
+}
+
+void AudioIOCSL::handleRead(void *, CslPcmStream *)
+{
+ AudioSubSystem::the()->handleIO(AudioSubSystem::ioRead);
+}
+
+int AudioIOCSL::write(void *buffer, int size)
+{
+ arts_assert(outputStream != 0);
+
+ int result = csl_pcm_write(outputStream, size, buffer);
+ updateFds();
+
+ return result;
+}
+
+void AudioIOCSL::handleWrite(void *, CslPcmStream *)
+{
+ AudioSubSystem::the()->handleIO(AudioSubSystem::ioWrite);
+}
+
+/* mainloop integration: make CSL callbacks work inside the aRts mainloop */
+
+int AudioIOCSL::csl2iomanager(int cslTypes)
+{
+ /* FIXME: doublecheck this list */
+ int types = 0;
+
+ if(cslTypes & CSL_POLLIN)
+ types |= IOType::read;
+ if(cslTypes & CSL_POLLOUT)
+ types |= IOType::write;
+ if(cslTypes & CSL_POLLERR)
+ types |= IOType::except;
+
+ return types;
+}
+
+void AudioIOCSL::updateFds()
+{
+ unsigned int n_fds = csl_poll_count_fds(cslDriver);
+ CslPollFD *newFds = g_newa(CslPollFD, n_fds);
+
+ unsigned int have_fds = csl_poll_get_fds(cslDriver, n_fds, newFds);
+ arts_assert(have_fds == n_fds);
+
+ cslFds.clear();
+
+ unsigned int i;
+ for(i = 0; i < have_fds; i++)
+ cslFds.push_back(newFds[i]);
+
+ /* FIXME: if csl provided a flag for this, we could save some work here */
+ bool fdsChanged;
+ if(cslFds.size() == cslOldFds.size())
+ {
+ fdsChanged = false;
+ for(i = 0; i < have_fds; i++)
+ {
+ if(cslFds[i].events != cslOldFds[i].events)
+ fdsChanged = true;
+ if(cslFds[i].fd != cslOldFds[i].fd)
+ fdsChanged = true;
+ }
+ }
+ else
+ {
+ fdsChanged = true;
+ }
+ if(!fdsChanged)
+ return;
+
+ vector<CslPollFD>::iterator ci;
+
+ /* remove old watches */
+ /*
+ * UGLY! due to broken API, we can only remove all watches here, and not
+ * do anything selectively - its not a problem for the code here, but it
+ * might be a problem elsewhere. Unfortunately, it can't be fixed without
+ * breaking BC.
+ */
+ Dispatcher::the()->ioManager()->remove(this, IOType::all);
+ arts_debug("AudioIOCSL::updateFds(): removing watches");
+
+ /* add new watches */
+ for(ci = cslFds.begin(); ci < cslFds.end(); ci++)
+ {
+ int types = csl2iomanager(ci->events);
+ if(types)
+ {
+ Dispatcher::the()->ioManager()->watchFD(ci->fd, types, this);
+ arts_debug("AudioIOCSL::updateFds(): adding watch on %d", ci->fd);
+ }
+ }
+
+ cslOldFds = cslFds;
+}
+
+void AudioIOCSL::notifyIO(int fd, int type)
+{
+ vector<CslPollFD>::iterator fi;
+
+ for(fi = cslFds.begin(); fi != cslFds.end(); fi++)
+ {
+ if(fi->fd == fd)
+ {
+ int ftype = csl2iomanager(fi->events);
+ fi->revents = 0;
+
+ if(type & ftype & IOType::read)
+ fi->revents |= CSL_POLLIN;
+ if(type & ftype & IOType::write)
+ fi->revents |= CSL_POLLOUT;
+ if(type & ftype & IOType::except)
+ fi->revents |= CSL_POLLERR;
+
+ if(fi->revents)
+ csl_poll_handle_fds(cslDriver, 1, &(*fi));
+ }
+ }
+ updateFds();
+}
+
+#endif
diff --git a/flow/audioioesd.cc b/flow/audioioesd.cc
new file mode 100644
index 0000000..a3fa4b5
--- /dev/null
+++ b/flow/audioioesd.cc
@@ -0,0 +1,231 @@
+ /*
+
+ Copyright (C) 2001 Jochen Hoenicke
+ jochen@gnu.org
+
+ Copyright (C) 2003 Ian Chiew
+ ian@snork.net
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/**
+ * only compile esound AudioIO class if libesd was detected during
+ * configure
+ */
+#ifdef HAVE_LIBESD
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <iostream>
+
+#include "audioio.h"
+#include "audiosubsys.h"
+#include "iomanager.h"
+#include "dispatcher.h"
+
+#include <esd.h>
+
+#ifdef __BIG_ENDIAN__
+#define _format_bits 17
+#else
+#define _format_bits 16
+#endif
+
+namespace Arts {
+
+class AudioIOESD : public AudioIO, public IONotify {
+protected:
+ int server_fd, read_fd, write_fd;
+
+public:
+ AudioIOESD();
+
+ void setParam(AudioParam param, int& value);
+ int getParam(AudioParam param);
+ void notifyIO(int fd, int type);
+
+ bool open();
+ void close();
+ void run();
+ int read(void *buffer, int size);
+ int write(void *buffer, int size);
+};
+
+REGISTER_AUDIO_IO(AudioIOESD,"esd","Enlightened Sound Daemon");
+}
+
+using namespace std;
+using namespace Arts;
+
+AudioIOESD::AudioIOESD()
+{
+ /*
+ * default parameters
+ */
+ param(samplingRate) = 44100;
+ paramStr(deviceName) = "null";
+ param(fragmentSize) = 1024;
+ param(fragmentCount) = 7;
+ param(format) = _format_bits;
+ param(channels) = 2;
+ param(direction) = 2;
+
+ server_fd = -1;
+ read_fd = -1;
+ write_fd = -1;
+}
+
+bool AudioIOESD::open()
+{
+ int& _channels = param(channels);
+ int& _direction = param(direction);
+ int& _samplingRate = param(samplingRate);
+ int& _format = param(format);
+ string& _error = paramStr(lastError);
+
+ if ((server_fd = esd_open_sound(NULL)) == -1)
+ {
+ _error = "Couldn't connect to server";
+ return false;
+ }
+
+ esd_server_info_t *server_info = esd_get_server_info(server_fd);
+
+ if (server_info == NULL)
+ {
+ _error = "Unable to query EsounD server";
+ return false;
+ }
+
+ esd_format_t server_format = server_info->format;
+
+ _samplingRate = server_info->rate;
+ _channels = (server_format & ESD_STEREO) ? 2 : 1;
+ _format = (server_format & ESD_BITS16) ? _format_bits : 8;
+
+ esd_free_server_info(server_info);
+
+ if (_direction & directionRead)
+ {
+ read_fd = esd_record_stream(server_format, _samplingRate,
+ NULL, "aRts");
+ if (read_fd == -1)
+ {
+ _error = "Couldn't create read uflow";
+ return false;
+ }
+ }
+
+ if (_direction & directionWrite)
+ {
+ write_fd = esd_play_stream(server_format, _samplingRate,
+ NULL, "aRts");
+ if (write_fd == -1)
+ {
+ _error = "Couldn't create write flow";
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void AudioIOESD::notifyIO(int, int)
+{
+}
+
+void AudioIOESD::close()
+{
+ if (write_fd != -1)
+ esd_close(write_fd);
+
+ if (read_fd != -1)
+ esd_close(read_fd);
+
+ if (server_fd != -1)
+ esd_close(server_fd);
+}
+
+void AudioIOESD::setParam(AudioParam p, int& value)
+{
+ switch(p)
+ {
+ case channels:
+ case format:
+ case direction:
+ case samplingRate:
+ param(p) = value;
+ close();
+ open();
+ return;
+
+ default:
+ param(p) = value;
+ return;
+ }
+}
+
+int AudioIOESD::getParam(AudioParam p)
+{
+ switch(p)
+ {
+ case selectReadFD:
+ return read_fd;
+
+ case selectWriteFD:
+ return write_fd;
+
+ case canRead:
+ return ESD_BUF_SIZE;
+
+ case canWrite:
+ return ESD_BUF_SIZE;
+
+ // ESD handles are actually socket descriptors, and I know not
+ // of any portable way to peek at the socket's send or receive
+ // buffers.
+
+ default:
+ return param(p);
+ }
+}
+
+int AudioIOESD::read(void *buffer, int size)
+{
+ return ::read(read_fd, buffer, size);
+}
+
+int AudioIOESD::write(void *buffer, int size)
+{
+ return ::write(write_fd, buffer, size);
+}
+
+#endif
diff --git a/flow/audioiojack.cc b/flow/audioiojack.cc
new file mode 100644
index 0000000..787ac03
--- /dev/null
+++ b/flow/audioiojack.cc
@@ -0,0 +1,346 @@
+/*
+ Copyright (C) 2004 Matthias Kretz <kretz@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_LIBJACK
+
+#include <jack/jack.h>
+#include <jack/ringbuffer.h>
+
+#include "debug.h"
+#include "audioio.h"
+#include "audiosubsys.h"
+#include "iomanager.h"
+#include "dispatcher.h"
+
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+#undef DEBUG_WAVEFORM
+#ifdef DEBUG_WAVEFORM
+#include <fstream>
+#endif
+
+#include <cstdlib>
+#include <cstring>
+
+namespace Arts {
+
+class AudioIOJack : public AudioIO, public TimeNotify {
+private:
+#ifdef DEBUG_WAVEFORM
+ std::ofstream plotfile;
+#endif
+ char * processBuffer;
+ size_t buffersize;
+
+protected:
+ jack_client_t *jack;
+ jack_port_t *outleft, *outright;
+ jack_port_t *inleft, *inright;
+ jack_ringbuffer_t *olb, *orb, *ilb, *irb;
+
+public:
+ AudioIOJack();
+
+ void notifyTime();
+
+ void setParam( AudioParam p, int & val );
+ int getParam(AudioParam param);
+
+ static int jackCallback( jack_nframes_t, void * );
+
+ bool open();
+ void close();
+ int read(void *buffer, int size);
+ int write(void *buffer, int size);
+};
+
+REGISTER_AUDIO_IO(AudioIOJack,"jack","Jack Audio Connection Kit");
+}
+
+using namespace std;
+using namespace Arts;
+
+AudioIOJack::AudioIOJack()
+ :
+#ifdef DEBUG_WAVEFORM
+ plotfile( "/dev/shm/audioiojack.plot" ),
+#endif
+ jack( 0 )
+ , outleft( 0 )
+ , outright( 0 )
+ , inleft( 0 )
+ , inright( 0 )
+{
+ /*
+ * default parameters
+ */
+ param( samplingRate ) = 44100;
+ paramStr( deviceName ) = "jack";
+ param( fragmentSize ) = 512;
+ param( fragmentCount ) = 2;
+ param( channels ) = 2;
+ param( direction ) = 2;
+ param( format ) = 32;
+}
+
+bool AudioIOJack::open()
+{
+ string& _error = paramStr( lastError );
+ jack = jack_client_new( "artsd" );
+ if( jack == 0 )
+ {
+ _error = "Couldn't connect to jackd";
+ return false;
+ }
+
+ int& _sampleRate = param(samplingRate);
+ _sampleRate = jack_get_sample_rate( jack );
+ int& _fragmentSize = param(fragmentSize);
+ int& _fragmentCount = param(fragmentCount);
+
+ /*
+ * don't allow unreasonable large fragmentSize/Count combinations,
+ * because "real" hardware also doesn't
+ */
+
+ if(_fragmentSize > 1024*8) _fragmentSize = 1024*8;
+
+ while(_fragmentSize * _fragmentCount > 1024*128)
+ _fragmentCount--;
+
+ jack_set_process_callback( jack, Arts::AudioIOJack::jackCallback, this );
+
+ if( param( direction ) & directionWrite )
+ {
+ outleft = jack_port_register( jack, "out_1",
+ JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 );
+ outright = jack_port_register( jack, "out_2",
+ JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 );
+ olb = jack_ringbuffer_create(
+ sizeof( jack_default_audio_sample_t ) *
+ _fragmentSize * _fragmentCount );
+ orb = jack_ringbuffer_create(
+ sizeof( jack_default_audio_sample_t ) *
+ _fragmentSize * _fragmentCount );
+ }
+ if( param( direction ) & directionRead )
+ {
+ inleft = jack_port_register( jack, "in_1",
+ JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 );
+ inright = jack_port_register( jack, "in_2",
+ JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 );
+ ilb = jack_ringbuffer_create(
+ sizeof( jack_default_audio_sample_t ) *
+ 1024 * 64 );
+ irb = jack_ringbuffer_create(
+ sizeof( jack_default_audio_sample_t ) *
+ 1024 * 64 );
+ }
+
+ if( jack_activate( jack ) )
+ {
+ _error = "Activating as jack client failed.";
+ return false;
+ }
+
+ const char **ports;
+ if( param( direction ) & directionRead )
+ {
+ ports = jack_get_ports( jack, 0, 0, JackPortIsPhysical
+ | JackPortIsOutput );
+ if( ports == 0 )
+ {
+ arts_warning( "Cannot find any capture ports to"
+ " connect to. You need to manually connect"
+ " the capture ports in jack" );
+ }
+ else
+ {
+ if( ports[ 0 ] != 0 )
+ jack_connect( jack, ports[ 0 ],
+ jack_port_name( inleft ) );
+ if( ports[ 1 ] != 0 )
+ jack_connect( jack, ports[ 1 ],
+ jack_port_name( inright ) );
+ free( ports );
+ }
+ }
+ if( param( direction ) & directionWrite )
+ {
+ ports = jack_get_ports( jack, 0, 0, JackPortIsPhysical
+ | JackPortIsInput );
+ if( ports == 0 )
+ {
+ arts_warning( "Cannot find any playback ports to"
+ " connect to. You need to manually connect"
+ " the playback ports in jack" );
+ }
+ else
+ {
+ if( ports[ 0 ] != 0 )
+ jack_connect( jack, jack_port_name( outleft ),
+ ports[ 0 ] );
+ if( ports[ 1 ] != 0 )
+ jack_connect( jack, jack_port_name( outright ),
+ ports[ 1 ] );
+ free( ports );
+ }
+ }
+
+ // Install the timer
+ Dispatcher::the()->ioManager()->addTimer(10, this);
+
+ return true;
+}
+
+void AudioIOJack::close()
+{
+ jack_client_close( jack );
+ Dispatcher::the()->ioManager()->removeTimer(this);
+}
+
+int AudioIOJack::jackCallback( jack_nframes_t nframes, void * args )
+{
+ AudioIOJack * that = static_cast<AudioIOJack*>( args );
+
+ that->buffersize = nframes * sizeof( jack_default_audio_sample_t );
+ if( that->outleft )
+ {
+ if( jack_ringbuffer_read_space( that->olb ) < that->buffersize )
+ {
+ that->processBuffer = static_cast<char *>(
+ jack_port_get_buffer( that->outleft, nframes ) );
+ memset( that->processBuffer, 0, that->buffersize );
+ that->processBuffer = static_cast<char *>(
+ jack_port_get_buffer( that->outright, nframes ) );
+ memset( that->processBuffer, 0, that->buffersize );
+ }
+ else
+ {
+ that->processBuffer = static_cast<char *>(
+ jack_port_get_buffer( that->outleft, nframes ) );
+ jack_ringbuffer_read( that->olb, that->processBuffer, that->buffersize );
+ that->processBuffer = static_cast<char *>(
+ jack_port_get_buffer( that->outright, nframes ) );
+ jack_ringbuffer_read( that->orb, that->processBuffer, that->buffersize );
+ }
+ }
+ if( that->inleft )
+ {
+ that->processBuffer = static_cast<char *>(
+ jack_port_get_buffer( that->inleft, nframes ) );
+ jack_ringbuffer_write( that->ilb, that->processBuffer, that->buffersize );
+ that->processBuffer = static_cast<char *>(
+ jack_port_get_buffer( that->inright, nframes ) );
+ jack_ringbuffer_write( that->irb, that->processBuffer, that->buffersize );
+ }
+ return 0;
+}
+
+void AudioIOJack::setParam( AudioParam p, int& val )
+{
+ // don't change the format - jack only supports 32 bit float
+ if( p == format )
+ return;
+ AudioIO::setParam( p, val );
+}
+
+int AudioIOJack::getParam(AudioParam p)
+{
+ switch(p)
+ {
+ case canRead:
+ return MIN( jack_ringbuffer_read_space( ilb ), jack_ringbuffer_read_space( irb ) ) * param( channels );
+ case canWrite:
+ return MIN( jack_ringbuffer_write_space( olb ), jack_ringbuffer_write_space( orb ) ) * param( channels );
+ default:
+ return AudioIO::getParam( p );
+ }
+}
+
+int AudioIOJack::read(void *buffer, int size)
+{
+ float * floatbuffer = static_cast<float *>( buffer );
+ if( param( channels ) == 2 )
+ {
+ float * end = ( float * )( static_cast<char *>( buffer ) + size );
+ while( floatbuffer < end )
+ {
+ jack_ringbuffer_read( ilb, ( char* )( floatbuffer++ ), sizeof( float ) );
+#ifdef DEBUG_WAVEFORM
+ plotfile << *( floatbuffer - 1 ) << "\n";
+#endif
+ jack_ringbuffer_read( irb, ( char* )( floatbuffer++ ), sizeof( float ) );
+ }
+ }
+ else if( param( channels ) == 1 )
+ {
+ jack_ringbuffer_read( ilb, ( char* )( floatbuffer ), size );
+ }
+ return size;
+}
+
+int AudioIOJack::write(void *buffer, int size)
+{
+ float * floatbuffer = static_cast<float *>( buffer );
+ if( param( channels ) == 2 )
+ {
+ float * end = ( float * )( static_cast<char *>( buffer ) + size );
+ while( floatbuffer < end )
+ {
+ jack_ringbuffer_write( olb, ( char* )( floatbuffer++ ), sizeof( float ) );
+ jack_ringbuffer_write( orb, ( char* )( floatbuffer++ ), sizeof( float ) );
+ }
+ }
+ else if( param( channels ) == 1 )
+ {
+ jack_ringbuffer_write( olb, ( char* )( floatbuffer ), size );
+ }
+ return size;
+}
+
+void AudioIOJack::notifyTime()
+{
+ int& _direction = param(direction);
+ int& _fragmentSize = param(fragmentSize);
+
+ for( ;; )
+ {
+ int todo = 0;
+ if( ( _direction & directionRead ) && ( getParam( canRead ) >= _fragmentSize ) )
+ todo |= AudioSubSystem::ioRead;
+
+ if( ( _direction & directionWrite ) && ( getParam( canWrite ) >= _fragmentSize ) )
+ todo |= AudioSubSystem::ioWrite;
+
+ if( ! todo )
+ return;
+
+ AudioSubSystem::the()->handleIO( todo );
+ }
+}
+
+#endif
+// vim: sw=4 ts=4
diff --git a/flow/audioiolibaudioio.cc b/flow/audioiolibaudioio.cc
new file mode 100644
index 0000000..e7c545e
--- /dev/null
+++ b/flow/audioiolibaudioio.cc
@@ -0,0 +1,236 @@
+ /*
+
+ Copyright (C) 2001 Robert Lunnon
+ bob@yarrabee.net.au
+ Copyright (C) 2001 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/**
+ * only compile 'LibAudioIO' AudioIO class if libaudio was detected during
+ * configure
+ */
+#ifdef HAVE_LIBAUDIOIO
+
+#include <libaudioio.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h> // Needed on some systems.
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <iostream>
+#include <algorithm>
+
+#include "debug.h"
+#include "audioio.h"
+
+namespace Arts {
+
+class AudioIOLibAudioIO : public AudioIO {
+protected:
+ int audio_fd;
+ int requestedFragmentSize;
+ int requestedFragmentCount;
+ SampleSpec_t spec;
+
+public:
+ AudioIOLibAudioIO();
+
+ void setParam(AudioParam param, int& value);
+ int getParam(AudioParam param);
+
+ bool open();
+ void close();
+ int read(void *buffer, int size);
+ int write(void *buffer, int size);
+};
+
+REGISTER_AUDIO_IO(AudioIOLibAudioIO,"libaudioio"," Portable Audio Library");
+};
+
+using namespace std;
+using namespace Arts;
+
+AudioIOLibAudioIO::AudioIOLibAudioIO()
+{
+ /*
+ * default parameters
+ */
+ param(samplingRate) = spec.rate=44100;
+ paramStr(deviceName) = "/dev/Audio";
+ requestedFragmentSize = param(fragmentSize) = 4096;
+ requestedFragmentCount =spec.max_blocks= param(fragmentCount) = 7;
+ param(channels) = spec.channels=2;
+ param(direction) = 2;
+}
+
+bool AudioIOLibAudioIO::open()
+{
+ string& _error = paramStr(lastError);
+ string& _deviceName = paramStr(deviceName);
+ int& _channels = param(channels);
+ int& _fragmentSize = param(fragmentSize);
+ int& _fragmentCount = param(fragmentCount);
+ int& _samplingRate = param(samplingRate);
+ int& _format = param(format);
+
+ int mode;
+ spec.channels=_channels;
+ spec.max_blocks= param(fragmentCount);
+ spec.rate= _samplingRate;
+ spec.encoding= ENCODE_PCM;
+ spec.precision=16 ;
+ spec.endian=ENDIAN_NATURAL;
+ spec.disable_threads=1;
+
+ if(param(direction) == 3)
+ mode = O_RDWR|O_NDELAY;
+ else if(param(direction) == 2)
+ mode = O_WRONLY|O_NDELAY;
+ else
+ {
+ _error = "invalid direction";
+ return false;
+ }
+
+ audio_fd = ::AudioIOOpenX( mode, &spec,&spec );
+ if(audio_fd == -1)
+ {
+ _error = "device ";
+ _error += _deviceName.c_str();
+ _error += " can't be opened (";
+ _error += strerror(errno);
+ _error += ")";
+ return false;
+ }
+
+
+ /*
+ * since we use spec.endian=ENDIAN_NATURAL we'll have little endian audio
+ * on little endian machines and big endian audio on big endian machines:
+ */
+#ifdef WORDS_BIGENDIAN
+ _format = 17;
+#else
+ _format = 16;
+#endif
+
+ spec.channels=_channels;
+
+ spec.rate = _samplingRate;
+
+
+ _fragmentSize = requestedFragmentSize;
+ spec.max_blocks=_fragmentCount = requestedFragmentCount;
+
+
+ artsdebug("buffering: %d fragments with %d bytes "
+ "(audio latency is %1.1f ms)", _fragmentCount, _fragmentSize,
+ (float)(_fragmentSize*_fragmentCount) /
+ (float)(2.0 * _samplingRate * _channels)*1000.0);
+
+ return(true);
+}
+
+void AudioIOLibAudioIO::close()
+{
+ ::AudioIOClose();
+}
+
+void AudioIOLibAudioIO::setParam(AudioParam p, int& value)
+{
+ switch(p)
+ {
+ case fragmentSize:
+ param(p) = requestedFragmentSize = value;
+ break;
+ case fragmentCount:
+ param(p) = requestedFragmentCount = value;
+ break;
+ default:
+ param(p) = value;
+ break;
+ }
+}
+
+int AudioIOLibAudioIO::getParam(AudioParam p)
+{
+ switch(p)
+ {
+ case canRead:
+ return AudioIOCheckRead();
+ break;
+
+ case canWrite:
+ return (AudioIOCheckWriteReady()) ? (16*1024) : 0;
+ // Assume if writable can write 16K
+ // Arts Really doesn't care
+ break;
+
+ case selectReadFD:
+ return (param(direction) & directionRead)?audio_fd:-1;
+ break;
+
+ case selectWriteFD:
+ return (param(direction) & directionWrite)?audio_fd:-1;
+ break;
+
+ case autoDetect:
+ /*
+ * if there is a "native" aRts driver, we'll rather use this
+ * than the generic libaudioio one, because the native one
+ * is likely to be better optimized to the needs of aRts than
+ * a generic driver, so keep the value small
+ */
+ return 3;
+ break;
+
+ default:
+ return param(p);
+ break;
+ }
+}
+
+int AudioIOLibAudioIO::read(void *buffer, int size)
+{
+ arts_assert(audio_fd != 0);
+ return ::AudioIORead(buffer,size);
+}
+
+int AudioIOLibAudioIO::write(void *buffer, int size)
+{
+ arts_assert(audio_fd != 0);
+ return ::AudioIOWrite(buffer,size);
+}
+
+#endif
diff --git a/flow/audioiomas.cc b/flow/audioiomas.cc
new file mode 100644
index 0000000..e49fec2
--- /dev/null
+++ b/flow/audioiomas.cc
@@ -0,0 +1,619 @@
+ /*
+
+ Copyright (C) 2001-2003 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/*
+ * Only compile this AudioIO class if we have MAS
+ */
+#ifdef HAVE_LIBMAS
+
+extern "C" {
+#include <mas/mas.h>
+#include <mas/mas_getset.h>
+#include <mas/mas_source.h>
+}
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <iostream>
+#include <algorithm>
+
+#include "debug.h"
+#include "audioio.h"
+#include "audiosubsys.h"
+#include "iomanager.h"
+#include "dispatcher.h"
+
+namespace Arts {
+
+ class AudioIOMAS : public AudioIO, public TimeNotify {
+ protected:
+ mas_channel_t audio_channel;
+ mas_port_t mix_sink;
+ mas_port_t srate_source, srate_sink;
+ mas_port_t audio_source, audio_sink;
+ mas_port_t endian_sink, endian_source;
+ mas_port_t sbuf_source, sbuf_sink;
+ mas_port_t squant_sink, squant_source;
+ mas_port_t open_source; /* (!) */
+ mas_device_t endian;
+ mas_device_t srate;
+ mas_device_t squant;
+ mas_device_t sbuf;
+ mas_data *data;
+ mas_package package;
+ int32 mas_error;
+
+ std::list<mas_channel_t> allocated_channels;
+ std::list<mas_port_t> allocated_ports;
+ std::list<mas_device_t> allocated_devices;
+
+ double lastUpdate, bytesPerSec;
+ int readBufferAvailable;
+ int writeBufferAvailable;
+
+ double currentTime();
+ void updateBufferSizes();
+
+#ifdef WORDS_BIGENDIAN
+ static const int defaultFormat = 17;
+#else
+ static const int defaultFormat = 16;
+#endif
+ bool close_with_error(const std::string& text);
+ public:
+ AudioIOMAS();
+
+ // Timer callback
+ void notifyTime();
+
+ void setParam(AudioParam param, int& value);
+ int getParam(AudioParam param);
+
+ bool open();
+ void close();
+ int read(void *buffer, int size);
+ int write(void *buffer, int size);
+ };
+
+ REGISTER_AUDIO_IO(AudioIOMAS,"mas","MAS Audio Input/Output");
+
+};
+
+using namespace std;
+using namespace Arts;
+
+AudioIOMAS::AudioIOMAS()
+{
+ /*
+ * default parameters
+ */
+ param(samplingRate) = 44100;
+ paramStr(deviceName) = ""; // TODO
+ param(fragmentSize) = 4096;
+ param(fragmentCount) = 7;
+ param(channels) = 2;
+ param(direction) = 2;
+ param(format) = defaultFormat;
+}
+
+namespace {
+ int masInitCount = 0;
+}
+
+// Opens the audio device
+bool AudioIOMAS::open()
+{
+ string& _error = paramStr(lastError);
+ string& _deviceName = paramStr(deviceName);
+ int& _channels = param(channels);
+ int& _fragmentSize = param(fragmentSize);
+ int& _fragmentCount = param(fragmentCount);
+ int& _samplingRate = param(samplingRate);
+ int& _format = param(format);
+
+ /* FIXME: do we need to free what we allocate with mas_init() in close() */
+ if (!masInitCount)
+ {
+ mas_error = mas_init();
+
+ if (mas_error < 0)
+ return close_with_error("error connecting to MAS server");
+ }
+ masInitCount++;
+
+ if (param(direction) != 2)
+ {
+ _error = "unsupported direction (currently no full duplex support)";
+ return false;
+ }
+
+ /*
+ * data path
+ *
+ * audio_sink
+ * audio_channel: data_channel ("artsd")
+ * audio_source
+ * |
+ * V
+ * endian_sink
+ * endian: instantiate_device ("endian")
+ * open_source = endian_source
+ * |
+ * V
+ * [squant_sink]
+ * [squant]
+ * [squant_source]
+ * |
+ * V
+ * [srate_sink]
+ * [srate]
+ * [srate_source]
+ * |
+ * V
+ * sbuf_sink
+ * sbuf
+ * sbuf_source
+ * |
+ * V
+ * mix_sink: port ("default_mix_sink")
+ */
+
+ // audio_channel, source & sink
+ mas_error = mas_make_data_channel("artsd", &audio_channel, &audio_source, &audio_sink);
+ if (mas_error < 0)
+ return close_with_error("error initializing MAS data channel");
+
+ allocated_channels.push_back(audio_channel);
+ allocated_ports.push_back(audio_source);
+ allocated_ports.push_back(audio_sink);
+
+ // endian, source & sink
+ mas_error = mas_asm_instantiate_device( "endian", 0, 0, &endian );
+ if ( mas_error < 0 )
+ return close_with_error("error initantiating MAS endian device");
+
+ allocated_devices.push_back(endian);
+
+ mas_error = mas_asm_get_port_by_name( endian, "sink", &endian_sink );
+ if ( mas_error < 0 )
+ return close_with_error("error getting MAS endian device sink port");
+
+ allocated_ports.push_back(endian_sink);
+
+ mas_error = mas_asm_get_port_by_name( endian, "source", &endian_source );
+ if ( mas_error < 0 )
+ return close_with_error("error getting MAS endian device source port");
+
+ allocated_ports.push_back(endian_source);
+
+ char ratestring[16], resolutionstring[16];
+ sprintf (ratestring, "%u", _samplingRate);
+ sprintf (resolutionstring, "%u", _format);
+
+ mas_data_characteristic* dc;
+
+ dc = (mas_data_characteristic *)MAS_NEW( dc );
+ masc_setup_dc( dc, 6 );
+ masc_append_dc_key_value( dc, "format", (_format==8) ? "ulinear":"linear" );
+
+ masc_append_dc_key_value( dc, "resolution", resolutionstring );
+ masc_append_dc_key_value( dc, "sampling rate", ratestring );
+ masc_append_dc_key_value( dc, "channels", "2" );
+ masc_append_dc_key_value( dc, "endian", "little" );
+
+ mas_error = mas_asm_connect_source_sink( audio_source, endian_sink, dc );
+ if ( mas_error < 0 )
+ return close_with_error("error connecting MAS net audio source to endian sink");
+
+ /* The next device is 'if needed' only. After the following if()
+ statement, open_source will contain the current unconnected
+ source in the path (will be either endian_source or
+ squant_source in this case)
+ */
+ open_source = endian_source;
+
+ if ( _format != 16 )
+ {
+ arts_debug("MAS output: Sample resolution is not 16 bit/sample, instantiating squant device.");
+
+ // squant, source & sink
+ mas_error = mas_asm_instantiate_device( "squant", 0, 0, &squant );
+ if ( mas_error < 0 )
+ return close_with_error("error creating MAS squant device");
+
+ allocated_devices.push_back(squant);
+
+ mas_error = mas_asm_get_port_by_name( squant, "sink", &squant_sink );
+ if ( mas_error < 0 )
+ return close_with_error("error getting MAS squant device sink port");
+
+ allocated_ports.push_back(squant_sink);
+
+ mas_error = mas_asm_get_port_by_name( squant, "source", &squant_source );
+ if ( mas_error < 0 )
+ return close_with_error("error getting MAS squant device source port");
+
+ allocated_ports.push_back(squant_source);
+
+ arts_debug( "MAS output: Connecting endian -> squant.");
+
+ masc_strike_dc( dc );
+ masc_setup_dc( dc, 6 );
+ masc_append_dc_key_value( dc,"format",(_format==8) ? "ulinear":"linear" );
+ masc_append_dc_key_value( dc, "resolution", resolutionstring );
+ masc_append_dc_key_value( dc, "sampling rate", ratestring );
+ masc_append_dc_key_value( dc, "channels", "2" );
+ masc_append_dc_key_value( dc, "endian", "host" );
+
+ mas_error = mas_asm_connect_source_sink( endian_source, squant_sink, dc );
+ if ( mas_error < 0 )
+ return close_with_error("error connecting MAS endian output to squant device");
+
+ /* sneaky: the squant device is optional -> pretend it isn't there */
+ open_source = squant_source;
+ }
+
+
+ /* Another 'if necessary' device, as above */
+ if ( _samplingRate != 44100 )
+ {
+ arts_debug ("MAS output: Sample rate is not 44100, instantiating srate device.");
+
+ // srate, source & sink
+ mas_error = mas_asm_instantiate_device( "srate", 0, 0, &srate );
+ if ( mas_error < 0 )
+ return close_with_error("error initantiating MAS srate device");
+
+ allocated_devices.push_back(srate);
+
+ mas_error = mas_asm_get_port_by_name( srate, "sink", &srate_sink );
+ if ( mas_error < 0 )
+ return close_with_error("error getting MAS srate sink port");
+
+ allocated_ports.push_back(srate_sink);
+
+ mas_error = mas_asm_get_port_by_name( srate, "source", &srate_source );
+ if ( mas_error < 0 )
+ return close_with_error("error getting MAS srate source port");
+
+ allocated_ports.push_back(srate_source);
+
+ arts_debug( "MAS output: Connecting to srate.");
+
+ masc_strike_dc( dc );
+ masc_setup_dc( dc, 6 );
+ masc_append_dc_key_value( dc, "format", "linear" );
+ masc_append_dc_key_value( dc, "resolution", "16" );
+ masc_append_dc_key_value( dc, "sampling rate", ratestring );
+ masc_append_dc_key_value( dc, "channels", "2" );
+ masc_append_dc_key_value( dc, "endian", "host" );
+
+ mas_error = mas_asm_connect_source_sink( open_source, srate_sink, dc );
+ if ( mas_error < 0 )
+ return close_with_error("error connecting to MAS srate device");
+
+ open_source = srate_source;
+ }
+
+ // sbuf, source & sink
+ mas_error = mas_asm_instantiate_device( "sbuf", 0, 0, &sbuf );
+ if ( mas_error < 0 )
+ return close_with_error("error initantiating MAS sbuf device");
+
+ allocated_devices.push_back(sbuf);
+
+ mas_error = mas_asm_get_port_by_name( sbuf, "sink", &sbuf_sink );
+ if ( mas_error < 0 )
+ return close_with_error("error getting MAS sbuf device sink port");
+
+ allocated_ports.push_back(sbuf_sink);
+
+ mas_error = mas_asm_get_port_by_name( sbuf, "source", &sbuf_source );
+ if ( mas_error < 0 )
+ return close_with_error("error getting MAS sbuf device source port");
+
+ allocated_ports.push_back(sbuf_source);
+
+ masc_strike_dc( dc );
+ masc_setup_dc( dc, 6 );
+
+ masc_append_dc_key_value( dc, "format", "linear" );
+ masc_append_dc_key_value( dc, "resolution", "16" );
+ masc_append_dc_key_value( dc, "sampling rate", "44100" );
+ masc_append_dc_key_value( dc, "channels", "2" );
+ masc_append_dc_key_value( dc, "endian", "host" );
+
+ arts_debug("MAS output: Connecting to sbuf.");
+
+ mas_error = mas_asm_connect_source_sink( open_source, sbuf_sink, dc );
+ if ( mas_error < 0 )
+ return close_with_error("error connecting to MAS mixer device");
+
+ /* configure sbuf */
+
+ float BUFTIME_MS = _fragmentSize * _fragmentCount;
+ BUFTIME_MS *= 1000.0;
+ BUFTIME_MS /= (float)_channels;
+ if (_format > 8)
+ BUFTIME_MS /= 2.0;
+ BUFTIME_MS /= (float)_samplingRate;
+
+ arts_debug("MAS output: BUFTIME_MS = %f", BUFTIME_MS);
+
+ masc_setup_package( &package, NULL, 0, 0 );
+ masc_pushk_uint32( &package, "buftime_ms", (uint32) BUFTIME_MS );
+ masc_finalize_package( &package );
+ mas_set( sbuf, "buftime_ms", &package );
+ masc_strike_package( &package );
+
+ masc_setup_package( &package, NULL, 0, 0 );
+ masc_pushk_int32( &package, "mc_clkid", 9 );
+ masc_finalize_package( &package );
+ mas_set( sbuf, "mc_clkid", &package );
+ masc_strike_package( &package );
+
+ mas_source_play( sbuf );
+
+ // mix_sink
+ mas_error = mas_asm_get_port_by_name( 0, "default_mix_sink", &mix_sink );
+ if (mas_error < 0)
+ return close_with_error("error finding MAS default sink");
+
+ allocated_ports.push_back(mix_sink);
+
+ arts_debug("MAS output: Connecting sbuf to mix_sink.");
+
+ mas_error = mas_asm_connect_source_sink( sbuf_source, mix_sink, dc );
+ if ( mas_error < 0 )
+ return close_with_error("error connecting to MAS mixer device");
+
+ data = (mas_data *)MAS_NEW( data );
+ masc_setup_data( data, _fragmentSize ); /* we can reuse this */
+ data->length = _fragmentSize;
+ data->allocated_length = data->length;
+ data->header.type = 10;
+
+ arts_debug("MAS output: playing.");
+
+ // Install the timer
+ Dispatcher::the()->ioManager()->addTimer(10, this);
+
+ bytesPerSec = _channels * _samplingRate;
+ if (_format > 8)
+ bytesPerSec *= 2;
+
+ lastUpdate = 0;
+
+ return true;
+}
+
+double AudioIOMAS::currentTime()
+{
+ timeval tv;
+ gettimeofday(&tv,0);
+
+ return (double)tv.tv_sec + (double)tv.tv_usec/1000000.0;
+}
+
+bool AudioIOMAS::close_with_error(const string& text)
+{
+ string& error = paramStr(lastError);
+ error = text;
+ error += masc_strmerror (mas_error);
+ return false;
+}
+
+void AudioIOMAS::close()
+{
+ list<mas_port_t>::iterator pi;
+ for (pi = allocated_ports.begin(); pi != allocated_ports.end(); pi++)
+ mas_free_port (*pi);
+ allocated_ports.clear();
+
+ list<mas_channel_t>::iterator ci;
+ for (ci = allocated_channels.begin(); ci != allocated_channels.end(); ci++)
+ mas_free_channel (*ci);
+ allocated_channels.clear();
+
+ list<mas_device_t>::iterator di;
+ for (di = allocated_devices.begin(); di != allocated_devices.end(); di++)
+ {
+ mas_device_t device = *di;
+ mas_error = mas_asm_terminate_device_instance(device, 0);
+ if (mas_error < 0)
+ arts_warning ("MAS output: error while closing device: %s", masc_strmerror(mas_error));
+
+ mas_free_device(device);
+ }
+ allocated_devices.clear();
+
+ Dispatcher::the()->ioManager()->removeTimer(this);
+}
+
+void AudioIOMAS::updateBufferSizes()
+{
+ double time = currentTime();
+ double waterMark = param(fragmentSize);
+ waterMark *= 1.3;
+
+ if ((time - lastUpdate) * bytesPerSec < waterMark)
+ return;
+
+ lastUpdate = time;
+
+ uint32 inbuf_ms;
+ int32 mas_error;
+
+ mas_error = mas_get( sbuf, "inbuf_ms", 0 , &package );
+ if ( mas_error < 0 )
+ arts_fatal ("MAS output: error getting size of buffer: %s", masc_strmerror(mas_error));
+
+ masc_pull_uint32( &package, &inbuf_ms );
+ masc_strike_package( &package );
+
+ //arts_debug(" inbuf_ms = %u", inbuf_ms);
+
+ float bytes = inbuf_ms;
+ bytes /= 1000.0;
+ bytes *= param(samplingRate);
+ bytes *= param(channels);
+ if(param(format) > 8)
+ bytes *= 2;
+
+ int bytesFree = param(fragmentSize) * param(fragmentCount) - (int)bytes;
+
+ if (bytesFree < param(fragmentSize))
+ bytesFree = 0;
+
+ writeBufferAvailable = bytesFree;
+
+ arts_debug ("MAS output buffer: %6d / %6d bytes used => %6d bytes free",
+ (int)bytes, param(fragmentSize) * param(fragmentCount), writeBufferAvailable);
+}
+
+// This is called on each timer tick
+void AudioIOMAS::notifyTime()
+{
+ updateBufferSizes();
+
+ int& _direction = param(direction);
+ int& _fragmentSize = param(fragmentSize);
+
+ for (;;) {
+ int todo = 0;
+
+ if ((_direction & directionRead) && (getParam(canRead) >= _fragmentSize))
+ todo |= AudioSubSystem::ioRead;
+
+ if ((_direction & directionWrite) && (getParam(canWrite) >= _fragmentSize))
+ todo |= AudioSubSystem::ioWrite;
+
+ if (!todo)
+ return;
+
+ AudioSubSystem::the()->handleIO(todo);
+ }
+}
+
+void AudioIOMAS::setParam(AudioParam p, int& value)
+{
+ switch(p) {
+#if 0
+ case fragmentSize:
+ param(p) = requestedFragmentSize = value;
+ break;
+ case fragmentCount:
+ param(p) = requestedFragmentCount = value;
+ break;
+#endif
+ default:
+ param(p) = value;
+ break;
+ }
+}
+
+int AudioIOMAS::getParam(AudioParam p)
+{
+ int bytes;
+ int count;
+
+ switch(p)
+ {
+#if 0
+ case canRead:
+ if (ioctl(audio_fd, AUDIO_GETINFO, &auinfo) < 0)
+ return (0);
+ bytes = (auinfo.record.samples * bytesPerSample) - bytesRead;
+ if (bytes < 0) {
+ printf("Error: bytes %d < 0, samples=%u, bytesRead=%u\n",
+ bytes, auinfo.record.samples, bytesRead);
+ bytes = 0;
+ }
+ return bytes;
+
+ case canWrite:
+ if (ioctl(audio_fd, AUDIO_GETINFO, &auinfo) < 0)
+ return (0);
+ count = SUN_MAX_BUFFER_SIZE -
+ (bytesWritten - (auinfo.play.samples * bytesPerSample));
+ return count;
+#endif
+ case canWrite:
+ return writeBufferAvailable;
+
+ case autoDetect:
+ /*
+ * Fairly small priority, for we haven't tested this a lot
+ */
+ return 3;
+
+ default:
+ return param(p);
+ }
+}
+
+int AudioIOMAS::read(void *buffer, int size)
+{
+#if 0
+ size = ::read(audio_fd, buffer, size);
+ if (size < 0)
+ return 0;
+
+ bytesRead += size;
+ return size;
+#endif
+ return 0;
+}
+
+int AudioIOMAS::write(void *buffer, int size)
+{
+ static int ts = 0;
+ static int seq = 0;
+ data->header.sequence = seq++;
+ data->header.media_timestamp = ts;
+ ts += size / 4;
+
+ assert(size == data->length);
+ memcpy(data->segment, buffer, size);
+
+ int32 mas_error = mas_send( audio_channel , data );
+ if (mas_error < 0)
+ arts_fatal ("MAS output: problem during mas_send: %s", masc_strmerror(mas_error));
+
+ writeBufferAvailable -= size;
+ return size;
+}
+
+#endif /* HAVE_LIBMAS */
diff --git a/flow/audioionas.cc b/flow/audioionas.cc
new file mode 100644
index 0000000..3106ade
--- /dev/null
+++ b/flow/audioionas.cc
@@ -0,0 +1,260 @@
+ /*
+
+ Copyright (C) 2001 Jochen Hoenicke
+ jochen@gnu.org
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/**
+ * only compile nas AudioIO class if libaudio was detected during
+ * configure
+ */
+#ifdef HAVE_LIBAUDIONAS
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <iostream>
+
+#include "audioio.h"
+#include "audiosubsys.h"
+#include "iomanager.h"
+#include "dispatcher.h"
+
+#include <audio/audiolib.h>
+
+namespace Arts {
+
+static AuBool
+eventHandler(AuServer *, AuEvent *ev, AuEventHandlerRec *handler);
+
+class AudioIONAS : public AudioIO, public IONotify {
+protected:
+ AuServer *aud;
+ AuDeviceID device;
+ AuFlowID flow;
+ AuElement elements[2];
+
+ int freeBytes;
+
+public:
+ AudioIONAS();
+
+ void setParam(AudioParam param, int& value);
+ int getParam(AudioParam param);
+
+ bool open();
+ void close();
+ void run();
+ void notifyIO(int, int);
+ int read(void *buffer, int size);
+ int write(void *buffer, int size);
+
+ friend AuBool
+ eventHandler(AuServer *, AuEvent *ev, AuEventHandlerRec *handler);
+};
+
+REGISTER_AUDIO_IO(AudioIONAS,"nas","Network Audio System");
+}
+
+using namespace std;
+using namespace Arts;
+
+static AuBool
+Arts::eventHandler(AuServer *, AuEvent *ev, AuEventHandlerRec *handler)
+{
+ AudioIONAS *nas = (AudioIONAS *) handler->data;
+ if (ev->type == AuEventTypeElementNotify)
+ {
+ AuElementNotifyEvent *event = (AuElementNotifyEvent *) ev;
+
+ switch (event->kind)
+ {
+ case AuElementNotifyKindLowWater:
+ nas->freeBytes += event->num_bytes;
+ AudioSubSystem::the()->handleIO
+ (AudioSubSystem::ioWrite);
+ break;
+ case AuElementNotifyKindState:
+ if (event->cur_state == AuStatePause
+ && event->reason != AuReasonUser)
+ {
+ nas->freeBytes += event->num_bytes;
+ AudioSubSystem::the()->handleIO
+ (AudioSubSystem::ioWrite);
+ }
+ break;
+ }
+ }
+ return true;
+}
+
+AudioIONAS::AudioIONAS()
+{
+ /*
+ * default parameters
+ */
+ param(samplingRate) = 11025;
+ paramStr(deviceName) = "null";
+ param(fragmentSize) = 1024;
+ param(fragmentCount) = 7;
+ param(format) = 16;
+ param(channels) = 2;
+ param(direction) = 2;
+}
+
+bool AudioIONAS::open()
+{
+ char *server_msg;
+
+ int& _channels = param(channels);
+ int& _direction = param(direction);
+ int& _fragmentSize = param(fragmentSize);
+ int& _fragmentCount = param(fragmentCount);
+ int& _samplingRate = param(samplingRate);
+ int& _format = param(format);
+ string& _device = paramStr(deviceName);
+ string& _error = paramStr(lastError);
+ int _buf_samples, i;
+
+ if((_direction & directionRead))
+ {
+ _error = "no record audio device";
+ return false;
+ }
+
+ aud = AuOpenServer(_device.compare("null") == 0
+ ? NULL : _device.c_str(),
+ 0, NULL, 0, NULL, &server_msg);
+ if(aud == NULL)
+ {
+ _error = "device ";
+ _error += _device;
+ _error += " can't be opened (";
+ _error += server_msg;
+ _error += ")";
+ return false;
+ }
+
+ device = AuNone;
+ for (i = 0; i < AuServerNumDevices(aud); i++)
+ {
+ AuDeviceAttributes *devattr = AuServerDevice(aud, i);
+ if (AuDeviceKind(devattr) == AuComponentKindPhysicalOutput
+ && AuDeviceNumTracks(devattr) == _channels)
+ {
+ device = AuDeviceIdentifier(devattr);
+ break;
+ }
+ }
+
+ if (device == AuNone)
+ {
+ _error = "Couldn't find an output device";
+ return false;
+ }
+
+ if (!(flow = AuCreateFlow(aud, NULL)))
+ {
+ _error = "Couldn't create flow";
+ return false;
+ }
+
+ _buf_samples = _fragmentSize;
+ AuMakeElementImportClient(&elements[0], _samplingRate,
+ _format == 8 ? AuFormatLinearUnsigned8
+ : AuFormatLinearSigned16LSB,
+ _channels, AuTrue,
+ _buf_samples * _fragmentCount,
+ _buf_samples * (_fragmentCount)/2,
+ 0, NULL);
+ AuMakeElementExportDevice(&elements[1], 0, device, _samplingRate,
+ AuUnlimitedSamples, 0, NULL);
+ AuSetElements(aud, flow, AuTrue, 2, elements, NULL);
+ AuRegisterEventHandler(aud, AuEventHandlerIDMask, 0, flow,
+ eventHandler, (AuPointer) this);
+
+ freeBytes = 0;
+ AuStartFlow(aud, flow, NULL);
+
+ Dispatcher::the()->ioManager()->watchFD(aud->fd, IOType::read, this);
+
+ AuHandleEvents(aud);
+ return true;
+}
+
+void AudioIONAS::close()
+{
+ Dispatcher::the()->ioManager()->remove(this, IOType::all);
+ AuWriteElement(aud, flow, 0, 0, NULL, AuTrue, NULL);
+ AuCloseServer(aud);
+ aud = NULL;
+}
+
+void AudioIONAS::setParam(AudioParam p, int& value)
+{
+ param(p) = value;
+}
+
+int AudioIONAS::getParam(AudioParam p)
+{
+ switch(p)
+ {
+ case canWrite:
+ return freeBytes;
+
+ default:
+ return param(p);
+ }
+}
+
+void AudioIONAS::notifyIO(int, int)
+{
+ AuHandleEvents(aud);
+}
+
+int AudioIONAS::read(void *, int )
+{
+ return 0;
+}
+
+int AudioIONAS::write(void *buffer, int size)
+{
+ if (size > freeBytes)
+ size = freeBytes;
+ if (size > 0)
+ AuWriteElement(aud, flow, 0, size, buffer, AuFalse, NULL);
+ freeBytes -= size;
+ if (freeBytes > 0)
+ AudioSubSystem::the()->handleIO(AudioSubSystem::ioWrite);
+ return size;
+}
+
+#endif
diff --git a/flow/audioionull.cc b/flow/audioionull.cc
new file mode 100644
index 0000000..a8cd050
--- /dev/null
+++ b/flow/audioionull.cc
@@ -0,0 +1,184 @@
+ /*
+
+ Copyright (C) 2001 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <iostream>
+#include <algorithm>
+#include <cstring>
+
+#include "debug.h"
+#include "audioio.h"
+#include "audiosubsys.h"
+#include "iomanager.h"
+#include "dispatcher.h"
+
+namespace Arts {
+
+class AudioIONull : public AudioIO, public TimeNotify {
+protected:
+ timeval start;
+ double samplesRead, samplesWritten, bytesPerSec;
+
+public:
+ AudioIONull();
+
+ void notifyTime();
+
+ void setParam(AudioParam param, int& value);
+ int getParam(AudioParam param);
+
+ bool open();
+ void close();
+ int read(void *buffer, int size);
+ int write(void *buffer, int size);
+};
+
+REGISTER_AUDIO_IO(AudioIONull,"null","No Audio Input/Output");
+}
+
+using namespace std;
+using namespace Arts;
+
+AudioIONull::AudioIONull()
+{
+ /*
+ * default parameters
+ */
+ param(samplingRate) = 44100;
+ paramStr(deviceName) = "null";
+ param(fragmentSize) = 1024;
+ param(fragmentCount) = 7;
+ param(channels) = 2;
+ param(direction) = 2;
+}
+
+bool AudioIONull::open()
+{
+ int& _channels = param(channels);
+ int& _fragmentSize = param(fragmentSize);
+ int& _fragmentCount = param(fragmentCount);
+ int& _samplingRate = param(samplingRate);
+ int& _format = param(format);
+ _format = 16;
+
+ /*
+ * don't allow unreasonable large fragmentSize/Count combinations,
+ * because "real" hardware also doesn't
+ */
+
+ if(_fragmentSize > 1024*128) _fragmentSize = 1024*128;
+
+ while(_fragmentSize * _fragmentCount > 1024*128)
+ _fragmentCount--;
+
+ Dispatcher::the()->ioManager()->addTimer(10, this);
+
+ samplesRead = samplesWritten = 0.0;
+ bytesPerSec = _channels * 2 * _samplingRate;
+ gettimeofday(&start,0);
+
+ return true;
+}
+
+void AudioIONull::close()
+{
+ Dispatcher::the()->ioManager()->removeTimer(this);
+}
+
+void AudioIONull::notifyTime()
+{
+ int& _direction = param(direction);
+ int& _fragmentSize = param(fragmentSize);
+
+ for(;;)
+ {
+ int todo = 0;
+
+ if((_direction & directionRead) && getParam(canRead) >= _fragmentSize)
+ todo |= AudioSubSystem::ioRead;
+
+ if((_direction & directionWrite) && getParam(canWrite) >= _fragmentSize)
+ todo |= AudioSubSystem::ioWrite;
+
+ if(!todo)
+ return;
+
+ AudioSubSystem::the()->handleIO(todo);
+ }
+}
+
+void AudioIONull::setParam(AudioParam p, int& value)
+{
+ param(p) = value;
+}
+
+int AudioIONull::getParam(AudioParam p)
+{
+ timeval now;
+ double delta;
+ int bytes;
+
+ switch(p)
+ {
+ case canRead:
+ case canWrite:
+ gettimeofday(&now,0);
+ delta = (double)now.tv_sec + (double)now.tv_usec/1000000.0;
+ delta -= (double)start.tv_sec + (double)start.tv_usec/1000000.0;
+ bytes = (int)( (delta * bytesPerSec)
+ - ((p == canRead)?samplesRead:samplesWritten)
+ );
+ return bytes;
+ break;
+
+ default:
+ return param(p);
+ break;
+ }
+}
+
+int AudioIONull::read(void *buffer, int size)
+{
+ samplesRead += size;
+ memset(buffer, 0, size);
+ return size;
+}
+
+int AudioIONull::write(void *, int size)
+{
+ samplesWritten += size;
+ return size;
+}
diff --git a/flow/audioiooss.cc b/flow/audioiooss.cc
new file mode 100644
index 0000000..214cd3b
--- /dev/null
+++ b/flow/audioiooss.cc
@@ -0,0 +1,485 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
+#if defined(HAVE_SYS_SOUNDCARD_H)
+ #include <sys/soundcard.h>
+ #define COMPILE_AUDIOIO_OSS 1
+#elif defined(HAVE_SOUNDCARD_H)
+ #include <soundcard.h>
+ #define COMPILE_AUDIOIO_OSS 1
+#endif
+
+/**
+ * only compile 'oss' AudioIO class if sys/soundcard.h or soundcard.h is present
+ */
+#ifdef COMPILE_AUDIOIO_OSS
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_SYS_SELECT_H
+ #include <sys/select.h> // Needed on some systems.
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <iostream>
+#include <algorithm>
+#include <cstring>
+
+#include "debug.h"
+#include "audioio.h"
+
+namespace Arts {
+
+class AudioIOOSS : public AudioIO {
+protected:
+ int audio_fd;
+ int requestedFragmentSize;
+ int requestedFragmentCount;
+
+ std::string findDefaultDevice();
+ int ossBits(int format);
+
+public:
+ AudioIOOSS();
+
+ void setParam(AudioParam param, int& value);
+ int getParam(AudioParam param);
+
+ bool open();
+ void close();
+ int read(void *buffer, int size);
+ int write(void *buffer, int size);
+};
+
+REGISTER_AUDIO_IO(AudioIOOSS,"oss","Open Sound System");
+}
+
+using namespace std;
+using namespace Arts;
+
+/*
+ * Tries to figure out which is the OSS device we should write to
+ */
+string AudioIOOSS::findDefaultDevice()
+{
+ static const char *device[] = {
+ "/dev/dsp", /* The usual device */
+ // how does access(2) deal with a directory?
+ // I don't know, but, since /dev/sound/dsp is a linux bogosity
+ #if defined(__linux__)
+ "/dev/sound/dsp", /* Linux with devfs-only installation */
+ #else
+ "/dev/sound", /* NetBSD */
+ #endif
+ "/dev/audio", /* OpenBSD */
+ 0
+ };
+
+ for(int i = 0; device[i]; i++)
+ if(access(device[i],F_OK) == 0)
+ return device[i];
+
+ // Should this really return a valid device if we have access to none?
+ return device[0];
+}
+
+int AudioIOOSS::ossBits(int format)
+{
+ arts_return_val_if_fail (format == AFMT_U8
+ || format == AFMT_S16_LE
+ || format == AFMT_S16_BE, 16);
+
+ return (format == AFMT_U8)?8:16;
+}
+
+AudioIOOSS::AudioIOOSS()
+{
+ /*
+ * default parameters
+ */
+ param(samplingRate) = 44100;
+ paramStr(deviceName) = findDefaultDevice();
+ requestedFragmentSize = param(fragmentSize) = 1024;
+ requestedFragmentCount = param(fragmentCount) = 7;
+ param(channels) = 2;
+ param(direction) = 2;
+}
+
+bool AudioIOOSS::open()
+{
+ string& _error = paramStr(lastError);
+ string& _deviceName = paramStr(deviceName);
+ int& _channels = param(channels);
+ int& _fragmentSize = param(fragmentSize);
+ int& _fragmentCount = param(fragmentCount);
+ int& _samplingRate = param(samplingRate);
+ int& _format = param(format);
+
+ int mode;
+
+ if(param(direction) == 3)
+ mode = O_RDWR|O_NDELAY;
+ else if(param(direction) == 2)
+ mode = O_WRONLY|O_NDELAY;
+ else
+ {
+ _error = "invalid direction";
+ return false;
+ }
+
+ audio_fd = ::open(_deviceName.c_str(), mode, 0);
+
+ if(audio_fd == -1)
+ {
+ _error = "device ";
+ _error += _deviceName.c_str();
+ _error += " can't be opened (";
+ _error += strerror(errno);
+ _error += ")";
+ return false;
+ }
+ /*
+ * check device capabilities
+ */
+ int device_caps;
+ if(ioctl(audio_fd,SNDCTL_DSP_GETCAPS,&device_caps) == -1)
+ device_caps=0;
+
+ string caps = "";
+ if(device_caps & DSP_CAP_DUPLEX) caps += "duplex ";
+ if(device_caps & DSP_CAP_REALTIME) caps += "realtime ";
+ if(device_caps & DSP_CAP_BATCH) caps += "batch ";
+ if(device_caps & DSP_CAP_COPROC) caps += "coproc ";
+ if(device_caps & DSP_CAP_TRIGGER) caps += "trigger ";
+ if(device_caps & DSP_CAP_MMAP) caps += "mmap ";
+ artsdebug("device capabilities: revision%d %s",
+ device_caps & DSP_CAP_REVISION, caps.c_str());
+
+ int requestedFormat = (_format == 8)?AFMT_U8:AFMT_S16_LE;
+ int gotFormat = requestedFormat;
+ if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &gotFormat)==-1)
+ {
+ _error = "SNDCTL_DSP_SETFMT failed - ";
+ _error += strerror(errno);
+
+ close();
+ return false;
+ }
+
+ if (_format && (ossBits(gotFormat) != ossBits(requestedFormat)))
+ {
+ char details[80];
+ sprintf(details," (_format = %d, asked driver to give %d, got %d)",
+ _format, requestedFormat, gotFormat);
+
+ _error = "Can't set playback format";
+ _error += details;
+
+ close();
+ return false;
+ }
+
+ if(gotFormat == AFMT_U8)
+ _format = 8;
+ else if(gotFormat == AFMT_S16_LE)
+ _format = 16;
+ else if(gotFormat == AFMT_S16_BE)
+ _format = 17;
+ else
+ {
+ char details[80];
+ sprintf(details," (_format = %d, asked driver to give %d, got %d)",
+ _format, requestedFormat, gotFormat);
+
+ _error = "unknown format given by driver";
+ _error += details;
+
+ close();
+ return false;
+ }
+
+
+ int stereo=-1; /* 0=mono, 1=stereo */
+
+ if(_channels == 1)
+ {
+ stereo = 0;
+ }
+ if(_channels == 2)
+ {
+ stereo = 1;
+ }
+
+ if(stereo == -1)
+ {
+ _error = "internal error; set channels to 1 (mono) or 2 (stereo)";
+
+ close();
+ return false;
+ }
+
+ int requeststereo = stereo;
+
+ if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo)==-1)
+ {
+ _error = "SNDCTL_DSP_STEREO failed - ";
+ _error += strerror(errno);
+
+ close();
+ return false;
+ }
+
+ if (requeststereo != stereo)
+ {
+ _error = "audio device doesn't support number of requested channels";
+
+ close();
+ return false;
+ }
+
+ int speed = _samplingRate;
+
+ if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &speed)==-1)
+ {
+ _error = "SNDCTL_DSP_SPEED failed - ";
+ _error += strerror(errno);
+
+ close();
+ return false;
+ }
+
+ /*
+ * Some soundcards seem to be able to only supply "nearly" the requested
+ * sampling rate, especially PAS 16 cards seem to quite radical supplying
+ * something different than the requested sampling rate ;)
+ *
+ * So we have a quite large tolerance here (when requesting 44100 Hz, it
+ * will accept anything between 38690 Hz and 49510 Hz). Most parts of the
+ * aRts code will do resampling where appropriate, so it shouldn't affect
+ * sound quality.
+ */
+ int tolerance = _samplingRate/10+1000;
+
+ if (abs(speed-_samplingRate) > tolerance)
+ {
+ _error = "can't set requested samplingrate";
+
+ char details[80];
+ sprintf(details," (requested rate %d, got rate %d)",
+ _samplingRate, speed);
+ _error += details;
+
+ close();
+ return false;
+ }
+ _samplingRate = speed;
+
+ /*
+ * set the fragment settings to what the user requested
+ */
+
+ _fragmentSize = requestedFragmentSize;
+ _fragmentCount = requestedFragmentCount;
+
+ /*
+ * lower 16 bits are the fragment size (as 2^S)
+ * higher 16 bits are the number of fragments
+ */
+ int frag_arg = 0;
+
+ int size = _fragmentSize;
+ while(size > 1) { size /= 2; frag_arg++; }
+ frag_arg += (_fragmentCount << 16);
+ if(ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag_arg) == -1)
+ {
+ char buffer[1024];
+ _error = "can't set requested fragments settings";
+ sprintf(buffer,"size%d:count%d\n",_fragmentSize,_fragmentCount);
+ close();
+ return false;
+ }
+
+ /*
+ * now see what we really got as cards aren't required to supply what
+ * we asked for
+ */
+ audio_buf_info info;
+ if(ioctl(audio_fd,SNDCTL_DSP_GETOSPACE, &info) == -1)
+ {
+ _error = "can't retrieve fragment settings";
+ close();
+ return false;
+ }
+
+ // update fragment settings with what we got
+ _fragmentSize = info.fragsize;
+ _fragmentCount = info.fragstotal;
+
+ artsdebug("buffering: %d fragments with %d bytes "
+ "(audio latency is %1.1f ms)", _fragmentCount, _fragmentSize,
+ (float)(_fragmentSize*_fragmentCount) /
+ (float)(2.0 * _samplingRate * _channels)*1000.0);
+
+ /*
+ * Workaround for broken kernel drivers: usually filling up the audio
+ * buffer is _only_ required if _fullDuplex is true. However, there
+ * are kernel drivers around (especially everything related to ES1370/1371)
+ * which will not trigger select()ing the file descriptor unless we have
+ * written something first.
+ */
+ char *zbuffer = (char *)calloc(sizeof(char), _fragmentSize);
+ if(_format == 8)
+ for(int zpos = 0; zpos < _fragmentSize; zpos++)
+ zbuffer[zpos] |= 0x80;
+
+ for(int fill = 0; fill < _fragmentCount; fill++)
+ {
+ int len = write(zbuffer,_fragmentSize);
+ if(len != _fragmentSize)
+ {
+ arts_debug("AudioIOOSS: failed prefilling audio buffer (might cause synchronization problems in conjunction with full duplex)");
+ fill = _fragmentCount+1;
+ }
+ }
+ free(zbuffer);
+
+ /*
+ * Triggering - the original aRts code did this for full duplex:
+ *
+ * - stop audio i/o using SETTRIGGER(~(PCM_ENABLE_INPUT|PCM_ENABLE_OUTPUT))
+ * - fill buffer (see zbuffer code two lines above)
+ * - start audio i/o using SETTRIGGER(PCM_ENABLE_INPUT|PCM_ENABLE_OUTPUT)
+ *
+ * this should guarantee synchronous start of input/output. Today, it
+ * seems there are too many broken drivers around for this.
+ */
+
+ if(device_caps & DSP_CAP_TRIGGER)
+ {
+ int enable_bits = 0;
+
+ if(param(direction) & 1) enable_bits |= PCM_ENABLE_INPUT;
+ if(param(direction) & 2) enable_bits |= PCM_ENABLE_OUTPUT;
+
+ if(ioctl(audio_fd,SNDCTL_DSP_SETTRIGGER, &enable_bits) == -1)
+ {
+ _error = "can't start sound i/o";
+
+ close();
+ return false;
+ }
+ }
+ return true;
+}
+
+void AudioIOOSS::close()
+{
+ ::close(audio_fd);
+}
+
+void AudioIOOSS::setParam(AudioParam p, int& value)
+{
+ switch(p)
+ {
+ case fragmentSize:
+ param(p) = requestedFragmentSize = value;
+ break;
+ case fragmentCount:
+ param(p) = requestedFragmentCount = value;
+ break;
+ default:
+ param(p) = value;
+ break;
+ }
+}
+
+int AudioIOOSS::getParam(AudioParam p)
+{
+ audio_buf_info info;
+ switch(p)
+ {
+ case canRead:
+ ioctl(audio_fd, SNDCTL_DSP_GETISPACE, &info);
+ return info.bytes;
+ break;
+
+ case canWrite:
+ ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info);
+ return info.bytes;
+ break;
+
+ case selectReadFD:
+ return (param(direction) & directionRead)?audio_fd:-1;
+ break;
+
+ case selectWriteFD:
+ return (param(direction) & directionWrite)?audio_fd:-1;
+ break;
+
+ case autoDetect:
+ /* OSS works reasonable almost everywhere where it compiles */
+ return 10;
+ break;
+
+ default:
+ return param(p);
+ break;
+ }
+}
+
+int AudioIOOSS::read(void *buffer, int size)
+{
+ arts_assert(audio_fd != 0);
+
+ int result;
+ do {
+ result = ::read(audio_fd,buffer,size);
+ } while(result == -1 && errno == EINTR);
+
+ return result;
+}
+
+int AudioIOOSS::write(void *buffer, int size)
+{
+ arts_assert(audio_fd != 0);
+
+ int result;
+ do {
+ result = ::write(audio_fd,buffer,size);
+ } while(result == -1 && errno == EINTR);
+
+ return result;
+}
+
+#endif
diff --git a/flow/audioioossthreaded.cc b/flow/audioioossthreaded.cc
new file mode 100644
index 0000000..9b63c4a
--- /dev/null
+++ b/flow/audioioossthreaded.cc
@@ -0,0 +1,681 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ Multithreading support by
+ Matthias Welwarsky <matze@stud.fbi.fh-darmstadt.de>
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_SOUNDCARD_H
+#include <sys/soundcard.h>
+#define COMPILE_AUDIOIO_OSS 1
+#endif
+
+#ifdef HAVE_SOUNDCARD_H
+#include <soundcard.h>
+#define COMPILE_AUDIOIO_OSS 1
+#endif
+
+/**
+ * only compile 'oss' AudioIO class if sys/soundcard.h or soundcard.h is present
+ * also, only compile if libpthread was found
+ */
+#if defined(COMPILE_AUDIOIO_OSS) && defined(HAVE_LIBPTHREAD)
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <iostream>
+#include <cstring>
+#include <algorithm>
+
+#include "debug.h"
+#include "audioio.h"
+#include "audiosubsys.h"
+#include "iomanager.h"
+#include "dispatcher.h"
+
+// thread safe data queue implementation
+#include "thread.h"
+#include "bufferqueue.h"
+
+namespace Arts {
+
+class AudioIOOSSThreaded : public AudioIO, public TimeNotify {
+private:
+ class ReaderThread : public Arts::Thread {
+ public:
+ void run();
+ bool isRunning() { return runThread; }
+ void stop() { runThread = false; }
+ void setParent(AudioIOOSSThreaded* instance) { parent = instance; }
+
+ private:
+ bool runThread;
+ AudioIOOSSThreaded* parent;
+ };
+
+ class WriterThread : public Arts::Thread {
+ public:
+ void run();
+ bool isRunning() { return runThread; }
+ void stop() { runThread = false; }
+ void setParent(AudioIOOSSThreaded* instance) { parent = instance; }
+
+ private:
+ bool runThread;
+ AudioIOOSSThreaded* parent;
+ };
+
+ friend class ReaderThread;
+ friend class WriterThread;
+
+ void startThread();
+ void stopThread();
+
+ BufferQueue readerQueue;
+ BufferQueue writerQueue;
+
+ ReaderThread readerThread;
+ WriterThread writerThread;
+
+protected:
+ int audio_fd;
+ int requestedFragmentSize;
+ int requestedFragmentCount;
+
+ std::string findDefaultDevice();
+ int ossBits(int format);
+
+public:
+ AudioIOOSSThreaded();
+
+ void setParam(AudioParam param, int& value);
+ int getParam(AudioParam param);
+
+ bool open();
+ void close();
+ int read(void *buffer, int size);
+ int write(void *buffer, int size);
+
+ void notifyTime();
+};
+
+REGISTER_AUDIO_IO(AudioIOOSSThreaded,"toss","Threaded Open Sound System");
+}
+
+using namespace std;
+using namespace Arts;
+
+/*
+ * Tries to figure out which is the OSS device we should write to
+ */
+string AudioIOOSSThreaded::findDefaultDevice()
+{
+ static const char *device[] = {
+ "/dev/dsp", /* Linux (and lots of others) */
+ "/dev/sound/dsp0", /* Linux with devfs-only installation */
+ "/dev/audio", /* OpenBSD */
+ 0
+ };
+
+ for(int i = 0; device[i]; i++)
+ if(access(device[i],F_OK) == 0)
+ return device[i];
+
+ return device[0];
+}
+
+int AudioIOOSSThreaded::ossBits(int format)
+{
+ arts_return_val_if_fail (format == AFMT_U8
+ || format == AFMT_S16_LE
+ || format == AFMT_S16_BE, 16);
+
+ return (format == AFMT_U8)?8:16;
+}
+
+AudioIOOSSThreaded::AudioIOOSSThreaded()
+{
+ /*
+ * default parameters
+ */
+ param(samplingRate) = 44100;
+ paramStr(deviceName) = findDefaultDevice();
+ requestedFragmentSize = param(fragmentSize) = 1024;
+ requestedFragmentCount = param(fragmentCount) = 7;
+ param(channels) = 2;
+ param(direction) = 2;
+}
+
+bool AudioIOOSSThreaded::open()
+{
+ string& _error = paramStr(lastError);
+ string& _deviceName = paramStr(deviceName);
+ int& _channels = param(channels);
+ int& _fragmentSize = param(fragmentSize);
+ int& _fragmentCount = param(fragmentCount);
+ int& _samplingRate = param(samplingRate);
+ int& _format = param(format);
+
+ if (!SystemThreads::supported()) {
+ _error = "System does not support multithreading";
+ return false;
+ }
+
+ int mode;
+
+ if(param(direction) == 3)
+ mode = O_RDWR;
+ else if(param(direction) == 2)
+ mode = O_WRONLY;
+ else
+ {
+ _error = "invalid direction";
+ return false;
+ }
+
+ audio_fd = ::open(_deviceName.c_str(), mode, 0);
+
+ if(audio_fd == -1)
+ {
+ _error = "device ";
+ _error += _deviceName.c_str();
+ _error += " can't be opened (";
+ _error += strerror(errno);
+ _error += ")";
+ return false;
+ }
+ /*
+ * check device capabilities
+ */
+ int device_caps;
+ if(ioctl(audio_fd,SNDCTL_DSP_GETCAPS,&device_caps) == -1)
+ device_caps=0;
+
+ string caps = "";
+ if(device_caps & DSP_CAP_DUPLEX) caps += "duplex ";
+ if(device_caps & DSP_CAP_REALTIME) caps += "realtime ";
+ if(device_caps & DSP_CAP_BATCH) caps += "batch ";
+ if(device_caps & DSP_CAP_COPROC) caps += "coproc ";
+ if(device_caps & DSP_CAP_TRIGGER) caps += "trigger ";
+ if(device_caps & DSP_CAP_MMAP) caps += "mmap ";
+ artsdebug("device capabilities: revision%d %s",
+ device_caps & DSP_CAP_REVISION, caps.c_str());
+
+ int requestedFormat = (_format == 8)?AFMT_U8:AFMT_S16_LE;
+ int gotFormat = requestedFormat;
+ if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &gotFormat)==-1)
+ {
+ _error = "SNDCTL_DSP_SETFMT failed - ";
+ _error += strerror(errno);
+
+ close();
+ return false;
+ }
+
+ if (_format && (ossBits(gotFormat) != ossBits(requestedFormat)))
+ {
+ char details[80];
+ sprintf(details," (_format = %d, asked driver to give %d, got %d)",
+ _format, requestedFormat, gotFormat);
+
+ _error = "Can't set playback format";
+ _error += details;
+
+ close();
+ return false;
+ }
+
+ if(gotFormat == AFMT_U8)
+ _format = 8;
+ else if(gotFormat == AFMT_S16_LE)
+ _format = 16;
+ else if(gotFormat == AFMT_S16_BE)
+ _format = 17;
+ else
+ {
+ char details[80];
+ sprintf(details," (_format = %d, asked driver to give %d, got %d)",
+ _format, requestedFormat, gotFormat);
+
+ _error = "unknown format given by driver";
+ _error += details;
+
+ close();
+ return false;
+ }
+
+
+ int stereo=-1; /* 0=mono, 1=stereo */
+
+ if(_channels == 1)
+ {
+ stereo = 0;
+ }
+ if(_channels == 2)
+ {
+ stereo = 1;
+ }
+
+ if(stereo == -1)
+ {
+ _error = "internal error; set channels to 1 (mono) or 2 (stereo)";
+
+ close();
+ return false;
+ }
+
+ int requeststereo = stereo;
+
+ if (ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo)==-1)
+ {
+ _error = "SNDCTL_DSP_STEREO failed - ";
+ _error += strerror(errno);
+
+ close();
+ return false;
+ }
+
+ if (requeststereo != stereo)
+ {
+ _error = "audio device doesn't support number of requested channels";
+
+ close();
+ return false;
+ }
+
+ int speed = _samplingRate;
+
+ if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &speed)==-1)
+ {
+ _error = "SNDCTL_DSP_SPEED failed - ";
+ _error += strerror(errno);
+
+ close();
+ return false;
+ }
+
+ /*
+ * Some soundcards seem to be able to only supply "nearly" the requested
+ * sampling rate, especially PAS 16 cards seem to quite radical supplying
+ * something different than the requested sampling rate ;)
+ *
+ * So we have a quite large tolerance here (when requesting 44100 Hz, it
+ * will accept anything between 38690 Hz and 49510 Hz). Most parts of the
+ * aRts code will do resampling where appropriate, so it shouldn't affect
+ * sound quality.
+ */
+ int tolerance = _samplingRate/10+1000;
+
+ if (abs(speed-_samplingRate) > tolerance)
+ {
+ _error = "can't set requested samplingrate";
+
+ char details[80];
+ sprintf(details," (requested rate %d, got rate %d)",
+ _samplingRate, speed);
+ _error += details;
+
+ close();
+ return false;
+ }
+ _samplingRate = speed;
+
+ /*
+ * set the fragment settings to what the user requested
+ */
+
+ _fragmentSize = requestedFragmentSize;
+ _fragmentCount = requestedFragmentCount;
+
+ /*
+ * lower 16 bits are the fragment size (as 2^S)
+ * higher 16 bits are the number of fragments
+ */
+ unsigned int frag_arg = 0;
+
+ unsigned int size = _fragmentSize;
+ while(size > 1) { size /= 2; frag_arg++; }
+ frag_arg += (_fragmentCount << 16);
+
+ //////////////////////////////////////////////////////////////////////
+ // MW
+ // stopping here because the fragment settings cannot be done
+ // is not sensible. Especially not as we check the settings in the
+ // very next step. We should handle this gracefully.
+ //
+ ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag_arg);
+
+ /*
+ * now see what we really got as cards aren't required to supply what
+ * we asked for
+ */
+ audio_buf_info info;
+ if(ioctl(audio_fd,SNDCTL_DSP_GETOSPACE, &info) == -1)
+ {
+ _error = "can't retrieve fragment settings";
+ close();
+ return false;
+ }
+
+ // update fragment settings with what we got
+ //_fragmentSize = info.fragsize;
+ //_fragmentCount = info.fragstotal;
+
+ fprintf(stderr, "buffering: fragsize:%d fragstotal:%d\n",
+ _fragmentSize, _fragmentCount);
+
+ artsdebug("buffering: %d fragments with %d bytes "
+ "(audio latency is %1.1f ms)", _fragmentCount, _fragmentSize,
+ (float)(_fragmentSize*_fragmentCount) /
+ (float)(2.0 * _samplingRate * _channels)*1000.0);
+
+ // set the chunk size of the buffer queues.
+ readerQueue.setChunkSize(_fragmentSize);
+ writerQueue.setChunkSize(_fragmentSize);
+
+ /*
+ * Workaround for broken kernel drivers: usually filling up the audio
+ * buffer is _only_ required if _fullDuplex is true. However, there
+ * are kernel drivers around (especially everything related to ES1370/1371)
+ * which will not trigger select()ing the file descriptor unless we have
+ * written something first.
+ */
+ char *zbuffer = (char *)calloc(sizeof(char), _fragmentSize);
+ if(_format == 8)
+ for(int zpos = 0; zpos < _fragmentSize; zpos++)
+ zbuffer[zpos] |= 0x80;
+
+ for(int fill = 0; fill < _fragmentCount; fill++)
+ {
+ int len = ::write(audio_fd,zbuffer,_fragmentSize);
+ if(len != _fragmentSize)
+ {
+ arts_debug("AudioIOOSSThreaded: failed prefilling audio buffer (might cause synchronization problems in conjunction with full duplex)");
+ fill = _fragmentCount+1;
+ }
+ }
+ free(zbuffer);
+
+ /*
+ * Triggering - the original aRts code did this for full duplex:
+ *
+ * - stop audio i/o using SETTRIGGER(~(PCM_ENABLE_INPUT|PCM_ENABLE_OUTPUT))
+ * - fill buffer (see zbuffer code two lines above
+ * - start audio i/o using SETTRIGGER(PCM_ENABLE_INPUT|PCM_ENABLE_OUTPUT)
+ *
+ * this should guarantee synchronous start of input/output. Today, it
+ * seems there are too many broken drivers around for this.
+ */
+
+ if(device_caps & DSP_CAP_TRIGGER)
+ {
+ int enable_bits = 0;
+
+ if(param(direction) & 1) enable_bits |= PCM_ENABLE_INPUT;
+ if(param(direction) & 2) enable_bits |= PCM_ENABLE_OUTPUT;
+
+ if(ioctl(audio_fd,SNDCTL_DSP_SETTRIGGER, &enable_bits) == -1)
+ {
+ _error = "can't start of sound i/o operation";
+
+ close();
+ return false;
+ }
+ }
+
+ startThread();
+
+ Dispatcher::the()->ioManager()->addTimer(10, this);
+
+ return true;
+}
+
+void AudioIOOSSThreaded::close()
+{
+ fprintf(stderr, "AudioIO::close(): entering\n");
+ Dispatcher::the()->ioManager()->removeTimer(this);
+
+ ::close(audio_fd);
+ stopThread();
+ fprintf(stderr, "AudioIO::close(): leaving\n");
+}
+
+void AudioIOOSSThreaded::notifyTime()
+{
+ int& _direction = param(direction);
+
+ for(int i=0; i < 3; i++) {
+ int todo = 0;
+
+ if((_direction & directionRead) && getParam(canRead) > 0)
+ todo |= AudioSubSystem::ioRead;
+
+ if((_direction & directionWrite) && getParam(canWrite) > 0)
+ todo |= AudioSubSystem::ioWrite;
+
+ //fprintf(stderr, "AudioIO: can write %d, fragment size %d, todo %d\n",
+ // getParam(canWrite), _fragmentSize, todo);
+
+ if(!todo) // break endless loop
+ break;
+
+ AudioSubSystem::the()->handleIO(todo);
+ }
+}
+
+void AudioIOOSSThreaded::setParam(AudioParam p, int& value)
+{
+ switch(p) {
+ case fragmentSize:
+ param(p) = requestedFragmentSize = value;
+ break;
+
+ case fragmentCount:
+ param(p) = requestedFragmentCount = value;
+ break;
+
+ default:
+ param(p) = value;
+ break;
+ }
+}
+
+int AudioIOOSSThreaded::getParam(AudioParam p)
+{
+ switch(p) {
+ case canRead:
+ return readerQueue.bufferedChunks() * readerQueue.chunkSize();
+ break;
+
+ case canWrite:
+ return writerQueue.freeChunks() * writerQueue.chunkSize();
+ break;
+
+ case autoDetect:
+ /* It compiles, but Posix Threads don't work everywhere */
+ return 4;
+ break;
+
+ default:
+ return param(p);
+ break;
+ }
+}
+
+int AudioIOOSSThreaded::read(void *buffer, int size)
+{
+ int copied = 0;
+ int copySize;
+ ByteBuffer* tmpBuf = 0;
+ while (size > 0) {
+ if (!tmpBuf)
+ tmpBuf = readerQueue.waitProduced();
+
+ copySize = (size > tmpBuf->size())? tmpBuf->size():size;
+ memcpy(((char*)buffer)+copied, tmpBuf->get(), copySize);
+
+ if (tmpBuf->push(copySize) == 0) {
+ tmpBuf = 0;
+ readerQueue.consumed();
+ }
+
+ copied += copySize;
+ size -= copySize;
+ }
+ return copied;
+}
+
+int AudioIOOSSThreaded::write(void *buffer, int size)
+{
+ int copied = 0;
+ while (size > 0) {
+ int copySize = (size > writerQueue.chunkSize())?writerQueue.chunkSize():size;
+ if (!writerQueue.freeChunks())
+ fprintf(stderr, "AudioIO::write will block!\n");
+ writerQueue.write(buffer, copySize);
+ copied += copySize;
+ size -= copySize;
+ }
+ return copied;
+}
+
+/*
+ * posix thread to feed the audio device
+ */
+
+void AudioIOOSSThreaded::WriterThread::run()
+{
+ fprintf(stderr, "AudioIOOSSThreaded::writerThread() thread started\n");
+
+ setPriority(45);
+
+ runThread = true;
+
+ ssize_t size;
+ ByteBuffer* tmpBuf = 0;
+ while (runThread) {
+
+ if (!tmpBuf) {
+ tmpBuf = parent->writerQueue.waitProduced();
+
+ if (!tmpBuf->size()) {
+ tmpBuf = NULL;
+ parent->writerQueue.consumed();
+ continue;
+ }
+ }
+
+ size = ::write(parent->audio_fd, tmpBuf->get(), tmpBuf->size());
+
+ if (size >= 0) {
+ if (tmpBuf->push(size) == 0) {
+ tmpBuf = NULL;
+ parent->writerQueue.consumed();
+ }
+ } else if (errno != EINTR) {
+ // this is a fatal error. we cannot write to the fd any more.
+ runThread = false;
+ fprintf(stderr, "AudioIOOSSTHreaded::writerThread() fatal error writing to audio_fd\n");
+ }
+ }
+ fprintf(stderr, "AudioIOOSSThreaded::writerThread() thread stopped\n");
+}
+
+/*
+ * posix thread to read the audio device
+ */
+void AudioIOOSSThreaded::ReaderThread::run()
+{
+ fprintf(stderr, "AudioIOOSSThreaded::readerThread() thread started\n");
+
+ runThread = true;
+
+ ByteBuffer* tmpBuf;
+ ssize_t size;
+ while (runThread) {
+ tmpBuf = parent->readerQueue.waitConsumed();
+
+ size = ::read(parent->audio_fd, tmpBuf->reset(), tmpBuf->maxSize());
+
+ if (size >= 0) {
+ tmpBuf->set(size);
+ parent->readerQueue.produced();
+ } else if (errno != EINTR) {
+ runThread = false;
+ fprintf(stderr, "AudioIOOSSTHreaded::readerThread() fatal error reading from audio_fd\n");
+ }
+ }
+ fprintf(stderr, "AudioIOOSSThreaded::readerThread() thread stopped\n");
+}
+
+void AudioIOOSSThreaded::startThread()
+{
+ fprintf(stderr, "AudioIOOSSThreaded::startThread(): entering\n");
+
+ if (param(direction) & directionWrite) {
+ writerThread.setParent(this);
+ writerThread.start();
+ }
+ if (param(direction) & directionRead) {
+ readerThread.setParent(this);
+ readerThread.start();
+ }
+
+ fprintf(stderr, "AudioIOOSSThreaded::startThread(): leaving\n");
+}
+
+void AudioIOOSSThreaded::stopThread()
+{
+ fprintf(stderr, "AudioIOOSSThreaded::stopThread() entering\n");
+
+ if (param(direction) & directionWrite) {
+ writerThread.stop();
+ // make sure there's something to write, avoids race condition
+ if (writerQueue.isEmpty())
+ writerQueue.write(NULL, 0);
+ fprintf(stderr, "waiting for writerThread to finish\n");
+ writerThread.waitDone();
+ writerQueue.clear();
+ }
+
+ if (param(direction) & directionRead) {
+ readerThread.stop();
+ fprintf(stderr, "waiting for readerThread to finish\n");
+ readerThread.waitDone();
+ readerQueue.clear();
+ }
+
+ fprintf(stderr, "AudioIOOSSThreaded::stopThread(): leaving\n");
+}
+
+#endif
diff --git a/flow/audioiosgi.cc b/flow/audioiosgi.cc
new file mode 100644
index 0000000..96a677c
--- /dev/null
+++ b/flow/audioiosgi.cc
@@ -0,0 +1,274 @@
+ /*
+
+ Copyright (C) 2001 Carsten Kroll
+ ckroll@pinnaclesys.com
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/**
+ * only compile 'sgi' AudioIO class if compiled under IRIX
+ */
+#ifdef HAVE_IRIX
+
+#include <dmedia/audio.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h> // Needed on some systems.
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <iostream>
+#include <algorithm>
+
+#include "debug.h"
+#include "audioio.h"
+
+namespace Arts {
+
+class AudioIOSGI : public AudioIO {
+protected:
+ int requestedFragmentSize;
+ int requestedFragmentCount;
+ ALport audio_port,audio_port1;
+ ALconfig audioconfig;
+ int framesz;
+
+public:
+ AudioIOSGI();
+
+ void setParam(AudioParam param, int& value);
+ int getParam(AudioParam param);
+
+ bool open();
+ void close();
+ int read(void *buffer, int size);
+ int write(void *buffer, int size);
+};
+
+
+REGISTER_AUDIO_IO(AudioIOSGI,"sgi","SGI dmedia Audio I/O");
+};
+
+using namespace std;
+using namespace Arts;
+
+AudioIOSGI::AudioIOSGI()
+{
+ /*
+ * default parameters
+ */
+ param(samplingRate) = 44100;
+ paramStr(deviceName) = "audioio";
+ requestedFragmentSize = param(fragmentSize) = 4096;
+ requestedFragmentCount = param(fragmentCount) = 10;
+ audio_port=0;
+ audio_port1=0;
+ param(format)=17;
+ param(channels) = 2;
+ param(direction) = 2;
+}
+
+bool AudioIOSGI::open()
+{
+ string& _error = paramStr(lastError);
+ string& _deviceName = paramStr(deviceName);
+ int& _channels = param(channels);
+ int& _fragmentSize = param(fragmentSize);
+ int& _fragmentCount = param(fragmentCount);
+ int& _samplingRate = param(samplingRate);
+ int& _format = param(format);
+ int& _direction = param(direction);
+ int err;
+
+ if(_direction != 3 && _direction != 2){
+ _error = "invalid direction";
+ return false;
+ }
+ framesz=((_format & ~1) >> 3) * _channels;
+
+ audioconfig = alNewConfig();
+ alSetSampFmt(audioconfig,AL_SAMPFMT_TWOSCOMP);
+
+ alSetWidth(audioconfig, _format==8 ? AL_SAMPLE_8 : _format==16 || _format==17 ? AL_SAMPLE_16 : AL_SAMPLE_24);
+ alSetQueueSize(audioconfig,(requestedFragmentSize * requestedFragmentCount) / framesz);
+ alSetChannels(audioconfig,_channels);
+
+ audio_port = alOpenPort("out","w",audioconfig);
+
+
+ if (audio_port == (ALport) 0 ) {
+ err = oserror();
+ if (err == AL_BAD_NO_PORTS) {
+ _error = "System is out of audio ports";
+ } else if (err == AL_BAD_DEVICE_ACCESS) {
+ _error = "Couldn't access audio device";
+ } else if (err == AL_BAD_OUT_OF_MEM) {
+ _error = "Out of memory";
+ }
+ close();
+ return false;
+ }
+ if (_direction == 3){
+ audio_port1 = alOpenPort("in","r",audioconfig);
+ if (audio_port1 == (ALport) 0 ) {
+ err = oserror();
+ if (err == AL_BAD_NO_PORTS) {
+ _error = "System is out of audio ports";
+ } else if (err == AL_BAD_DEVICE_ACCESS) {
+ _error = "Couldn't access audio device";
+ } else if (err == AL_BAD_OUT_OF_MEM) {
+ _error = "Out of memory";
+ }
+ close();
+ return false;
+ }
+ }
+ /*
+ * Attempt to set a crystal-based sample-rate on the
+ * given device.
+ */
+ ALpv x[2];
+ x[0].param = AL_MASTER_CLOCK;
+ x[0].value.i = AL_CRYSTAL_MCLK_TYPE;
+ x[1].param = AL_RATE;
+ x[1].value.ll = alDoubleToFixed(double(_samplingRate));
+ if (alSetParams(alGetResource(audio_port),x, 2)<0) {
+ _error="setparams failed: ";
+ _error+=alGetErrorString(oserror());
+ close();
+ return false;
+ }
+ if (_direction == 3)
+ if (alSetParams(alGetResource(audio_port1),x, 2)<0) {
+ _error="setparams failed: ";
+ _error+=alGetErrorString(oserror());
+ close();
+ return false;
+ }
+ if (x[1].sizeOut < 0) {
+ _error="rate was invalid";
+ close();
+ return false;
+ }
+
+ alSetFillPoint(audio_port,(alGetQueueSize(audioconfig)*5)/10) ;//50 %
+ if (_direction == 3)
+ alSetFillPoint(audio_port1,(alGetQueueSize(audioconfig)*4)/10) ;//40 %
+ /*
+ * set the fragment settings to what the user requested
+ */
+
+ _fragmentSize = requestedFragmentSize;
+ _fragmentCount = requestedFragmentCount;
+
+
+ artsdebug("buffering: %d fragments with %d bytes "
+ "(audio latency is %1.1f ms)", _fragmentCount, _fragmentSize,
+ (float)(_fragmentSize*_fragmentCount) /
+ (float)(2.0 * _samplingRate * _channels)*1000.0);
+
+
+ return true;
+}
+
+void AudioIOSGI::close()
+{
+ alFreeConfig(audioconfig);
+ alClosePort(audio_port);
+ audio_port=0;
+ if (param(direction) == 3) {
+ alClosePort(audio_port1);
+ audio_port1=0;
+ }
+}
+
+void AudioIOSGI::setParam(AudioParam p, int& value)
+{
+ switch(p)
+ {
+ case fragmentSize:
+ param(p) = requestedFragmentSize = value;
+ break;
+ case fragmentCount:
+ param(p) = requestedFragmentCount = value;
+ break;
+ default:
+ param(p) = value;
+ break;
+ }
+}
+
+int AudioIOSGI::getParam(AudioParam p)
+{
+ int frames;
+ switch(p)
+ {
+ case canRead:
+ frames=alGetFilled(audio_port);
+ return frames*framesz;
+ break;
+
+ case canWrite:
+ frames=alGetFillable(audio_port);
+ return frames*framesz;
+ break;
+
+ case selectReadFD:
+ return (param(direction) & directionRead)?
+ alGetFD(audio_port1):-1;
+ break;
+
+ case selectWriteFD:
+ return (param(direction) & directionWrite)?
+ alGetFD(audio_port):-1;
+ break;
+
+ default:
+ return param(p);
+ break;
+ }
+}
+
+int AudioIOSGI::read(void *buffer, int size)
+{
+ arts_assert(audio_port1 != 0);
+ ::alReadFrames(audio_port1,buffer,size/framesz);
+ return size;
+}
+
+int AudioIOSGI::write(void *buffer, int size)
+{
+ arts_assert(audio_port != 0);
+ ::alWriteFrames(audio_port,buffer,size/framesz);
+ return size;
+}
+
+#endif
diff --git a/flow/audioiosun.cc b/flow/audioiosun.cc
new file mode 100644
index 0000000..9b14aa4
--- /dev/null
+++ b/flow/audioiosun.cc
@@ -0,0 +1,442 @@
+ /*
+
+ Copyright (C) 2001 Aaron Williams
+ aaronw@home.com
+ (C) 2001 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+/*
+ * Audio support for Sun Solaris, written by Aaron Williams
+ *
+ *
+ * Please send comments to aaronw@home.com
+ *
+ * This code has been tested with Solaris 7 running on a Sun Ultra 5
+ *
+ * Note that in Solaris the select support appears to be broken.
+ * Because of this, we use a timer and a dispatcher instead so we
+ * arn't polling (and sucking up most of the CPU).
+ *
+ * Currently read support has not been tested and will likely break
+ * other code
+ *
+ * 8-bit audio support also does not work (which I don't consider a
+ * big deal).
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/*
+ * Only compile this AudioIO class if we're on Solaris
+ */
+#ifdef USE_SOLARIS
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#include <sys/audioio.h>
+#include <stropts.h>
+#include <sys/conf.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <iostream>
+#include <algorithm>
+
+#include "debug.h"
+#include "audioio.h"
+#include "audiosubsys.h"
+#include "iomanager.h"
+#include "dispatcher.h"
+
+// This looks like the maximum buffer size according to the sys/audio*.h
+// files on Solaris7
+#define SUN_MAX_BUFFER_SIZE (65536)
+
+namespace Arts {
+
+ class AudioIOSun : public AudioIO, public TimeNotify {
+ protected:
+ uint_t bytesRead, bytesWritten, bytesPerSec;
+ uint_t bytesPerSample;
+ timeval start;
+ int audio_fd;
+ int requestedFragmentSize;
+ int requestedFragmentCount;
+ audio_info_t auinfo;
+
+#ifdef WORDS_BIGENDIAN
+ static const int defaultFormat = 17;
+#else
+ static const int defaultFormat = 16;
+#endif
+
+ public:
+ AudioIOSun();
+
+ // Timer callback
+ void notifyTime();
+
+ void setParam(AudioParam param, int& value);
+
+ int getParam(AudioParam param);
+
+ bool open();
+ void close();
+ int read(void *buffer, int size);
+ int write(void *buffer, int size);
+ };
+
+ REGISTER_AUDIO_IO(AudioIOSun,"sun","Sun Audio Input/Output");
+
+};
+
+using namespace std;
+using namespace Arts;
+
+AudioIOSun::AudioIOSun()
+{
+ /*
+ * default parameters
+ */
+ param(samplingRate) = 44100;
+ // solaris convention to support SunRays run out-of-the-box
+ const char *audioDev = getenv("AUDIODEV");
+ paramStr(deviceName) = (audioDev != 0)?audioDev:"/dev/audio";
+ param(fragmentSize) = 1024;
+ param(fragmentCount) = 7;
+ param(channels) = 2;
+ param(direction) = 2;
+ param(format) = defaultFormat;
+}
+
+// Opens the audio device
+bool AudioIOSun::open()
+{
+ string& _error = paramStr(lastError);
+ string& _deviceName = paramStr(deviceName);
+ int& _channels = param(channels);
+ int& _fragmentSize = param(fragmentSize);
+ int& _fragmentCount = param(fragmentCount);
+ int& _samplingRate = param(samplingRate);
+ int& _format = param(format);
+
+ int mode;
+
+ if (param(direction) == 3)
+ mode = O_RDWR;
+ else if (param(direction) == 2)
+ mode = O_WRONLY;
+ else
+ {
+ _error = "invalid direction";
+ return false;
+ }
+
+ audio_fd = ::open(_deviceName.c_str(), mode, 0);
+
+ if (audio_fd < 0)
+ {
+ _error = "device ";
+ _error += _deviceName.c_str();
+ _error += " can't be opened (";
+ _error += strerror(errno);
+ _error += ")";
+ return false;
+ }
+
+ fcntl(audio_fd, F_SETFL, O_NDELAY);
+
+ AUDIO_INITINFO(&auinfo);
+
+ if (ioctl(audio_fd, AUDIO_GETINFO, &auinfo) < 0)
+ {
+ _error = "device ";
+ _error += _deviceName.c_str();
+ _error += " AUDIO_GETINFO failed (";
+ _error += strerror(errno);
+ _error += ")";
+ return false;
+ }
+
+ if(_format != 8) _format = defaultFormat;
+#if 0
+ printf("param(direction)=%d\n", param(direction));
+ printf("format: %d\n", _format);
+ printf("channels: %d\n", _channels);
+ printf("sampling rate: %d\n", _samplingRate);
+#endif
+
+ bytesPerSample = ((_format == 8) ? 8 : 16)/8 * _channels;
+
+ auinfo.play.precision = (_format == 8) ? 8 : 16;
+ if (param(direction) == 3)
+ auinfo.record.precision = (_format == 8) ? 8 : 16;
+
+ auinfo.play.encoding = AUDIO_ENCODING_LINEAR;
+ if (param(direction) == 3)
+ auinfo.record.encoding = AUDIO_ENCODING_LINEAR;
+
+ auinfo.play.channels = _channels;
+ if (param(direction) == 3)
+ auinfo.record.channels = _channels;
+
+ auinfo.play.sample_rate = _samplingRate;
+ if (param(direction) == 3)
+ auinfo.record.sample_rate = _samplingRate;
+
+ if (ioctl(audio_fd, AUDIO_SETINFO, &auinfo) < 0)
+ {
+ _error = "AUDIO_SETINFO failed - ";
+ _error += strerror(errno);
+
+ close();
+ return false;
+ }
+
+
+ if (ioctl(audio_fd, AUDIO_GETINFO, &auinfo) < 0)
+ {
+ _error = "device ";
+ _error += _deviceName.c_str();
+ _error += " AUDIO_GETINFO failed (";
+ _error += strerror(errno);
+ _error += ")";
+ return false;
+ }
+
+ if (auinfo.play.precision != (uint_t)((_format == 8) ? 8 : 16) ||
+ (param(direction) == 3 &&
+ auinfo.record.precision != (uint_t)((_format == 8) ? 8 : 16)))
+ {
+ char play_details[80];
+ char record_details[80];
+ sprintf(play_details,
+ " (_format = %d, asked driver to give %d, got %d)",
+ _format, _format, auinfo.play.precision);
+ if (param(direction) == 3)
+ sprintf(record_details,
+ " (_format = %d, asked driver to give %d, got %d)",
+ _format, _format, auinfo.record.precision);
+
+ _error = "Can't set playback and/or record format ";
+ _error += "Play format: ";
+ _error += play_details;
+ if (param(direction) == 3) {
+ _error += " Record format: ";
+ _error += record_details;
+ }
+ close();
+ return false;
+ }
+ if ((auinfo.play.encoding != (uint_t)AUDIO_ENCODING_LINEAR) ||
+ (param(direction) == 3 &&
+ auinfo.record.encoding != (uint_t)AUDIO_ENCODING_LINEAR))
+ {
+ char play_encoding[80], record_encoding[80];
+ sprintf(play_encoding, "(%d bits, %d encoding)",
+ auinfo.play.precision, auinfo.play.encoding);
+ sprintf(record_encoding, "(%d bits, %d encoding)",
+ auinfo.record.precision, auinfo.record.encoding);
+
+ _error = "Can't set playback and/or record format";
+ _error += "requested format was ";
+ _error += (_format == 8) ? "8-bit AUDIO_ENCODING_LINEAR" :
+ "16-bit AUDIO_ENCODING_LINEAR";
+ _error += ", got playback format ";
+ _error += play_encoding;
+ if (param(direction) == 3) {
+ _error += ", record format ";
+ _error += record_encoding;
+ }
+
+ close();
+ return false;
+ }
+
+ if (auinfo.play.channels != (uint_t)_channels) {
+ _error = "Audio device doesn't support number of ";
+ _error += "requested playback channels";
+ close();
+ return false;
+ }
+ if (param(direction) == 3 && auinfo.record.channels != (uint_t)_channels) {
+ _error = "Audio device doesn't support number of ";
+ _error += "requested record channels";
+ close();
+ return false;
+ }
+
+ int tolerance = _samplingRate/10+1000;
+
+ if (abs(int(auinfo.play.sample_rate - _samplingRate)) > tolerance)
+ {
+ _error = "can't set requested playback sampling rate";
+
+ char details[80];
+ sprintf(details," (requested rate %d, got rate %d)",
+ _samplingRate, auinfo.play.sample_rate);
+ _error += details;
+
+ close();
+ return false;
+ }
+
+ if (param(direction) == 3 &&
+ abs(int(auinfo.record.sample_rate - _samplingRate)) > tolerance)
+ {
+ _error = "can't set requested record sampling rate";
+
+ char details[80];
+ sprintf(details," (requested rate %d, got rate %d)",
+ _samplingRate, auinfo.play.sample_rate);
+ _error += details;
+
+ close();
+ return false;
+ }
+
+
+ /*
+ * don't allow unreasonable large fragmentSize/Count combinations,
+ * because "real" hardware also doesn't
+ */
+
+ if(_fragmentSize > SUN_MAX_BUFFER_SIZE)
+ _fragmentSize = SUN_MAX_BUFFER_SIZE;
+
+ while(_fragmentSize * _fragmentCount > SUN_MAX_BUFFER_SIZE)
+ _fragmentCount--;
+
+ bytesRead = bytesWritten = 0;
+ bytesPerSec = _channels * 2 * _samplingRate;
+
+ // Install the timer
+ Dispatcher::the()->ioManager()->addTimer(10, this);
+
+ gettimeofday(&start,0);
+
+ return true;
+}
+
+void AudioIOSun::close()
+{
+ ::close(audio_fd);
+ Dispatcher::the()->ioManager()->removeTimer(this);
+}
+
+// This is called on each timer tick
+void AudioIOSun::notifyTime()
+{
+ int& _direction = param(direction);
+ int& _fragmentSize = param(fragmentSize);
+
+ for (;;) {
+ int todo = 0;
+ if ((_direction & directionRead) && getParam(canRead) > _fragmentSize)
+ todo |= AudioSubSystem::ioRead;
+
+ if ((_direction & directionWrite) && getParam(canWrite) > _fragmentSize)
+ todo |= AudioSubSystem::ioWrite;
+
+ if (!todo)
+ return;
+
+ AudioSubSystem::the()->handleIO(todo);
+ }
+}
+
+void AudioIOSun::setParam(AudioParam p, int& value)
+{
+ switch(p) {
+ case fragmentSize:
+ param(p) = requestedFragmentSize = value;
+ break;
+ case fragmentCount:
+ param(p) = requestedFragmentCount = value;
+ break;
+ default:
+ param(p) = value;
+ break;
+ }
+}
+
+int AudioIOSun::getParam(AudioParam p)
+{
+ int bytes;
+ int count;
+
+ switch(p)
+ {
+ case canRead:
+ if (ioctl(audio_fd, AUDIO_GETINFO, &auinfo) < 0)
+ return (0);
+ bytes = (auinfo.record.samples * bytesPerSample) - bytesRead;
+ if (bytes < 0) {
+ printf("Error: bytes %d < 0, samples=%u, bytesRead=%u\n",
+ bytes, auinfo.record.samples, bytesRead);
+ bytes = 0;
+ }
+ return bytes;
+
+ case canWrite:
+ if (ioctl(audio_fd, AUDIO_GETINFO, &auinfo) < 0)
+ return (0);
+ count = SUN_MAX_BUFFER_SIZE -
+ (bytesWritten - (auinfo.play.samples * bytesPerSample));
+ return count;
+
+ case autoDetect:
+ /*
+ * If we're on Solaris, this driver is the one that will work,
+ * and if we're not on Solaris, it won't be compiled anyway.
+ */
+ return 12;
+
+ default:
+ return param(p);
+ }
+}
+
+int AudioIOSun::read(void *buffer, int size)
+{
+ size = ::read(audio_fd, buffer, size);
+ if (size < 0)
+ return 0;
+
+ bytesRead += size;
+ return size;
+}
+
+int AudioIOSun::write(void *buffer, int size)
+{
+ size = ::write(audio_fd, buffer, size);
+ bytesWritten += size;
+ return size;
+}
+
+#endif /* USE_SOLARIS */
diff --git a/flow/audiomanager_impl.cc b/flow/audiomanager_impl.cc
new file mode 100644
index 0000000..c2d2567
--- /dev/null
+++ b/flow/audiomanager_impl.cc
@@ -0,0 +1,325 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include "artsflow.h"
+#include "flowsystem.h"
+#include "stdsynthmodule.h"
+#include "bus.h"
+
+using namespace Arts;
+using namespace std;
+
+namespace Arts {
+
+class AudioManagerClient_impl;
+
+class AudioManagerAssignable {
+public:
+ virtual long ID() = 0;
+ virtual void destination(const string& newDestination) = 0;
+};
+
+#ifdef __SUNPRO_CC
+/* Bloody SunPRO CC has problems with instantiation of the below two
+ templates, if the _clients and assignable member of AudioManager_impl
+ are declared to be directly the type list<xxx *>. So instead be move
+ a typedef in between, which makes it magically work.
+ We could also use an explicit instantiation, but this is not allowed
+ on all C++ compilers in this scope. Note also, that we don't need
+ to replace _all_ occurrences of list<xxx*> below, only the two in the
+ member declaration. What a mess. */
+typedef list<AudioManagerClient_impl *> L_AMC;
+typedef list<AudioManagerAssignable *> L_AMA;
+#else
+/* with normal compilers there is no need for this typedef. */
+#define L_AMC list<AudioManagerClient_impl *>
+#define L_AMA list<AudioManagerAssignable *>
+#endif
+
+class AudioManager_impl : virtual public AudioManager_skel
+{
+protected:
+ L_AMC _clients;
+ L_AMA assignable;
+ long _changes, nextID;
+ static AudioManager_impl *instance;
+public:
+ AudioManager_impl()
+ {
+ assert(!instance);
+ instance = this;
+ _changes = 0;
+ nextID = 1;
+ }
+ ~AudioManager_impl()
+ {
+ assert(instance);
+ instance = 0;
+ }
+ vector<string> *destinations() { return BusManager::the()->busList(); }
+ long changes() { return _changes; }
+
+ vector<AudioManagerInfo> *clients();
+ void setDestination(long ID, const string& newDestination);
+ AudioManagerClient_impl *findClient(long ID);
+
+ // non MCOP interface
+ static AudioManager_impl *the() {
+ assert(instance);
+ return instance;
+ }
+ long addClient(AudioManagerClient_impl *client) {
+ _clients.push_back(client);
+ _changes++;
+ return nextID++;
+ }
+ void removeClient(AudioManagerClient_impl *client) {
+ _changes++;
+ _clients.remove(client);
+ }
+ void addAssignable(AudioManagerAssignable *a);
+ void removeAssignable(AudioManagerAssignable *a) {
+ assignable.remove(a);
+ }
+};
+
+AudioManager_impl *AudioManager_impl::instance = 0;
+
+class AudioManagerClient_impl :virtual public AudioManagerClient_skel
+{
+protected:
+ string _title, _autoRestoreID;
+ long _ID;
+ AudioManagerDirection _direction;
+ string _destination;
+
+public:
+ AudioManagerClient_impl() {
+ _ID = AudioManager_impl::the()->addClient(this);
+ }
+ ~AudioManagerClient_impl() {
+ AudioManager_impl::the()->removeClient(this);
+ }
+
+ void title(const string& newvalue) { _title = newvalue; }
+ string title() { return _title; }
+
+ void autoRestoreID(const string& newvalue) { _autoRestoreID = newvalue; }
+ string autoRestoreID() { return _autoRestoreID; }
+
+ long ID() { return _ID; }
+
+ AudioManagerDirection direction() { return _direction; }
+ void direction(AudioManagerDirection newvalue) { _direction = newvalue; }
+
+ void constructor(AudioManagerDirection cdirection, const string& ctitle,
+ const string& cautoRestoreID)
+ {
+ direction(cdirection);
+ title(ctitle);
+ autoRestoreID(cautoRestoreID);
+ }
+
+ /* non MCOP interface */
+ string destination() { return _destination; }
+ void destination(const string& newvalue) { _destination = newvalue; }
+};
+
+// this suffers a tiny bit from copypasting due to simpler
+// inheritance hierarchy
+class Synth_AMAN_PLAY_impl :virtual public Synth_AMAN_PLAY_skel,
+ virtual public AudioManagerAssignable,
+ virtual public StdSynthModule
+{
+protected:
+ Synth_BUS_UPLINK uplink;
+ AudioManagerClient client;
+public:
+ /* forward requests for title/autoRestoreID to client */
+ void title(const string& newvalue) { client.title(newvalue); }
+ string title() { return client.title(); }
+
+ void autoRestoreID(const string& newvalue) {client.autoRestoreID(newvalue);}
+ string autoRestoreID() { return client.autoRestoreID(); }
+
+ /* assign an already well-known client */
+ void constructor(AudioManagerClient client) {
+ this->client = client;
+ assert(client.direction() == amPlay);
+ }
+
+ Synth_AMAN_PLAY_impl() {
+ // Set direction of the client to amPlay, but actually it would
+ // be nice to do that only when we know we won't get a different client
+ // to use.
+ client.direction(amPlay);
+ _node()->virtualize("left",uplink._node(),"left");
+ _node()->virtualize("right",uplink._node(),"right");
+ }
+ void streamInit() {
+ AudioManager_impl::the()->addAssignable(this);
+ uplink.start();
+ }
+ void streamEnd() {
+ AudioManager_impl::the()->removeAssignable(this);
+ uplink.stop();
+ }
+ AutoSuspendState autoSuspend() {
+ return asSuspend;
+ }
+
+ // Assignable:
+ void destination(const string& destination) { uplink.busname(destination); }
+ long ID() { return client.ID(); }
+};
+
+// this suffers a tiny bit from copypasting due to simpler
+// inheritance hierarchy
+class Synth_AMAN_RECORD_impl :virtual public Synth_AMAN_RECORD_skel,
+ virtual public AudioManagerAssignable,
+ virtual public StdSynthModule
+{
+protected:
+ Synth_BUS_DOWNLINK downlink;
+ AudioManagerClient client;
+public:
+ /* forward requests for title/autoRestoreID to client */
+ void title(const string& newvalue) { client.title(newvalue); }
+ string title() { return client.title(); }
+
+ void autoRestoreID(const string& newvalue) {client.autoRestoreID(newvalue);}
+ string autoRestoreID() { return client.autoRestoreID(); }
+
+ /* assign an already well-known client */
+ void constructor(AudioManagerClient client) {
+ this->client = client;
+ assert(client.direction() == amRecord);
+ }
+
+ Synth_AMAN_RECORD_impl() {
+ // Set direction of the client to amRecord, but actually it would
+ // be nice to do that only when we know we won't get a different client
+ // to use.
+ client.direction(amRecord);
+ _node()->virtualize("left",downlink._node(),"left");
+ _node()->virtualize("right",downlink._node(),"right");
+ }
+
+ void streamInit() {
+ AudioManager_impl::the()->addAssignable(this);
+ downlink.start();
+ }
+ void streamEnd() {
+ AudioManager_impl::the()->removeAssignable(this);
+ downlink.stop();
+ }
+
+ // Assignable:
+ void destination(const string& destination){downlink.busname(destination);}
+ long ID() { return client.ID(); }
+};
+
+vector<AudioManagerInfo> *AudioManager_impl::clients()
+{
+ vector<AudioManagerInfo> *result = new vector<AudioManagerInfo>;
+ list<AudioManagerClient_impl *>::iterator i;
+
+ for(i = _clients.begin(); i != _clients.end(); i++)
+ {
+ AudioManagerClient_impl *client = *i;
+
+ AudioManagerInfo info;
+ info.ID = client->ID();
+ info.direction = client->direction();
+ info.title = client->title();
+ info.autoRestoreID = client->autoRestoreID();
+ info.destination = client->destination();
+
+ result->push_back(info);
+ }
+ return result;
+}
+
+
+AudioManagerClient_impl *AudioManager_impl::findClient(long ID)
+{
+ list<AudioManagerClient_impl *>::iterator i;
+
+ for(i = _clients.begin(); i != _clients.end(); i++)
+ {
+ AudioManagerClient_impl *client = *i;
+
+ if(client->ID() == ID)
+ return client;
+ }
+ return 0;
+}
+
+void AudioManager_impl::setDestination(long ID, const string& newDestination)
+{
+ AudioManagerClient_impl *client = findClient(ID);
+ if(client)
+ {
+ client->destination(newDestination);
+
+ list<AudioManagerAssignable *>::iterator i;
+ for(i = assignable.begin(); i != assignable.end(); i++)
+ {
+ AudioManagerAssignable *a = *i;
+ if(a->ID() == ID) a->destination(newDestination);
+ }
+ _changes++;
+ }
+}
+
+void AudioManager_impl::addAssignable(AudioManagerAssignable *a)
+{
+ // ensure that this client is assigned properly
+ AudioManagerClient_impl *client = findClient(a->ID());
+ assert(client);
+
+ if(client->destination().empty())
+ {
+ // TODO: more flexible default assignment policies - load autoRestoreID
+ // related stuff here (or somewhere else)
+
+ switch(client->direction())
+ {
+ case amPlay: client->destination("out_soundcard");
+ break;
+ case amRecord: client->destination("in_soundcard");
+ break;
+ }
+ }
+
+ assignable.push_back(a);
+ a->destination(client->destination());
+}
+
+REGISTER_IMPLEMENTATION(AudioManagerClient_impl);
+REGISTER_IMPLEMENTATION(AudioManager_impl);
+REGISTER_IMPLEMENTATION(Synth_AMAN_PLAY_impl);
+REGISTER_IMPLEMENTATION(Synth_AMAN_RECORD_impl);
+
+}
+
+// vim: sw=4 ts=4 noet
diff --git a/flow/audiosubsys.cc b/flow/audiosubsys.cc
new file mode 100644
index 0000000..a1238fc
--- /dev/null
+++ b/flow/audiosubsys.cc
@@ -0,0 +1,645 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h> // Needed on some systems.
+#endif
+
+#ifdef HAVE_SYS_SOUNDCARD_H
+#include <sys/soundcard.h>
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <iostream>
+#include <algorithm>
+#include <cstring>
+
+#include "debug.h"
+#include "audiosubsys.h"
+#include "audioio.h"
+
+#define DEFAULT_DEVICE_NAME "/dev/dsp"
+
+#undef DEBUG_WAVEFORM
+#ifdef DEBUG_WAVEFORM
+#include <fstream>
+#endif
+
+using namespace std;
+using namespace Arts;
+
+//--- automatic startup class
+
+static AudioSubSystemStart aStart;
+
+void AudioSubSystemStart::startup()
+{
+ _instance = new AudioSubSystem();
+}
+
+void AudioSubSystemStart::shutdown()
+{
+ delete _instance;
+}
+
+//--- AudioSubSystemPrivate data
+
+class Arts::AudioSubSystemPrivate
+{
+public:
+#ifdef DEBUG_WAVEFORM
+ ofstream plotfile;
+#endif
+ AudioIO *audioIO;
+ string audioIOName;
+ bool audioIOInit;
+
+ unsigned int adjustDuplexOffsetIndex;
+ int adjustDuplexOffset[4];
+ int adjustDuplexCount;
+};
+
+//--- AudioSubSystem implementation
+
+AudioSubSystem *AudioSubSystem::the()
+{
+ return aStart.the();
+}
+
+const char *AudioSubSystem::error()
+{
+ return _error.c_str();
+}
+
+AudioSubSystem::AudioSubSystem()
+{
+ d = new AudioSubSystemPrivate;
+#ifdef DEBUG_WAVEFORM
+ d->plotfile.open( "/dev/shm/audiosubsystem.plot" );
+#endif
+ d->audioIO = 0;
+ d->audioIOInit = false;
+
+ _running = false;
+ consumer = 0;
+ producer = 0;
+ fragment_buffer = 0;
+}
+
+AudioSubSystem::~AudioSubSystem()
+{
+ delete d->audioIO;
+ delete d;
+}
+
+bool AudioSubSystem::attachProducer(ASProducer *producer)
+{
+ assert(producer);
+ if(this->producer) return false;
+
+ this->producer = producer;
+ return true;
+}
+
+bool AudioSubSystem::attachConsumer(ASConsumer *consumer)
+{
+ assert(consumer);
+ if(this->consumer) return false;
+
+ this->consumer = consumer;
+ return true;
+}
+
+void AudioSubSystem::detachProducer()
+{
+ assert(producer);
+ producer = 0;
+
+ if(_running) close();
+}
+
+void AudioSubSystem::detachConsumer()
+{
+ assert(consumer);
+ consumer = 0;
+
+ if(_running) close();
+}
+
+/* initially creates default AudioIO */
+void AudioSubSystem::initAudioIO()
+{
+ /* auto detect */
+ if(!d->audioIOInit)
+ {
+ string bestName;
+ int bestValue = 0;
+
+ arts_debug("autodetecting driver: ");
+ for(int i = 0; i < AudioIO::queryAudioIOCount(); i++)
+ {
+ string name = AudioIO::queryAudioIOParamStr(i, AudioIO::name);
+ AudioIO *aio = AudioIO::createAudioIO(name.c_str());
+ int value = aio->getParam(AudioIO::autoDetect);
+
+ arts_debug(" - %s: %d", name.c_str(), value);
+ if(value > bestValue)
+ {
+ bestName = name;
+ bestValue = value;
+ }
+ delete aio;
+ }
+ if(bestValue)
+ {
+ arts_debug("... which means we'll default to %s", bestName.c_str());
+ audioIO(bestName);
+ }
+ else
+ {
+ arts_debug("... nothing we could use as default found");
+ }
+ }
+}
+
+void AudioSubSystem::audioIO(const string& audioIO)
+{
+ if(d->audioIO)
+ delete d->audioIO;
+
+ d->audioIOName = audioIO;
+ d->audioIO = AudioIO::createAudioIO(audioIO.c_str());
+ d->audioIOInit = true;
+}
+
+string AudioSubSystem::audioIO()
+{
+ initAudioIO();
+
+ return d->audioIOName;
+}
+
+void AudioSubSystem::deviceName(const string& deviceName)
+{
+ initAudioIO();
+ if(!d->audioIO) return;
+
+ d->audioIO->setParamStr(AudioIO::deviceName, deviceName.c_str());
+}
+
+string AudioSubSystem::deviceName()
+{
+ initAudioIO();
+ if(!d->audioIO) return "";
+
+ return d->audioIO->getParamStr(AudioIO::deviceName);
+}
+
+void AudioSubSystem::fragmentCount(int fragmentCount)
+{
+ initAudioIO();
+ if(!d->audioIO) return;
+
+ d->audioIO->setParam(AudioIO::fragmentCount, fragmentCount);
+}
+
+int AudioSubSystem::fragmentCount()
+{
+ initAudioIO();
+ if(!d->audioIO) return 0;
+
+ return d->audioIO->getParam(AudioIO::fragmentCount);
+}
+
+void AudioSubSystem::fragmentSize(int fragmentSize)
+{
+ initAudioIO();
+ if(!d->audioIO) return;
+
+ d->audioIO->setParam(AudioIO::fragmentSize, fragmentSize);
+}
+
+int AudioSubSystem::fragmentSize()
+{
+ initAudioIO();
+ if(!d->audioIO) return 0;
+
+ return d->audioIO->getParam(AudioIO::fragmentSize);
+}
+
+void AudioSubSystem::samplingRate(int samplingRate)
+{
+ initAudioIO();
+ if(!d->audioIO) return;
+
+ d->audioIO->setParam(AudioIO::samplingRate, samplingRate);
+}
+
+int AudioSubSystem::samplingRate()
+{
+ initAudioIO();
+ if(!d->audioIO) return 0;
+
+ return d->audioIO->getParam(AudioIO::samplingRate);
+}
+
+void AudioSubSystem::channels(int channels)
+{
+ initAudioIO();
+ if(!d->audioIO) return;
+
+ d->audioIO->setParam(AudioIO::channels, channels);
+}
+
+int AudioSubSystem::channels()
+{
+ initAudioIO();
+ if(!d->audioIO) return 0;
+
+ return d->audioIO->getParam(AudioIO::channels);
+}
+
+void AudioSubSystem::format(int format)
+{
+ initAudioIO();
+ if(!d->audioIO) return;
+
+ d->audioIO->setParam(AudioIO::format, format);
+}
+
+int AudioSubSystem::format()
+{
+ initAudioIO();
+ if(!d->audioIO) return 0;
+
+ return d->audioIO->getParam(AudioIO::format);
+}
+
+int AudioSubSystem::bits()
+{
+ int _format = format();
+ arts_assert(_format == 0 || _format == 8 || _format == 16 || _format == 17 || _format == 32);
+ return (_format & (32 | 16 | 8));
+}
+
+void AudioSubSystem::fullDuplex(bool fullDuplex)
+{
+ initAudioIO();
+ if(!d->audioIO) return;
+
+ int direction = fullDuplex?3:2;
+ d->audioIO->setParam(AudioIO::direction, direction);
+}
+
+bool AudioSubSystem::fullDuplex()
+{
+ initAudioIO();
+ if(!d->audioIO) return false;
+
+ return d->audioIO->getParam(AudioIO::direction) == 3;
+}
+
+int AudioSubSystem::selectReadFD()
+{
+ initAudioIO();
+ if(!d->audioIO) return false;
+
+ return d->audioIO->getParam(AudioIO::selectReadFD);
+}
+
+int AudioSubSystem::selectWriteFD()
+{
+ initAudioIO();
+ if(!d->audioIO) return false;
+
+ return d->audioIO->getParam(AudioIO::selectWriteFD);
+}
+
+bool AudioSubSystem::check()
+{
+ bool ok = open();
+
+ if(ok) close();
+ return ok;
+}
+
+bool AudioSubSystem::open()
+{
+ assert(!_running);
+
+ initAudioIO();
+ if(!d->audioIO)
+ {
+ if(d->audioIOName.empty())
+ _error = "couldn't auto detect which audio I/O method to use";
+ else
+ _error = "unable to select '"+d->audioIOName+"' style audio I/O";
+ return false;
+ }
+
+ if(d->audioIO->open())
+ {
+ _running = true;
+
+ _fragmentSize = d->audioIO->getParam(AudioIO::fragmentSize);
+ _fragmentCount = d->audioIO->getParam(AudioIO::fragmentCount);
+
+ // allocate global buffer to do I/O
+ assert(fragment_buffer == 0);
+ fragment_buffer = new char[_fragmentSize];
+
+ d->adjustDuplexCount = 0;
+ return true;
+ }
+ else
+ {
+ _error = d->audioIO->getParamStr(AudioIO::lastError);
+ return false;
+ }
+}
+
+void AudioSubSystem::close()
+{
+ assert(_running);
+ assert(d->audioIO);
+
+ d->audioIO->close();
+
+ wBuffer.clear();
+ rBuffer.clear();
+
+ _running = false;
+ if(fragment_buffer)
+ {
+ delete[] fragment_buffer;
+ fragment_buffer = 0;
+ }
+}
+
+bool AudioSubSystem::running()
+{
+ return _running;
+}
+
+void AudioSubSystem::handleIO(int type)
+{
+ assert(d->audioIO);
+
+ if(type & ioRead)
+ {
+ int len = d->audioIO->read(fragment_buffer,_fragmentSize);
+
+ if(len > 0)
+ {
+ if(rBuffer.size() < _fragmentSize * _fragmentCount * bits() / 8 * channels())
+ {
+ rBuffer.write(len,fragment_buffer);
+#ifdef DEBUG_WAVEFORM
+ float * end = (float *)(fragment_buffer + len);
+ float * floatbuffer = (float *)fragment_buffer;
+ while(floatbuffer < end)
+ {
+ d->plotfile << *floatbuffer++ << "\n";
+ ++floatbuffer;
+ }
+#endif
+ }
+ else
+ {
+ arts_debug( "AudioSubSystem: rBuffer is too full" );
+ }
+ }
+ }
+
+ if(type & ioWrite)
+ {
+ /*
+ * make sure that we have a fragment full of data at least
+ */
+Rewrite:
+ while(wBuffer.size() < _fragmentSize)
+ {
+ long wbsz = wBuffer.size();
+ producer->needMore();
+
+ if(wbsz == wBuffer.size())
+ {
+ /*
+ * Even though we asked the client to supply more
+ * data, he didn't give us more. So we can't supply
+ * output data as well. Bad luck. Might produce a
+ * buffer underrun - but we can't help here.
+ */
+ arts_info("full duplex: no more data available (underrun)");
+ return;
+ }
+ }
+
+ /*
+ * look how much we really can write without blocking
+ */
+ int space = d->audioIO->getParam(AudioIO::canWrite);
+ int can_write = min(space, _fragmentSize);
+
+ if(can_write > 0)
+ {
+ /*
+ * ok, so write it (as we checked that our buffer has enough data
+ * to do so and the soundcardbuffer has enough data to handle this
+ * write, nothing can go wrong here)
+ */
+ int rSize = wBuffer.read(can_write,fragment_buffer);
+ assert(rSize == can_write);
+
+ int len = d->audioIO->write(fragment_buffer,can_write);
+ if(len != can_write)
+ arts_fatal("AudioSubSystem::handleIO: write failed\n"
+ "len = %d, can_write = %d, errno = %d (%s)\n\n"
+ "This might be a sound hardware/driver specific problem"
+ " (see aRts FAQ)",len,can_write,errno,strerror(errno));
+
+ if(fullDuplex())
+ {
+ /*
+ * if we're running full duplex, here is a good place to check
+ * for full duplex drift
+ */
+ d->adjustDuplexCount += can_write;
+ if(d->adjustDuplexCount > samplingRate())
+ {
+ adjustDuplexBuffers();
+ d->adjustDuplexCount = 0;
+ }
+ }
+ }
+
+ // If we can write a fragment more, then do so right now:
+ if (space >= _fragmentSize*2) goto Rewrite;
+ }
+
+ assert((type & ioExcept) == 0);
+}
+
+void AudioSubSystem::read(void *buffer, int size)
+{
+ /* if not enough data can be read, produce some */
+ while(rBuffer.size() < size)
+ adjustInputBuffer(1);
+
+ /* finally, just take the data out of the input buffer */
+ int rSize = rBuffer.read(size,buffer);
+ assert(rSize == size);
+}
+
+void AudioSubSystem::write(void *buffer, int size)
+{
+ wBuffer.write(size,buffer);
+}
+
+float AudioSubSystem::outputDelay()
+{
+ int fsize = _fragmentSize;
+ int fcount = _fragmentCount;
+
+ if(fsize > 0 && fcount > 0) // not all AudioIO classes need to support this
+ {
+ double hardwareBuffer = fsize * fcount;
+ double freeOutputSpace = d->audioIO->getParam(AudioIO::canWrite);
+ double playSpeed = channels() * samplingRate() * (bits() / 8);
+
+ return (hardwareBuffer - freeOutputSpace) / playSpeed;
+ }
+ else return 0.0;
+}
+
+void AudioSubSystem::adjustDuplexBuffers()
+{
+ int fsize = _fragmentSize;
+ int fcount = _fragmentCount;
+
+ if(fsize > 0 && fcount > 0) // not all AudioIO classes need to support this
+ {
+ int bound = 2; //max(fcount/2, 1);
+ int optimalOffset = fsize * (fcount + bound);
+ int minOffset = fsize * fcount;
+ int maxOffset = fsize * (fcount + 2 * bound);
+
+ int canRead = d->audioIO->getParam(AudioIO::canRead);
+ if(canRead < 0)
+ {
+ arts_warning("AudioSubSystem::adjustDuplexBuffers: canRead < 0?");
+ canRead = 0;
+ }
+
+ int canWrite = d->audioIO->getParam(AudioIO::canWrite);
+ if(canWrite < 0)
+ {
+ arts_warning("AudioSubSystem::adjustDuplexBuffers: canWrite < 0?");
+ canWrite = 0;
+ }
+
+ int currentOffset = rBuffer.size() + wBuffer.size()
+ + canRead + max((fsize * fcount) - canWrite, 0);
+
+ d->adjustDuplexOffset[d->adjustDuplexOffsetIndex++ & 3] = currentOffset;
+ if(d->adjustDuplexOffsetIndex <= 4) return;
+
+ int avgOffset;
+ avgOffset = d->adjustDuplexOffset[0]
+ + d->adjustDuplexOffset[1]
+ + d->adjustDuplexOffset[2]
+ + d->adjustDuplexOffset[3];
+ avgOffset /= 4;
+
+ /*
+ printf("offset: %d avg %d min %d opt %d max %d\r", currentOffset,
+ avgOffset, minOffset, optimalOffset, maxOffset);
+ fflush(stdout);
+ */
+ if(minOffset <= avgOffset && avgOffset <= maxOffset)
+ return;
+
+ d->adjustDuplexOffsetIndex = 0;
+ int adjust = (optimalOffset - currentOffset) / _fragmentSize;
+ arts_debug("AudioSubSystem::adjustDuplexBuffers(%d)", adjust);
+ }
+}
+
+void AudioSubSystem::adjustInputBuffer(int count)
+{
+ if(format() == 8)
+ {
+ memset( fragment_buffer, 0x80, _fragmentSize );
+ }
+ else
+ {
+ memset( fragment_buffer, 0, _fragmentSize );
+ }
+
+ while(count > 0 && rBuffer.size() < _fragmentSize * _fragmentCount * 4)
+ {
+ rBuffer.write(_fragmentSize, fragment_buffer);
+#ifdef DEBUG_WAVEFORM
+ float * end = (float *)(fragment_buffer + _fragmentSize);
+ float * floatbuffer = (float *)fragment_buffer;
+ while(floatbuffer < end)
+ {
+ d->plotfile << *floatbuffer++ << "\n";
+ ++floatbuffer;
+ }
+#endif
+ count--;
+ }
+
+ while(count < 0 && rBuffer.size() >= _fragmentSize)
+ {
+ rBuffer.read(_fragmentSize, fragment_buffer);
+ count++;
+ }
+}
+
+void AudioSubSystem::emergencyCleanup()
+{
+ if(producer || consumer)
+ {
+ fprintf(stderr, "AudioSubSystem::emergencyCleanup\n");
+
+ if(producer)
+ detachProducer();
+ if(consumer)
+ detachConsumer();
+ }
+}
diff --git a/flow/audiosubsys.h b/flow/audiosubsys.h
new file mode 100644
index 0000000..ede38c2
--- /dev/null
+++ b/flow/audiosubsys.h
@@ -0,0 +1,236 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef AUDIOSUBSYS_H
+#define AUDIOSUBSYS_H
+#include <string>
+
+#include "arts_export.h"
+#include "pipebuffer.h"
+#include "startupmanager.h"
+
+/*
+ * BC - Status (2002-03-08): AudioSubSystem, ASProducer, ASConsumer.
+ *
+ * These classes are kept binary compatible. You can rely on them.
+ * AudioSubSystem has a private data pointer to do so. Even if ports to
+ * other architectures or hardware will require different organization
+ * (i.e. no fragments, direct memory access via mmap), the data members
+ * and functions exported here MAY NOT BE CHANGED. Use the private data
+ * pointer for adding data members.
+ *
+ * If ASProducer/ASConsumer doesn't suit the needs any longer, do NOT
+ * change them. Add new classes instead.
+ */
+
+namespace Arts {
+
+class ASProducer {
+public:
+ virtual void needMore() = 0;
+};
+
+// FIXME: haveMore won't be called currently
+class ASConsumer {
+public:
+ virtual void haveMore() = 0;
+};
+
+class ARTS_EXPORT AudioSubSystemStart :public StartupClass {
+protected:
+ class AudioSubSystem *_instance;
+public:
+ inline AudioSubSystem *the() { return _instance; };
+ void startup();
+ void shutdown();
+};
+
+class AudioSubSystemPrivate;
+
+class ARTS_EXPORT AudioSubSystem {
+ class AudioSubSystemPrivate *d;
+
+ std::string _error;
+ char *fragment_buffer;
+
+ int _fragmentCount;
+ int _fragmentSize;
+
+ bool _running;
+ PipeBuffer wBuffer, rBuffer;
+ ASConsumer *consumer;
+ ASProducer *producer;
+
+ friend class AudioSubSystemStart;
+ AudioSubSystem();
+ ~AudioSubSystem();
+
+ void close();
+ void initAudioIO();
+
+ /**
+ * checks that full duplex doesn't go out of sync
+ */
+ void adjustDuplexBuffers();
+
+ /**
+ * creates count empty fragments of input in rBuffer if count > 0
+ * removes count fragments of input from rBuffer if count < 0
+ */
+ void adjustInputBuffer(int count);
+
+public:
+ enum { ioRead=1, ioWrite=2, ioExcept=4 };
+
+ // singleton
+ static AudioSubSystem *the();
+
+ /*
+ * Currently, if you want to use the AudioSubSystem, you need to
+ *
+ * 1. - attach one producer
+ * - attach one consumer (only for full duplex)
+ * - open the audio subsystem using open (watch the fd)
+ * (in any order)
+ *
+ * 2. react on the callbacks you get for the producer
+ *
+ * 3. if you don't need the audio subsystem any longer, call detach
+ * both, the producer and the cosumer.
+ *
+ * Be careful that you don't read/write from/to the audio subsystem
+ * when running() is not true.
+ */
+
+ bool attachProducer(ASProducer *producer);
+ bool attachConsumer(ASConsumer *consumer);
+
+ void detachProducer();
+ void detachConsumer();
+
+ /*
+ * can be used to select the AudioIO class to use, reasonable choices
+ * may be "oss" or "alsa" at this point in time - you need to choose
+ * this before doing anything else
+ */
+ void audioIO(const std::string& audioIO);
+ std::string audioIO();
+
+ // which device to use for audio output (default /dev/dsp)
+ void deviceName(const std::string& deviceName);
+ std::string deviceName();
+
+ void fragmentSize(int size);
+ int fragmentSize();
+
+ void fragmentCount(int fragments);
+ int fragmentCount();
+
+ void samplingRate(int samplingrate);
+ int samplingRate();
+
+ void channels(int channels);
+ int channels();
+
+ void format(int format);
+ int format();
+
+ /**
+ * As opposed to format(), this one returns the number of bits used per
+ * sample. Thats sometimes a difference, for instance 16bit big endian
+ * encoding has the format() 17, whereas bits() would return 16.
+ */
+ int bits();
+
+ void fullDuplex(bool newFullDuplex);
+ bool fullDuplex();
+
+ bool check();
+
+ /**
+ * Opens the audio device.
+ *
+ * After opening, you must check selectReadFD() and selectWriteFD() to
+ * select() on the appropriate file descriptors. Whenever select()ing is
+ * successful, handleIO needs to be called.
+ *
+ * The type for handleIO must be set to ioRead if fd is ready for
+ * reading, ioWrite if fd is ready for writing, ioExcept if something
+ * special happend or any combination of these using bitwise or.
+ *
+ * @returns true if audio device has been opened successfully,
+ * false otherwise
+ */
+ bool open();
+
+ /**
+ * human readable error message that descibes why opening the audio device
+ * failed
+ */
+ const char *error();
+
+ /**
+ * File descriptor to select on for reading (@see open()), -1 if there is
+ * none.
+ */
+ int selectReadFD();
+
+ /**
+ * File descriptor to select on for writing (@see open()), -1 if there is
+ * none.
+ */
+ int selectWriteFD();
+
+ /**
+ * Needs to be called to handle I/O on the filedescriptors given by
+ * selectReadFD() and selectWriteFD() (@see open()).
+ */
+ void handleIO(int type);
+
+ void read(void *buffer, int size);
+ void write(void *buffer, int size);
+
+ /**
+ * this returns the time in seconds it will take until everything written
+ * to the AudioSubSystem so far will be played - in other words, it returns
+ * the time it will take until the next sample written by the application
+ * will be heard by the user
+ */
+ float outputDelay();
+
+ /**
+ * returns true as long as the audio subsystem is opened and active (that
+ * is, between successful opening, with attaching producer, and the first
+ * detachConsumer/detachProducer)
+ */
+ bool running();
+
+ /**
+ * called during crashes, to release the opened device (and other resources)
+ * don't use this method for other purposes than emergencies
+ */
+ void emergencyCleanup();
+};
+
+}
+
+#endif /* AUDIOSUBSYS_H */
diff --git a/flow/audiotobytestream_impl.cc b/flow/audiotobytestream_impl.cc
new file mode 100644
index 0000000..866b85a
--- /dev/null
+++ b/flow/audiotobytestream_impl.cc
@@ -0,0 +1,223 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+ 2001, 2003 Matthias Kretz
+ kretz@kde.org
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include "artsflow.h"
+#include "stdsynthmodule.h"
+#include "debug.h"
+
+#include <vector>
+#include <iostream>
+#include <math.h>
+
+#undef DEBUG_MESSAGES
+
+using namespace std;
+using namespace Arts;
+
+namespace Arts {
+
+class AudioToByteStream_impl : public AudioToByteStream_skel,
+ public StdSynthModule
+{
+ long _samplingRate, _channels, _bits;
+ long sampleSize;
+ double step;
+ bool interpolate;
+ vector<float> leftbuffer;
+ vector<float> rightbuffer;
+ int range;
+ double _pos;
+protected:
+ void updateSampleSize()
+ {
+ sampleSize = _channels * _bits / 8;
+ }
+
+public:
+ AudioToByteStream_impl() :
+ _pos(0)
+ {
+ samplingRate(44100);
+ channels(2);
+ bits(16);
+ }
+
+ long samplingRate() { return _samplingRate; }
+ void samplingRate(long newRate) {
+ double newStep = samplingRateFloat / (float)newRate;
+ arts_return_if_fail(newStep > 0);
+ _samplingRate = newRate;
+ step = newStep;
+
+ double delta = step - floor(step);
+ interpolate = fabs(delta) > 0.001;
+#ifdef DEBUG_MESSAGES
+ arts_debug( "samplingRate(%i): step = %e, delta = %e, interpolate: %i", newRate, step, delta, interpolate );
+#endif
+ }
+
+ long channels() { return _channels; }
+ void channels(long newChannels) {
+ arts_return_if_fail(newChannels == 1 || newChannels == 2);
+ _channels = newChannels;
+ updateSampleSize();
+ }
+
+ long bits() { return _bits; }
+ void bits(long newBits) {
+ arts_return_if_fail(newBits == 8 || newBits == 16);
+ _bits = newBits;
+ range = (newBits == 8 ) ? 128 : 32768;
+ updateSampleSize();
+ }
+
+ void calculateBlock(unsigned long samples)
+ {
+ leftbuffer.resize( 1 + samples );
+ rightbuffer.resize( 1 + samples );
+ for( unsigned long i = 0; i < samples; ++i ) {
+ leftbuffer[1 + i] = (left[i] > 1.0f) ? 1.0f : (left[i] < -1.0f) ? -1.0f : left[i];
+ rightbuffer[1 + i] = (right[i] > 1.0f) ? 1.0f : (right[i] < -1.0f) ? -1.0f : right[i];
+ }
+
+ int samplestosend = (int)ceil(leftbuffer.size() / step);
+ DataPacket<mcopbyte> *packet = outdata.allocPacket( samplestosend * sampleSize );
+#ifdef DEBUG_MESSAGES
+ arts_debug( "calculateBlock(%i): send %i samples", samples, samplestosend );
+#endif
+
+ int processed = 0;
+ if( interpolate ) {
+ double pos = 0;
+ if( _channels == 2 ) {
+ if( _bits == 16 ) {
+ while( _pos < (double)leftbuffer.size() - 1 ) {
+ double error = modf(_pos, &pos);
+ int intpos = (int)pos;
+#ifdef DEBUG_MESSAGES
+ arts_debug( "pos=%i, error=%e", intpos, error );
+#endif
+ long leftchannel = long((leftbuffer[intpos] * (1.0 - error) + leftbuffer[intpos + 1] * error) * 32768) + 32768;
+ long rightchannel = long((rightbuffer[intpos] * (1.0 - error) + rightbuffer[intpos + 1] * error) * 32768) + 32768;
+ packet->contents[processed ] = leftchannel;
+ packet->contents[processed + 1] = (leftchannel >> 8) - 128;
+ packet->contents[processed + 2] = rightchannel;
+ packet->contents[processed + 3] = (rightchannel >> 8) - 128;
+ _pos += step;
+ processed += 4;
+ }
+ } else if( _bits == 8 ) {
+ while( _pos < (double)leftbuffer.size() - 1 ) {
+ double error = modf(_pos, &pos);
+ int intpos = (int)pos;
+ long leftchannel = long((leftbuffer[intpos] * (1.0 - error) + leftbuffer[intpos + 1] * error) * 128) + 128;
+ long rightchannel = long((rightbuffer[intpos] * (1.0 - error) + rightbuffer[intpos + 1] * error) * 128) + 128;
+ packet->contents[processed ] = leftchannel;
+ packet->contents[processed + 1] = rightchannel;
+ _pos += step;
+ processed += 2;
+ }
+ }
+ } else {
+ if( _bits == 16 ) {
+ while( _pos < (double)leftbuffer.size() - 1 ) {
+ double error = modf(_pos, &pos);
+ int intpos = (int)pos;
+ long leftchannel = long(((leftbuffer[intpos] + rightbuffer[intpos]) * (1.0 - error) + (leftbuffer[intpos + 1] + rightbuffer[intpos + 1]) * error) * 16384) + 32768;
+ packet->contents[processed ] = leftchannel;
+ packet->contents[processed + 1] = (leftchannel >> 8) - 128;
+ _pos += step;
+ processed += 2;
+ }
+ } else if( _bits == 8 ) {
+ while( _pos < (double)leftbuffer.size() - 1 ) {
+ double error = modf(_pos, &pos);
+ int intpos = (int)pos;
+ long leftchannel = long(((leftbuffer[intpos] + rightbuffer[intpos]) * (1.0 - error) + (leftbuffer[intpos + 1] + rightbuffer[intpos + 1]) * error) * 64) + 128;
+ packet->contents[processed] = leftchannel;
+ _pos += step;
+ ++processed;
+ }
+ }
+ }
+ } else {
+ if( _channels == 2 ) {
+ if( _bits == 16 ) {
+ while( _pos < (double)leftbuffer.size() - 1 ) {
+ int intpos = (int)_pos;
+ long leftchannel = long(leftbuffer[intpos] * 32768) + 32768;
+ long rightchannel = long(rightbuffer[intpos] * 32768) + 32768;
+ packet->contents[processed ] = leftchannel;
+ packet->contents[processed + 1] = (leftchannel >> 8) - 128;
+ packet->contents[processed + 2] = rightchannel;
+ packet->contents[processed + 3] = (rightchannel >> 8) - 128;
+ _pos += step;
+ processed += 4;
+ }
+ } else if( _bits == 8 ) {
+ while( _pos < (double)leftbuffer.size() - 1 ) {
+ int intpos = (int)_pos;
+ long leftchannel = long(leftbuffer[intpos] * 128) + 128;
+ long rightchannel = long(rightbuffer[intpos] * 128) + 128;
+ packet->contents[processed ] = leftchannel;
+ packet->contents[processed + 1] = rightchannel;
+ _pos += step;
+ processed += 2;
+ }
+ }
+ } else {
+ if( _bits == 16 ) {
+ while( _pos < (double)leftbuffer.size() - 1 ) {
+ int intpos = (int)_pos;
+ long leftchannel = long((leftbuffer[intpos] + rightbuffer[intpos]) * 16384) + 32768;
+ packet->contents[processed ] = leftchannel;
+ packet->contents[processed + 1] = (leftchannel >> 8) - 128;
+ _pos += step;
+ processed += 2;
+ }
+ } else if( _bits == 8 ) {
+ while( _pos < (double)leftbuffer.size() - 1 ) {
+ int intpos = (int)_pos;
+ long leftchannel = long((leftbuffer[intpos] + rightbuffer[intpos]) * 64) + 128;
+ packet->contents[processed] = leftchannel;
+ _pos += step;
+ ++processed;
+ }
+ }
+ }
+ }
+ leftbuffer[0] = leftbuffer.back();
+ rightbuffer[0] = rightbuffer.back();
+ _pos = _pos - floor(_pos);
+ packet->size = processed;
+ packet->send();
+#ifdef DEBUG_MESSAGES
+ arts_debug( "calculateBlock(%i): %i samples sent, _pos = %e", samples, processed / sampleSize, _pos );
+#endif
+ }
+};
+
+REGISTER_IMPLEMENTATION(AudioToByteStream_impl);
+
+}
diff --git a/flow/bufferqueue.h b/flow/bufferqueue.h
new file mode 100644
index 0000000..5344c4a
--- /dev/null
+++ b/flow/bufferqueue.h
@@ -0,0 +1,148 @@
+/*
+ * BC - Status (2002-03-08): ByteBuffer, BufferQueue
+ *
+ * None of these classes is considered part of the public API. Do NOT use it
+ * in your apps. These are part of the implementation of libartsflow's
+ * AudioSubSystem, and subject to change/disappearing due to optimization
+ * work.
+ */
+
+#ifndef _BUFFERQUEUE_H
+#define _BUFFERQUEUE_H
+
+#include "thread.h"
+
+#define _DEFAULT_CHUNK_SIZE 4096
+#define _MAX_CHUNKS 3
+
+namespace Arts
+{
+
+class ByteBuffer
+{
+ unsigned char* content;
+ int _size;
+ int _maxSize;
+ int rp;
+
+public:
+ ByteBuffer() {
+ _size = rp = 0;
+ _maxSize = _DEFAULT_CHUNK_SIZE;
+ content = new unsigned char[_DEFAULT_CHUNK_SIZE];
+ }
+ ByteBuffer(const void* s, int len) {
+ _maxSize = _DEFAULT_CHUNK_SIZE;
+ content = new unsigned char[_DEFAULT_CHUNK_SIZE];
+ put(s, len);
+ }
+
+ ~ByteBuffer() { delete [] content; }
+
+ void put(const void* s, int len) {
+ if ((_size = len) != 0)
+ memcpy(content, s, len);
+ rp = 0;
+ }
+
+ void* get() { return content+rp; }
+ void* reset() { _size = 0; rp = 0; return content; }
+ int push(int len) { _size -= len; rp += len; return _size; }
+ void set(int len) { _size = len; rp = 0; }
+ int size() const { return _size; }
+ int maxSize() const { return _maxSize; }
+
+ void setMaxSize(int size) {
+ delete [] content;
+ content = new unsigned char[size];
+ _maxSize = size;
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+class BufferQueue
+{
+private:
+ ByteBuffer bufs[_MAX_CHUNKS];
+ int rp;
+ int wp;
+ Arts::Semaphore* sema_produced;
+ Arts::Semaphore* sema_consumed;
+
+ void semaReinit() {
+ delete sema_consumed;
+ delete sema_produced;
+ sema_consumed = new Arts::Semaphore(0, _MAX_CHUNKS);
+ sema_produced = new Arts::Semaphore(0, 0);
+ }
+
+
+public:
+ BufferQueue() {
+ rp = wp = 0;
+ sema_consumed = new Arts::Semaphore(0, _MAX_CHUNKS);
+ sema_produced = new Arts::Semaphore(0, 0);
+ }
+
+ ~BufferQueue() {
+ delete sema_consumed;
+ delete sema_produced;
+ }
+
+ void write(void* data, int len);
+ ByteBuffer* waitConsumed();
+ void produced();
+
+ ByteBuffer* waitProduced();
+ void consumed();
+
+ bool isEmpty() const { return sema_produced->getValue() == 0; }
+ int bufferedChunks() const { return sema_produced->getValue(); }
+ int freeChunks() const { return sema_consumed->getValue(); }
+ int maxChunks() const { return _MAX_CHUNKS; }
+ int chunkSize() const { return bufs[0].maxSize(); }
+ void clear() { rp = wp = 0; semaReinit(); }
+ void setChunkSize(int size){
+ for (int i=0; i < maxChunks(); i++)
+ bufs[i].setMaxSize(size);
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+inline void BufferQueue::write(void* data, int len)
+{
+ sema_consumed->wait();
+ bufs[wp].put(data, len);
+ ++wp %= _MAX_CHUNKS;
+ sema_produced->post();
+}
+
+inline ByteBuffer* BufferQueue::waitConsumed()
+{
+ sema_consumed->wait();
+ return &bufs[wp];
+}
+
+inline void BufferQueue::produced()
+{
+ ++wp %= _MAX_CHUNKS;
+ sema_produced->post();
+}
+
+inline ByteBuffer* BufferQueue::waitProduced()
+{
+ sema_produced->wait();
+ return &bufs[rp];
+}
+
+inline void BufferQueue::consumed()
+{
+ ++rp %=_MAX_CHUNKS;
+ sema_consumed->post();
+}
+
+}
+
+#endif
diff --git a/flow/bus.cc b/flow/bus.cc
new file mode 100644
index 0000000..ba5e778
--- /dev/null
+++ b/flow/bus.cc
@@ -0,0 +1,367 @@
+ /*
+
+ Copyright (C) 1998-2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include "bus.h"
+#include "flowsystem.h"
+#include "debug.h"
+#include <iostream>
+#include <set>
+
+#ifdef __SUNPRO_CC
+/* SunPRO CC looses to link this when the_BusManager is static, because
+ later a template implementation file references this symbol. */
+#define the_BusManager __internal_aRts_the_BusManager__Bahh__
+#else
+static
+#endif
+ Arts::BusManager *the_BusManager = 0;
+
+using namespace Arts;
+using namespace std;
+
+// shutdown bus manager on termination
+
+namespace Arts {
+ static class BusManagerShutdown :public StartupClass
+ {
+ public:
+ void startup() { };
+ void shutdown()
+ {
+ if(::the_BusManager)
+ {
+ delete ::the_BusManager;
+ ::the_BusManager = 0;
+ }
+ }
+ } The_BusManagerShutdown;
+}
+
+BusManager::BusManager()
+{
+ // this constructor isn't public (Singleton)
+}
+
+BusManager *BusManager::the()
+{
+ if(!::the_BusManager) ::the_BusManager = new BusManager;
+ return(::the_BusManager);
+}
+
+BusManager::Bus *BusManager::findBus(const string& name)
+{
+ list<Bus *>::iterator bi;
+
+ for(bi = _busList.begin(); bi != _busList.end(); bi++)
+ {
+ if((*bi)->name == name) return(*bi);
+ }
+ Bus *bus = new Bus;
+ bus->left.start();
+ bus->right.start();
+ bus->name = name;
+ _busList.push_back(bus);
+
+ return(bus);
+}
+
+vector<string> *BusManager::busList()
+{
+ set<string> names;
+ set<string>::iterator si;
+
+ list<Bus *>::iterator bi;
+ for(bi = _busList.begin(); bi != _busList.end(); bi++)
+ names.insert((*bi)->name);
+
+ vector<string> *bl = new vector<string>;
+ for(si=names.begin();si != names.end();si++) bl->push_back(*si);
+ return bl;
+}
+
+void BusManager::addClient(const string& busname, BusClient *client)
+{
+ Bus *bus = findBus(busname);
+ bus->clients.push_back(client);
+
+ // attach the new client
+ client->snode()->virtualize("left", bus->left._node(), "invalue");
+ client->snode()->virtualize("right", bus->right._node(), "invalue");
+}
+
+void BusManager::removeClient(BusClient *client)
+{
+ list<Bus *>::iterator bi;
+ for(bi = _busList.begin(); bi != _busList.end(); bi++)
+ {
+ Bus *bus = *bi;
+
+ list<BusClient *>::iterator ci;
+ for(ci = bus->clients.begin(); ci != bus->clients.end(); ci++)
+ {
+ if(*ci == client)
+ {
+ bus->clients.erase(ci);
+
+ if(bus->clients.empty() && bus->servers.empty())
+ {
+ _busList.erase(bi);
+ delete bus;
+ }
+ else
+ {
+ client->snode()->devirtualize("left",
+ bus->left._node(), "invalue");
+ client->snode()->devirtualize("right",
+ bus->right._node(), "invalue");
+ }
+ return;
+ }
+ }
+ }
+}
+
+void BusManager::addServer(const string& busname, BusClient *server)
+{
+ Bus *bus = findBus(busname);
+ bus->servers.push_back(server);
+
+ server->snode()->virtualize("left",bus->left._node(),"outvalue");
+ server->snode()->virtualize("right",bus->right._node(),"outvalue");
+}
+
+void BusManager::removeServer(BusClient *server)
+{
+ list<Bus *>::iterator bi;
+
+ for(bi = _busList.begin(); bi != _busList.end(); bi++)
+ {
+ Bus *bus = *bi;
+
+ list<BusClient *>::iterator si;
+ for(si = bus->servers.begin(); si != bus->servers.end(); si++)
+ {
+ if(*si == server)
+ {
+ bus->servers.erase(si);
+ if(bus->clients.empty() && bus->servers.empty())
+ {
+ _busList.erase(bi);
+ delete bus;
+ }
+ else
+ {
+ server->snode()->devirtualize("left",
+ bus->left._node(), "outvalue");
+ server->snode()->devirtualize("right",
+ bus->right._node(),"outvalue");
+ }
+ return;
+ }
+ }
+ }
+}
+
+namespace Arts {
+
+class Synth_BUS_UPLINK_impl :public Synth_BUS_UPLINK_skel,
+ public StdSynthModule, public BusClient
+{
+ BusManager *bm;
+ bool running, active, relink;
+ string _busname;
+public:
+ Synth_BUS_UPLINK_impl();
+
+ string busname() { return _busname; }
+ void busname(const string& newname);
+ AutoSuspendState autoSuspend() { return asSuspend; }
+ void streamInit();
+ void streamEnd();
+ ScheduleNode *snode() { return _node(); }
+
+ void CallBack();
+
+ void connect();
+ void disconnect();
+};
+
+REGISTER_IMPLEMENTATION(Synth_BUS_UPLINK_impl);
+
+}
+
+Synth_BUS_UPLINK_impl::Synth_BUS_UPLINK_impl() :running(false)
+{
+ bm = BusManager::the();
+}
+
+void Synth_BUS_UPLINK_impl::streamInit()
+{
+ assert(!running);
+ running = true;
+ active = relink = false;
+
+ connect(); // connect to the BusManager
+}
+
+void Synth_BUS_UPLINK_impl::busname(const string& newname)
+{
+ _busname = newname;
+
+ /* TODO */
+ // to be sure that reconnection happens when outside the scheduling cycle
+ if(running)
+ {
+ relink = true;
+ CallBack();
+ }
+}
+
+void Synth_BUS_UPLINK_impl::connect()
+{
+ assert(active == false);
+ if(!_busname.empty())
+ {
+ active = true;
+ bm->addClient(_busname, this);
+ }
+}
+
+void Synth_BUS_UPLINK_impl::disconnect()
+{
+ if(active == true)
+ {
+ bm->removeClient(this);
+ active = false;
+ }
+}
+
+void Synth_BUS_UPLINK_impl::CallBack()
+{
+ if(relink)
+ {
+ disconnect();
+ connect();
+ relink = false;
+ }
+}
+
+void Synth_BUS_UPLINK_impl::streamEnd()
+{
+ disconnect();
+
+ assert(running);
+ running = false;
+}
+
+namespace Arts {
+
+class Synth_BUS_DOWNLINK_impl :public Synth_BUS_DOWNLINK_skel,
+ public StdSynthModule, public BusClient
+{
+ bool running, active, relink;
+ BusManager *bm;
+
+ string _busname;
+
+ void connect();
+ void disconnect();
+
+public:
+ string busname() { return _busname; }
+ void busname(const string& newname);
+
+ Synth_BUS_DOWNLINK_impl();
+ AutoSuspendState autoSuspend() { return asSuspend; }
+ void streamInit();
+ void streamEnd();
+ void CallBack();
+ ScheduleNode *snode() { return _node(); }
+};
+
+REGISTER_IMPLEMENTATION(Synth_BUS_DOWNLINK_impl);
+
+}
+
+Synth_BUS_DOWNLINK_impl::Synth_BUS_DOWNLINK_impl() :running(false)
+{
+ bm = BusManager::the();
+}
+
+void Synth_BUS_DOWNLINK_impl::streamInit()
+{
+ assert(!running);
+ running = true;
+
+ active = relink = false;
+ connect();
+}
+
+void Synth_BUS_DOWNLINK_impl::streamEnd()
+{
+ assert(running);
+ running = false;
+
+ disconnect();
+}
+
+void Synth_BUS_DOWNLINK_impl::connect()
+{
+ assert(active == false);
+ if(!_busname.empty())
+ {
+ active = true;
+ bm->addServer(_busname, this);
+ }
+}
+
+void Synth_BUS_DOWNLINK_impl::disconnect()
+{
+ if(active == true)
+ {
+ bm->removeServer(this);
+ active = false;
+ }
+}
+
+void Synth_BUS_DOWNLINK_impl::CallBack()
+{
+ if(relink)
+ {
+ disconnect();
+ connect();
+ relink = false;
+ }
+}
+
+void Synth_BUS_DOWNLINK_impl::busname(const string& newname)
+{
+ _busname = newname;
+
+ /* TODO */
+ // to be sure that reconnection happens when outside the scheduling cycle
+ if(running)
+ {
+ relink = true;
+ CallBack();
+ }
+}
diff --git a/flow/bus.h b/flow/bus.h
new file mode 100644
index 0000000..747932b
--- /dev/null
+++ b/flow/bus.h
@@ -0,0 +1,76 @@
+ /*
+
+ Copyright (C) 1998-2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef ARTS_BUS_H
+#define ARTS_BUS_H
+
+#include "stdsynthmodule.h"
+#include "artsflow.h"
+
+/*
+ * BC - Status (2002-03-08): BusClient, BusManager
+ *
+ * None of these classes is considered part of the public API. Do NOT use it
+ * in your apps. These are part of the implementation of libartsflow's
+ * Synth_BUS_* and Synth_AMAN_* and AudioManager interfaces. Use these for
+ * public use instead, and don't touch this here.
+ */
+
+
+namespace Arts {
+
+class BusClient
+{
+public:
+ virtual Arts::ScheduleNode *snode() = 0;
+};
+
+
+class BusManager
+{
+protected:
+ struct Bus
+ {
+ std::string name;
+ std::list<BusClient *> clients;
+ std::list<BusClient *> servers;
+ Arts::Synth_MULTI_ADD left, right;
+ };
+ std::list<Bus *> _busList;
+
+ BusManager();
+
+public:
+ Bus* findBus(const std::string& name);
+
+ void addClient(const std::string& busname, BusClient *client);
+ void removeClient(BusClient *client);
+ void addServer(const std::string& busname, BusClient *server);
+ void removeServer(BusClient *server);
+
+ std::vector<std::string> *busList();
+
+ static BusManager *the();
+};
+}
+
+#endif /* ARTS_BUS_H */
diff --git a/flow/bytestreamtoaudio_impl.cc b/flow/bytestreamtoaudio_impl.cc
new file mode 100644
index 0000000..73714cf
--- /dev/null
+++ b/flow/bytestreamtoaudio_impl.cc
@@ -0,0 +1,119 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include "artsflow.h"
+#include "stdsynthmodule.h"
+#include "resample.h"
+
+#include <cstring>
+
+using namespace std;
+using namespace Arts;
+
+namespace Arts {
+
+class PacketRefiller : public Refiller {
+protected:
+ queue< DataPacket<mcopbyte>* > inqueue;
+ int pos;
+
+public:
+ PacketRefiller() : pos(0)
+ {
+ }
+ void process(DataPacket<mcopbyte>* packet)
+ {
+ inqueue.push(packet);
+ }
+ unsigned long read(unsigned char *buffer, unsigned long bytes)
+ {
+ unsigned long done = 0;
+ while(!inqueue.empty())
+ {
+ long tocopy = bytes - done;
+ if(tocopy == 0) return bytes; /* complete? */
+
+ DataPacket<mcopbyte> *packet = inqueue.front();
+ if(tocopy > (packet->size - pos))
+ tocopy = (packet->size - pos);
+
+ memcpy(&buffer[done],&packet->contents[pos],tocopy);
+ pos += tocopy;
+ done += tocopy;
+
+ if(pos == packet->size) {
+ packet->processed();
+ pos = 0;
+ inqueue.pop();
+ }
+ }
+ return done;
+ }
+};
+
+class ByteStreamToAudio_impl : public ByteStreamToAudio_skel,
+ public StdSynthModule
+{
+ PacketRefiller refiller;
+ Resampler resampler;
+ long _samplingRate, _channels, _bits;
+public:
+ ByteStreamToAudio_impl() :resampler(&refiller),
+ _samplingRate(44100), _channels(2), _bits(16)
+ {
+ //
+ }
+
+ long samplingRate() { return _samplingRate; }
+ void samplingRate(long newRate) {
+ _samplingRate = newRate;
+ resampler.setStep((float)_samplingRate / samplingRateFloat);
+ }
+
+ long channels() { return _channels; }
+ void channels(long newChannels) {
+ _channels = newChannels;
+ resampler.setChannels(_channels);
+ }
+
+ long bits() { return _bits; }
+ void bits(long newBits) {
+ _bits = newBits;
+ resampler.setBits(_bits);
+ }
+
+ bool running() { return !resampler.underrun(); }
+
+ void process_indata(DataPacket<mcopbyte> *packet)
+ {
+ refiller.process(packet);
+ }
+
+ void calculateBlock(unsigned long samples)
+ {
+ resampler.run(left,right,samples);
+ }
+};
+
+REGISTER_IMPLEMENTATION(ByteStreamToAudio_impl);
+
+}
diff --git a/flow/cache.cc b/flow/cache.cc
new file mode 100644
index 0000000..0c7cfcc
--- /dev/null
+++ b/flow/cache.cc
@@ -0,0 +1,274 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include "cache.h"
+#include "debug.h"
+#include "iomanager.h"
+#include "dispatcher.h"
+#include <iostream>
+#include <assert.h>
+
+using namespace std;
+using namespace Arts;
+
+bool CachedObject::isValid()
+{
+ return true;
+}
+
+void CachedObject::setKey(string key)
+{
+ _object_key = key;
+}
+
+string CachedObject::getKey()
+{
+ return _object_key;
+}
+
+void CachedObject::decRef()
+{
+ _ref_cnt--;
+ time(&_lastAccess);
+}
+
+void CachedObject::incRef()
+{
+ _ref_cnt++;
+}
+
+int CachedObject::refCnt()
+{
+ return _ref_cnt;
+}
+
+time_t CachedObject::lastAccess()
+{
+ return(_lastAccess);
+}
+
+CachedObject::CachedObject(Cache *cache)
+{
+ _ref_cnt = 1;
+ cache->add(this);
+}
+
+CachedObject::~CachedObject()
+{
+ assert(_ref_cnt == 0);
+}
+
+//------------------------- Cache implementation ---------------------------
+long Cache::memused = 0;
+
+CachedObject *Cache::get(string key)
+{
+ list<CachedObject *>::iterator i;
+
+ for(i=objects.begin();i != objects.end(); i++)
+ {
+ if((*i)->getKey() == key && (*i)->isValid())
+ {
+ (*i)->incRef();
+ return(*i);
+ }
+ }
+ return 0;
+}
+
+void Cache::add(CachedObject *object)
+{
+ objects.push_back(object);
+}
+
+long Cache::cleanUp(long cacheLimit)
+{
+ time_t lastAccess;
+
+ list<CachedObject *>::iterator i;
+ long memory = 0;
+
+ // delete all invalid unused entries (invalid entries that are still
+ // in use, e.g. cached wav files which have changed on disk but are
+ // still played can't be deleted!)
+
+ for(i=objects.begin();i != objects.end(); i++)
+ {
+ CachedObject *co = (*i);
+
+ if(co->refCnt() == 0 && !co->isValid())
+ {
+ objects.remove(co);
+ delete co;
+ i = objects.begin();
+ }
+ }
+
+ for(i=objects.begin();i != objects.end(); i++)
+ {
+ memory += (*i)->memoryUsage();
+ }
+
+ bool freeok = true;
+ while(memory > cacheLimit && freeok)
+ {
+ CachedObject *freeme;
+
+ freeok = false;
+
+ // only start freeing objects which have not been accessed
+ // in the last 5 seconds
+
+ time(&lastAccess);
+ lastAccess -= 5;
+
+
+ for(i=objects.begin();!freeok && (i != objects.end()); i++)
+ {
+ CachedObject *co = (*i);
+
+ assert(co->refCnt() >= 0);
+ if(co->refCnt() == 0 && (co->lastAccess() < lastAccess))
+ {
+ lastAccess = co->lastAccess();
+ freeme = co;
+ freeok = true;
+ }
+ else
+ {
+ //artsdebug("%d => %ld\n",co->refCnt(),co->lastAccess());
+ }
+ }
+
+ if(freeok)
+ {
+ memory -= freeme->memoryUsage();
+ objects.remove(freeme);
+ delete(freeme);
+ }
+ else
+ {
+ //artsdebug("cache problem: memory overused, but nothing there to free\n");
+ }
+ }
+
+ memused = memory/1024;
+ return(memory);
+}
+
+Cache *Cache::_instance = 0;
+
+Cache::Cache()
+{
+ assert(!_instance);
+ _instance = this;
+}
+
+Cache::~Cache()
+{
+ list<CachedObject *>::iterator i;
+ for(i=objects.begin(); i != objects.end(); i++)
+ delete (*i);
+ objects.clear();
+
+ assert(_instance);
+ _instance = 0;
+}
+
+
+Cache *Cache::the()
+{
+ if(!_instance) _instance = new Cache();
+ return _instance;
+}
+
+void Cache::shutdown()
+{
+ if(_instance)
+ {
+ list<CachedObject *>::iterator i;
+ long rcnt = 0;
+ for(i=_instance->objects.begin(); i != _instance->objects.end(); i++)
+ rcnt += (*i)->refCnt();
+
+ if(rcnt == 0)
+ {
+ delete _instance;
+ _instance = 0;
+ }
+ else
+ {
+ arts_warning("cache shutdown while still active objects in cache");
+ }
+ }
+}
+
+namespace Arts { // internal helpers
+
+// periodic cache clean
+class CacheClean : public TimeNotify {
+public:
+ CacheClean();
+ void notifyTime();
+ virtual ~CacheClean();
+};
+
+// cache startup & shutdown
+class CacheStartup :public StartupClass
+{
+public:
+ void startup();
+ void shutdown();
+private:
+ CacheClean *cacheClean;
+};
+
+}
+
+CacheClean::CacheClean()
+{
+ Dispatcher::the()->ioManager()->addTimer(5000, this);
+}
+
+void CacheClean::notifyTime()
+{
+ // TODO: make this configurable
+ Cache::the()->cleanUp(8192*1024);
+}
+
+CacheClean::~CacheClean()
+{
+ Dispatcher::the()->ioManager()->removeTimer(this);
+}
+
+void CacheStartup::startup()
+{
+ cacheClean = new CacheClean;
+}
+
+void CacheStartup::shutdown()
+{
+ delete cacheClean;
+ Cache::shutdown();
+}
+
+static CacheStartup cacheStartup;
diff --git a/flow/cache.h b/flow/cache.h
new file mode 100644
index 0000000..3f093df
--- /dev/null
+++ b/flow/cache.h
@@ -0,0 +1,92 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef _SYNTH_CACHE_H
+#define _SYNTH_CACHE_H
+
+#include <time.h>
+#include <list>
+#include <string>
+#include "startupmanager.h"
+#include "arts_export.h"
+
+/*
+ * BC - Status (2002-03-08): Cache, CachedObject
+ *
+ * At the current point in time, there are NO GUARANTEES, so only use this
+ * in apps part of official KDE releases (such as kdemultimedia apps), which
+ * know what is happening here.
+ */
+
+namespace Arts {
+class Cache;
+
+class ARTS_EXPORT CachedObject
+{
+private:
+ std::string _object_key;
+ int _ref_cnt;
+ time_t _lastAccess;
+
+protected:
+ void setKey(std::string key);
+
+public:
+ std::string getKey();
+
+ time_t lastAccess();
+
+ void decRef();
+ void incRef();
+ int refCnt();
+
+ virtual bool isValid();
+ virtual int memoryUsage() = 0;
+
+ CachedObject(Cache *cache);
+ virtual ~CachedObject();
+};
+
+class ARTS_EXPORT Cache
+{
+protected:
+ std::list<CachedObject *> objects;
+ Cache();
+ ~Cache();
+
+ static Cache *_instance;
+
+public:
+ static Cache *the();
+ static void shutdown();
+
+ static long memused;
+
+ CachedObject *get(std::string key);
+ void add(CachedObject *object);
+
+ // garbage collection; returns amount of memory used (after cleaning)
+ long cleanUp(long cacheLimit);
+};
+
+}
+#endif
diff --git a/flow/cachedwav.h b/flow/cachedwav.h
new file mode 100644
index 0000000..99df156
--- /dev/null
+++ b/flow/cachedwav.h
@@ -0,0 +1,81 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef CACHEDWAV_H
+#define CACHEDWAV_H
+
+#include "config.h"
+#include "arts_export.h"
+#ifdef HAVE_LIBAUDIOFILE
+#include "cache.h"
+#include <sys/stat.h>
+#include <unistd.h>
+
+/*
+ * BC - Status (2002-03-08): CachedWav.
+ *
+ * At the current point in time, there are NO GUARANTEES, so only use this
+ * in apps part of official KDE releases (such as kdemultimedia apps), which
+ * know what is happening here. Especially, in SOME kde versions this class
+ * might not even exist, as it gets conditionally compiled.
+ */
+
+namespace Arts {
+
+class ARTS_EXPORT CachedWav : public CachedObject
+{
+protected:
+ struct stat oldstat;
+ std::string filename;
+ bool initOk;
+
+ CachedWav(Cache *cache, std::string filename);
+ ~CachedWav();
+
+ typedef unsigned char uchar;
+public:
+ double samplingRate;
+ long bufferSize;
+ int channelCount;
+ int sampleWidth;
+ unsigned char *buffer;
+
+ static CachedWav *load(Cache *cache, std::string filename);
+ /**
+ * validity test for the cache - returns false if the object is having
+ * reflecting the correct contents anymore (e.g. if the file on the
+ * disk has changed), and there is no point in keeping it in the cache any
+ * longer
+ */
+ bool isValid();
+ /**
+ * memory usage for the cache
+ */
+ int memoryUsage();
+
+ std::string mediaName() const { return filename; }
+};
+
+}
+
+#endif /* HAVE_LIBAUDIOFILE */
+#endif /* CACHEDWAV_H */
diff --git a/flow/convert.cc b/flow/convert.cc
new file mode 100644
index 0000000..d5ca2f8
--- /dev/null
+++ b/flow/convert.cc
@@ -0,0 +1,418 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include "convert.h"
+#include <math.h>
+#include <string.h>
+#include <assert.h>
+#include <config.h>
+
+#ifdef HAVE_X86_FLOAT_INT
+static inline long QRound (float inval)
+{
+#if (__GNUC__ == 3 && __GNUC_MINOR__ == 0)
+ volatile
+#warning "workaround for gcc-3.0 bug c++/2733 enabled"
+#endif
+ int ret;
+ __asm__ ("fistpl %0" : "=m" (ret) : "t" (inval) : "st");
+ return ret;
+}
+#else
+static inline long QRound (float inval)
+{
+ return (long)inval;
+}
+#endif
+
+/*---------------------------- new code begin -------------------------- */
+
+#define compose_16le(ptr) \
+ ((((*((ptr)+1)+128)&0xff) << 8)+*(ptr))
+
+#define compose_16be(ptr) \
+ ((((*(ptr)+128)&0xff) << 8)+*((ptr)+1))
+
+#define conv_16_float(x) \
+ ((float)((x)-32768)/32768.0)
+
+#define convert_16le_float(x) conv_16_float(compose_16le(&(x)))
+#define convert_16be_float(x) conv_16_float(compose_16be(&(x)))
+
+#define conv_8_float(x) \
+ ((float)((x)-128)/128.0)
+
+#define convert_8_float(x) \
+ ((float)((x)-128)/128.0)
+
+#define convert_float_float(x) x
+
+/*
+ * 16le, 16be, 8, float
+ */
+
+#define datatype_16le unsigned char
+#define datasize_16le 2
+
+#define datatype_16be unsigned char
+#define datasize_16be 2
+
+#define datatype_8 unsigned char
+#define datasize_8 1
+
+#define datatype_float float
+#define datasize_float 1
+
+#define mk_converter(from_format,to_format) \
+void Arts::convert_mono_ ## from_format ## _ ## to_format (unsigned long samples, \
+ datatype_ ## from_format *from, \
+ datatype_ ## to_format *to) \
+{ \
+ datatype_ ## to_format *end = to+samples * (datasize_ ## to_format); \
+ while(to<end) { \
+ *to = convert_ ## from_format ## _ ## to_format(*from); \
+ from += datasize_ ## from_format; \
+ to += datasize_ ## to_format; \
+ } \
+} \
+void Arts::interpolate_mono_ ## from_format ## _ ## to_format (unsigned long samples,\
+ double startpos, double speed, \
+ datatype_ ## from_format *from, \
+ datatype_ ## to_format *to) \
+{ \
+ double flpos = startpos; \
+ while(samples) { \
+ long position = ((long)(flpos)) * (datasize_ ## from_format); \
+ double error = flpos - floor(flpos); \
+ *to = (convert_ ## from_format ## _ ## to_format(from[position])) * \
+ (1.0-error) + (convert_ ## from_format ## _ ## \
+ to_format(from[position + datasize_ ## from_format])) * error; \
+ to += datasize_ ## to_format; \
+ flpos += speed; \
+ samples--; \
+ } \
+} \
+void Arts::convert_stereo_i ## from_format ## _2 ## to_format (unsigned long samples,\
+ datatype_ ## from_format *from, \
+ datatype_ ## to_format *left, \
+ datatype_ ## to_format *right) \
+{ \
+ datatype_ ## to_format *end = left+samples * (datasize_ ## to_format); \
+ while(left<end) { \
+ *left = convert_ ## from_format ## _ ## to_format(*from); \
+ from += datasize_ ## from_format; \
+ left += datasize_ ## to_format; \
+ *right = convert_ ## from_format ## _ ## to_format(*from); \
+ from += datasize_ ## from_format; \
+ right += datasize_ ## to_format; \
+ } \
+} \
+void Arts::interpolate_stereo_i ## from_format ## _2 ## to_format (unsigned long samples,\
+ double startpos, double speed, \
+ datatype_ ## from_format *from, \
+ datatype_ ## to_format *left, \
+ datatype_ ## to_format *right) \
+{ \
+ double flpos = startpos; \
+ while(samples) { \
+ long position = ((long)(flpos)) * (datasize_ ## from_format) * 2; \
+ double error = flpos - floor(flpos); \
+ *left = (convert_ ## from_format ## _ ## to_format(from[position])) * \
+ (1.0-error) + (convert_ ## from_format ## _ ## \
+ to_format(from[position + 2*datasize_ ## from_format]))*error; \
+ left += datasize_ ## to_format; \
+ position += datasize_ ## from_format; \
+ *right =(convert_ ## from_format ## _ ## to_format(from[position])) * \
+ (1.0-error) + (convert_ ## from_format ## _ ## \
+ to_format(from[position + 2*datasize_ ## from_format]))*error; \
+ right += datasize_ ## to_format; \
+ flpos += speed; \
+ samples--; \
+ } \
+}
+
+mk_converter(8,float)
+mk_converter(16le,float)
+mk_converter(16be,float)
+mk_converter(float,float)
+
+/*----------------------------- new code end --------------------------- */
+
+/*
+void old_convert_mono_8_float(unsigned long samples, unsigned char *from, float *to)
+{
+ float *end = to+samples;
+
+ while(to<end) *to++ = conv_8_float(*from++);
+}
+
+void old_convert_mono_16le_float(unsigned long samples, unsigned char *from, float *to)
+{
+ float *end = to+samples;
+
+ while(to<end)
+ {
+ *to++ = conv_16le_float(compose_16le(from));
+ from += 2;
+ }
+}
+
+
+void old_convert_stereo_i8_2float(unsigned long samples, unsigned char *from, float *left, float *right)
+{
+ float *end = left+samples;
+ while(left < end)
+ {
+ *left++ = conv_8_float(*from++);
+ *right++ = conv_8_float(*from++);
+ }
+}
+
+void old_convert_stereo_i16le_2float(unsigned long samples, unsigned char *from, float *left, float *right)
+{
+ float *end = left+samples;
+ while(left < end)
+ {
+ *left++ = conv_16le_float(compose_16le(from));
+ *right++ = conv_16le_float(compose_16le(from+2));
+ from += 4;
+ }
+}
+*/
+
+void Arts::convert_stereo_2float_i16le(unsigned long samples, float *left, float *right, unsigned char *to)
+{
+ float *end = left+samples;
+ long syn;
+
+ while(left < end)
+ {
+ syn = QRound((*left++)*32767);
+
+ if(syn < -32768) syn = -32768; /* clipping */
+ if(syn > 32767) syn = 32767;
+
+ *to++ = syn & 0xff;
+ *to++ = (syn >> 8) & 0xff;
+
+ syn = QRound((*right++)*32767);
+
+ if(syn < -32768) syn = -32768; /* clipping */
+ if(syn > 32767) syn = 32767;
+
+ *to++ = syn & 0xff;
+ *to++ = (syn >> 8) & 0xff;
+ }
+}
+
+void Arts::convert_mono_float_16le(unsigned long samples, float *from, unsigned char *to)
+{
+ float *end = from+samples;
+
+ while(from < end)
+ {
+ long syn = QRound((*from++)*32767);
+
+ if(syn < -32768) syn = -32768; /* clipping */
+ if(syn > 32767) syn = 32767;
+
+ *to++ = syn & 0xff;
+ *to++ = (syn >> 8) & 0xff;
+ }
+}
+
+void Arts::convert_stereo_2float_i16be(unsigned long samples, float *left, float *right, unsigned char *to)
+{
+ float *end = left+samples;
+ long syn;
+
+ while(left < end)
+ {
+ syn = QRound((*left++)*32767);
+
+ if(syn < -32768) syn = -32768; /* clipping */
+ if(syn > 32767) syn = 32767;
+
+ *to++ = (syn >> 8) & 0xff;
+ *to++ = syn & 0xff;
+
+ syn = QRound((*right++)*32767);
+
+ if(syn < -32768) syn = -32768; /* clipping */
+ if(syn > 32767) syn = 32767;
+
+ *to++ = (syn >> 8) & 0xff;
+ *to++ = syn & 0xff;
+ }
+}
+
+void Arts::convert_mono_float_16be(unsigned long samples, float *from, unsigned char *to)
+{
+ float *end = from+samples;
+
+ while(from < end)
+ {
+ long syn = QRound((*from++)*32767);
+
+ if(syn < -32768) syn = -32768; /* clipping */
+ if(syn > 32767) syn = 32767;
+
+ *to++ = (syn >> 8) & 0xff;
+ *to++ = syn & 0xff;
+ }
+}
+
+void Arts::convert_stereo_2float_i8(unsigned long samples, float *left, float *right, unsigned char *to)
+{
+ float *end = left+samples;
+ long syn;
+
+ while(left < end)
+ {
+ syn = (int)((*left++)*127+128);
+
+ if(syn < 0) syn = 0; /* clipping */
+ if(syn > 255) syn = 255;
+
+ *to++ = syn;
+
+ syn = (int)((*right++)*127+128);
+
+ if(syn < 0) syn = 0; /* clipping */
+ if(syn > 255) syn = 255;
+
+ *to++ = syn;
+ }
+}
+
+void Arts::convert_mono_float_8(unsigned long samples, float *from, unsigned char *to)
+{
+ float *end = from+samples;
+
+ while(from < end)
+ {
+ long syn = (int)((*from++)*127+128);
+
+ if(syn < 0) syn = 0; /* clipping */
+ if(syn > 255) syn = 255;
+
+ *to++ = syn;
+ }
+}
+
+unsigned long Arts::uni_convert_stereo_2float(
+ unsigned long samples, // number of required samples
+ unsigned char *from, // buffer containing the samples
+ unsigned long fromLen, // length of the buffer
+ unsigned int fromChannels, // channels stored in the buffer
+ unsigned int fromBits, // number of bits per sample
+ float *left, float *right, // output buffers for left and right channel
+ double speed, // speed (2.0 means twice as fast)
+ double startposition // startposition
+ )
+{
+ unsigned long doSamples = 0, sampleSize = fromBits/8;
+
+ if(fromBits == uni_convert_float_ne)
+ sampleSize = sizeof(float);
+
+ // how many samples does the from-buffer contain?
+ double allSamples = fromLen / (fromChannels * sampleSize);
+
+ // how many samples are remaining?
+ // subtract one due to interpolation and another against rounding errors
+ double fHaveSamples = allSamples - startposition - 2.0;
+ fHaveSamples /= speed;
+
+ // convert do "how many samples to do"?
+ if(fHaveSamples > 0)
+ {
+ doSamples = (int)fHaveSamples;
+ if(doSamples > samples) doSamples = samples;
+ }
+
+ // do conversion
+ if(doSamples)
+ {
+ if(fromChannels == 1)
+ {
+ if(fromBits == uni_convert_float_ne) {
+ interpolate_mono_float_float(doSamples,
+ startposition,speed,(float *)from,left);
+ }
+ else if(fromBits == uni_convert_s16_be) {
+ interpolate_mono_16be_float(doSamples,
+ startposition,speed,from,left);
+ }
+ else if(fromBits == uni_convert_s16_le) {
+ interpolate_mono_16le_float(doSamples,
+ startposition,speed,from,left);
+ }
+ else {
+ interpolate_mono_8_float(doSamples,
+ startposition,speed,from,left);
+ }
+ memcpy(right,left,sizeof(float)*doSamples);
+ }
+ else if(fromChannels == 2)
+ {
+ if(fromBits == uni_convert_float_ne) {
+ interpolate_stereo_ifloat_2float(doSamples,
+ startposition,speed,(float *)from,left,right);
+ }
+ else if(fromBits == uni_convert_s16_be) {
+ interpolate_stereo_i16be_2float(doSamples,
+ startposition,speed,from,left,right);
+ }
+ else if(fromBits == uni_convert_s16_le) {
+ interpolate_stereo_i16le_2float(doSamples,
+ startposition,speed,from,left,right);
+ }
+ else {
+ interpolate_stereo_i8_2float(doSamples,
+ startposition,speed,from,left,right);
+ }
+ } else {
+ assert(false);
+ }
+ }
+ return doSamples;
+}
+
+// undefine all that stuff (due to --enable-final)
+#undef compose_16le
+#undef compose_16be
+#undef conv_16_float
+#undef convert_16le_float
+#undef convert_16be_float
+#undef conv_8_float
+#undef convert_8_float
+#undef convert_float_float
+#undef datatype_16le
+#undef datasize_16le
+#undef datatype_16be
+#undef datasize_16be
+#undef datatype_8
+#undef datasize_8
+#undef datatype_float
+#undef datasize_float
+#undef mk_converter
diff --git a/flow/convert.h b/flow/convert.h
new file mode 100644
index 0000000..35551a1
--- /dev/null
+++ b/flow/convert.h
@@ -0,0 +1,164 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef _arts_convert_h
+#define _arts_convert_h
+
+#include "arts_export.h"
+
+/*
+ * BC - Status (2002-03-08): conversion functions
+ *
+ * None of them will be removed or changed, so it is safe to use them in
+ * your apps. It is *recommended* (though not necessary) to use the new
+ * resampling code (Resampler) where possible.
+ */
+
+namespace Arts {
+
+/*
+ * Simple conversion routines. The function names are chosen like
+ *
+ * convert_mono_FROM_TO for mono conversions
+ * convert_stereo_FROM_TO for stereo conversions
+ *
+ * while FROM/TO are
+ *
+ * 8 for 8bit signed data
+ * 16le for 16bit signed little endian
+ * float for float data between -1 and 1
+ *
+ * and may be prefixed by 2 to indicate that stereo is done with two seperate
+ * buffers or i to indicate interleaved stereo (one buffer which contains
+ * one sample left, one sample right, one sample left etc.)
+ *
+ * The parameter speed (for interpolations) is *not* the samplingrate, but
+ * a relative value. A speed of 2.0 means "play twice as fast".
+ */
+
+// upconversions from integer to float
+void ARTS_EXPORT convert_mono_8_float(unsigned long samples,
+ unsigned char *from, float *to);
+
+void ARTS_EXPORT interpolate_mono_8_float(unsigned long samples,
+ double startpos, double speed,
+ unsigned char *from, float *to);
+
+void ARTS_EXPORT convert_mono_16le_float(unsigned long samples,
+ unsigned char *from, float *to);
+
+void ARTS_EXPORT interpolate_mono_16le_float(unsigned long samples,
+ double startpos, double speed,
+ unsigned char *from, float *to);
+
+void ARTS_EXPORT convert_mono_16be_float(unsigned long samples,
+ unsigned char *from, float *to);
+
+void ARTS_EXPORT interpolate_mono_16be_float(unsigned long samples,
+ double startpos, double speed,
+ unsigned char *from, float *to);
+
+void ARTS_EXPORT convert_stereo_i8_2float(unsigned long samples,
+ unsigned char *from, float *left, float *right);
+
+void ARTS_EXPORT interpolate_stereo_i8_2float(unsigned long samples,
+ double startpos, double speed,
+ unsigned char *from, float *left, float *right);
+
+void ARTS_EXPORT convert_stereo_i16le_2float(unsigned long samples,
+ unsigned char *from, float *left, float *right);
+
+void ARTS_EXPORT interpolate_stereo_i16le_2float(unsigned long samples,
+ double startpos, double speed,
+ unsigned char *from, float *left, float *right);
+
+void ARTS_EXPORT convert_stereo_i16be_2float(unsigned long samples,
+ unsigned char *from, float *left, float *right);
+
+void ARTS_EXPORT interpolate_stereo_i16be_2float(unsigned long samples,
+ double startpos, double speed,
+ unsigned char *from, float *left, float *right);
+
+void ARTS_EXPORT convert_mono_float_float(unsigned long samples,
+ float *from, float *to);
+
+void ARTS_EXPORT interpolate_mono_float_float(unsigned long samples,
+ double startpos, double speed,
+ float *from, float *to);
+
+void ARTS_EXPORT convert_stereo_ifloat_2float(unsigned long samples,
+ float *from, float *left, float *right);
+
+void ARTS_EXPORT interpolate_stereo_ifloat_2float(unsigned long samples,
+ double startpos, double speed,
+ float *from, float *left, float *right);
+
+// downconversions from float to integer
+void ARTS_EXPORT convert_mono_float_16le(unsigned long samples,
+ float *from, unsigned char *to);
+
+void ARTS_EXPORT convert_stereo_2float_i16le(unsigned long samples,
+ float *left, float *right, unsigned char *to);
+
+void ARTS_EXPORT convert_mono_float_16be(unsigned long samples,
+ float *from, unsigned char *to);
+
+void ARTS_EXPORT convert_stereo_2float_i16be(unsigned long samples,
+ float *left, float *right, unsigned char *to);
+
+void ARTS_EXPORT convert_mono_float_8(unsigned long samples,
+ float *from, unsigned char *to);
+
+void ARTS_EXPORT convert_stereo_2float_i8(unsigned long samples,
+ float *left, float *right, unsigned char *to);
+
+
+/*
+ * This practical routine picks the right conversion routine for given
+ * parameters and makes boundary checks
+ */
+
+// returnvalue: number of samples generated
+
+/* formats for unified conversion */
+enum {
+ uni_convert_u8 = 8, // unsigned 8 bit
+ uni_convert_s16_le = 16, // signed 16 bit, little endian
+ uni_convert_s16_be = 17, // signed 16 bit, big endian
+ uni_convert_float_ne = 0x100 // float, in native size/byteorder
+};
+
+unsigned long ARTS_EXPORT uni_convert_stereo_2float(
+ unsigned long samples, // number of required samples
+ unsigned char *from, // buffer containing the samples
+ unsigned long fromLen, // length of the buffer
+ unsigned int fromChannels, // channels stored in the buffer
+ unsigned int fromBits, // number of bits per sample
+ // (also: uni_convert_ formats given above)
+ float *left, float *right, // output buffers for left and right channel
+ double speed, // speed (2.0 means twice as fast)
+ double startposition // startposition
+ );
+
+}
+
+#endif
diff --git a/flow/cpuinfo.cc b/flow/cpuinfo.cc
new file mode 100644
index 0000000..8b03295
--- /dev/null
+++ b/flow/cpuinfo.cc
@@ -0,0 +1,232 @@
+ /*
+
+ Copyright (C) 2001 Malte Starostik <malte@kde.org>
+ 2001 Darian Lanx <bio@gmx.net>
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include <config.h>
+#include "startupmanager.h"
+#include "cpuinfo.h"
+
+#include <setjmp.h>
+#include <signal.h>
+
+using namespace Arts;
+
+int CpuInfo::s_flags = 0;
+
+namespace Arts
+{
+ class CpuInfoStartup : public StartupClass
+ {
+ public:
+ virtual void startup();
+
+ private:
+ static jmp_buf s_sseCheckEnv;
+ static void sseCheckHandler(int);
+ };
+}
+
+jmp_buf CpuInfoStartup::s_sseCheckEnv;
+
+void CpuInfoStartup::sseCheckHandler(int)
+{
+ longjmp(s_sseCheckEnv, 1);
+}
+
+void CpuInfoStartup::startup()
+{
+#ifdef HAVE_X86_SSE
+/*
+ * Taken with thanks from mmx.h:
+ *
+ * MultiMedia eXtensions GCC interface library for IA32.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR ANY PARTICULAR PURPOSE.
+ */
+
+/* Returns 1 if MMX instructions are supported,
+ * 3 if Cyrix MMX and Extended MMX instructions are supported
+ * 5 if AMD MMX and 3DNow! instructions are supported
+ * 9 if MMX and Intel ISSE instructions are supported
+ * 0 if hardware does not support any of these
+*/
+ __asm__ __volatile__ (
+ "pushl %%ebx \n\t"
+ "pushl %%ecx \n\t"
+ "pushl %%edx \n\t"
+
+ // See if CPUID instruction is supported ...
+ // ... Get copies of EFLAGS into eax and ecx
+ "pushf \n\t"
+ "popl %%eax \n\t"
+ "movl %%eax, %%ecx \n\t"
+
+ // ... Toggle the ID bit in one copy and store
+ // to the EFLAGS reg
+ "xorl $0x00200000, %%eax \n\t"
+ "push %%eax \n\t"
+ "popf \n\t"
+
+ // ... Get the (hopefully modified) EFLAGS
+ "pushf \n\t"
+ "popl %%eax \n\t"
+
+ // ... Compare and test result
+ "xorl %%eax, %%ecx \n\t"
+ "testl $0x00200000, %%ecx \n\t"
+ "jz NotSupported \n\t"
+
+ // Get standard CPUID information, and
+ // go to a specific vendor section
+ "movl $0, %%eax \n\t"
+ "cpuid \n\t"
+
+ // Check for Intel
+ "cmpl $0x756e6547, %%ebx \n\t" // Genu
+ "jne TryAMD \n\t"
+ "cmpl $0x49656e69, %%edx \n\t" // ineI
+ "jne TryAMD \n\t"
+ "cmpl $0x6c65746e, %%ecx \n\t" // ntel
+ "jne TryAMD \n\t"
+ "jmp Intel \n\t"
+
+ // Check for AMD
+ "TryAMD: \n\t"
+ "cmpl $0x68747541, %%ebx \n\t" // Auth
+ "jne TryCyrix \n\t"
+ "cmpl $0x69746e65, %%edx \n\t" // enti
+ "jne TryCyrix \n\t"
+ "cmpl $0x444d4163, %%ecx \n\t" // cAMD
+ "jne TryCyrix \n\t"
+ "jmp AMD \n\t"
+
+ // Check for Cyrix
+ "TryCyrix: \n\t"
+ "cmpl $0x69727943, %%ebx \n\t" // Cyri
+ "jne NotSupported \n\t"
+ "cmpl $0x736e4978, %%edx \n\t" // xIns
+ "jne NotSupported \n\t"
+ "cmpl $0x64616574, %%ecx \n\t" // tead
+ "jne NotSupported \n\t"
+ // Drop through to Cyrix...
+
+ // Cyrix Section
+ // See if extended CPUID is supported
+ "movl $0x80000000, %%eax \n\t"
+ "cpuid \n\t"
+ "cmpl $0x80000000, %%eax \n\t"
+ "jl MMXtest \n\t" // try std CPUID
+
+ // Extended CPUID supported, so get extended features
+ "movl $0x80000001, %%eax \n\t"
+ "cpuid \n\t"
+ "testl $0x00800000, %%eax \n\t" // test for MMX
+ "jz NotSupported \n\t" // no MMX
+ "movl $1, %0 \n\t" // has MMX
+ "testl $0x01000000, %%eax \n\t" // test for EMMX
+ "jz Return \n\t" // no EMMX
+ "addl $2, %0 \n\t" // has EMMX
+ "jmp Return \n\t"
+
+ // AMD Section
+ "AMD: \n\t"
+
+ // See if extended CPUID is supported
+ "movl $0x80000000, %%eax \n\t"
+ "cpuid \n\t"
+ "cmpl $0x80000000, %%eax \n\t"
+ "jl MMXtest \n\t" // try std CPUID
+
+ // Extended CPUID supported, so get extended features
+ "movl $0x80000001, %%eax \n\t"
+ "cpuid \n\t"
+ "testl $0x00800000, %%edx \n\t" // test for MMX
+ "jz NotSupported \n\t" // no MMX
+ "movl $1, %0 \n\t" // has MMX
+ "testl $0x80000000, %%edx \n\t" // test for 3DNow!
+ "jz Return \n\t"
+ "addl $4, %0 \n\t" // has 3DNow!
+ // Athlon(tm) XP has both 3DNow! and SSE
+ "pushl %%eax \n\t"
+ "movl $1, %%eax \n\t"
+ "cpuid \n\t"
+ "popl %%eax \n\t"
+ "testl $0x02000000, %%edx \n\t" // test for SSE
+ "jz Return \n\t" // no SSE
+ "addl $8, %0 \n\t" // has SSE
+ "jmp Return \n\t"
+
+ // Intel Section
+ "Intel: \n\t"
+
+ // Check for MMX
+ "MMXtest: \n\t"
+ "movl $1, %%eax \n\t"
+ "cpuid \n\t"
+ "testl $0x00800000, %%edx \n\t" // test for MMX
+ "jz NotSupported \n\t" // no MMX
+ "movl $1, %0 \n\t" // has MMX
+ "testl $0x02000000, %%edx \n\t" // test for SSE
+ "jz Return \n\t" // no SSE
+ "addl $8, %0 \n\t" // has SSE
+ "jmp Return \n\t"
+
+ // Nothing supported
+ "NotSupported: \n\t"
+ "movl $0, %0 \n\t"
+
+ "Return: \n\t"
+ "popl %%edx \n\t"
+ "popl %%ecx \n\t"
+ "popl %%ebx \n\t"
+ : "=a" (CpuInfo::s_flags)
+ : /* no input */
+ : "memory"
+ );
+ // SSE must be supported by the OS, if it's not, any SSE insn will
+ // trigger an invalid opcode exception, to check for this, a SIGILL
+ // handler is installed and a SSE insn run. If the handler is called,
+ // the SSE bit is cleared in CpuInfo::s_flags
+ if (CpuInfo::s_flags & CpuInfo::CpuSSE)
+ {
+ void (*oldHandler)(int) = signal(SIGILL, sseCheckHandler);
+ if (setjmp(s_sseCheckEnv))
+ {
+ CpuInfo::s_flags &= ~CpuInfo::CpuSSE;
+ }
+ else
+ {
+ __asm__ __volatile__ (
+ "subl $0x10, %esp \n"
+ "movups %xmm0, (%esp) \n"
+ "emms \n"
+ "addl $0x10, %esp \n"
+ );
+ }
+ signal(SIGILL, oldHandler);
+ }
+#endif /* HAVE_X86_SSE */
+}
+
+static CpuInfoStartup cpuInfoStartup;
diff --git a/flow/cpuinfo.h b/flow/cpuinfo.h
new file mode 100644
index 0000000..927f682
--- /dev/null
+++ b/flow/cpuinfo.h
@@ -0,0 +1,72 @@
+ /*
+
+ Copyright (C) 2001 Malte Starostik <malte@kde.org>
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef _arts_cpuinfo_h
+#define _arts_cpuinfo_h
+
+#include "arts_export.h"
+/*
+ * BC - Status (2002-03-08): CpuInfo
+ *
+ * This class will be kept binary compatible - it just exports the static
+ * CpuInfo::flags() function as only functionality.
+ */
+
+namespace Arts {
+
+ /**
+ * Provides information about the availability of the various
+ * "Multimedia extensions" the CPU supports. If you implement
+ * a routine in assembler, use @ref flags() to know which
+ * SIMD instructions the user's CPU knows about.
+ *
+ * @short Information about the CPU's SIMD implementation
+ */
+ class ARTS_EXPORT CpuInfo
+ {
+ public:
+ /**
+ * Values for the detected features of the CPU:
+ * @li CpuMMX - CPU supports MMX
+ * @li CpuEMMX - CPU supports Cyrix Extended MMX
+ * @li Cpu3DNow - CPU supports AMD 3DNow!
+ * @li CpuSSE - CPU supports Intel SSE
+ */
+ enum Flags
+ {
+ CpuMMX = 0x001, // Pentium MMX
+ CpuEMMX = 0x002, // Cyrix Extended MMX
+ Cpu3DNow = 0x004, // AMD 3DNow!
+ CpuSSE = 0x008 // Pentium III SSE
+ };
+ /**
+ * @return the @ref Flags values that correspond to the
+ * CPU's features. Multiple values are bitwised or'ed
+ */
+ static int flags() { return s_flags; }
+
+ private:
+ friend class CpuInfoStartup;
+ static int s_flags;
+ };
+}
+
+#endif // _arts_cpuinfo_h
diff --git a/flow/datahandle_impl.cc b/flow/datahandle_impl.cc
new file mode 100644
index 0000000..e576e75
--- /dev/null
+++ b/flow/datahandle_impl.cc
@@ -0,0 +1,499 @@
+ /*
+
+ Copyright (C) 2002 Hans Meine
+ hans_meine@gmx.net
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include <gsl/gsldatahandle.h>
+#include <gsl/gslloader.h>
+#include <gsl/gslwaveosc.h>
+#include "artsflow.h"
+#include "stdsynthmodule.h"
+#include "debug.h"
+#include <algorithm>
+#include <cstring>
+#include <gslpp/datahandle.h>
+
+using namespace std;
+
+namespace Arts {
+
+static GSL::DataHandle getDHandle(DataHandle handle);
+
+class DataHandle_impl : virtual public DataHandle_skel
+{
+protected:
+ GSL::DataHandle dhandle_;
+ long errno_;
+ friend GSL::DataHandle getDHandle(DataHandle handle);
+
+public:
+ DataHandle_impl(GSL::DataHandle dhandle = GSL::DataHandle::null())
+ : dhandle_(dhandle)
+ {
+ errno_ = dhandle_.isNull() ? 0 : dhandle_.open();
+ }
+
+ ~DataHandle_impl()
+ {
+ if(dhandle_.isOpen())
+ dhandle_.close();
+ }
+
+ long valueCount()
+ {
+ return dhandle_.valueCount();
+ }
+
+ long bitDepth()
+ {
+ return dhandle_.bitDepth();
+ }
+
+ long channelCount()
+ {
+ return dhandle_.channelCount();
+ }
+
+ long errorNo()
+ {
+ return errno_;
+ }
+
+ GSL::DataHandle createCropped(long headCutValueCount,
+ long tailCutValueCount)
+ {
+ return dhandle_.createCropped(headCutValueCount, tailCutValueCount);
+ }
+
+ GSL::DataHandle createCut(long cutOffset,
+ long cutValueCount)
+ {
+ return dhandle_.createCut(cutOffset, cutValueCount);
+ }
+
+ GSL::DataHandle createReversed()
+ {
+ return dhandle_.createReversed();
+ }
+};
+
+class ReversedDataHandle_impl : virtual public DataHandle_impl,
+ virtual public ReversedDataHandle_skel
+{
+ void init(DataHandle sourceHandle)
+ {
+ DataHandle_impl *impl = dynamic_cast<DataHandle_impl *>(sourceHandle._base());
+ dhandle_ = impl->createReversed();
+ }
+};
+
+class CroppedDataHandle_impl : virtual public DataHandle_impl,
+ virtual public CroppedDataHandle_skel
+{
+ void init(DataHandle sourceHandle,
+ long headCutValueCount,
+ long tailCutValueCount)
+ {
+ DataHandle_impl *impl = dynamic_cast<DataHandle_impl *>(sourceHandle._base());
+ dhandle_ = impl->createCropped(headCutValueCount, tailCutValueCount);
+ }
+};
+
+class CutDataHandle_impl : virtual public DataHandle_impl,
+ virtual public CutDataHandle_skel
+{
+ void init(DataHandle sourceHandle,
+ long cutOffset,
+ long cutValueCount)
+ {
+ DataHandle_impl *impl = dynamic_cast<DataHandle_impl *>(sourceHandle._base());
+ dhandle_ = impl->createCut(cutOffset, cutValueCount);
+ }
+};
+
+static GSL::DataHandle getDHandle(DataHandle handle)
+{
+ DataHandle_impl *impl = dynamic_cast<DataHandle_impl *>(handle._base());
+ if(impl)
+ return impl->dhandle_;
+ return GSL::DataHandle::null();
+}
+
+GslWaveChunk* const_wchunk_from_freq(gpointer wchunk_data, gfloat)
+{
+ return (GslWaveChunk*)wchunk_data;
+}
+
+// FIXME: Think about whether this is needed as a parameter like mixerFrequency
+#define OSCILLATOR_FREQUENCY 440.0f
+
+class DataHandlePlay_impl : virtual public DataHandlePlay_skel,
+ virtual public StdSynthModule
+{
+protected:
+ DataHandle dhandle_;
+
+ GSL::DataHandle gslDHandle_;
+ int errno_;
+ GslWaveChunk *wchunk_;
+ GslErrorType wchunkError_;
+ GslWaveOscData *wosc_;
+
+ float mixerFrequency_;
+ unsigned short channelIndex_;
+ float speed_;
+ unsigned long pos_;
+ bool finished_;
+ bool paused_;
+
+public:
+ DataHandlePlay_impl()
+ : dhandle_(DataHandle::null()),
+ gslDHandle_(GSL::DataHandle::null()),
+ wchunk_(NULL),
+ wosc_(NULL),
+ mixerFrequency_(0), // FIXME: doc says soundserver's freq
+ channelIndex_(0),
+ speed_(1.0f),
+ pos_(0),
+ finished_(false),
+ paused_(false)
+ {}
+
+ ~DataHandlePlay_impl()
+ {
+ handle(DataHandle::null());
+ }
+
+ DataHandle handle()
+ {
+ return dhandle_;
+ }
+
+ void handle(DataHandle handle)
+ {
+ deleteWaveChunk();
+
+ if(!gslDHandle_.isNull() && !errno_)
+ gslDHandle_.close();
+
+ dhandle_ = handle;
+
+ if(handle.isNull())
+ gslDHandle_ = GSL::DataHandle::null();
+ else
+ {
+ gslDHandle_ = getDHandle(dhandle_);
+
+ if(gslDHandle_.isNull())
+ {
+ arts_debug("ERROR: could not get internal GSL::DataHandle!");
+ finished(true); // FIXME: can this happen?
+ }
+ else
+ {
+ errno_ = gslDHandle_.open();
+ if(errno_)
+ arts_debug("DataHandlePlay got error from GSL::DataHandle.open(): '%s'",
+ strerror(errno_));
+ }
+ }
+ }
+
+ void streamInit()
+ {
+ if(!gslDHandle_.isNull() && !wosc_)
+ {
+ if(!wchunk_)
+ createWaveChunk();
+ configureWaveOsc();
+ }
+ }
+
+ float mixerFrequency() { return wosc_ ? wosc_->mix_freq : 0; }
+ void mixerFrequency(float f)
+ {
+ if(wchunk_)
+ arts_warning("DataHandlePlay: cannot change mixerFrequency after start of sound processing!");
+
+ if(mixerFrequency() != f)
+ {
+ mixerFrequency_ = f;
+ mixerFrequency_changed(f);
+ }
+ }
+
+ long channelIndex() { return channelIndex_; }
+ void channelIndex(long ci)
+ {
+ if(channelIndex_ != ci)
+ {
+ channelIndex_ = ci;
+ if(wosc_)
+ {
+ GslWaveOscConfig config = wosc_->config;
+ config.channel = ci;
+ gsl_wave_osc_config(wosc_, &config);
+ }
+ channelIndex_changed(ci);
+ }
+ }
+
+ float speed() { return speed_; }
+ void speed(float s)
+ {
+ if(speed_ != s)
+ {
+ speed_ = s;
+ if(wosc_)
+ {
+ GslWaveOscConfig config = wosc_->config;
+ config.cfreq = OSCILLATOR_FREQUENCY * speed();
+ gsl_wave_osc_config(wosc_, &config);
+ }
+ speed_changed(s);
+ }
+ }
+
+ long pos() { return wosc_ ? wosc_->block.offset : 0; }
+ void pos(long p)
+ {
+ if(pos() != p)
+ {
+ GslWaveOscConfig config = wosc_->config;
+ config.start_offset = p;
+ gsl_wave_osc_config(wosc_, &config);
+ pos_changed(p);
+ }
+ }
+
+ bool finished() { return finished_; }
+ void finished(bool f)
+ {
+ if(finished_ != f)
+ {
+ finished_ = f;
+ finished_changed(f);
+ }
+ }
+
+ bool paused() { return paused_; }
+ void paused(bool p)
+ {
+ paused_ = p;
+ }
+
+ void deleteWaveChunk()
+ {
+ deleteWaveOsc();
+
+ if(wchunk_)
+ {
+ arts_debug("DataHandlePlay_impl: close()ing gsl_wave_chunk");
+ gsl_wave_chunk_close(wchunk_);
+ gsl_wave_chunk_unref(wchunk_);
+ wchunk_ = NULL;
+ }
+ }
+
+ void createWaveChunk()
+ {
+ deleteWaveChunk();
+
+ if(!gslDHandle_.isNull() && gslDHandle_.isOpen())
+ {
+ GslDataCache *dcache = gslDHandle_.createGslDataCache();
+ if(!dcache)
+ {
+ arts_debug("FATAL: creating data cache failed!");
+ finished(true); // FIXME: can this happen?
+ }
+ else
+ {
+ wchunk_ =
+ gsl_wave_chunk_new(dcache,
+ OSCILLATOR_FREQUENCY,
+ mixerFrequency_,
+ GSL_WAVE_LOOP_NONE,
+ 0, 0, 0);
+ arts_debug("DataHandlePlay_impl: open()ing gsl_wave_chunk");
+ wchunkError_ = gsl_wave_chunk_open(wchunk_);
+ gsl_data_cache_unref(dcache);
+ }
+ }
+ }
+
+ void deleteWaveOsc()
+ {
+ if(wosc_)
+ {
+ gsl_wave_osc_shutdown(wosc_);
+ delete wosc_;
+ wosc_ = NULL;
+ }
+ }
+
+ void configureWaveOsc()
+ {
+ if(wchunk_)
+ {
+ GslWaveOscConfig config;
+ memset(&config, 0, sizeof (GslWaveOscConfig));
+ config.start_offset = 0;
+ config.play_dir = 1;
+ config.wchunk_data = (gpointer)wchunk_;
+ config.wchunk_from_freq = &const_wchunk_from_freq;
+ config.channel = channelIndex();
+ config.cfreq = OSCILLATOR_FREQUENCY * speed();
+
+ if(!wosc_)
+ {
+ wosc_ = new GslWaveOscData();
+ gsl_wave_osc_init(wosc_);
+ }
+
+ gsl_wave_osc_config(wosc_, &config);
+ }
+ }
+
+ void calculateBlock(unsigned long samples)
+ {
+ if(!paused_ && wchunk_)
+ {
+ if (!gsl_wave_osc_process(wosc_, samples, 0, 0, 0, outvalue))
+ arts_debug("gsl_wave_osc_process failed.");
+ finished(wosc_->done);
+ }
+ else
+ for(unsigned long i = 0; i < samples; i++)
+ outvalue[i] = 0.f;
+ /*
+ unsigned long haveSamples = 0;
+
+ while(haveSamples != samples)
+ {
+ long n = min(gslDHandle_.valueCount() - pos_, samples - haveSamples);
+ long got = gslDHandle_.isNull() ?
+ 0 : gslDHandle_.read(pos_, n, &outvalue[haveSamples]);
+ if(got <= 0)
+ {
+ for(unsigned long i = haveSamples; i < samples; i++)
+ outvalue[i] = 0.f;
+ break;
+ }
+ pos_ += got;
+ haveSamples += got;
+ }
+ finished(pos_ >= gslDHandle_.valueCount());
+ */
+ }
+
+ DataHandlePlay clone()
+ {
+ arts_debug("DataHandlePlay_impl: clone()ing myself");
+ DataHandlePlay_impl *result = new DataHandlePlay_impl();
+
+ result->dhandle_ = dhandle_;
+ result->gslDHandle_ = gslDHandle_;
+ result->errno_ = errno_;
+
+ createWaveChunk();
+ if(wchunk_)
+ {
+ result->wchunk_ = wchunk_;
+ gsl_wave_chunk_ref(wchunk_);
+ result->wchunkError_ = gsl_wave_chunk_open(wchunk_);
+ }
+ else
+ result->wchunkError_ = wchunkError_;
+
+ result->mixerFrequency_ = mixerFrequency_;
+ result->channelIndex_ = channelIndex_;
+ result->speed_ = speed_;
+ result->pos_ = pos_;
+ result->finished_ = finished_;
+ result->paused_ = paused_;
+
+ return DataHandlePlay::_from_base(result);
+ }
+};
+
+class WaveDataHandle_impl : virtual public DataHandle_impl,
+ virtual public WaveDataHandle_skel
+{
+ GSL::WaveDataHandle wdhandle_;
+
+public:
+ WaveDataHandle_impl() : wdhandle_(GSL::WaveDataHandle::null()) {}
+
+ float mixerFrequency()
+ {
+ return wdhandle_.mixerFrequency();
+ }
+
+ float oscillatorFrequency()
+ {
+ return wdhandle_.oscillatorFrequency();
+ }
+
+ bool load(const string& filename)
+ {
+ return load(filename, 0, 0);
+ }
+
+ bool load(const string& filename,
+ long waveIndex,
+ long chunkIndex)
+ {
+ wdhandle_ = GSL::WaveDataHandle(filename, waveIndex, chunkIndex);
+ if(dhandle_.isOpen())
+ dhandle_.close();
+ dhandle_ = wdhandle_;
+ errno_ = dhandle_.isNull() ? 0 : dhandle_.open();
+ return isLoaded();
+ }
+
+ bool isLoaded()
+ {
+ if(wdhandle_.isNull())
+ return false;
+
+ return !wdhandle_.error();
+ }
+
+ DataHandlePlay createPlayer()
+ {
+ DataHandlePlay_impl *result= new DataHandlePlay_impl();
+
+ result->mixerFrequency(mixerFrequency());
+ result->handle(WaveDataHandle::_from_base(this->_copy()));
+
+ return DataHandlePlay::_from_base(result);
+ }
+};
+
+REGISTER_IMPLEMENTATION(DataHandlePlay_impl);
+REGISTER_IMPLEMENTATION(DataHandle_impl);
+REGISTER_IMPLEMENTATION(CroppedDataHandle_impl);
+REGISTER_IMPLEMENTATION(CutDataHandle_impl);
+REGISTER_IMPLEMENTATION(ReversedDataHandle_impl);
+REGISTER_IMPLEMENTATION(WaveDataHandle_impl);
+
+}
diff --git a/flow/fft.c b/flow/fft.c
new file mode 100644
index 0000000..15c821f
--- /dev/null
+++ b/flow/fft.c
@@ -0,0 +1,32 @@
+#include "gsl/gslfft.h"
+#include "fft.h"
+
+void arts_fft_float (
+ unsigned NumSamples,
+ int InverseTransform,
+ float *RealIn,
+ float *ImagIn,
+ float *RealOut,
+ float *ImagOut )
+{
+ double *ri_in = g_newa(double, NumSamples*4);
+ double *ri_out = ri_in + NumSamples*2;
+ unsigned int i;
+
+ for(i = 0; i < NumSamples; i++)
+ {
+ ri_in[2*i] = RealIn[i];
+ ri_in[2*i+1] = (ImagIn?ImagIn[i]:0.0);
+ }
+
+ if(InverseTransform == 0)
+ gsl_power2_fftac (NumSamples, ri_in, ri_out);
+ else
+ gsl_power2_fftsc (NumSamples, ri_in, ri_out);
+
+ for(i = 0; i < NumSamples; i++)
+ {
+ RealOut[i] = ri_out[2*i];
+ ImagOut[i] = ri_out[2*i+1];
+ }
+}
diff --git a/flow/fft.h b/flow/fft.h
new file mode 100644
index 0000000..009f764
--- /dev/null
+++ b/flow/fft.h
@@ -0,0 +1,32 @@
+#ifndef ARTS_FFT_H
+#define ARTS_FFT_H
+
+/*
+ * BC - Status (2002-03-08): arts_fft_float
+ *
+ * This fft interface should be obsoleted in the future in favour of one
+ * exploiting the capabilities of gsl fully. However, it will be kept binary
+ * compatible to avoid everybody to reimplement/duplicate their own fft.
+ */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * performs an fft
+ */
+void arts_fft_float (
+ unsigned NumSamples, /* must be a power of 2 */
+ int InverseTransform, /* 0=forward FFT, 1=inverse FFT */
+ float *RealIn, /* array of input's real samples */
+ float *ImaginaryIn, /* array of input's imag samples */
+ float *RealOut, /* array of output's reals */
+ float *ImaginaryOut ); /* array of output's imaginaries */
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* ARTS_FFT_H */
diff --git a/flow/gsl/Makefile.am b/flow/gsl/Makefile.am
new file mode 100644
index 0000000..41a4dab
--- /dev/null
+++ b/flow/gsl/Makefile.am
@@ -0,0 +1,24 @@
+
+EXTRA_DIST =
+CLEANFILES =
+MAINTAINERCLEANFILES =
+
+gslincludedir=$(includedir)/arts/gsl
+include gslmakefile.inc
+
+INCLUDES = -I$(top_srcdir)/flow -I$(top_builddir)/flow -I$(top_srcdir)/mcop -I$(top_builddir)/mcop -I$(top_builddir) $(all_includes)
+AM_CFLAGS = $(GSL_CFLAGS)
+
+noinst_LTLIBRARIES = libgsl.la
+
+libgsl_la_SOURCES = $(GSL_C_SRC) gslfilehash.c gslartsthreads.cc
+libgsl_la_LIBADD = $(top_builddir)/mcop/libmcop.la -lm $(LIBPOSIX4) $(GSL_LIBS) $(LIB_POLL) $(GLIB_LIBADD)
+libgsl_la_LDFLAGS = -no-undefined $(all_libraries)
+
+#noinst_PROGRAMS = $(GSL_NOINST_PROGS)
+
+GSL_progs_ldadd = libgsl.la -lm $(LIBPTHREAD)
+
+GSL_cc_dummy = dummy.cc
+$(srcdir)/dummy.cc: gslconfig.h
+
diff --git a/flow/gsl/arts-patches b/flow/gsl/arts-patches
new file mode 100644
index 0000000..e5bf761
--- /dev/null
+++ b/flow/gsl/arts-patches
@@ -0,0 +1,73 @@
+Those are aRts/KDE-specific changes which won't be backfolded into the
+original GSL repository but are needed here:
+
+--- gsldatahandle-vorbis.c Tue Jul 30 01:26:06 2002
++++ /usr/src/arts.dh/flow/gsl/gsldatahandle-vorbis.c Tue Jul 30 17:46:33 2002
+@@ -19,4 +19,5 @@
+ #include "gsldatahandle-vorbis.h"
+
++#if GSL_HAVE_OGGVORBIS
+ #include "gslfilehash.h"
+ #include <ogg/ogg.h>
+@@ -239,5 +240,9 @@ read_packet (VorbisHandle *vhandle)
+
+ vhandle->pcm_pos = ov_pcm_tell (&vhandle->ofile) - vhandle->soffset;
++#if GSL_HAVE_OGGVORBIS_RC3
+ vhandle->pcm_length = ov_read_float (&vhandle->ofile, &pcm, &stream_id);
++#else
++ vhandle->pcm_length = ov_read_float (&vhandle->ofile, &pcm, (~0U>>1), &stream_id);
++#endif
+ if (vhandle->pcm_pos < 0 || vhandle->pcm_length < 0 || stream_id != vhandle->stream)
+ {
+@@ -368,2 +373,4 @@ gsl_data_handle_new_ogg_vorbis (const gc
+ }
+ }
++#endif /* GSL_HAVE_OGGVORBIS */
++
+--- gsldefs.h Wed Jul 24 05:50:17 2002
++++ /usr/src/arts.dh/flow/gsl/gsldefs.h Tue Jul 30 02:29:55 2002
+@@ -20,5 +20,8 @@
+ #define __GSL_DEFS_H__
+
+-#ifdef GSL_WANT_GLIB_WRAPPER
++/* configure checks */
++#include <gsl/gslconfig.h>
++
++#if GSL_USE_GSL_GLIB
+ #include <gsl/gslglib.h> /* GSL just uses a certain subset of GLib */
+ #else
+@@ -26,9 +29,4 @@
+ #endif
+
+-
+-/* configure checks */
+-#include <gsl/gslconfig.h>
+-
+-
+ #ifdef __cplusplus
+ extern "C" {
+@@ -103,5 +101,5 @@ typedef void (*GslModuleFreeFunc)
+
+ #if defined (BSE_COMPILATION) || defined (BSE_PLUGIN_FALLBACK) \
+- || defined (GSL_WANT_GLIB_WRAPPER) || defined (GSL_EXTENSIONS)
++ || (GSL_USE_GSL_GLIB) || defined (GSL_EXTENSIONS)
+ # define if_expect(cond) if (GSL_GCC_EXPECT (cond))
+ # define if_reject(cond) if (GSL_GCC_REJECT (cond))
+--- gslloader-oggvorbis.c Tue Jul 30 01:26:06 2002
++++ /usr/src/arts.dh/flow/gsl/gslloader-oggvorbis.c Tue Jul 30 05:06:32 2002
+@@ -19,4 +19,5 @@
+ #include "gsl/gslloader.h"
+
++#if GSL_HAVE_OGGVORBIS
+ #include <gsl/gsldatahandle.h>
+ #include "gsldatahandle-vorbis.h"
+@@ -168,2 +169,9 @@ _gsl_init_loader_oggvorbis (void)
+ gsl_loader_register (&loader);
+ }
++#else
++void
++_gsl_init_loader_oggvorbis (void)
++{
++ /* dummy */
++}
++#endif /* GSL_HAVE_OGGVORBIS */
diff --git a/flow/gsl/configure.in.in b/flow/gsl/configure.in.in
new file mode 100644
index 0000000..3b147b9
--- /dev/null
+++ b/flow/gsl/configure.in.in
@@ -0,0 +1,224 @@
+dnl Portability defines that help interoperate with classic and modern autoconfs
+ifdef([AC_TR_SH],[
+define([GLIB_TR_SH],[AC_TR_SH([$1])])
+define([GLIB_TR_CPP],[AC_TR_CPP([$1])])
+], [
+define([GLIB_TR_SH],
+ [patsubst(translit([[$1]], [*+], [pp]), [[^a-zA-Z0-9_]], [_])])
+define([GLIB_TR_CPP],
+ [patsubst(translit([[$1]],
+ [*abcdefghijklmnopqrstuvwxyz],
+ [PABCDEFGHIJKLMNOPQRSTUVWXYZ]),
+ [[^A-Z0-9_]], [_])])
+])
+
+
+dnl GLIB_SIZEOF (INCLUDES, TYPE, ALIAS [, CROSS-SIZE])
+AC_DEFUN([GLIB_SIZEOF],
+[pushdef([glib_Sizeof], GLIB_TR_SH([glib_cv_sizeof_$3]))dnl
+AC_CACHE_CHECK([size of $2], glib_Sizeof,
+[AC_TRY_RUN([#include <stdio.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+$1
+main()
+{
+ FILE *f=fopen("conftestval", "w");
+ if (!f) exit(1);
+ fprintf(f, "%d\n", sizeof($2));
+ exit(0);
+}],
+ [glib_Sizeof=`cat conftestval` dnl''
+],
+ [glib_Sizeof=0],
+ ifelse([$4], [], [], [glib_Sizeof=$4]))])
+AC_DEFINE_UNQUOTED(GLIB_TR_CPP(glib_sizeof_$3), [$[]glib_Sizeof], [Size of $3])
+popdef([glib_Sizeof])dnl
+])
+
+AC_DEFUN([AC_GSL_REQUIREMENTS],
+[
+ dnl === Ogg/Vorbis check ===
+ AC_ARG_ENABLE(vorbis,
+ [ --disable-arts-vorbis disable arts Ogg Vorbis support],
+ [arts_want_vorbis="$enableval"],[arts_want_vorbis="yes"])
+
+ if test "$arts_want_vorbis" = "yes"; then
+ ov_headers=0
+ AC_CHECK_LIB(vorbisfile, ov_read_float,
+ [KDE_CHECK_HEADER(ogg/ogg.h, ov_headers=`expr $ov_headers + 1`)]
+ [KDE_CHECK_HEADER(vorbis/vorbisfile.h, ov_headers=`expr $ov_headers + 1`)]
+ [KDE_CHECK_HEADER(vorbis/vorbisenc.h, ov_headers=`expr $ov_headers + 1`)]
+ ,
+ ov_headers=0, -lvorbisenc -lvorbis -logg)
+ if test $ov_headers = 3 ; then
+ GSL_LIBS="$GSL_LIBS -lvorbisfile -lvorbisenc -lvorbis -logg"
+ GSL_HAVE_OGGVORBIS=1
+ else
+ GSL_HAVE_OGGVORBIS=0
+ fi
+ dnl AC_DEFINE(GSL_HAVE_OGGVORBIS,1,[Define if you want Ogg Vorbis support unconditionally])
+ else
+ GSL_HAVE_OGGVORBIS=0
+ dnl AC_MSG_WARN([failed to detect Ogg/Vorbis library (>=1.0rc3) or headers])
+ fi
+ AC_SUBST(GSL_HAVE_OGGVORBIS)
+
+ dnl check for ov_read_float parameter count (differs in 1.0 vs. rc3)
+ if test $GSL_HAVE_OGGVORBIS = 1; then
+ AC_MSG_CHECKING([for ov_read_float() from rc3])
+ AC_TRY_COMPILE([
+ #include <vorbis/vorbisfile.h>
+ ], [
+ ov_read_float(0,0,0);
+ ], [
+ GSL_HAVE_OGGVORBIS_RC3=1
+ AC_MSG_RESULT(yes)
+ ], [
+ GSL_HAVE_OGGVORBIS_RC3=0
+ AC_MSG_RESULT(no)
+ ])
+ AC_SUBST(GSL_HAVE_OGGVORBIS_RC3)
+ fi
+
+ dnl === libmad MPEG decoder check ===
+ AC_ARG_ENABLE(libmad,
+ [ --disable-libmad disable arts MAD mp3 decoder support],
+ [arts_want_libmad="$enableval"],[arts_want_libmad="yes"])
+
+ if test "$arts_want_libmad" = "yes"; then
+ mad_detect=0
+ AC_CHECK_LIB(mad, mad_synth_frame,
+ [AC_CHECK_HEADER(mad.h, mad_detect=1)]
+ ,
+ mad_detect=0, -lmad)
+ if test $mad_detect = 1 ; then
+ GSL_LIBS="$GSL_LIBS -lmad"
+ GSL_HAVE_LIBMAD=1
+ else
+ dnl AC_MSG_WARN([failed to detect libmad (MPEG I-III audio decoder) or headers])
+ GSL_HAVE_LIBMAD=0
+ fi
+ else
+ dnl AC_MSG_WARN([failed to detect libmad (MPEG I-III audio decoder) or headers])
+ GSL_HAVE_LIBMAD=0
+ fi
+ AC_SUBST(GSL_HAVE_LIBMAD)
+
+ dnl === Check library requirements ===
+ AC_MSG_CHECKING([the required GSL-Loader library set])
+ if true; then dnl echo $GSL_LIBS | grep ".*-lvorbis.*" >/dev/null ; then
+ AC_MSG_RESULT([complete])
+ else
+ AC_MSG_RESULT([])
+ AC_MSG_ERROR([Ogg/Vorbis is missing, but required])
+ fi
+ AC_SUBST(GSL_LIBS)
+
+ dnl === sizeof types ===
+ GLIB_SIZEOF([#include <pthread.h>], pthread_mutex_t, pth_mutex_t)
+ GSL_SIZEOF_PTH_MUTEX_T="$glib_cv_sizeof_pth_mutex_t"
+ AC_SUBST(GSL_SIZEOF_PTH_MUTEX_T)
+ GLIB_SIZEOF([#include <pthread.h>], pthread_cond_t, pth_cond_t)
+ GSL_SIZEOF_PTH_COND_T="$glib_cv_sizeof_pth_cond_t"
+ AC_SUBST(GSL_SIZEOF_PTH_COND_T)
+ GLIB_SIZEOF([#include <inttypes.h>], intmax_t, std_intmax_t)
+ GSL_SIZEOF_STD_INTMAX_T="$glib_cv_sizeof_std_intmax_t"
+ AC_SUBST(GSL_SIZEOF_STD_INTMAX_T)
+
+ dnl === pthread_mutexattr_settype ===
+ AC_MSG_CHECKING([for pthread_mutexattr_settype()])
+ AC_TRY_COMPILE([
+ #define _XOPEN_SOURCE 500
+ #include <pthread.h>
+ ], [
+ int (*attr_settype) (pthread_mutexattr_t *__attr, int __kind) = pthread_mutexattr_settype;
+ int val = PTHREAD_MUTEX_RECURSIVE;
+ attr_settype = 0; val = 0;
+ ],
+ GSL_HAVE_MUTEXATTR_SETTYPE=1
+ AC_MSG_RESULT(yes)
+ ,
+ GSL_HAVE_MUTEXATTR_SETTYPE=0
+ AC_MSG_RESULT(no)
+ )
+ AC_SUBST(GSL_HAVE_MUTEXATTR_SETTYPE)
+])
+
+AC_DEFUN([AC_GSL_GLIB_REQUIREMENTS],
+[
+ AC_CHECK_FUNCS(getcwd)
+ AC_FUNC_ALLOCA
+
+dnl **********************
+dnl *** va_copy checks ***
+dnl **********************
+dnl we currently check for all three va_copy possibilities, so we get
+dnl all results in config.log for bug reports.
+AC_CACHE_CHECK([for an implementation of va_copy()],glib_cv_va_copy,[
+ AC_TRY_RUN([
+ #include <stdarg.h>
+ void f (int i, ...) {
+ va_list args1, args2;
+ va_start (args1, i);
+ va_copy (args2, args1);
+ if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42)
+ exit (1);
+ va_end (args1); va_end (args2);
+ }
+ int main() {
+ f (0, 42);
+ return 0;
+ }],
+ [glib_cv_va_copy=yes],
+ [glib_cv_va_copy=no],
+ [])
+])
+AC_CACHE_CHECK([for an implementation of __va_copy()],glib_cv___va_copy,[
+ AC_TRY_RUN([
+ #include <stdarg.h>
+ void f (int i, ...) {
+ va_list args1, args2;
+ va_start (args1, i);
+ __va_copy (args2, args1);
+ if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42)
+ exit (1);
+ va_end (args1); va_end (args2);
+ }
+ int main() {
+ f (0, 42);
+ return 0;
+ }],
+ [glib_cv___va_copy=yes],
+ [glib_cv___va_copy=no],
+ [])
+])
+
+if test "x$glib_cv_va_copy" = "xyes"; then
+ g_va_copy_func=va_copy
+else if test "x$glib_cv___va_copy" = "xyes"; then
+ g_va_copy_func=__va_copy
+fi
+fi
+])
+
+AC_GSL_REQUIREMENTS
+AC_GSL_GLIB_REQUIREMENTS
+
+dnl get rid of lots and lots of useless warnings
+
+GSL_CFLAGS="$CFLAGS"
+for warn in -W -Wshadow -pedantic # -Wwrite-strings
+do
+ GSL_CFLAGS="`echo $GSL_CFLAGS | sed 's/ '$warn' / /g'`"
+done
+AC_SUBST(GSL_CFLAGS)
+
+dnl enable aRts version of glib / thread support
+
+GSL_USE_GSL_GLIB=1
+GSL_USE_ARTS_THREADS=1
+AC_SUBST(GSL_USE_GSL_GLIB)
+AC_SUBST(GSL_USE_ARTS_THREADS)
diff --git a/flow/gsl/dummy.cc b/flow/gsl/dummy.cc
new file mode 100644
index 0000000..9fde279
--- /dev/null
+++ b/flow/gsl/dummy.cc
@@ -0,0 +1,3 @@
+/* this is a C++ dummy source to force c++ linkage of the examples */
+
+namespace Arts { int arts_flow_gsl_dummy = 0; }
diff --git a/flow/gsl/gbsearcharray.h b/flow/gsl/gbsearcharray.h
new file mode 100644
index 0000000..df06231
--- /dev/null
+++ b/flow/gsl/gbsearcharray.h
@@ -0,0 +1,292 @@
+/* GBSearchArray - Binary Searchable Array implementation
+ * Copyright (C) 2000-2002 Tim Janik
+ *
+ * This software is provided "as is"; redistribution and modification
+ * is permitted, provided that the following disclaimer is retained.
+ *
+ * This software 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.
+ * In no event shall the authors 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 __G_BSEARCH_ARRAY_H__
+#define __G_BSEARCH_ARRAY_H__
+
+#include <gsl/gsldefs.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* this implementation is intended to be usable in third-party code
+ * simply by pasting the contents of this file. as such, the
+ * implementation needs to be self-contained within this file.
+ */
+
+/* convenience macro to avoid signed overflow for value comparisons */
+#define G_BSEARCH_ARRAY_CMP(v1,v2) ((v1) > (v2) ? +1 : (v1) == (v2) ? 0 : -1)
+
+
+/* --- typedefs --- */
+typedef gint (*GBSearchCompareFunc) (gconstpointer bsearch_node1, /* key */
+ gconstpointer bsearch_node2);
+typedef enum
+{
+ G_BSEARCH_ARRAY_ALIGN_POWER2 = 1 << 0, /* memory is power2 aligned */
+ G_BSEARCH_ARRAY_FORCE_SHRINK = 1 << 1 /* removal shrinks with realloc() */
+} GBSearchArrayFlags;
+
+
+/* --- structures --- */
+typedef struct
+{
+ guint sizeof_node;
+ GBSearchCompareFunc cmp_nodes;
+ guint flags;
+} GBSearchConfig;
+typedef union
+{
+ guint n_nodes;
+ /*< private >*/
+ gpointer alignment_dummy1;
+ glong alignment_dummy2;
+ gdouble alignment_dummy3;
+} GBSearchArray;
+
+
+/* --- public API --- */
+static inline GBSearchArray* g_bsearch_array_create (const GBSearchConfig *bconfig);
+static inline gpointer g_bsearch_array_get_nth (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ guint nth);
+static inline guint g_bsearch_array_get_index (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ gconstpointer node_in_array);
+static inline GBSearchArray* g_bsearch_array_remove (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ guint index);
+/* preserve uninitialized space at index for node insertion
+ */
+static inline GBSearchArray* g_bsearch_array_grow (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ guint index);
+/* insert key_node into array, or if it exists, replace
+ * the existing node's contents with key_node
+ */
+static inline GBSearchArray* g_bsearch_array_insert (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ gconstpointer key_node);
+static inline void g_bsearch_array_free (GBSearchArray *barray,
+ const GBSearchConfig *bconfig);
+#define g_bsearch_array_get_n_nodes(barray) (((GBSearchArray*) (barray))->n_nodes)
+
+/* g_bsearch_array_lookup():
+ * return NULL or exact match node
+ */
+#define g_bsearch_array_lookup(barray, bconfig, key_node) \
+ g_bsearch_array_lookup_fuzzy ((barray), (bconfig), (key_node), 0)
+
+/* g_bsearch_array_lookup_sibling():
+ * return NULL for barray->n_nodes==0, otherwise return the
+ * exact match node, or, if there's no such node, return the
+ * node last visited, which is pretty close to an exact match
+ * (will be one off into either direction).
+ */
+#define g_bsearch_array_lookup_sibling(barray, bconfig, key_node) \
+ g_bsearch_array_lookup_fuzzy ((barray), (bconfig), (key_node), 1)
+
+/* g_bsearch_array_lookup_insertion():
+ * return NULL for barray->n_nodes==0 or exact match, otherwise
+ * return the node where key_node should be inserted (may be one
+ * after end, i.e. g_bsearch_array_get_index(result) <= barray->n_nodes).
+ */
+#define g_bsearch_array_lookup_insertion(barray, bconfig, key_node) \
+ g_bsearch_array_lookup_fuzzy ((barray), (bconfig), (key_node), 2)
+
+
+
+/* --- implementation --- */
+/* helper macro to cut down realloc()s */
+#ifdef DISABLE_MEM_POOLS
+#define G_BSEARCH_UPPER_POWER2(n) (n)
+#else /* !DISABLE_MEM_POOLS */
+#define G_BSEARCH_UPPER_POWER2(n) ((n) ? 1 << g_bit_storage ((n) - 1) : 0)
+#endif /* !DISABLE_MEM_POOLS */
+#define G_BSEARCH_ARRAY_NODES(barray) (((guint8*) (barray)) + sizeof (GBSearchArray))
+static inline GBSearchArray*
+g_bsearch_array_create (const GBSearchConfig *bconfig)
+{
+ GBSearchArray *barray;
+ guint size;
+
+ g_return_val_if_fail (bconfig != NULL, NULL);
+
+ size = sizeof (GBSearchArray) + bconfig->sizeof_node;
+ if (bconfig->flags & G_BSEARCH_ARRAY_ALIGN_POWER2)
+ size = G_BSEARCH_UPPER_POWER2 (size);
+ barray = g_realloc (NULL, size);
+ memset (barray, 0, sizeof (GBSearchArray));
+
+ return barray;
+}
+static inline gpointer
+g_bsearch_array_lookup_fuzzy (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ gconstpointer key_node,
+ const guint sibling_or_after);
+static inline gpointer
+g_bsearch_array_lookup_fuzzy (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ gconstpointer key_node,
+ const guint sibling_or_after)
+{
+ GBSearchCompareFunc cmp_nodes = bconfig->cmp_nodes;
+ guint8 *check = NULL, *nodes = G_BSEARCH_ARRAY_NODES (barray);
+ guint n_nodes = barray->n_nodes, offs = 0;
+ guint sizeof_node = bconfig->sizeof_node;
+ gint cmp = 0;
+
+ while (offs < n_nodes)
+ {
+ guint i = (offs + n_nodes) >> 1;
+
+ check = nodes + i * sizeof_node;
+ cmp = cmp_nodes (key_node, check);
+ if (cmp == 0)
+ return sibling_or_after > 1 ? NULL : check;
+ else if (cmp < 0)
+ n_nodes = i;
+ else /* (cmp > 0) */
+ offs = i + 1;
+ }
+
+ /* check is last mismatch, cmp > 0 indicates greater key */
+ return !sibling_or_after ? NULL : (sibling_or_after > 1 && cmp > 0) ? check + sizeof_node : check;
+}
+static inline gpointer
+g_bsearch_array_get_nth (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ guint nth)
+{
+ return (nth < barray->n_nodes ?
+ G_BSEARCH_ARRAY_NODES (barray) + nth * bconfig->sizeof_node :
+ NULL);
+}
+static inline guint
+g_bsearch_array_get_index (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ gconstpointer node_in_array)
+{
+ guint distance = ((guint8*) node_in_array) - G_BSEARCH_ARRAY_NODES (barray);
+
+ g_return_val_if_fail (node_in_array != NULL, barray->n_nodes);
+
+ distance /= bconfig->sizeof_node;
+
+ return MIN (distance, barray->n_nodes + 1); /* may return one after end */
+}
+static inline GBSearchArray*
+g_bsearch_array_grow (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ guint index)
+{
+ guint old_size = barray->n_nodes * bconfig->sizeof_node;
+ guint new_size = old_size + bconfig->sizeof_node;
+ guint8 *node;
+
+ g_return_val_if_fail (index <= barray->n_nodes, NULL);
+
+ if (bconfig->flags & G_BSEARCH_ARRAY_ALIGN_POWER2)
+ {
+ new_size = G_BSEARCH_UPPER_POWER2 (sizeof (GBSearchArray) + new_size);
+ old_size = G_BSEARCH_UPPER_POWER2 (sizeof (GBSearchArray) + old_size);
+ if (old_size != new_size)
+ barray = g_realloc (barray, new_size);
+ }
+ else
+ barray = g_realloc (barray, sizeof (GBSearchArray) + new_size);
+ node = G_BSEARCH_ARRAY_NODES (barray) + index * bconfig->sizeof_node;
+ g_memmove (node + bconfig->sizeof_node, node, (barray->n_nodes - index) * bconfig->sizeof_node);
+ barray->n_nodes += 1;
+ return barray;
+}
+static inline GBSearchArray*
+g_bsearch_array_insert (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ gconstpointer key_node)
+{
+ guint8 *node;
+
+ if (!barray->n_nodes)
+ {
+ barray = g_bsearch_array_grow (barray, bconfig, 0);
+ node = G_BSEARCH_ARRAY_NODES (barray);
+ }
+ else
+ {
+ node = g_bsearch_array_lookup_insertion (barray, bconfig, key_node);
+ if (node)
+ {
+ guint index = g_bsearch_array_get_index (barray, bconfig, node);
+
+ /* grow and insert */
+ barray = g_bsearch_array_grow (barray, bconfig, index);
+ node = G_BSEARCH_ARRAY_NODES (barray) + index * bconfig->sizeof_node;
+ }
+ else /* replace (relookup is ok, replace is comparatively cheap anyways) */
+ node = g_bsearch_array_lookup (barray, bconfig, key_node);
+ }
+ memcpy (node, key_node, bconfig->sizeof_node);
+ return barray;
+}
+static inline GBSearchArray*
+g_bsearch_array_remove (GBSearchArray *barray,
+ const GBSearchConfig *bconfig,
+ guint index)
+{
+ guint8 *node;
+
+ g_return_val_if_fail (index < barray->n_nodes, NULL);
+
+ barray->n_nodes -= 1;
+ node = G_BSEARCH_ARRAY_NODES (barray) + index * bconfig->sizeof_node;
+ g_memmove (node, node + bconfig->sizeof_node, (barray->n_nodes - index) * bconfig->sizeof_node);
+ if (bconfig->flags & G_BSEARCH_ARRAY_FORCE_SHRINK)
+ {
+ guint new_size = barray->n_nodes * bconfig->sizeof_node;
+ guint old_size = new_size + bconfig->sizeof_node;
+
+ if (bconfig->flags & G_BSEARCH_ARRAY_ALIGN_POWER2)
+ {
+ new_size = G_BSEARCH_UPPER_POWER2 (sizeof (GBSearchArray) + new_size);
+ old_size = G_BSEARCH_UPPER_POWER2 (sizeof (GBSearchArray) + old_size);
+ if (old_size != new_size)
+ barray = g_realloc (barray, new_size);
+ }
+ else
+ barray = g_realloc (barray, sizeof (GBSearchArray) + new_size);
+ }
+ return barray;
+}
+static inline void
+g_bsearch_array_free (GBSearchArray *barray,
+ const GBSearchConfig *bconfig)
+{
+ g_return_if_fail (barray != NULL);
+
+ g_free (barray);
+}
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* !__G_BSEARCH_ARRAY_H__ */
diff --git a/flow/gsl/gsl-fftconf.sh b/flow/gsl/gsl-fftconf.sh
new file mode 100755
index 0000000..71f33c3
--- /dev/null
+++ b/flow/gsl/gsl-fftconf.sh
@@ -0,0 +1,468 @@
+#!/bin/sh
+# GSL-GENFFT - Power2 FFT C Code Generator
+# Copyright (C) 2001 Tim Janik
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+
+# include files
+echo "#include $2"
+echo "#include <math.h>"
+
+MKFFT="$1"
+IEEE_TYPE="double"
+OPTIONS="--double"
+
+# provide macros and inline stubs
+$MKFFT $OPTIONS 0
+
+#
+# generate small fft sizes, seperating stage 2
+#
+for dir in --analysis --synthesis ; do
+ DOPT="$OPTIONS --skip-macros $dir"
+ echo "Generating FFT functions: $dir" >&2
+ $MKFFT $DOPT 2 F # standalone fft2
+ $MKFFT $DOPT 4 S F # reusable fft4
+ $MKFFT $DOPT 4 F X # standalone fft4
+ $MKFFT $DOPT 8 s F F # reusable fft8 w/o input fft2
+ $MKFFT $DOPT 8 F s X # standalone fft8
+ $MKFFT $DOPT 16 s F F F # reusable fft16
+ $MKFFT $DOPT 16 F s s X # standalone fft16
+ $MKFFT $DOPT 32 s F F F F
+ $MKFFT $DOPT 32 F s s s X
+ $MKFFT $DOPT 64 s R R R R F # reusable fft64
+ $MKFFT $DOPT 64 F s s s s X # standalone fft64
+ $MKFFT $DOPT 128 s R R R R R F # reusable fft128
+ $MKFFT $DOPT 128 L s s s s s X #
+ $MKFFT $DOPT 256 s s s s s s X T # reuse fft128
+ $MKFFT $DOPT 256 L s s s s s s X #
+ $MKFFT $DOPT 512 s s s s s s X T T # reuse fft128
+ $MKFFT $DOPT 512 L s s s s s s s X # fft512
+ $MKFFT $DOPT 1024 s s s s s s s s X L #
+ $MKFFT $DOPT 1024 L s s s s s s s s X #
+ $MKFFT $DOPT 2048 s s s s s s s s X L L # reusable fft2048
+ $MKFFT $DOPT 2048 L s s s s s s s s s X #
+ $MKFFT $DOPT 4096 s s s s s s s s s s X L # reuses fft2048
+ $MKFFT $DOPT 4096 L s s s s s s s s s s X # fft4096
+ $MKFFT $DOPT 8192 s s s s s s s s s s s X L # reusable impl. for 8192, reuses 2048
+ $MKFFT $DOPT 8192 L s s s s s s s s s s s X # real impl. for 8192
+done
+
+#
+# generic variable length implementation
+#
+echo "Generating generic FFT function for sizes >8192" >&2
+cat <<__EOF
+
+
+/* public FFT frontends and generic handling of huge fft sizes */
+
+
+static void
+gsl_power2_fftc_big (const unsigned int n_values,
+ const $IEEE_TYPE *rivalues_in,
+ $IEEE_TYPE *rivalues,
+ const int esign)
+{
+ const unsigned int n_values2 = n_values << 1;
+ double theta = esign < 0 ? -3.1415926535897932384626433832795029 : 3.1415926535897932384626433832795029;
+ unsigned int i, block_size = 8192 << 1;
+ double last_sin;
+
+ if (esign > 0)
+ {
+ if (rivalues_in)
+ bitreverse_fft2analysis (n_values, rivalues_in, rivalues);
+ for (i = 0; i < n_values; i += 8192)
+ gsl_power2_fft8192analysis_skip2 (rivalues + (i << 1), rivalues + (i << 1));
+ }
+ else
+ {
+ if (rivalues_in)
+ bitreverse_fft2synthesis (n_values, rivalues_in, rivalues);
+ for (i = 0; i < n_values; i += 8192)
+ gsl_power2_fft8192synthesis_skip2 (rivalues + (i << 1), rivalues + (i << 1));
+ }
+ theta *= (double) 1.0 / 8192.;
+ last_sin = sin (theta);
+
+ /* we're not combining the first and second halves coefficients
+ * in the below loop, since for fft sizes beyond 8192, it'd actually
+ * harm performance due to paging
+ */
+ do
+ {
+ double Dre, Dim, Wre, Wim;
+ unsigned int k, i, half_block = block_size >> 1;
+ unsigned int block_size2 = block_size << 1;
+
+ theta *= 0.5;
+ Dim = last_sin;
+ last_sin = sin (theta);
+ Dre = last_sin * last_sin * -2.;
+
+ /* loop over first coefficient in each block ==> w == {1,0} */
+ for (i = 0; i < n_values2; i += block_size2)
+ {
+ unsigned int v1 = i, v2 = i + block_size;
+
+ BUTTERFLY_10 (rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ __1, __0);
+ }
+ Wre = Dre + 1.0; /* update Wk */
+ Wim = Dim; /* update Wk */
+ /* loop for every Wk in the first half of each subblock */
+ for (k = 2; k < half_block; k += 2)
+ {
+ /* loop over kth coefficient in each block */
+ for (i = k; i < n_values2; i += block_size2)
+ {
+ unsigned int v1 = i, v2 = i + block_size;
+
+ BUTTERFLY_XY (rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, Dre, Dim); /* update Wk */
+ }
+ /* handle middle coefficient ==> w == {0,+-1} */
+ if (k < block_size)
+ {
+ /* loop over kth coefficient in each block */
+ if (esign > 0)
+ for (i = k; i < n_values2; i += block_size2)
+ {
+ unsigned int v1 = i, v2 = i + block_size;
+
+ BUTTERFLY_01 (rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ __0, __1);
+ }
+ else
+ for (i = k; i < n_values2; i += block_size2)
+ {
+ unsigned int v1 = i, v2 = i + block_size;
+
+ BUTTERFLY_0m (rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ __0, __1);
+ }
+ /* update Wk */
+ if (esign > 0)
+ {
+ Wre = -Dim;
+ Wim = Dre + 1.0;
+ }
+ else
+ {
+ Wre = Dim;
+ Wim = -Dre - 1.0;
+ }
+ k += 2;
+ }
+ /* loop for every Wk in the second half of each subblock */
+ for (; k < block_size; k += 2)
+ {
+ /* loop over kth coefficient in each block */
+ for (i = k; i < n_values2; i += block_size2)
+ {
+ unsigned int v1 = i, v2 = i + block_size;
+
+ BUTTERFLY_XY (rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, Dre, Dim); /* update Wk */
+ }
+ block_size = block_size2;
+ }
+ while (block_size <= n_values);
+}
+__EOF
+
+
+#
+# public complex fft frontends
+#
+echo "Generating public complex FFT frontends" >&2
+cat <<__EOF
+void
+gsl_power2_fftac (const unsigned int n_values,
+ const $IEEE_TYPE *rivalues_in,
+ $IEEE_TYPE *rivalues_out)
+{
+ g_return_if_fail ((n_values & (n_values - 1)) == 0 && n_values >= 1);
+
+ switch (n_values)
+ {
+ case 1: rivalues_out[0] = rivalues_in[0], rivalues_out[1] = rivalues_in[1]; break;
+ case 2: gsl_power2_fft2analysis (rivalues_in, rivalues_out); break;
+ case 4: gsl_power2_fft4analysis (rivalues_in, rivalues_out); break;
+ case 8: gsl_power2_fft8analysis (rivalues_in, rivalues_out); break;
+ case 16: gsl_power2_fft16analysis (rivalues_in, rivalues_out); break;
+ case 32: gsl_power2_fft32analysis (rivalues_in, rivalues_out); break;
+ case 64: gsl_power2_fft64analysis (rivalues_in, rivalues_out); break;
+ case 128: gsl_power2_fft128analysis (rivalues_in, rivalues_out); break;
+ case 256: gsl_power2_fft256analysis (rivalues_in, rivalues_out); break;
+ case 512: gsl_power2_fft512analysis (rivalues_in, rivalues_out); break;
+ case 1024: gsl_power2_fft1024analysis (rivalues_in, rivalues_out); break;
+ case 2048: gsl_power2_fft2048analysis (rivalues_in, rivalues_out); break;
+ case 4096: gsl_power2_fft4096analysis (rivalues_in, rivalues_out); break;
+ case 8192: gsl_power2_fft8192analysis (rivalues_in, rivalues_out); break;
+ default: gsl_power2_fftc_big (n_values, rivalues_in, rivalues_out, +1);
+ }
+}
+void
+gsl_power2_fftsc (const unsigned int n_values,
+ const $IEEE_TYPE *rivalues_in,
+ $IEEE_TYPE *rivalues_out)
+{
+ g_return_if_fail ((n_values & (n_values - 1)) == 0 && n_values >= 1);
+
+ switch (n_values)
+ {
+ case 1: rivalues_out[0] = rivalues_in[0], rivalues_out[1] = rivalues_in[1]; break;
+ case 2: gsl_power2_fft2synthesis (rivalues_in, rivalues_out); break;
+ case 4: gsl_power2_fft4synthesis (rivalues_in, rivalues_out); break;
+ case 8: gsl_power2_fft8synthesis (rivalues_in, rivalues_out); break;
+ case 16: gsl_power2_fft16synthesis (rivalues_in, rivalues_out); break;
+ case 32: gsl_power2_fft32synthesis (rivalues_in, rivalues_out); break;
+ case 64: gsl_power2_fft64synthesis (rivalues_in, rivalues_out); break;
+ case 128: gsl_power2_fft128synthesis (rivalues_in, rivalues_out); break;
+ case 256: gsl_power2_fft256synthesis (rivalues_in, rivalues_out); break;
+ case 512: gsl_power2_fft512synthesis (rivalues_in, rivalues_out); break;
+ case 1024: gsl_power2_fft1024synthesis (rivalues_in, rivalues_out); break;
+ case 2048: gsl_power2_fft2048synthesis (rivalues_in, rivalues_out); break;
+ case 4096: gsl_power2_fft4096synthesis (rivalues_in, rivalues_out); break;
+ case 8192: gsl_power2_fft8192synthesis (rivalues_in, rivalues_out); break;
+ default: gsl_power2_fftc_big (n_values, rivalues_in, rivalues_out, -1);
+ }
+ /* { unsigned int i; for (i = 0; i < n_values << 1; i++) rivalues_out[i] *= (double) n_values; } */
+}
+__EOF
+
+
+#
+# public real fft frontends
+#
+echo "Generating public real FFT frontends" >&2
+cat <<__EOF
+void
+gsl_power2_fftar (const unsigned int n_values,
+ const $IEEE_TYPE *r_values_in,
+ $IEEE_TYPE *rivalues_out)
+{
+ unsigned int n_cvalues = n_values >> 1;
+ double Dre, Dim, Wre, Wim, theta;
+ unsigned int i;
+
+ g_return_if_fail ((n_values & (n_values - 1)) == 0 && n_values >= 2);
+
+ gsl_power2_fftac (n_cvalues, r_values_in, rivalues_out);
+ theta = 3.1415926535897932384626433832795029;
+ theta /= (double) n_cvalues;
+
+ Dre = sin (0.5 * theta);
+ Dim = sin (theta);
+ Dre = Dre * Dre;
+ Wre = 0.5 - Dre;
+ Dre *= -2.;
+ Wim = Dim * 0.5;
+ for (i = 2; i < n_values >> 1; i += 2)
+ {
+ double F1re, F1im, F2re, F2im, H1re, H1im, H2re, H2im;
+ unsigned int r = n_values - i;
+ double FEre = rivalues_out[i] + rivalues_out[r];
+ double FEim = rivalues_out[i + 1] - rivalues_out[r + 1];
+ double FOre = rivalues_out[r] - rivalues_out[i];
+ double FOim = rivalues_out[r + 1] + rivalues_out[i + 1];
+
+ FEre *= 0.5;
+ FEim *= 0.5;
+ F2re = FOre * Wim;
+ F2im = FOim * Wim;
+ F1re = FOre * Wre;
+ F1im = FOim * Wre;
+
+ H1im = F2im + F1re;
+ H1re = F1im - F2re;
+ H2re = F2re - F1im;
+ H2im = H1im - FEim;
+ H1re += FEre;
+ H2re += FEre;
+ H1im += FEim;
+ rivalues_out[i] = H1re;
+ rivalues_out[i + 1] = H1im;
+ rivalues_out[r] = H2re;
+ rivalues_out[r + 1] = H2im;
+ WMULTIPLY (Wre, Wim, Dre, Dim);
+ }
+ Dre = rivalues_out[0];
+ rivalues_out[0] = Dre + rivalues_out[1];
+ rivalues_out[1] = Dre - rivalues_out[1];
+}
+void
+gsl_power2_fftsr (const unsigned int n_values,
+ const double *rivalues_in,
+ double *r_values_out)
+{
+ unsigned int n_cvalues = n_values >> 1;
+ double Dre, Dim, Wre, Wim, theta, scale;
+ unsigned int i, ri;
+
+ g_return_if_fail ((n_values & (n_values - 1)) == 0 && n_values >= 2);
+
+ theta = -3.1415926535897932384626433832795029;
+ theta /= (double) n_cvalues;
+
+ Dre = sin (0.5 * theta);
+ Dim = sin (theta);
+ Dre = Dre * Dre;
+ Wre = 0.5 - Dre;
+ Dre *= -2.;
+ Wim = Dim * 0.5;
+ for (i = 2, ri = 0; i < n_values >> 1; i += 2)
+ {
+ double F1re, F1im, F2re, F2im, H1re, H1im, H2re, H2im;
+ unsigned int g = n_values - i, j = n_values >> 2, rg = n_values - (ri << 1) - 2;
+ double FEre = rivalues_in[i] + rivalues_in[g];
+ double FEim = rivalues_in[i + 1] - rivalues_in[g + 1];
+ double FOre = rivalues_in[g] - rivalues_in[i];
+ double FOim = rivalues_in[g + 1] + rivalues_in[i + 1];
+
+ while (ri >= j)
+ {
+ ri -= j;
+ j >>= 1;
+ }
+ ri |= j;
+
+ FOre = -FOre;
+ FOim = -FOim;
+ FEre *= 0.5;
+ FEim *= 0.5;
+ F2re = FOre * Wim;
+ F2im = FOim * Wim;
+ F1re = FOre * Wre;
+ F1im = FOim * Wre;
+
+ H1im = F2im + F1re;
+ H1re = F1im - F2re;
+ H2re = F2re - F1im;
+ H2im = H1im - FEim;
+ H1re += FEre;
+ H2re += FEre;
+ H1im += FEim;
+
+ j = ri << 1;
+ r_values_out[j] = H1re;
+ r_values_out[j + 1] = H1im;
+ r_values_out[rg] = H2re;
+ r_values_out[rg + 1] = H2im;
+ WMULTIPLY (Wre, Wim, Dre, Dim);
+ }
+ Dre = rivalues_in[0];
+ r_values_out[0] = Dre + rivalues_in[1];
+ r_values_out[1] = Dre - rivalues_in[1];
+ r_values_out[0] *= 0.5;
+ r_values_out[1] *= 0.5;
+ if (n_values < 4)
+ return;
+ r_values_out[2] = rivalues_in[i];
+ r_values_out[2 + 1] = rivalues_in[i + 1];
+ scale = n_cvalues;
+ scale = 1.0 / scale;
+ for (i = 0; i < n_values; i += 4)
+ BUTTERFLY_10scale (r_values_out[i], r_values_out[i + 1],
+ r_values_out[i + 2], r_values_out[i + 3],
+ r_values_out[i], r_values_out[i + 1],
+ r_values_out[i + 2], r_values_out[i + 3],
+ scale);
+ switch (n_cvalues)
+ {
+ case 2: break;
+ case 4: gsl_power2_fft4synthesis_skip2 (NULL, r_values_out); break;
+ case 8: gsl_power2_fft8synthesis_skip2 (NULL, r_values_out); break;
+ case 16: gsl_power2_fft16synthesis_skip2 (NULL, r_values_out); break;
+ case 32: gsl_power2_fft32synthesis_skip2 (NULL, r_values_out); break;
+ case 64: gsl_power2_fft64synthesis_skip2 (NULL, r_values_out); break;
+ case 128: gsl_power2_fft128synthesis_skip2 (NULL, r_values_out); break;
+ case 256: gsl_power2_fft256synthesis_skip2 (NULL, r_values_out); break;
+ case 512: gsl_power2_fft512synthesis_skip2 (NULL, r_values_out); break;
+ case 1024: gsl_power2_fft1024synthesis_skip2 (NULL, r_values_out); break;
+ case 2048: gsl_power2_fft2048synthesis_skip2 (NULL, r_values_out); break;
+ case 4096: gsl_power2_fft4096synthesis_skip2 (NULL, r_values_out); break;
+ case 8192: gsl_power2_fft8192synthesis_skip2 (NULL, r_values_out); break;
+ default: gsl_power2_fftc_big (n_cvalues, NULL, r_values_out, -1);
+ }
+}
+void
+gsl_power2_fftar_simple (const unsigned int n_values,
+ const float *real_values,
+ float *complex_values)
+{
+ double *rv, *cv;
+ guint i;
+
+ g_return_if_fail ((n_values & (n_values - 1)) == 0 && n_values >= 2);
+
+ rv = g_new (double, n_values * 2);
+ cv = rv + n_values;
+ i = n_values;
+ while (i--)
+ rv[i] = real_values[i];
+ gsl_power2_fftar (n_values, rv, cv);
+ i = n_values;
+ while (i--)
+ complex_values[i] = cv[i];
+ complex_values[n_values] = complex_values[1];
+ complex_values[1] = 0.0;
+ complex_values[n_values + 1] = 0.0;
+ g_free (rv);
+}
+void
+gsl_power2_fftsr_simple (const unsigned int n_values,
+ const float *complex_values,
+ float *real_values)
+{
+ double *cv, *rv;
+ guint i;
+
+ g_return_if_fail ((n_values & (n_values - 1)) == 0 && n_values >= 2);
+
+ cv = g_new (double, n_values * 2);
+ rv = cv + n_values;
+ i = n_values;
+ while (i--)
+ cv[i] = complex_values[i];
+ cv[1] = complex_values[n_values];
+ gsl_power2_fftsr (n_values, cv, rv);
+ i = n_values;
+ while (i--)
+ real_values[i] = rv[i];
+ g_free (cv);
+}
+__EOF
diff --git a/flow/gsl/gsl-fftgen.pl b/flow/gsl/gsl-fftgen.pl
new file mode 100755
index 0000000..551f8c3
--- /dev/null
+++ b/flow/gsl/gsl-fftgen.pl
@@ -0,0 +1,810 @@
+#!/usr/bin/perl -w
+# GSL-GENFFT - Power2 FFT C Code Generator
+# Copyright (C) 2001 Tim Janik
+#
+# 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.
+
+# TODO:
+# - optimize L case more
+# - join 2 or 3 stages
+
+my $indent = " ";
+my $PI = 3.1415926535897932384626433832795029;
+my $ieee_type = "float";
+my $tmp_ieee_type = "double"; # don't change, decreases precision _and_ performance
+
+# arguments
+my $max_fft_size = 0;
+my $gen_macros = 1;
+my $max_unroll = 256;
+my $min_split = 2048;
+my $min_compress = 512;
+my $fft2loop = 0;
+my $single_stage = 0;
+my $negate_sign = 0;
+my $Wtest = 0;
+
+#
+# parse options
+#
+while ($_ = $ARGV[0], defined $_ && /^-/) {
+ shift;
+ last if (/^--$/);
+ if (/^--fft2loop$/) { $fft2loop = 1 }
+ elsif (/^--analysis$/) { $negate_sign = 0 }
+ elsif (/^--synthesis$/) { $negate_sign = 1 }
+ elsif (/^--Wtest$/) { $Wtest = 1 }
+ elsif (/^--double$/) { $ieee_type = "double" }
+ elsif (/^--skip-macros$/) { $gen_macros = 0 }
+ elsif (/^--max-unroll$/) { $max_unroll = shift }
+ elsif (/^--split-at$/) { $min_split = shift }
+ elsif (/^--min-compress$/) { $min_compress = shift }
+ elsif (/^--single-stage$/) { $single_stage = shift }
+}
+# parse arguments
+my @arguments = 0;
+if (defined $ARGV[0]) {
+ $max_fft_size = $ARGV[0];
+ shift;
+}
+while (defined $ARGV[0]) {
+ push @arguments, $ARGV[0];
+ shift;
+}
+
+#
+# check arguments and provide help
+#
+if ($max_fft_size && ($max_fft_size < 2 || $max_fft_size & ($max_fft_size - 1))) {
+ print(STDERR "usage: gsl-genfft [options] <fftsize>\n".
+ "Produces C code to calculate an FFT of specified <size> which has\n".
+ "to be a power of 2.\n".
+ " --max-unroll <size> max fft size to unroll loops and bodies\n".
+ " --min-compress <size> min fft size to unroll only loop bodies\n".
+ " --split-at <size> max fft size for which recursive ffts are joined\n".
+ " --fft2loop force bitreversing fft2 part into a loop\n".
+ "");
+ # " |\n"
+ exit 0;
+}
+
+
+#
+# utility functions
+#
+sub bitreverse {
+ my $h = shift; # fft_size;
+ my $n = shift;
+ my $r = 0;
+
+ while ($n) {
+ $h >>= 1;
+ $r |= $h if ($n & 1);
+ $n >>= 1;
+ }
+ return $r;
+}
+sub Wexponent {
+ my $fft_size = shift;
+ my $n_points = shift;
+ my $nth = shift; # nth coefficient of this <n_points> stage
+
+ my $r = $nth * $fft_size / $n_points;
+
+ return $r;
+}
+sub Wreal {
+ my $n = shift; # fft_size
+ my $k = shift; # power
+
+ my $x = cos ($PI * (2. * $k / $n));
+
+ return $x == 0 ? 0 : $x; # -0.0 == 0
+}
+sub Wimag {
+ my $n = shift; # fft_size
+ my $k = shift;
+
+ my $x = sin ($PI * (2. * $k / $n));
+ $x = -$x if ($negate_sign);
+
+ return $x == 0 ? 0 : $x; # -0.0 == 0
+}
+
+
+#
+# unrolled fft generation
+#
+sub butterfly {
+ my $type = shift;
+ my $offset1 = shift;
+ my $offset2 = shift;
+ my $Wre = shift;
+ my $Wim = shift;
+ my $var = shift;
+
+ # define BUTTERFLY_XY(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,Wre,Wim,T1re,T1im,T2re,T2im)
+ printf($indent."BUTTERFLY_%s (%s[%s], %s[%s + 1],\n".
+ $indent." %s[%s], %s[%s + 1],\n".
+ $indent." %s[%s], %s[%s + 1],\n".
+ $indent." %s[%s], %s[%s + 1],\n".
+ $indent." %s, %s);\n",
+ $type,
+ $var, $offset1, $var, $offset1,
+ $var, $offset2, $var, $offset2,
+ $var, $offset1, $var, $offset1,
+ $var, $offset2, $var, $offset2,
+ $Wre, $Wim);
+}
+sub butterfly_auto {
+ my $fft_size = shift;
+ my $index1 = shift;
+ my $index2 = $index1 + shift;
+ my $wk = shift;
+ my $ofs = shift;
+ my $inplace = shift;
+ my $ib = $inplace ? "Y" : "X";
+ my $rfact = Wreal ($fft_size, $wk);
+ my $ifact = Wimag ($fft_size, $wk);
+ my $index1r = !$inplace ? bitreverse ($fft_size, $index1 >> 1) << 1 : $index1;
+ my $index2r = !$inplace ? bitreverse ($fft_size, $index2 >> 1) << 1 : $index2;
+ my $btype = "XY";
+ my $optimize_10 = $wk == 0;
+ my $optimize_0x = $wk == $fft_size / 4;
+
+ if (abs ($rfact - 1.0) < 0.0000000000000005 &&
+ abs ($ifact - 0.0) < 0.0000000000000005) {
+ $btype = "10";
+ # print STDERR "10: ". $wk ."\n";
+ $optimize_10 = 0 if ($optimize_10);
+ } elsif (abs ($rfact - 0.0) < 0.0000000000000005 &&
+ abs ($ifact - 1.0) < 0.0000000000000005) {
+ $btype = "01";
+ # print STDERR "01: ". $wk ."\n";
+ $optimize_0x = 0 if ($optimize_0x);
+ } elsif (abs ($rfact - 0.0) < 0.0000000000000005 &&
+ abs ($ifact + 1.0) < 0.0000000000000005) {
+ $btype = "0m";
+ # print STDERR "0m: ". $wk ."\n";
+ $optimize_0x = 0 if ($optimize_0x);
+ } elsif (abs ($rfact - $ifact) < 0.0000000000000005) {
+ $btype = "XX"; # grr, this actually slows down the athlon (keep "XY")
+ } elsif (abs ($rfact + $ifact) < 0.0000000000000005) {
+ $btype = "yY"; # grr, this actually slows down the athlon (keep "XY")
+ }
+
+ if ($optimize_10 || $optimize_0x) {
+ die("optimization error for fft$fft_size: 10=". $optimize_10 .", 0x=". $optimize_0x .
+ ", Wre=". $rfact ." Wim=". $ifact .", wk=". $wk);
+ }
+
+ # BUTTERFLY_XY (X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,Wre,Wim,T1re,T1im,T2re,T2im);
+ printf($indent."BUTTERFLY_%s (%s[%s%u], /* W%u */\n".
+ $indent." %s[%s%u + 1],\n".
+ $indent." %s[%s%u],\n".
+ $indent." %s[%s%u + 1],\n".
+ $indent." Y[%s%u],\n".
+ $indent." Y[%s%u + 1],\n".
+ $indent." Y[%s%u],\n".
+ $indent." Y[%s%u + 1],\n".
+ $indent." (%s) %+.15f, (%s) %+.15f);\n",
+ $btype,
+ $ib, $ofs, $index1r, $wk, $ib, $ofs, $index1r, $ib, $ofs, $index2r, $ib, $ofs, $index2r,
+ $ofs, $index1, $ofs, $index1, $ofs, $index2, $ofs, $index2,
+ $tmp_ieee_type, $rfact, $tmp_ieee_type, $ifact);
+}
+sub unroll_stage {
+ my $fft_size = shift;
+ my $n_points = shift;
+ my $n_rep = shift; # repetitions
+ my $unroll_outer = shift;
+
+ if ($unroll_outer && $n_points == 2) {
+ for (my $i = 0; $i < $n_points >> 1; $i++) {
+ for (my $j = 0; $j < $n_rep; $j++) {
+ my $offset1 = ($j * $n_points + $i) * 2;
+ my $offset2 = $offset1 + $n_points;
+ my $offset1r = bitreverse ($fft_size, $offset1 >> 1) << 1;
+ my $offset2r = bitreverse ($fft_size, $offset2 >> 1) << 1;
+ my $scale = !$negate_sign ? "__1, __0" : sprintf "1.0 / (%s) %u", $tmp_ieee_type, $fft_size;
+ printf($indent."BUTTERFLY_10%s (X[%s], X[%s + 1],\n".
+ $indent." X[%s], X[%s + 1],\n".
+ $indent." Y[%s], Y[%s + 1],\n".
+ $indent." Y[%s], Y[%s + 1],\n".
+ $indent." %s);\n",
+ $negate_sign ? "scale" : "",
+ $offset1r, $offset1r,
+ $offset2r, $offset2r,
+ $offset1, $offset1,
+ $offset2, $offset2,
+ $scale);
+ }
+ }
+ } elsif ($unroll_outer) {
+ for (my $i = 0; $i < $n_points >> 1; $i++) {
+ for (my $j = 0; $j < $n_rep; $j++) {
+ butterfly_auto ($fft_size,
+ ($j * $n_points + $i) * 2,
+ $n_points,
+ Wexponent ($fft_size, $n_points, $i),
+ "", $n_points != 2);
+ }
+ }
+ } else {
+ die "cannot skip outer loop unrolling for fft2" if $n_points == 2;
+
+ printf "%sfor (block = 0; block < %u; block += %u) {\n", $indent, $n_points * 2 * $n_rep, $n_points * 2;
+ $indent .= " ";
+ for (my $i = 0; $i < $n_points >> 1; $i++) {
+ butterfly_auto ($fft_size,
+ $i * 2,
+ $n_points,
+ Wexponent ($fft_size, $n_points, $i),
+ "block + ", $n_points != 2);
+ }
+ $indent =~ s/\ \ $//;
+ printf "%s}\n", $indent;
+ }
+}
+sub table_stage {
+ my $fft_size = shift;
+ my $n_points = shift;
+ my $n_rep = shift; # repetitions
+
+ die "cannot loop over coefficient table for fft2" if $n_points == 2;
+
+ printf "%s{\n", $indent;
+ $indent .= " ";
+ printf "%sstatic const %s Wconst%u[] = {\n", $indent, $tmp_ieee_type, $n_points;
+ for (my $i = 1; $i < $n_points >> 2; $i++) {
+ my $wk = Wexponent ($fft_size, $n_points, $i);
+ printf "%s %+.15f, %+.15f,\n", $indent, Wreal ($fft_size, $wk), Wimag ($fft_size, $wk);
+ }
+ printf "%s};\n", $indent;
+ printf "%sconst %s *W = Wconst%u - 2;\n", $indent, $tmp_ieee_type, $n_points;
+ printf "%s%s *Z = Y + %u;\n", $indent, $ieee_type, $n_points >> 1;
+
+ # first half loops
+ printf("%sfor (offset = 0; offset < %u; offset += %u) {\n",
+ $indent, $n_points * 2 * $n_rep, $n_points * 2);
+ $indent .= " ";
+ $ofs2 = sprintf "offset + %u", $n_points;
+ butterfly ("10", "offset", $ofs2, "__1", "__0", "Y");
+ butterfly ($negate_sign ? "0m" : "01", "offset", $ofs2, "__0", "__1", "Z");
+ $indent =~ s/\ \ $//;
+ printf "%s}\n", $indent;
+ printf "%sfor (butterfly = 2; butterfly < %u; butterfly += 2) {\n", $indent, $n_points >> 1;
+ printf "%s Wre = W[butterfly]; Wim = W[butterfly + 1];\n", $indent;
+ printf "%s for (block = 0; block < %u; block += %u) {\n", $indent, $n_points * 2 * $n_rep, $n_points * 2;
+ $indent .= " ";
+ printf "%soffset = butterfly + block;\n", $indent;
+ $ofs2 = sprintf "offset + %u", $n_points;
+ butterfly ("XY", "offset", $ofs2, "Wre", "Wim", "Y");
+ butterfly ($negate_sign ? "yX" : "Yx", "offset", $ofs2, "Wre", "Wim", "Z");
+ $indent =~ s/\ \ \ \ $//;
+ printf "%s }\n", $indent;
+ printf "%s}\n", $indent;
+
+ # second half loops
+ if (0) {
+ printf("%sfor (offset = %u; offset < %u + %u; offset += %u) {\n",
+ $indent, $n_points >> 1, $n_points >> 1, $n_points * 2 * $n_rep, $n_points * 2);
+ $indent .= " ";
+ $ofs2 = sprintf "offset + %u", $n_points;
+ butterfly ($negate_sign ? "0m" : "01", "offset", $ofs2, "__0", "__1", "Y");
+ $indent =~ s/\ \ $//;
+ printf "%s}\n", $indent;
+ printf "%sW -= %u;\n", $indent, $n_points >> 1;
+ printf "%sfor (butterfly = %u + 2; butterfly < %u; butterfly += 2) {\n", $indent, $n_points >> 1, $n_points;
+ printf "%s Wre = W[butterfly]; Wim = W[butterfly + 1];\n", $indent;
+ printf "%s for (block = 0; block < %u; block += %u) {\n", $indent, $n_points * 2 * $n_rep, $n_points * 2;
+ $indent .= " ";
+ printf "%soffset = butterfly + block;\n", $indent;
+ $ofs2 = sprintf "offset + %u", $n_points;
+ butterfly ($negate_sign ? "yX" : "Yx", "offset", $ofs2, "Wre", "Wim", "Y");
+ $indent =~ s/\ \ \ \ $//;
+ printf "%s }\n", $indent;
+ printf "%s}\n", $indent;
+ }
+
+ $indent =~ s/\ \ $//;
+ printf "%s}\n", $indent;
+}
+sub bitreverse_fft2 {
+ # mul_result = gsl_complex (c1.re * c2.re - c1.im * c2.im, c1.re * c2.im + c1.im * c2.re);
+ printf "
+static inline void
+bitreverse_fft2analysis (const unsigned int n,
+ const %-6s *X,
+ %-6s *Y)
+{
+ const unsigned int n2 = n >> 1, n1 = n + n2, max = n >> 2;
+ unsigned int i, r;
+
+ BUTTERFLY_10 (X[0], X[1],
+ X[n], X[n + 1],
+ Y[0], Y[1],
+ Y[2], Y[3],
+ __1, __0);
+ BUTTERFLY_10 (X[n2], X[n2 + 1],
+ X[n1], X[n1 + 1],
+ Y[4], Y[5],
+ Y[6], Y[7],
+ __1, __0);
+ for (i = 1, r = 0; i < max; i++)
+ {
+ unsigned int k, j = n >> 1;
+
+ while (r >= j)
+ {
+ r -= j;
+ j >>= 1;
+ }
+ r |= j;
+
+ k = r >> 1;
+ j = i << 3;
+ BUTTERFLY_10 (X[k], X[k + 1],
+ X[k + n], X[k + n + 1],
+ Y[j], Y[j + 1],
+ Y[j + 2], Y[j + 3],
+ __1, __0);
+ k += n2;
+ j += 4;
+ BUTTERFLY_10 (X[k], X[k + 1],
+ X[k + n], X[k + n + 1],
+ Y[j], Y[j + 1],
+ Y[j + 2], Y[j + 3],
+ __1, __0);
+ }
+}
+static inline void
+bitreverse_fft2synthesis (const unsigned int n,
+ const %-6s *X,
+ %-6s *Y)
+{
+ const unsigned int n2 = n >> 1, n1 = n + n2, max = n >> 2;
+ unsigned int i, r;
+ %s scale = n;
+
+ scale = 1.0 / scale;
+ BUTTERFLY_10scale (X[0], X[1],
+ X[n], X[n + 1],
+ Y[0], Y[1],
+ Y[2], Y[3],
+ scale);
+ BUTTERFLY_10scale (X[n2], X[n2 + 1],
+ X[n1], X[n1 + 1],
+ Y[4], Y[5],
+ Y[6], Y[7],
+ scale);
+ for (i = 1, r = 0; i < max; i++)
+ {
+ unsigned int k, j = n >> 1;
+
+ while (r >= j)
+ {
+ r -= j;
+ j >>= 1;
+ }
+ r |= j;
+
+ k = r >> 1;
+ j = i << 3;
+ BUTTERFLY_10scale (X[k], X[k + 1],
+ X[k + n], X[k + n + 1],
+ Y[j], Y[j + 1],
+ Y[j + 2], Y[j + 3],
+ scale);
+ k += n2;
+ j += 4;
+ BUTTERFLY_10scale (X[k], X[k + 1],
+ X[k + n], X[k + n + 1],
+ Y[j], Y[j + 1],
+ Y[j + 2], Y[j + 3],
+ scale);
+ }
+}
+", $ieee_type, $ieee_type, $ieee_type, $ieee_type, $tmp_ieee_type;
+
+ # testing:
+ # define BUTTERFLY_10(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,Wre,Wim,T1re,T1im,T2re,T2im) \
+ # { int a = &X1re-X, b = &X2re-X, c = &Y1re-Y; \
+ # printf ("bufferfly: [%u,%u] -> [%u,%u]\n", (a)>>1, (b)>>1, (c)>>1, (c+2)>>1); \
+ # if (((a)|(b)|(c))&1) perror("****eek, extraneous bits!");}
+ # int main (int argc, char *argv[]) {
+ # bitreverse_fft2a (atoi (argv[1]), 0, 0);
+ # return 0;
+ # }
+}
+
+#
+# fft generation routines
+#
+sub gen_fft_loop_unoptimized {
+ my $fft_size = shift;
+ my $n_points = shift;
+ my $n_rep = shift; # repetitions
+ my $ofs2;
+
+ die "invalid fft size: " . $n_points if ($n_points < 4);
+
+ # incremental coefficient W for this fft
+ my $theta = $PI / ($n_points >> 1);
+ $theta = -$theta if ($negate_sign);
+ my $re = sin (0.5 * $theta);
+ my $im = sin ($theta);
+ $re = $re * $re * -2.;
+
+ # init variables, start loops
+ printf "%sWre = 1.0; Wim = 0.0;\n", $indent;
+ printf "%sfor (butterfly = 0; butterfly < %u; butterfly += 2) {\n", $indent, $n_points;
+ $indent .= " ";
+ printf "%sfor (block = 0; block < %u; block += %u) {\n", $indent, $n_rep * $n_points << 1, $n_points << 1;
+ $indent .= " ";
+
+ # do the butterfly
+ printf "%soffset = butterfly + block;\n", $indent;
+ $ofs2 = sprintf "offset + %u", $n_points;
+ butterfly ("XY", "offset", $ofs2, "Wre", "Wim", "Y");
+
+ # close inner loop, update W
+ $indent =~ s/\ \ $//;
+ printf "%s}\n", $indent;
+ printf("%sWMULTIPLY (Wre, Wim, %+.15f, %+.15f);\n",
+ $indent, $re, $im);
+
+ # close outer loop, done
+ $indent =~ s/\ \ $//;
+ printf "%s}\n", $indent;
+}
+sub gen_fft_loop_o10o0x {
+ my $fft_size = shift;
+ my $n_points = shift;
+ my $n_rep = shift; # repetitions
+ my $ofs2;
+
+ die "invalid fft size: " . $n_points if ($n_points < 4);
+
+ # coefficient {1,0} loop
+ printf "%sfor (offset = 0; offset < %u; offset += %u) {\n", $indent, $n_rep * $n_points << 1, $n_points << 1;
+ $indent .= " ";
+ $ofs2 = sprintf "offset + %u", $n_points;
+ butterfly ("10", "offset", $ofs2, "__1", "__0", "Y");
+ $indent =~ s/\ \ $//;
+ printf "%s}\n", $indent;
+
+ # incremental coefficient W for this fft
+ my $theta = $PI / ($n_points >> 1);
+ $theta = -$theta if ($negate_sign);
+ my $re = sin (0.5 * $theta);
+ my $im = sin ($theta);
+ $re = $re * $re * -2.;
+
+ # loop first half
+ if (2 < $n_points >> 1) {
+ printf "%sWre = %+.15f; Wim = %+.15f;\n", $indent, $re + 1.0, $im;
+ printf "%sfor (butterfly = 2; butterfly < %u; butterfly += 2) {\n", $indent, $n_points >> 1;
+ $indent .= " ";
+ printf "%sfor (block = 0; block < %u; block += %u) {\n", $indent, $n_rep * $n_points << 1, $n_points << 1;
+ $indent .= " ";
+ # do the butterfly
+ printf "%soffset = butterfly + block;\n", $indent;
+ $ofs2 = sprintf "offset + %u", $n_points;
+ butterfly ("XY", "offset", $ofs2, "Wre", "Wim", "Y");
+ # close inner loop, update W
+ $indent =~ s/\ \ $//;
+ printf "%s}\n", $indent;
+ printf("%sWMULTIPLY (Wre, Wim, %+.15f, %+.15f);\n",
+ $indent, $re, $im);
+ # close outer loop, done
+ $indent =~ s/\ \ $//;
+ printf "%s}\n", $indent;
+ }
+
+ # coefficient {0,1} loop
+ printf "%sfor (offset = %u; offset < %u; offset += %u) {\n", $indent, $n_points >> 1, $n_rep * $n_points << 1, $n_points << 1;
+ $indent .= " ";
+ $ofs2 = sprintf "offset + %u", $n_points;
+ butterfly ($negate_sign ? "0m" : "01", "offset", $ofs2, "__0", "__1", "Y");
+ $indent =~ s/\ \ $//;
+ printf "%s}\n", $indent;
+
+ # loop second half
+ if (($n_points >> 1) + 2 < $n_points) {
+ if ($negate_sign) {
+ printf "%sWre = %+.15f; Wim = %+.15f;\n", $indent, $im, -$re - 1.0;
+ } else {
+ printf "%sWre = %+.15f; Wim = %+.15f;\n", $indent, -$im, $re + 1.0;
+ }
+ printf "%sfor (butterfly = %u; butterfly < %u; butterfly += 2) {\n", $indent, ($n_points >> 1) + 2, $n_points;
+ $indent .= " ";
+ printf "%sfor (block = 0; block < %u; block += %u) {\n", $indent, $n_rep * $n_points << 1, $n_points << 1;
+ $indent .= " ";
+ # do the butterfly
+ printf "%soffset = butterfly + block;\n", $indent;
+ $ofs2 = sprintf "offset + %u", $n_points;
+ butterfly ("XY", "offset", $ofs2, "Wre", "Wim", "Y");
+ # close inner loop, update W
+ $indent =~ s/\ \ $//;
+ printf "%s}\n", $indent;
+ printf("%sWMULTIPLY (Wre, Wim, %+.15f, %+.15f);\n",
+ $indent, $re, $im);
+ # close outer loop, done
+ $indent =~ s/\ \ $//;
+ printf "%s}\n", $indent;
+ }
+}
+sub fft_loop_macros {
+ # mul_result = gsl_complex (c1.re * c2.re - c1.im * c2.im, c1.re * c2.im + c1.im * c2.re);
+ print "
+#define WMULTIPLY(Wre,Wim,Dre,Dim) { \\
+ register $tmp_ieee_type T1re, T1im, T2re, T2im; \\
+ T1re = Wre * Dre; \\
+ T1im = Wim * Dre; \\
+ T2re = Wim * Dim; \\
+ T2im = Wre * Dim; \\
+ T1re -= T2re; \\
+ T1im += T2im; \\
+ Wre += T1re; \\
+ Wim += T1im; \\
+}";
+}
+sub butterfly_macros {
+ # mul_result = gsl_complex (c1.re * c2.re - c1.im * c2.im, c1.re * c2.im + c1.im * c2.re);
+ # add_result = gsl_complex (c1.re + c2.re, c1.im + c2.im);
+ print "
+#define BUTTERFLY_XY(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,Wre,Wim) { \\
+ register $tmp_ieee_type T1re, T1im, T2re, T2im; \\
+ T1re = X2re * Wre; \\
+ T1im = X2im * Wre; \\
+ T2re = X2im * Wim; \\
+ T2im = X2re * Wim; \\
+ T1re -= T2re; \\
+ T1im += T2im; \\
+ T2re = X1re - T1re; \\
+ T2im = X1im - T1im; \\
+ Y1re = X1re + T1re; \\
+ Y1im = X1im + T1im; \\
+ Y2re = T2re; \\
+ Y2im = T2im; \\
+}
+#define BUTTERFLY_Yx(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,Wre,Wim) { \\
+ register $tmp_ieee_type T1re, T1im, T2re, T2im; \\
+ T1re = X2re * Wim; \\
+ T1im = X2im * Wim; \\
+ T2re = X2im * Wre; \\
+ T2im = X2re * Wre; \\
+ T1re += T2re; \\
+ T1im -= T2im; \\
+ T2re = X1re + T1re; \\
+ T2im = X1im + T1im; \\
+ Y1re = X1re - T1re; \\
+ Y1im = X1im - T1im; \\
+ Y2re = T2re; \\
+ Y2im = T2im; \\
+}
+#define BUTTERFLY_yX(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,Wre,Wim) { \\
+ register $tmp_ieee_type T1re, T1im, T2re, T2im; \\
+ T1re = X2re * Wim; \\
+ T1im = X2im * Wim; \\
+ T2re = X2im * Wre; \\
+ T2im = X2re * Wre; \\
+ T1re += T2re; \\
+ T1im -= T2im; \\
+ T2re = X1re - T1re; \\
+ T2im = X1im - T1im; \\
+ Y1re = X1re + T1re; \\
+ Y1im = X1im + T1im; \\
+ Y2re = T2re; \\
+ Y2im = T2im; \\
+}
+#define BUTTERFLY_10(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,_1,_2) { \\
+ register $tmp_ieee_type T2re, T2im; \\
+ T2re = X1re - X2re; \\
+ T2im = X1im - X2im; \\
+ Y1re = X1re + X2re; \\
+ Y1im = X1im + X2im; \\
+ Y2re = T2re; \\
+ Y2im = T2im; \\
+}
+#define BUTTERFLY_01(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,_1,_2) { \\
+ register $tmp_ieee_type T2re, T2im; \\
+ T2re = X1re + X2im; \\
+ T2im = X1im - X2re; \\
+ Y1re = X1re - X2im; \\
+ Y1im = X1im + X2re; \\
+ Y2re = T2re; \\
+ Y2im = T2im; \\
+}
+#define BUTTERFLY_0m(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,_1,_2) { \\
+ register $tmp_ieee_type T2re, T2im; \\
+ T2re = X1re - X2im; \\
+ T2im = X1im + X2re; \\
+ Y1re = X1re + X2im; \\
+ Y1im = X1im - X2re; \\
+ Y2re = T2re; \\
+ Y2im = T2im; \\
+}
+#define BUTTERFLY_XX(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,Wre,_2) { \\
+ register $tmp_ieee_type T1re, T1im, T2re, T2im; \\
+ T1re = X2re * Wre; \\
+ T1im = X2im * Wre; \\
+ T2re = T1im; \\
+ T2im = T1re; \\
+ T1re -= T2re; \\
+ T1im += T2im; \\
+ T2re = X1re - T1re; \\
+ T2im = X1im - T1im; \\
+ Y1re = X1re + T1re; \\
+ Y1im = X1im + T1im; \\
+ Y2re = T2re; \\
+ Y2im = T2im; \\
+}
+#define BUTTERFLY_yY(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,Wre,_2) { \\
+ register $tmp_ieee_type T1re, T1im, T2re, T2im; \\
+ T1re = X2re * Wre; \\
+ T1im = X2im * Wre; \\
+ T2re = T1im; \\
+ T2im = T1re; \\
+ T1re += T2re; \\
+ T1im -= T2im; \\
+ T2re = X1re - T1re; \\
+ T2im = X1im - T1im; \\
+ Y1re = X1re + T1re; \\
+ Y1im = X1im + T1im; \\
+ Y2re = T2re; \\
+ Y2im = T2im; \\
+}
+#define BUTTERFLY_10scale(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,S) { \\
+ register $tmp_ieee_type T2re, T2im; \\
+ T2re = X1re - X2re; \\
+ T2im = X1im - X2im; \\
+ Y1re = X1re + X2re; \\
+ Y1im = X1im + X2im; \\
+ Y2re = T2re * S; \\
+ Y2im = T2im * S; \\
+ Y1re *= S; \\
+ Y1im *= S; \\
+}
+";
+}
+
+
+#
+# stage generation
+#
+sub gen_stage {
+ my $fft_size = shift;
+ my $n_points = shift;
+ my $kind = shift;
+ my $times = $fft_size / $n_points;
+
+ if ($kind eq 'S') {
+ printf "\n%s/* skipping %u times fft%u */\n", $indent, $times, $n_points;
+ return;
+ }
+ if ($n_points == 2) { # input stage needs special handling
+ if ($kind eq 'L') {
+ printf "\n%s/* perform fft2 and bitreverse input */\n", $indent;
+ printf "%sbitreverse_fft2%s (%u, X, Y);\n", $indent, $negate_sign ? "synthesis" : "analysis", $fft_size;
+ } elsif ($kind eq 'F') {
+ printf "\n%s/* perform %u times fft2 */\n", $indent, $times;
+ unroll_stage ($fft_size, $n_points, $times, 1);
+ } else {
+ die "need one of 'L' or 'F' for input stage";
+ }
+ } else {
+ if ($kind eq 'L') {
+ printf "\n%s/* perform %u times fft%u */\n", $indent, $times, $n_points;
+ gen_fft_loop_o10o0x ($fft_size, $n_points, $times);
+ } elsif ($kind eq 'F') {
+ printf "\n%s/* perform %u times fft%u */\n", $indent, $times, $n_points;
+ unroll_stage ($fft_size, $n_points, $times, 1);
+ } elsif ($kind eq 'R') {
+ printf "\n%s/* perform %u times fft%u */\n", $indent, $times, $n_points;
+ unroll_stage ($fft_size, $n_points, $times, $times == 1);
+ } elsif ($kind eq 'T') {
+ printf "\n%s/* perform %u times fft%u */\n", $indent, $times, $n_points;
+ table_stage ($fft_size, $n_points, $times);
+ } elsif ($kind eq 'X') {
+ printf "\n%s/* perform %u times fft%u */\n", $indent, $times, $n_points;
+ for (my $i = 0; $i < $times; $i++) {
+ if ($i) {
+ printf($indent."gsl_power2_fft%u%s_skip2 (X + %u, Y + %u);\n",
+ $n_points, $negate_sign ? "synthesis" : "analysis", $n_points * $i << 1, $n_points * $i << 1);
+ } else {
+ printf($indent."gsl_power2_fft%u%s_skip2 (X, Y);\n",
+ $n_points, $negate_sign ? "synthesis" : "analysis");
+ }
+ }
+ } else {
+ die "unknown kind: $kind";
+ }
+ }
+}
+
+#
+# test output
+#
+if ($Wtest) {
+ my $fft_size = $max_fft_size;
+
+ for (my $i = 0; $i < $fft_size >> 1; $i++) {
+ my $wk = Wexponent ($fft_size, $fft_size, $i);
+ printf "$fft_size: %4u: %+.15f, %+.15f,\n", $i, Wreal ($fft_size, $wk), Wimag ($fft_size, $wk);
+ }
+ exit 0;
+}
+if (0) {
+ # reversal test
+ for (my $i = 0; $i < $fft_size; $i++) {
+ printf STDERR "%-3u <-> %3u %s\n", $i, bitreverse ($fft_size, $i), $i % 4 ? "" : "XXX";
+ }
+}
+
+
+#
+# main output
+#
+if ($gen_macros) {
+ butterfly_macros ();
+ fft_loop_macros ();
+ bitreverse_fft2 ();
+}
+exit 0 if (!$max_fft_size);
+
+my $max_stages = 0;
+for ($i = $max_fft_size >> 1; $i; $i >>= 1) {
+ $max_stages++;
+}
+die "missing stage specifications ($max_stages stages, $#arguments specs)" if ($max_stages > $#arguments);
+die "too many stage specifications ($max_stages stages, $#arguments specs)" if ($max_stages < $#arguments);
+print "/**\n";
+printf(" ** Generated data (by gsl-genfft $max_fft_size");
+for (my $i = 1; $i < @arguments; $i++) {
+ printf " %s", uc ($arguments[$i]);
+}
+printf ")\n";
+print " **/\n";
+{
+ my $fft_size = $max_fft_size;
+ my $skip2 = uc ($arguments[1]) eq 'S';
+
+ printf STDERR "FFT-%-5u: ", $fft_size;
+
+ printf "static void\n";
+ printf("gsl_power2_fft%u%s%s (const %s *X, %s *Y)\n{\n",
+ $fft_size, $negate_sign ? "synthesis" : "analysis",
+ $skip2 ? "_skip2" : "",
+ $ieee_type, $ieee_type);
+ printf "%sregister unsigned int butterfly, block, offset;\n", $indent;
+ printf "%sregister %s Wre, Wim;\n\n", $indent, $tmp_ieee_type, $tmp_ieee_type;
+ printf "%sbutterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */\n", $indent;
+
+ my $seen_rule = 0;
+ for (my $i = 1; $i < @arguments && 1 << $i <= $fft_size; $i++) {
+ my $stage = uc ($arguments[$i]);
+ printf STDERR "%u-%s ", 1 << $i, $stage;
+ die "X follows non Skip" if ($stage eq "X" && $seen_rule);
+ gen_stage ($fft_size, 1 << $i, $stage);
+ $seen_rule |= (1 << $i) > 2 && !($stage eq "S");
+ }
+ printf "}\n";
+ printf STDERR "\n";
+}
+print "\n/**\n";
+print " ** Generated data ends here\n";
+print " **/\n";
diff --git a/flow/gsl/gsl-iplan.txt b/flow/gsl/gsl-iplan.txt
new file mode 100644
index 0000000..e37b55d
--- /dev/null
+++ b/flow/gsl/gsl-iplan.txt
@@ -0,0 +1,57 @@
+How to integrate the GSL engine into artsd?
+
+Open issues:
+ - adapting the driver model
+ - adapting main loop callbacks
+ - adapting the start()/stop() semantics
+ - multi streams
+ - midi/audio timing
+ - synchronization
+ - threadsafe module api
+ - how to live without the threading layer
+
+[*] adapting main loop callbacks
+
+the engine uses a three-state mainloop callback, which consists of
+
+1. prepare
+2. check
+3. dispatch
+
+with the following rules applying
+
+1. you always need to prepare, to obtain pollfds
+2. you check to see whether something needs to be done
+3. you dispatch to make the engine do something
+
+which will need to be treated in aRts as two state strategy, which is:
+================================================================================
+INIT:
+ prepare -> register fds with the IOManager
+--
+ON NOTIFY:
+ unregister fds with the IOManager
+
+ reselect all fds
+ check -> check if engine needs work
+ dispatch -> make engine do something
+
+ prepare -> reregister fds with the IOManager
+
+as temporary measure, we could eventually build an imaginary fd into the
+engine, which could be used for triggering calculations manually - we might
+also take the real fd, on the other hand, which would only lead to the
+IOManager sending out two notifications, which is not too critical
+================================================================================
+problem:
+
+iomanager reentrancy - the engine probably needs to be partially reentrant,
+if we are to expect that a synchronous destruction of a module (such as in
+a remote unref) transactionsynchronizes itself with the engine - but if we
+expect this, then we will need to register some fds reentrant with the engine
+
+well - we could - for a start - try to NOT reselect all fds to get a snapshot
+of the whole world in one piece - but try to 1:1 map iomanager callbacks to
+revents - this might or might not work
+
+
diff --git a/flow/gsl/gsl-mplan.txt b/flow/gsl/gsl-mplan.txt
new file mode 100644
index 0000000..2a80811
--- /dev/null
+++ b/flow/gsl/gsl-mplan.txt
@@ -0,0 +1,226 @@
+The GSL Engine
+==============
+
+The following gives an outline of the conceptual approach to
+simulate flow-system behavior and carries details of the
+implementation along.
+
+Introductionary remarks:
+------------------------
+The GSL Engine simulates signal flow systems by mapping them
+onto a network of signal processing modules which are connected
+via signal streams.
+The signal streams are value quantized and time discrete, where
+floats are used to store the quantized values and the samples are
+taken at arbitrary but equidistant points in time. Also, the
+sampling periods are assumed to be synchronous for all nodes.
+In the public GSL C API, engine modules are exposed as GslModule
+structures, for the internal engine implementation, each
+GslModule is embedded in an OpNode structure.
+
+Node Model:
+-----------
+* a node has n_istreams input streams
+* a node has n_jstreams joint input streams facilities, that is,
+ an unlimited number of ouput streams can be connected to each
+ "joint" input stream
+* a node has n_ostreams output streams
+* all streams are equally value quantized as IEEE754 floats,
+ usually within the range -1..1
+* all streams are synchronously time discrete
+* the flow-system behavior can be iteratively approximated
+ by calculating a node's output streams from its input streams
+* since all streams are equally time discrete, n output
+ values for all output streams can be calculated from n input
+ values at all input streams of a single network
+* some nodes always react delayed ("deferred" nodes) and can
+ guarantee that they can always produce n output values ahead
+ of receiving the corresponding n input values, with n>=1
+* a node that has no output facilities (n_ostreams==0) is
+ considered a "consumer" and has to be processed // FIXME
+
+Node Methods:
+-------------
+->process()
+ This method specifies through one of its arguments
+ the number of iterations the node has to perform,
+ and therefore the number of values that are supplied
+ in its stream input buffers and which have to be supplied
+ in its stream output buffers.
+->process_deferred()
+ This method specifies the number of input values supplied
+ and the number of output values that should be supplied.
+ The number of input values may be smaller than the number
+ of output values requested, in which case the node may return
+ less output values than requested.
+
+Node Relationships:
+-------------------
+Node B is an "input" of node A if:
+ * one of A's input streams is connected to one of B's output streams,
+ or
+ * node C is an "input" of A and B is an "input" of C
+
+Processing Order:
+-----------------
+If node A has an input node B and A is not a deferred node, B has to
+be processed prior to processing A.
+
+Connection Cycles:
+------------------
+Nodes A and B "form a cycle" if A is an input to B and B is an
+input to A.
+
+Invalid Connections:
+--------------------
+For nodes A and B (not necessarily distinct) which form a cycle,
+the connections that the cycle consists of are only valid if
+the following is true:
+ (C is a deferred node) and
+ (C==A or C==B or (if C is completely disconnected, the nodes
+ A and B do not anymore form the cycle))
+
+
+Implementation Notes
+====================
+* if a node is deferred, all output channels are delayed
+* independent leaf nodes (nodes that have no inputs) can be
+ scheduled separately
+* nodes contained in a cycle have to be scheduled together
+
+Scheduling Algorithm
+--------------------
+To schedule a consumer and its dependency nodes, schedule_query() it:
+
+Query and Schedule Node:
+* tag current node
+* ignore scheduled input nodes
+* schedule_query_node on untagged input nodes, then do one of:
+ * schedule input node (if it has no cycles)
+ * resolve all input nodes cycles and then schedule
+ the input nodes cycle (if not self in cycle)
+ * take over cycle dependencies from input node
+* a tagged node is added to the precondition list (opens new cycle)
+* own leaf level is MAX() of input node leaf-levels + 1
+* untag node
+
+Resolving Cycles:
+* eliminate child from precondition list, once the list
+ is empty the cycle is resolved
+* at least one node being eliminated has to be deferred
+ for the cycle to be valid
+
+Scheduling:
+* nodes need to be processed in the order of leaf-level
+* within leaf-levels, processing is determined by a per-node
+ processing costs hint (cheap, normal, expensive)
+
+Implementation Considerations:
+------------------------------
+For deferred nodes, the number n specifying the amount of output
+values that are produced ahead of input can be considered
+mostly-fixed. that is, it's unlikely to change often and will do
+so only at block boundaries.
+Supporting n to be completely variable or considering it mostly
+fixed has certain implications. Here're the considerations that
+led to supporting a completely variable n for the implementation:
+
+n is block-boundary fixed:
++ for complex cycles (i.e. cycles that contain other cycles,
+ "subcycles"), the subcycles can be scheduled separately
+ if the n of the subcycle is >= block_size
+- if n is the only thing that changed at a block-boundary,
+ rescheduling the flow-graph is required in the cases
+ where n = old_n + x with old_n < block_size or if x < 0
+- deferred nodes can not change their delay in response to
+ values of an input stream
+
+n is variable for every iteration step:
++ no rescheduling is required if n changes at block-boundary
+- subcycles can not be scheduled separately from their outermost
+ cycle
++ the delay of deferred nodes can correlate to an input stream
+
+
+Threads, communication, main loops
+==================================
+
+Thread types:
+* UserThread; for the scope of the engine (the functions exposed in
+ gslengine.h), only one user thread may execute API functions
+ at a time.
+ i.e. if more than one user thread need to call engine API
+ functions, the user has to take measures to avoid concurrency
+ in calling these functions, e.g. by using a GslMutex which is
+ to be locked around engine API calls.
+* MasterThread; the engine, if configured accordingly,
+ sets up one master thread which
+ - processes transactions from the UserThread
+ - schedules processing order of engine modules
+ - processes single modules when required
+ - processes module cycles when required
+ - passes back processed transactions and flow jobs to the
+ UserThread for garbage collection
+* SlaveThread; the engine can be configured to spawn slave threads which,
+ in addition to the master thread
+ - process single modules when required
+ - process module cycles when required
+
+Communication at thread boundaries:
+* Job transaction queue; the UserThread constructs job transactions and
+ enqueues them for the MasterThread. The UserThread also dequeues already
+ processed transactions, in order for destroy functions of modules and
+ accessors to only be executed within the UserThread.
+ Also, the UserThread can wait (block) until all pending transactions
+ have been processed by the MasterThread (in order to sync state with
+ module network contained in the engine).
+* Flow job collection list; the MasterThread adds processed flow jobs into
+ a collection queue, the UserThread then collects the queued flow jobs
+ and frees them.
+* Module/cycle pool; the MasterThread fills in the module/cycle pool with
+ modules which need to be processed. The MasterThread and the SlaveThreads
+ pop modules/cycles from this pool, process them, and push back processed
+ nodes.
+* load control; // FIXME
+
+Main loop integration:
+in order to process certain engine modules only from within
+the UserThread and to drive the engine even without master
+or slave threads, the engine can be hooked up to a main loop
+mechanism supplied by the UserThread.
+The engine provides API entry points to:
+- export file descriptors and timeout, suitable for main loop backends
+ such as poll(2)
+- check whether dispatching is necessary
+- dispatch outstanding work to be performed by the engine
+FIXME: needs mentioning of pollfd/callback jobs
+
+
+TODO:
+=====
+- virtualization (poke ibuffer into outbuffer) flag (needs memcpy for deferred nodes)
+- flag UserThread nodes
+- sample timed jobs
+- need global timestamp
+- need async-queues that have time-stamped jobs
+- process only so much samples until a time-stamped
+ job needs to be processed
+- self-input cycles need to be resolved in parent as well
+- node-locale async timestamped jobs
+- engine-init: { block(pipe-fd), check }
+- sample-timed activation can offset node's block-boundary
+- need complete_blocks_only flag in node classes
+- cost rating: cost*n_inputs+cost*n_outputs
+- multi-input(joint) streams: job_disconnect(dmod,distr,smod,sistr); (jstreams)
+
+Jan 07 2002 Tim Janik
+ * cosmetic updates, flow jobs
+Aug 19 2001 Tim Janik
+ * notes on threads, communication, main loops
+Jul 29 2001 Tim Janik
+ * wording/spelling fixups
+May 05 2001 Tim Janik
+ * initial writeup
+
+LocalWords: GSL API GslModule OpNode istreams ostreams A's B's sync
+LocalWords: gslengine GslMutex UserThread MasterThread SlaveThread SlaveThreads
diff --git a/flow/gsl/gsl.3 b/flow/gsl/gsl.3
new file mode 100644
index 0000000..2f7bb31
--- /dev/null
+++ b/flow/gsl/gsl.3
@@ -0,0 +1,822 @@
+.TH "GSL-Functions" 3 "17 May 2002" "BEAST-0.4.1" "BEAST-0.4.1"
+.SH NAME
+GSL-Functions \- GSL Function Reference
+.SH SYNOPSIS
+\fBgsl_thread_wakeup\fP (\fIthread\fP);
+.br
+\fBgsl_thread_abort\fP (\fIthread\fP);
+.br
+\fBgsl_thread_queue_abort\fP (\fIthread\fP);
+.br
+\fBgsl_thread_aborted\fP ();
+.br
+\fBgsl_thread_sleep\fP (\fImax_msec\fP);
+.br
+\fBgsl_thread_awake_after\fP (\fItick_stamp\fP);
+.br
+\fBgsl_thread_awake_before\fP (\fItick_stamp\fP);
+.br
+\fBgsl_tick_stamp\fP ();
+.br
+\fBgsl_data_find_block\fP (\fIhandle\fP, \fIn_values\fP, \fIvalues\fP, \fIepsilon\fP);
+.br
+\fBgsl_module_tick_stamp\fP (\fImodule\fP);
+.br
+\fBgsl_job_integrate\fP (\fImodule\fP);
+.br
+\fBgsl_job_discard\fP (\fImodule\fP);
+.br
+\fBgsl_job_connect\fP (\fIsrc_module\fP, \fIsrc_ostream\fP, \fIdest_module\fP, \fIdest_istream\fP);
+.br
+\fBgsl_job_disconnect\fP (\fIdest_module\fP, \fIdest_istream\fP);
+.br
+\fBGslAccessFunc\fP (\fImodule\fP, \fIdata\fP);
+.br
+\fBgsl_job_access\fP (\fImodule\fP, \fIaccess_func\fP, \fIdata\fP, \fIfree_func\fP);
+.br
+\fBgsl_flow_job_access\fP (\fImodule\fP, \fItick_stamp\fP, \fIaccess_func\fP, \fIdata\fP, \fIfree_func\fP);
+.br
+\fBGslPollFunc\fP (\fIdata\fP, \fIn_values\fP, \fItimeout_p\fP, \fIn_fds\fP, \fIfds\fP, \fIrevents_filled\fP);
+.br
+\fBgsl_job_add_poll\fP (\fIpoll_func\fP, \fIdata\fP, \fIfree_func\fP, \fIn_fds\fP, \fIfds\fP);
+.br
+\fBgsl_job_remove_poll\fP (\fIpoll_func\fP, \fIdata\fP);
+.br
+\fBgsl_job_debug\fP (\fIdebug\fP);
+.br
+\fBgsl_trans_open\fP ();
+.br
+\fBgsl_trans_add\fP (\fItrans\fP, \fIjob\fP);
+.br
+\fBgsl_trans_commit\fP (\fItrans\fP);
+.br
+\fBgsl_trans_dismiss\fP (\fItrans\fP);
+.br
+\fBgsl_transact\fP (\fIjob\fP, \fI...\fP);
+.br
+\fBgsl_engine_init\fP (\fIrun_threaded\fP, \fIblock_size\fP, \fIsample_freq\fP, \fIsub_sample_mask\fP);
+.br
+\fBgsl_engine_wait_on_trans\fP ();
+.br
+\fBgsl_power2_fftac\fP (\fIn_values\fP, \fIri_values_in\fP, \fIri_values_out\fP);
+.br
+\fBgsl_power2_fftsc\fP (\fIn_values\fP, \fIri_values_in\fP, \fIri_values_out\fP);
+.br
+\fBgsl_power2_fftar\fP (\fIn_values\fP, \fIr_values_in\fP, \fIri_values_out\fP);
+.br
+\fBgsl_power2_fftsr\fP (\fIn_values\fP, \fIri_values_in\fP, \fIr_values_out\fP);
+.br
+\fBgsl_filter_tscheb2_steepness_db\fP (\fIiorder\fP, \fIc_freq\fP, \fIepsilon\fP, \fIstopband_db\fP);
+.br
+\fBgsl_filter_tscheb2_steepness\fP (\fIiorder\fP, \fIc_freq\fP, \fIepsilon\fP, \fIresidue\fP);
+.br
+\fBgsl_filter_butter_lp\fP (\fIiorder\fP, \fIfreq\fP, \fIepsilon\fP, \fIa\fP, \fIb\fP);
+.br
+\fBgsl_filter_tscheb1_lp\fP (\fIiorder\fP, \fIfreq\fP, \fIepsilon\fP, \fIa\fP, \fIb\fP);
+.br
+\fBgsl_filter_tscheb2_lp\fP (\fIiorder\fP, \fIfreq\fP, \fIsteepness\fP, \fIepsilon\fP, \fIa\fP, \fIb\fP);
+.br
+\fBgsl_filter_butter_hp\fP (\fIiorder\fP, \fIfreq\fP, \fIepsilon\fP, \fIa\fP, \fIb\fP);
+.br
+\fBgsl_filter_tscheb1_hp\fP (\fIiorder\fP, \fIfreq\fP, \fIepsilon\fP, \fIa\fP, \fIb\fP);
+.br
+\fBgsl_filter_tscheb2_hp\fP (\fIiorder\fP, \fIfreq\fP, \fIsteepness\fP, \fIepsilon\fP, \fIa\fP, \fIb\fP);
+.br
+\fBgsl_filter_butter_bp\fP (\fIiorder\fP, \fIfreq1\fP, \fIfreq2\fP, \fIepsilon\fP, \fIa\fP, \fIb\fP);
+.br
+\fBgsl_filter_tscheb1_bp\fP (\fIiorder\fP, \fIfreq1\fP, \fIfreq2\fP, \fIepsilon\fP, \fIa\fP, \fIb\fP);
+.br
+\fBgsl_filter_tscheb2_bp\fP (\fIiorder\fP, \fIfreq1\fP, \fIfreq2\fP, \fIsteepness\fP, \fIepsilon\fP, \fIa\fP, \fIb\fP);
+.br
+\fBgsl_filter_butter_bs\fP (\fIiorder\fP, \fIfreq1\fP, \fIfreq2\fP, \fIepsilon\fP, \fIa\fP, \fIb\fP);
+.br
+\fBgsl_filter_tscheb1_bs\fP (\fIiorder\fP, \fIfreq1\fP, \fIfreq2\fP, \fIepsilon\fP, \fIa\fP, \fIb\fP);
+.br
+\fBgsl_filter_tscheb2_bs\fP (\fIiorder\fP, \fIfreq1\fP, \fIfreq2\fP, \fIsteepness\fP, \fIepsilon\fP, \fIa\fP, \fIb\fP);
+.br
+\fBgsl_filter_fir_approx\fP (\fIiorder\fP, \fIfreq\fP, \fIvalue\fP);
+.br
+\fBgsl_filter_sine_scan\fP (\fIorder\fP, \fIa\fP, \fIb\fP, \fIfreq\fP, \fIn_values\fP);
+.br
+\fBgsl_engine_garbage_collect\fP ();
+.br
+\fBgsl_signal_exp2\fP ();
+.br
+\fBgsl_approx_exp2\fP (\fIex\fP);
+.br
+\fBgsl_approx_atan1\fP (\fIx\fP);
+.br
+\fBgsl_approx_atan1_prescale\fP (\fIboost_amount\fP);
+.br
+\fBgsl_approx_qcircle1\fP (\fIx\fP);
+.br
+\fBgsl_approx_qcircle2\fP (\fIx\fP);
+.br
+\fBgsl_approx_qcircle3\fP (\fIx\fP);
+.br
+\fBgsl_approx_qcircle4\fP (\fIx\fP);
+.br
+.SH DESCRIPTION
+.SS \fBgsl_thread_wakeup\fP (\fIthread\fP);
+.PD 0
+.IP \fIGslThread*\ thread\fP 19
+thread to wake up
+.PD 1
+.PP
+Wake up a currently sleeping thread. In practice, this function simply causes the next call to \fBgsl_thread_sleep()\fP within \fIthread\fP to last for 0 seconds.
+.PD
+.SS \fBgsl_thread_abort\fP (\fIthread\fP);
+.PD 0
+.IP \fIGslThread*\ thread\fP 19
+thread to abort
+.PD 1
+.PP
+Abort a currently running thread. This function does not return until the thread in question terminated execution. Note that the thread handle gets invalidated with invocation of \fBgsl_thread_abort()\fP or \fBgsl_thread_queue_abort()\fP.
+.PD
+.SS \fBgsl_thread_queue_abort\fP (\fIthread\fP);
+.PD 0
+.IP \fIGslThread*\ thread\fP 19
+thread to abort
+.PD 1
+.PP
+Same as \fBgsl_thread_abort()\fP, but returns as soon as possible, even if thread hasn't stopped execution yet. Note that the thread handle gets invalidated with invocation of \fBgsl_thread_abort()\fP or \fBgsl_thread_queue_abort()\fP.
+.PD
+.SS \fBgsl_thread_aborted\fP ();
+.PD 0
+.IP \fIRETURNS:\fP 11
+\fITRUE\fP if the thread should abort execution
+.PD 1
+.PP
+Find out if the currently running thread should be aborted (the thread is supposed to return from its main thread function).
+.PD
+.SS \fBgsl_thread_sleep\fP (\fImax_msec\fP);
+.PD 0
+.IP \fIglong\ \ max_msec\fP 17
+maximum amount of milli seconds to sleep (-1 for infinite time)
+.IP \fIRETURNS:\fP 17
+\fITRUE\fP if the thread should continue execution
+.PD 1
+.PP
+Sleep for the amount of time given. This function may get interrupted by wakeup or abort requests, it returns whether the thread is supposed to continue execution after waking up.
+.PD
+.SS \fBgsl_thread_awake_after\fP (\fItick_stamp\fP);
+.PD 0
+.IP \fIguint64\ \ tick_stamp\fP 21
+tick stamp update to trigger wakeup
+.PD 1
+.PP
+Wakeup the currently running thread after the global tick stamp (see \fBgsl_tick_stamp()\fP) has been updated to \fItick_stamp\fP. (If the moment of wakeup has already passed by, the thread is woken up at the next global tick stamp update.)
+.PD
+.SS \fBgsl_thread_awake_before\fP (\fItick_stamp\fP);
+.PD 0
+.IP \fIguint64\ \ tick_stamp\fP 21
+tick stamp update to trigger wakeup
+.PD 1
+.PP
+Wakeup the currently running thread upon the last global tick stamp update (see \fBgsl_tick_stamp()\fP) that happens prior to updating the global tick stamp to \fItick_stamp\fP. (If the moment of wakeup has already passed by, the thread is woken up at the next global tick stamp update.)
+.PD
+.SS \fBgsl_tick_stamp\fP ();
+.PD 0
+.IP \fIRETURNS:\fP 11
+GSL's execution tick stamp as unsigned 64bit integer
+.PD 1
+.PP
+Retrive the GSL global tick stamp. GSL increments its global tick stamp at certain intervals, by specific amounts (refer to \fBgsl_engine_init()\fP for further details). The tick stamp is a non-wrapping, unsigned 64bit integer greater than 0. Threads can schedule sleep interruptions at certain tick stamps with \fBgsl_thread_awake_after()\fP and \fBgsl_thread_awake_before()\fP. Tick stamp updating occours at GSL engine block processing boundaries, so code that can guarantee to not run across those boundaries (for instance \fBGslProcessFunc()\fP functions) may use the macro \fIGSL_TICK_STAMP\fP to retrive the current tick in a faster manner (not involving mutex locking). See also \fBgsl_module_tick_stamp()\fP.
+.PD
+.SS \fBgsl_data_find_block\fP (\fIhandle\fP, \fIn_values\fP, \fIvalues\fP, \fIepsilon\fP);
+.PD 0
+.IP \fIGslDataHandle*\ handle\fP 25
+an open GslDataHandle
+.IP \fIguint\ \ \ \ \ \ \ \ \ \ n_values\fP 25
+amount of values to look for
+.IP \fIconst\ gfloat*\ \ values\fP 25
+values to find
+.IP \fIgfloat\ \ \ \ \ \ \ \ \ epsilon\fP 25
+maximum difference upon comparisions
+.IP \fIRETURNS:\fP 25
+position of values in data handle or -1
+.PD 1
+.PP
+Find the position of a block of values within a data handle, where all values compare to the reference values with a delta smaller than epsilon.
+.PD
+.SS \fBgsl_module_tick_stamp\fP (\fImodule\fP);
+.PD 0
+.IP \fIGslModule*\ module\fP 19
+a GSL engine module
+.IP \fIRETURNS:\fP 19
+the module's tick stamp, indicating its process status
+.PD 1
+.PP
+Any thread may call this function on a valid engine module. The module specific tick stamp is updated to \fBgsl_tick_stamp()\fP + \fIn_values\fP every time its \fBGslProcessFunc()\fP function was called. See also \fBgsl_tick_stamp()\fP.
+.PD
+.SS \fBgsl_job_integrate\fP (\fImodule\fP);
+.PD 0
+.IP \fIGslModule*\ module\fP 19
+The module to integrate
+.IP \fIRETURNS:\fP 19
+New job suitable for \fBgsl_trans_add()\fP
+.PD 1
+.PP
+Create a new transaction job to integrate \fImodule\fP into the engine.
+.PD
+.SS \fBgsl_job_discard\fP (\fImodule\fP);
+.PD 0
+.IP \fIGslModule*\ module\fP 19
+The module to discard
+.IP \fIRETURNS:\fP 19
+New job suitable for \fBgsl_trans_add()\fP
+.PD 1
+.PP
+Create a new transaction job which removes \fImodule\fP from the engine and destroys it.
+.PD
+.SS \fBgsl_job_connect\fP (\fIsrc_module\fP, \fIsrc_ostream\fP, \fIdest_module\fP, \fIdest_istream\fP);
+.PD 0
+.IP \fIGslModule*\ src_module\fP 25
+Module with output stream
+.IP \fIguint\ \ \ \ \ \ src_ostream\fP 25
+Index of output stream of \fIsrc_module\fP
+.IP \fIGslModule*\ dest_module\fP 25
+Module with unconnected input stream
+.IP \fIguint\ \ \ \ \ \ dest_istream\fP 25
+Index of input stream of \fIdest_module\fP
+.IP \fIRETURNS:\fP 25
+New job suitable for \fBgsl_trans_add()\fP
+.PD 1
+.PP
+Create a new transaction job which connects the ouput stream \fIsrc_ostream\fP of module \fIsrc_module\fP to the input stream \fIdest_istream\fP of module \fIdest_module\fP (it is an error if the input stream is already connected by the time the job is executed).
+.PD
+.SS \fBgsl_job_disconnect\fP (\fIdest_module\fP, \fIdest_istream\fP);
+.PD 0
+.IP \fIGslModule*\ dest_module\fP 25
+Module with connected input stream
+.IP \fIguint\ \ \ \ \ \ dest_istream\fP 25
+Index of input stream of \fIdest_module\fP
+.IP \fIRETURNS:\fP 25
+New job suitable for \fBgsl_trans_add()\fP
+.PD 1
+.PP
+Create a new transaction job which causes the input stream \fIdest_istream\fP of \fIdest_module\fP to be disconnected (it is an error if the input stream isn't connected by the time the job is executed).
+.PD
+.SS \fBGslAccessFunc\fP (\fImodule\fP, \fIdata\fP);
+.PD 0
+.IP \fI\ module\fP 9
+Module to operate on
+.IP \fI\ data\fP 9
+Accessor data
+.PD 1
+.PP
+The GslAccessFunc is a user supplied callback function which can access a module in times it is not processing. Accessors are usually used to either read out a module's current state, or to modify its state. An accessor may only operate on the \fIdata\fP and the \fImodule\fP passed in to it.
+.PD
+.SS \fBgsl_job_access\fP (\fImodule\fP, \fIaccess_func\fP, \fIdata\fP, \fIfree_func\fP);
+.PD 0
+.IP \fIGslModule*\ \ \ \ \ module\fP 28
+The module to access
+.IP \fIGslAccessFunc\ \ access_func\fP 28
+The accessor function
+.IP \fIgpointer\ \ \ \ \ \ \ data\fP 28
+Data passed in to the accessor
+.IP \fIGslFreeFunc\ \ \ \ free_func\fP 28
+Function to free \fIdata\fP
+.IP \fIRETURNS:\fP 28
+New job suitable for \fBgsl_trans_add()\fP
+.PD 1
+.PP
+Create a new transaction job which will invoke \fIaccess_func\fP on \fImodule\fP with \fIdata\fP when the transaction queue is processed to modify the module's state.
+.PD
+.SS \fBgsl_flow_job_access\fP (\fImodule\fP, \fItick_stamp\fP, \fIaccess_func\fP, \fIdata\fP, \fIfree_func\fP);
+.PD 0
+.IP \fIGslModule*\ \ \ \ \ module\fP 28
+
+.IP \fIguint64\ \ \ \ \ \ \ \ tick_stamp\fP 28
+
+.IP \fIGslAccessFunc\ \ access_func\fP 28
+
+.IP \fIgpointer\ \ \ \ \ \ \ data\fP 28
+
+.IP \fIGslFreeFunc\ \ \ \ free_func\fP 28
+
+.PD 1
+.PP
+
+.PD
+.SS \fBGslPollFunc\fP (\fIdata\fP, \fIn_values\fP, \fItimeout_p\fP, \fIn_fds\fP, \fIfds\fP, \fIrevents_filled\fP);
+.PD 0
+.IP \fI\ data\fP 17
+Data of poll function
+.IP \fI\ n_values\fP 17
+Minimum number of values the engine wants to process
+.IP \fI\ timeout_p\fP 17
+Location of timeout value
+.IP \fI\ n_fds\fP 17
+Number of file descriptors used for polling
+.IP \fI\ fds\fP 17
+File descriptors to be used for polling
+.IP \fI\ revents_filled\fP 17
+Indicates whether \fIfds\fP actually have their ->revents field filled with valid data.
+.IP \fIRETURNS:\fP 17
+A boolean value indicating whether the engine should process data right now
+.PD 1
+.PP
+The GslPollFunc is a user supplied callback function which can be hooked into the GSL engine. The engine uses the poll functions to determine whether processing of \fIn_values\fP in its module network is necessary. In order for the poll functions to react to extern events, such as device driver status changes, the engine will \fBpoll(2)\fP the \fIfds\fP of the poll function and invoke the callback with \fIrevents_filled\fP==\fITRUE\fP if any of its \fIfds\fP changed state. The callback may also be invoked at other random times with \fIrevents_filled\fP=\fIFALSE\fP. It is supposed to return \fITRUE\fP if network processing is currently necessary, and \fIFALSE\fP if not. If \fIFALSE\fP is returned, \fItimeout_p\fP may be filled with the number of milliseconds the engine should use for polling at maximum.
+.PD
+.SS \fBgsl_job_add_poll\fP (\fIpoll_func\fP, \fIdata\fP, \fIfree_func\fP, \fIn_fds\fP, \fIfds\fP);
+.PD 0
+.IP \fIGslPollFunc\ \ \ \ \ \ poll_func\fP 28
+Poll function to add
+.IP \fIgpointer\ \ \ \ \ \ \ \ \ data\fP 28
+Data of poll function
+.IP \fIGslFreeFunc\ \ \ \ \ \ free_func\fP 28
+Function to free \fIdata\fP
+.IP \fIguint\ \ \ \ \ \ \ \ \ \ \ \ n_fds\fP 28
+Number of poll file descriptors
+.IP \fIconst\ GslPollFD*\ fds\fP 28
+File descriptors to \fBselect(2)\fP or \fBpoll(2)\fP on
+.IP \fIRETURNS:\fP 28
+New job suitable for \fBgsl_trans_add()\fP
+.PD 1
+.PP
+Create a new transaction job which adds a poll function to the engine. The poll function is used by the engine to determine whether processing is currently necessary.
+.PD
+.SS \fBgsl_job_remove_poll\fP (\fIpoll_func\fP, \fIdata\fP);
+.PD 0
+.IP \fIGslPollFunc\ \ poll_func\fP 24
+Poll function to remove
+.IP \fIgpointer\ \ \ \ \ data\fP 24
+Data of poll function
+.IP \fIRETURNS:\fP 24
+New job suitable for \fBgsl_trans_add()\fP
+.PD 1
+.PP
+Create a new transaction job which removes a previously inserted poll function from the engine.
+.PD
+.SS \fBgsl_job_debug\fP (\fIdebug\fP);
+.PD 0
+.IP \fIconst\ gchar*\ debug\fP 20
+Debug message
+.IP \fIRETURNS:\fP 20
+New job suitable for \fBgsl_trans_add()\fP
+.PD 1
+.PP
+Create a new transaction job which issues \fIdebug\fP message when the job is executed. This function is meant for debugging purposes during development phase only and shouldn't be used in production code.
+.PD
+.SS \fBgsl_trans_open\fP ();
+.PD 0
+.IP \fIRETURNS:\fP 11
+Newly opened empty transaction
+.PD 1
+.PP
+Open up a new transaction to commit jobs to the GSL engine. This function may cause garbage collection (see \fBgsl_engine_garbage_collect()\fP).
+.PD
+.SS \fBgsl_trans_add\fP (\fItrans\fP, \fIjob\fP);
+.PD 0
+.IP \fIGslTrans*\ trans\fP 17
+Opened transaction
+.IP \fIGslJob*\ \ \ job\fP 17
+Job to add
+.PD 1
+.PP
+Append a job to an opened transaction.
+.PD
+.SS \fBgsl_trans_commit\fP (\fItrans\fP);
+.PD 0
+.IP \fIGslTrans*\ trans\fP 17
+Opened transaction
+.PD 1
+.PP
+Close the transaction and commit it to the engine. The engine will execute the jobs contained in this transaction as soon as it has completed its current processing cycle. The jobs will be executed in the exact order they were added to the transaction.
+.PD
+.SS \fBgsl_trans_dismiss\fP (\fItrans\fP);
+.PD 0
+.IP \fIGslTrans*\ trans\fP 17
+Opened transaction
+.PD 1
+.PP
+Close and discard the transaction, destroy all jobs currently contained in it and do not execute them. This function may cause garbage collection (see \fBgsl_engine_garbage_collect()\fP).
+.PD
+.SS \fBgsl_transact\fP (\fIjob\fP, \fI...\fP);
+.PD 0
+.IP \fI\ job\fP 6
+First job
+.IP \fI\ ...\fP 6
+\fINULL\fP terminated job list
+.PD 1
+.PP
+Convenience function which openes up a new transaction, collects the \fINULL\fP terminated job list passed to the function, and commits the transaction.
+.PD
+.SS \fBgsl_engine_init\fP (\fIrun_threaded\fP, \fIblock_size\fP, \fIsample_freq\fP, \fIsub_sample_mask\fP);
+.PD 0
+.IP \fIgboolean\ \ run_threaded\fP 27
+
+.IP \fIguint\ \ \ \ \ block_size\fP 27
+number of values to process block wise
+.IP \fIguint\ \ \ \ \ sample_freq\fP 27
+
+.IP \fIguint\ \ \ \ \ sub_sample_mask\fP 27
+
+.PD 1
+.PP
+Initialize the GSL engine, this function must be called prior to any other engine related function and can only be invoked once. The \fIblock_size\fP determines the amount by which the global tick stamp (see \fBgsl_tick_stamp()\fP) is updated everytime the whole module network completed processing \fIblock_size\fP values.
+.PD
+.SS \fBgsl_engine_wait_on_trans\fP ();
+.PD 0
+.PD 1
+.PP
+Wait until all pending transactions have been processed by the GSL Engine. This function may cause garbage collection (see \fBgsl_engine_garbage_collect()\fP).
+.PD
+.SS \fBgsl_power2_fftac\fP (\fIn_values\fP, \fIri_values_in\fP, \fIri_values_out\fP);
+.PD 0
+.IP \fI\ n_values\fP 16
+Number of complex values
+.IP \fI\ ri_values_in\fP 16
+Complex sample values [0..n_values*2-1]
+.IP \fI\ ri_values_out\fP 16
+Complex frequency values [0..n_values*2-1]
+.PD 1
+.PP
+This function performs a decimation in time fourier transformation in forward direction, where the input values are equidistant sampled data, and the output values contain the frequency proportions of the input. The input and output arrays are complex values with real and imaginery portions interleaved, adressable in the range [0..2*n_values-1], where n_values must be a power of two. Frequencies are stored in-order, the K-th output corresponds to the frequency K/n_values. (If you want to interpret negative frequencies, note that the frequencies -K/n_values and (n_values-K)/n_values are equivalent). Note that the transformation is performed out of place, the input array is not modified, and may not overlap with the output array.
+.PD
+.SS \fBgsl_power2_fftsc\fP (\fIn_values\fP, \fIri_values_in\fP, \fIri_values_out\fP);
+.PD 0
+.IP \fI\ n_values\fP 16
+Number of complex values
+.IP \fI\ ri_values_in\fP 16
+Complex frequency values [0..n_values*2-1]
+.IP \fI\ ri_values_out\fP 16
+Complex sample values [0..n_values*2-1]
+.PD 1
+.PP
+This function performs a decimation in time fourier transformation in backwards direction with normalization. As such, this function represents the counterpart to \fBgsl_power2_fftac()\fP, that is, a value array which is transformed into the frequency domain with \fBgsl_power2_fftac()\fP can be reconstructed by issuing \fBgsl_power2_fftsc()\fP on the transform. Note that the transformation is performed out of place, the input array is not modified, and may not overlap with the output array.
+.PD
+.SS \fBgsl_power2_fftar\fP (\fIn_values\fP, \fIr_values_in\fP, \fIri_values_out\fP);
+.PD 0
+.IP \fI\ n_values\fP 16
+Number of complex values
+.IP \fI\ r_values_in\fP 16
+Real sample values [0..n_values-1]
+.IP \fI\ ri_values_out\fP 16
+Complex frequency values [0..n_values-1]
+.PD 1
+.PP
+Real valued variant of \fBgsl_power2_fftac()\fP, the input array contains real valued equidistant sampled data [0..n_values-1], and the output array contains the positive frequency half of the complex valued fourier transform. Note, that the complex valued fourier transform H of a purely real valued set of data, satisfies \fBH(-f)\fP = Conj(\fBH(f)\fP), where \fBConj()\fP denotes the complex conjugate, so that just the positive frequency half suffices to describe the entire frequency spectrum. Even so, the resulting n_values/2 complex frequencies are one value off in storage size, but the resulting frequencies \fBH(0)\fP and \fBH(n_values/2)\fP are both real valued, so the real portion of \fBH(n_values/2)\fP is stored in ri_values_out[1] (the imaginery part of \fBH(0)\fP), so that both r_values_in and ri_values_out can be of size n_values. Note that the transformation is performed out of place, the input array is not modified, and may not overlap with the output array.
+.PD
+.SS \fBgsl_power2_fftsr\fP (\fIn_values\fP, \fIri_values_in\fP, \fIr_values_out\fP);
+.PD 0
+.IP \fI\ n_values\fP 15
+Number of complex values
+.IP \fI\ ri_values_in\fP 15
+Complex frequency values [0..n_values-1]
+.IP \fI\ r_values_out\fP 15
+Real sample values [0..n_values-1]
+.PD 1
+.PP
+Real valued variant of \fBgsl_power2_fftsc()\fP, counterpart to \fBgsl_power2_fftar()\fP, using the same frequency storage format. A real valued data set transformed into the frequency domain with \fBgsl_power2_fftar()\fP can be reconstructed using this function. Note that the transformation is performed out of place, the input array is not modified, and may not overlap with the output array.
+.PD
+.SS \fBgsl_filter_tscheb2_steepness_db\fP (\fIiorder\fP, \fIc_freq\fP, \fIepsilon\fP, \fIstopband_db\fP);
+.PD 0
+.IP \fIunsigned\ int\ \ iorder\fP 27
+filter order
+.IP \fIdouble\ \ \ \ \ \ \ \ c_freq\fP 27
+passband cutoff frequency (0..pi)
+.IP \fIdouble\ \ \ \ \ \ \ \ epsilon\fP 27
+fall off at passband frequency (0..1)
+.IP \fIdouble\ \ \ \ \ \ \ \ stopband_db\fP 27
+reduction in stopband in dB (>= 0)
+.PD 1
+.PP
+Calculates the steepness parameter for Tschebyscheff type 2 lowpass filter, based on the ripple residue in the stop band.
+.PD
+.SS \fBgsl_filter_tscheb2_steepness\fP (\fIiorder\fP, \fIc_freq\fP, \fIepsilon\fP, \fIresidue\fP);
+.PD 0
+.IP \fIunsigned\ int\ \ iorder\fP 23
+filter order
+.IP \fIdouble\ \ \ \ \ \ \ \ c_freq\fP 23
+passband cutoff frequency (0..pi)
+.IP \fIdouble\ \ \ \ \ \ \ \ epsilon\fP 23
+fall off at passband frequency (0..1)
+.IP \fIdouble\ \ \ \ \ \ \ \ residue\fP 23
+maximum of transfer function in stopband (0..1)
+.PD 1
+.PP
+Calculates the steepness parameter for Tschebyscheff type 2 lowpass filter, based on ripple residue in the stop band.
+.PD
+.SS \fBgsl_filter_butter_lp\fP (\fIiorder\fP, \fIfreq\fP, \fIepsilon\fP, \fIa\fP, \fIb\fP);
+.PD 0
+.IP \fI\ iorder\fP 10
+filter order
+.IP \fI\ freq\fP 10
+cutoff frequency (0..pi)
+.IP \fI\ epsilon\fP 10
+fall off at cutoff frequency (0..1)
+.IP \fI\ a\fP 10
+root polynomial coefficients a[0..iorder]
+.IP \fI\ b\fP 10
+pole polynomial coefficients b[0..iorder]
+.PD 1
+.PP
+Butterworth lowpass filter.
+.PD
+.SS \fBgsl_filter_tscheb1_lp\fP (\fIiorder\fP, \fIfreq\fP, \fIepsilon\fP, \fIa\fP, \fIb\fP);
+.PD 0
+.IP \fI\ iorder\fP 10
+filter order
+.IP \fI\ freq\fP 10
+cutoff frequency (0..pi)
+.IP \fI\ epsilon\fP 10
+fall off at cutoff frequency (0..1)
+.IP \fI\ a\fP 10
+root polynomial coefficients a[0..iorder]
+.IP \fI\ b\fP 10
+pole polynomial coefficients b[0..iorder]
+.PD 1
+.PP
+Tschebyscheff type 1 lowpass filter.
+.PD
+.SS \fBgsl_filter_tscheb2_lp\fP (\fIiorder\fP, \fIfreq\fP, \fIsteepness\fP, \fIepsilon\fP, \fIa\fP, \fIb\fP);
+.PD 0
+.IP \fI\ iorder\fP 12
+filter order
+.IP \fI\ freq\fP 12
+passband cutoff frequency (0..pi)
+.IP \fI\ steepness\fP 12
+frequency steepness (c_freq * steepness < pi)
+.IP \fI\ epsilon\fP 12
+fall off at passband frequency (0..1)
+.IP \fI\ a\fP 12
+root polynomial coefficients a[0..iorder]
+.IP \fI\ b\fP 12
+pole polynomial coefficients b[0..iorder]
+.PD 1
+.PP
+Tschebyscheff type 2 lowpass filter. To gain a transition band between freq1 and freq2, pass arguements \fIfreq\fP=freq1 and \fIsteepness\fP=freq2/freq1. To specify the transition band width in fractions of octaves, pass \fIsteepness\fP=2^octave_fraction.
+.PD
+.SS \fBgsl_filter_butter_hp\fP (\fIiorder\fP, \fIfreq\fP, \fIepsilon\fP, \fIa\fP, \fIb\fP);
+.PD 0
+.IP \fI\ iorder\fP 10
+filter order
+.IP \fI\ freq\fP 10
+passband frequency (0..pi)
+.IP \fI\ epsilon\fP 10
+fall off at passband frequency (0..1)
+.IP \fI\ a\fP 10
+root polynomial coefficients a[0..iorder]
+.IP \fI\ b\fP 10
+pole polynomial coefficients b[0..iorder]
+.PD 1
+.PP
+Butterworth highpass filter.
+.PD
+.SS \fBgsl_filter_tscheb1_hp\fP (\fIiorder\fP, \fIfreq\fP, \fIepsilon\fP, \fIa\fP, \fIb\fP);
+.PD 0
+.IP \fI\ iorder\fP 10
+filter order
+.IP \fI\ freq\fP 10
+passband frequency (0..pi)
+.IP \fI\ epsilon\fP 10
+fall off at passband frequency (0..1)
+.IP \fI\ a\fP 10
+root polynomial coefficients a[0..iorder]
+.IP \fI\ b\fP 10
+pole polynomial coefficients b[0..iorder]
+.PD 1
+.PP
+Tschebyscheff type 1 highpass filter.
+.PD
+.SS \fBgsl_filter_tscheb2_hp\fP (\fIiorder\fP, \fIfreq\fP, \fIsteepness\fP, \fIepsilon\fP, \fIa\fP, \fIb\fP);
+.PD 0
+.IP \fI\ iorder\fP 12
+filter order
+.IP \fI\ freq\fP 12
+stopband frequency (0..pi)
+.IP \fI\ steepness\fP 12
+frequency steepness
+.IP \fI\ epsilon\fP 12
+fall off at passband frequency (0..1)
+.IP \fI\ a\fP 12
+root polynomial coefficients a[0..iorder]
+.IP \fI\ b\fP 12
+pole polynomial coefficients b[0..iorder]
+.PD 1
+.PP
+Tschebyscheff type 2 highpass filter.
+.PD
+.SS \fBgsl_filter_butter_bp\fP (\fIiorder\fP, \fIfreq1\fP, \fIfreq2\fP, \fIepsilon\fP, \fIa\fP, \fIb\fP);
+.PD 0
+.IP \fI\ iorder\fP 10
+filter order (must be even)
+.IP \fI\ freq1\fP 10
+stopband end frequency (0..pi)
+.IP \fI\ freq2\fP 10
+passband end frequency (0..pi)
+.IP \fI\ epsilon\fP 10
+fall off at passband frequency (0..1)
+.IP \fI\ a\fP 10
+root polynomial coefficients a[0..iorder]
+.IP \fI\ b\fP 10
+pole polynomial coefficients b[0..iorder]
+.PD 1
+.PP
+Butterworth bandpass filter.
+.PD
+.SS \fBgsl_filter_tscheb1_bp\fP (\fIiorder\fP, \fIfreq1\fP, \fIfreq2\fP, \fIepsilon\fP, \fIa\fP, \fIb\fP);
+.PD 0
+.IP \fI\ iorder\fP 10
+filter order (must be even)
+.IP \fI\ freq1\fP 10
+stopband end frequency (0..pi)
+.IP \fI\ freq2\fP 10
+passband end frequency (0..pi)
+.IP \fI\ epsilon\fP 10
+fall off at passband frequency (0..1)
+.IP \fI\ a\fP 10
+root polynomial coefficients a[0..iorder]
+.IP \fI\ b\fP 10
+pole polynomial coefficients b[0..iorder]
+.PD 1
+.PP
+Tschebyscheff type 1 bandpass filter.
+.PD
+.SS \fBgsl_filter_tscheb2_bp\fP (\fIiorder\fP, \fIfreq1\fP, \fIfreq2\fP, \fIsteepness\fP, \fIepsilon\fP, \fIa\fP, \fIb\fP);
+.PD 0
+.IP \fI\ iorder\fP 12
+filter order (must be even)
+.IP \fI\ freq1\fP 12
+stopband end frequency (0..pi)
+.IP \fI\ freq2\fP 12
+passband end frequency (0..pi)
+.IP \fI\ steepness\fP 12
+frequency steepness factor
+.IP \fI\ epsilon\fP 12
+fall off at passband frequency (0..1)
+.IP \fI\ a\fP 12
+root polynomial coefficients a[0..iorder]
+.IP \fI\ b\fP 12
+pole polynomial coefficients b[0..iorder]
+.PD 1
+.PP
+Tschebyscheff type 2 bandpass filter.
+.PD
+.SS \fBgsl_filter_butter_bs\fP (\fIiorder\fP, \fIfreq1\fP, \fIfreq2\fP, \fIepsilon\fP, \fIa\fP, \fIb\fP);
+.PD 0
+.IP \fI\ iorder\fP 10
+filter order (must be even)
+.IP \fI\ freq1\fP 10
+passband end frequency (0..pi)
+.IP \fI\ freq2\fP 10
+stopband end frequency (0..pi)
+.IP \fI\ epsilon\fP 10
+fall off at passband frequency (0..1)
+.IP \fI\ a\fP 10
+root polynomial coefficients a[0..iorder]
+.IP \fI\ b\fP 10
+pole polynomial coefficients b[0..iorder]
+.PD 1
+.PP
+Butterworth bandstop filter.
+.PD
+.SS \fBgsl_filter_tscheb1_bs\fP (\fIiorder\fP, \fIfreq1\fP, \fIfreq2\fP, \fIepsilon\fP, \fIa\fP, \fIb\fP);
+.PD 0
+.IP \fI\ iorder\fP 10
+filter order (must be even)
+.IP \fI\ freq1\fP 10
+passband end frequency (0..pi)
+.IP \fI\ freq2\fP 10
+stopband end frequency (0..pi)
+.IP \fI\ epsilon\fP 10
+fall off at passband frequency (0..1)
+.IP \fI\ a\fP 10
+root polynomial coefficients a[0..iorder]
+.IP \fI\ b\fP 10
+pole polynomial coefficients b[0..iorder]
+.PD 1
+.PP
+Tschebyscheff type 1 bandstop filter.
+.PD
+.SS \fBgsl_filter_tscheb2_bs\fP (\fIiorder\fP, \fIfreq1\fP, \fIfreq2\fP, \fIsteepness\fP, \fIepsilon\fP, \fIa\fP, \fIb\fP);
+.PD 0
+.IP \fI\ iorder\fP 12
+filter order (must be even)
+.IP \fI\ freq1\fP 12
+passband end frequency (0..pi)
+.IP \fI\ freq2\fP 12
+stopband end frequency (0..pi)
+.IP \fI\ steepness\fP 12
+frequency steepness factor
+.IP \fI\ epsilon\fP 12
+fall off at passband frequency (0..1)
+.IP \fI\ a\fP 12
+root polynomial coefficients a[0..iorder]
+.IP \fI\ b\fP 12
+pole polynomial coefficients b[0..iorder]
+.PD 1
+.PP
+Tschebyscheff type 2 bandstop filter.
+.PD
+.SS \fBgsl_filter_fir_approx\fP (\fIiorder\fP, \fIfreq\fP, \fIvalue\fP);
+.PD 0
+.IP \fI\ iorder\fP 9
+order of the filter (must be oven, >= 2)
+.IP \fI\ freq\fP 9
+the frequencies of the transfer function
+.IP \fI\ value\fP 9
+the desired value of the transfer function
+.PD 1
+.PP
+Approximates a given transfer function with an iorder-coefficient FIR filter. It is recommended to provide enough frequency values, so that \fIn_points\fP >= \fIiorder\fP.
+.PD
+.SS \fBgsl_filter_sine_scan\fP (\fIorder\fP, \fIa\fP, \fIb\fP, \fIfreq\fP, \fIn_values\fP);
+.PD 0
+.IP \fIguint\ \ \ \ \ \ \ \ \ \ order\fP 25
+order of the iir filter
+.IP \fIconst\ gdouble*\ a\fP 25
+root polynomial coefficients of the filter a[0..order]
+.IP \fIconst\ gdouble*\ b\fP 25
+pole polynomial coefficients of the filter b[0..order]
+.IP \fIgdouble\ \ \ \ \ \ \ \ freq\fP 25
+frequency to test
+.IP \fIguint\ \ \ \ \ \ \ \ \ \ n_values\fP 25
+number of samples
+.PD 1
+.PP
+This function sends a sine signal of the desired frequency through an IIR filter, to test the value of the transfer function at a given point. It uses gsl_iir_filter_eval to do so. Compared to a "mathematical approach" of finding the transfer function, this function makes it possible to see the effects of finite arithmetic during filter evaluation. The first half of the output signal is not considered, since a lot of IIR filters have a transient phase where also overshoot is possible. For n_values, you should specify a reasonable large value. It should be a lot larger than the filter order, and large enough to let the input signal become (close to) 1.0 multiple times.
+.PD
+.SS \fBgsl_engine_garbage_collect\fP ();
+.PD 0
+.PD 1
+.PP
+GSL Engine user thread function. Collects processed jobs and transactions from the engine and frees them, this involves callback invocation of \fBGslFreeFunc()\fP functions, e.g. from \fBgsl_job_access()\fP or \fBgsl_flow_job_access()\fP jobs. This function may only be called from the user thread, as \fBGslFreeFunc()\fP functions are guranteed to be executed in the user thread.
+.PD
+.SS \fBgsl_signal_exp2\fP ();
+.PD 0
+.PD 1
+.PP
+Deprecated in favour of \fBgsl_approx_exp2()\fP.
+.PD
+.SS \fBgsl_approx_exp2\fP (\fIex\fP);
+.PD 0
+.IP \fIfloat\ \ ex\fP 11
+exponent within [-127..127]
+.IP \fIRETURNS:\fP 11
+y approximating 2^x
+.PD 1
+.PP
+Fast approximation of 2 raised to the power of x. Multiplicative error stays below 8e-6 and aproaches zero for integer values of x (i.e. x - floor (x) = 0).
+.PD
+.SS \fBgsl_approx_atan1\fP (\fIx\fP);
+.PD 0
+.IP \fIregister\ double\ \ x\fP 20
+
+.PD 1
+.PP
+Fast \fBatan(x)\fP/(PI/2) approximation, with maximum error < 0.01 and \fBgsl_approx_atan1(0)\fP==0, according to the formula: n1 = -0.41156875521951602506487246309908; n2 = -1.0091272542790025586079663559158; d1 = 0.81901156857081841441890603235599; d2 = 1.0091272542790025586079663559158; \fBpositive_atan1(x)\fP = 1 + (n1 * x + n2) / ((1 + d1 * x) * x + d2);
+.PD
+.SS \fBgsl_approx_atan1_prescale\fP (\fIboost_amount\fP);
+.PD 0
+.IP \fI\ boost_amount\fP 15
+boost amount between [0..1]
+.IP \fIRETURNS:\fP 15
+prescale factor for \fBgsl_approx_atan1()\fP
+.PD 1
+.PP
+Calculate the prescale factor for \fBgsl_approx_atan1(x*prescale)\fP from a linear boost factor, where 0.5 amounts to prescale=1.0, 1.0 results in maximum boost and 0.0 results in maximum attenuation.
+.PD
+.SS \fBgsl_approx_qcircle1\fP (\fIx\fP);
+.PD 0
+.IP \fIregister\ double\ \ x\fP 20
+x within [0..1]
+.IP \fIRETURNS:\fP 20
+y for circle approximation within [0..1]
+.PD 1
+.PP
+Fast approximation of the upper right quadrant of a circle. Errors at x=0 and x=1 are zero, for the rest of the curve, the error wasn't minimized, but distributed to best fit the curverture of a quarter circle. The maximum error is below 0.092.
+.PD
+.SS \fBgsl_approx_qcircle2\fP (\fIx\fP);
+.PD 0
+.IP \fIregister\ double\ \ x\fP 20
+x within [0..1]
+.IP \fIRETURNS:\fP 20
+y for circle approximation within [0..1]
+.PD 1
+.PP
+Fast approximation of the upper left quadrant of a circle. Errors at x=0 and x=1 are zero, for the rest of the curve, the error wasn't minimized, but distributed to best fit the curverture of a quarter circle. The maximum error is below 0.092.
+.PD
+.SS \fBgsl_approx_qcircle3\fP (\fIx\fP);
+.PD 0
+.IP \fIregister\ double\ \ x\fP 20
+x within [0..1]
+.IP \fIRETURNS:\fP 20
+y for circle approximation within [0..1]
+.PD 1
+.PP
+Fast approximation of the lower left quadrant of a circle. Errors at x=0 and x=1 are zero, for the rest of the curve, the error wasn't minimized, but distributed to best fit the curverture of a quarter circle. The maximum error is below 0.092.
+.PD
+.SS \fBgsl_approx_qcircle4\fP (\fIx\fP);
+.PD 0
+.IP \fIregister\ double\ \ x\fP 20
+x within [0..1]
+.IP \fIRETURNS:\fP 20
+y for circle approximation within [0..1]
+.PD 1
+.PP
+Fast approximation of the lower right quadrant of a circle. Errors at x=0 and x=1 are zero, for the rest of the curve, the error wasn't minimized, but distributed to best fit the curverture of a quarter circle. The maximum error is below 0.092.
+.PD
+
diff --git a/flow/gsl/gsl.gnuplot b/flow/gsl/gsl.gnuplot
new file mode 100644
index 0000000..e50c2ae
--- /dev/null
+++ b/flow/gsl/gsl.gnuplot
@@ -0,0 +1,5 @@
+dB(x)=20*log(abs(x))/log(10) # logarithmische Filterdarstellung in dB (s/20/10/ for abs(x)^2)
+s2z(s)=(1+s)/(1-s) # s-Ebene -> z-Ebene (bilinear Trans.)
+j={0,1} # sqrt(-1)
+Z(x)=exp({0,-1}*x) # gnuplot laufvariable x fuer H(z)
+set samples 4000 # more accuracy
diff --git a/flow/gsl/gslarrows b/flow/gsl/gslarrows
new file mode 100644
index 0000000..04ba5e4
--- /dev/null
+++ b/flow/gsl/gslarrows
@@ -0,0 +1,30 @@
+
+
+# $0+0 == number of arrows
+# $1+0 = first arrow
+# $2+0 = second arrow
+# e.g.
+# gnuplot> call "arrows" 3 "2*3" "0.5*pi" "sqrt(7)"
+
+#debug-args # 0:$0 1:$1 2:$2 3:$3 4:$4 5:$5 6:$6 7:$7 8:$8 9:$9
+
+
+arrow_line_type=0
+set arrow 1 from first $1+0,graph 0 to first $1+0,graph 1 nohead lt arrow_line_type
+set arrow 2 from first $2+0,graph 0 to first $2+0,graph 1 nohead lt arrow_line_type
+set arrow 3 from first $3+0,graph 0 to first $3+0,graph 1 nohead lt arrow_line_type
+set arrow 4 from first $4+0,graph 0 to first $4+0,graph 1 nohead lt arrow_line_type
+set arrow 5 from first $5+0,graph 0 to first $5+0,graph 1 nohead lt arrow_line_type
+set arrow 6 from first $6+0,graph 0 to first $6+0,graph 1 nohead lt arrow_line_type
+set arrow 7 from first $7+0,graph 0 to first $7+0,graph 1 nohead lt arrow_line_type
+set arrow 8 from first $8+0,graph 0 to first $8+0,graph 1 nohead lt arrow_line_type
+set arrow 9 from first $9+0,graph 0 to first $9+0,graph 1 nohead lt arrow_line_type
+if ($0+0 < 9) set noarrow 9
+if ($0+0 < 8) set noarrow 8
+if ($0+0 < 7) set noarrow 7
+if ($0+0 < 6) set noarrow 6
+if ($0+0 < 5) set noarrow 5
+if ($0+0 < 4) set noarrow 4
+if ($0+0 < 3) set noarrow 3
+if ($0+0 < 2) set noarrow 2
+if ($0+0 < 1) set noarrow 1
diff --git a/flow/gsl/gslartsthreads.cc b/flow/gsl/gslartsthreads.cc
new file mode 100644
index 0000000..98094b7
--- /dev/null
+++ b/flow/gsl/gslartsthreads.cc
@@ -0,0 +1,205 @@
+ /*
+
+ Copyright (C) 2001-2002 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include "thread.h"
+#include "debug.h"
+#include "gslglib.h"
+#include <pthread.h>
+
+#if defined(__DECCXX)
+#define EXTC extern "C"
+#else
+#define EXTC
+#endif
+
+EXTC gpointer
+gsl_arts_mutex_new ()
+{
+ return new Arts::Mutex;
+}
+
+EXTC void
+gsl_arts_mutex_free (gpointer mutex)
+{
+ Arts::Mutex *m = static_cast<Arts::Mutex *>(mutex);
+ delete m;
+}
+
+EXTC void
+gsl_arts_mutex_lock (gpointer mutex)
+{
+ Arts::Mutex *m = static_cast<Arts::Mutex *>(mutex);
+ m->lock();
+}
+
+EXTC gboolean
+gsl_arts_mutex_trylock (gpointer mutex)
+{
+ Arts::Mutex *m = static_cast<Arts::Mutex *>(mutex);
+ return m->tryLock();
+}
+
+EXTC void
+gsl_arts_mutex_unlock (gpointer mutex)
+{
+ Arts::Mutex *m = static_cast<Arts::Mutex *>(mutex);
+ m->unlock();
+}
+
+EXTC gpointer
+gsl_arts_cond_new ()
+{
+ return new Arts::ThreadCondition;
+}
+
+EXTC void
+gsl_arts_cond_free (gpointer cond)
+{
+ Arts::ThreadCondition *c = static_cast<Arts::ThreadCondition *>(cond);
+ delete c;
+}
+
+EXTC void
+gsl_arts_cond_signal (gpointer cond)
+{
+ Arts::ThreadCondition *c = static_cast<Arts::ThreadCondition *>(cond);
+ c->wakeOne();
+}
+
+EXTC void
+gsl_arts_cond_broadcast (gpointer cond)
+{
+ Arts::ThreadCondition *c = static_cast<Arts::ThreadCondition *>(cond);
+ c->wakeAll();
+}
+
+EXTC void
+gsl_arts_cond_wait (gpointer cond, gpointer mutex)
+{
+ Arts::ThreadCondition *c = static_cast<Arts::ThreadCondition *>(cond);
+ Arts::Mutex *m = static_cast<Arts::Mutex *>(mutex);
+
+ c->wait(*m);
+}
+
+EXTC void
+gsl_arts_cond_timed_wait (gpointer /*cond*/, gpointer /*mutex*/, GTimeVal * /*time*/)
+{
+ arts_assert(false);
+}
+
+
+class GslArtsThread : public Arts::Thread {
+protected:
+ gpointer (*func)(gpointer data);
+ gpointer data;
+ gpointer result;
+
+public:
+ GThread gthread;
+
+ GslArtsThread(gpointer (*func)(gpointer data), gpointer data)
+ : func(func), data(data)
+ {
+ gthread.data = 0;
+ }
+ void run()
+ {
+ result = func(data);
+ }
+};
+
+
+/* KCC (KAI C++) is buggy. If we write out the type of the first argument
+ to gsl_arts_thread_create(), ala
+ gsl_arts_thread_create (gpointer (*func) (gpointer data2), ...)
+ it becomes C++ linkage, i.e. it's name gets mangled, _despite_ declared
+ extern "C" in the header. Other sources only calling this function,
+ i.e. those only seeing the prototype correctly call the unmangled
+ extern "C" variant, but for the above reason it isn't defined anywhere.
+ The solution is to go through a typedef for that argument, _which must
+ also be declared extern "C"_. I'm not sure, but I think it's an error
+ of KCC, that it puts the invisible type of the first arg into C++ mode,
+ although the whole function should be C only. If one declares
+ two equal function types, one extern "C", one not, they are even assignment
+ compatible. But somehow KCC puts that type into C++ mode, which for
+ other strange reasons force the whole function to go into C++ linkage.
+ It's enough, when this typedef is local to this file. (matz) */
+
+/* Due to gcc's unhappyness with 'extern "C" typedef ...' we enclose
+ it in a real extern "C" {} block. */
+extern "C" {
+typedef gpointer (*t_func)(gpointer data2);
+}
+
+// This is C++:
+GThread* gsl_arts_thread_create_full_CPP(gpointer (*func)(gpointer data),
+ gpointer data,
+ gulong /*stack_size*/,
+ gboolean /*joinable*/,
+ gboolean /*bound*/,
+ GThreadPriority /*priority*/,
+ GError ** /*error*/)
+{
+ GslArtsThread *thread = new GslArtsThread(func, data);
+ return &thread->gthread;
+}
+
+// This is C:
+extern "C" GThread*
+gsl_arts_thread_create_full(gpointer (*func)(gpointer data),
+ gpointer data,
+ gulong stack_size,
+ gboolean joinable,
+ gboolean bound,
+ GThreadPriority priority,
+ GError **error)
+{
+ return gsl_arts_thread_create_full_CPP(func,
+ data,
+ stack_size,
+ joinable,
+ bound,
+ priority,
+ error);
+}
+
+EXTC gpointer
+gsl_arts_thread_self ()
+{
+ GslArtsThread *current = static_cast<GslArtsThread *>(Arts::SystemThreads::the()->getCurrentThread());
+
+ if(current)
+ return &current->gthread;
+ else
+ {
+ static GThread mainThread = { 0, };
+ return &mainThread;
+ }
+}
+
+EXTC void
+gsl_arts_thread_init (gpointer /*arg*/)
+{
+}
+
+/* vim:set ts=8 sts=2 sw=2: */
diff --git a/flow/gsl/gslartsthreads.h b/flow/gsl/gslartsthreads.h
new file mode 100644
index 0000000..c9ebf19
--- /dev/null
+++ b/flow/gsl/gslartsthreads.h
@@ -0,0 +1,102 @@
+ /*
+
+ Copyright (C) 2001-2002 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef GSLARTSTHREADS_H
+#define GSLARTSTHREADS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* --- typedefs & structures --- */
+
+typedef struct _GError {
+ const char *message;
+} GError;
+
+typedef struct _GThread {
+ void *data;
+} GThread;
+
+typedef enum
+{
+ G_THREAD_PRIORITY_LOW,
+ G_THREAD_PRIORITY_NORMAL,
+ G_THREAD_PRIORITY_HIGH,
+ G_THREAD_PRIORITY_URGENT
+} GThreadPriority;
+
+#define g_mutex_lock gsl_arts_mutex_lock
+#define g_mutex_trylock gsl_arts_mutex_trylock
+#define g_mutex_unlock gsl_arts_mutex_unlock
+#define g_mutex_new gsl_arts_mutex_new
+#define g_mutex_free gsl_arts_mutex_free
+
+#define g_cond_new gsl_arts_cond_new
+#define g_cond_free gsl_arts_cond_free
+#define g_cond_signal gsl_arts_cond_signal
+#define g_cond_broadcast gsl_arts_cond_broadcast
+#define g_cond_wait gsl_arts_cond_wait
+#define g_cond_timed_wait gsl_arts_cond_timed_wait
+
+#define g_thread_create_full gsl_arts_thread_create_full
+#define g_thread_self gsl_arts_thread_self
+
+#define g_thread_init gsl_arts_thread_init
+
+#define g_error_free(x) g_assert_not_reached()
+
+/* --- prototypes --- */
+
+gpointer gsl_arts_mutex_new ();
+void gsl_arts_mutex_free (gpointer mutex);
+void gsl_arts_mutex_lock (gpointer mutex);
+gboolean gsl_arts_mutex_trylock (gpointer mutex);
+void gsl_arts_mutex_unlock (gpointer mutex);
+
+gpointer gsl_arts_cond_new ();
+void gsl_arts_cond_free (gpointer cond);
+void gsl_arts_cond_signal (gpointer cond);
+void gsl_arts_cond_broadcast (gpointer cond);
+void gsl_arts_cond_wait (gpointer cond, gpointer mutex);
+void gsl_arts_cond_timed_wait (gpointer cond, gpointer mutex, GTimeVal *abstime);
+
+GThread* gsl_arts_thread_create_full(gpointer (*func)(gpointer data),
+ gpointer data,
+ gulong stack_size,
+ gboolean joinable,
+ gboolean bound,
+ GThreadPriority priority,
+ GError **error);
+
+gpointer gsl_arts_thread_self ();
+
+void gsl_arts_thread_init (gpointer arg);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+/* vim:set ts=8 sts=2 sw=2: */
+
+#endif // GSLARTSTHREADS_H
+
diff --git a/flow/gsl/gslcommon.c b/flow/gsl/gslcommon.c
new file mode 100644
index 0000000..cb16b05
--- /dev/null
+++ b/flow/gsl/gslcommon.c
@@ -0,0 +1,1651 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001 Tim Janik
+ *
+ * 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.
+ */
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/utsname.h>
+#include <string.h>
+#include <sched.h>
+#include <errno.h>
+#include <sys/poll.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+
+#include "gslcommon.h"
+#include "gsldatacache.h"
+
+/* some systems don't have ERESTART (which is what linux returns for system
+ * calls on pipes which are being interrupted). most propably just use EINTR,
+ * and maybe some can return both. so we check for both in the below code,
+ * and alias ERESTART to EINTR if it's not present. compilers are supposed
+ * to catch and optimize the doubled check arising from this.
+ */
+#ifndef ERESTART
+#define ERESTART EINTR
+#endif
+
+
+#define PREALLOC (8)
+#define SIMPLE_CACHE_SIZE (64)
+#define TS8_SIZE (MAX (sizeof (GTrashStack), 8))
+#define DBG8_SIZE (MAX (sizeof (gsize), 8))
+
+
+/* --- variables --- */
+volatile guint64 gsl_externvar_tick_stamp = 0;
+static guint64 tick_stamp_system_time = 0;
+static guint global_tick_stamp_leaps = 0;
+static GslDebugFlags gsl_debug_flags = 0;
+
+
+/* --- memory allocation --- */
+static GslMutex global_memory = { 0, };
+static GTrashStack *simple_cache[SIMPLE_CACHE_SIZE] = { 0, 0, 0, /* ... */ };
+static gulong memory_allocated = 0;
+
+const guint
+gsl_alloc_upper_power2 (const gulong number)
+{
+ return number ? 1 << g_bit_storage (number - 1) : 0;
+}
+
+static inline gpointer
+low_alloc (gsize mem_size)
+{
+ gpointer mem;
+
+ if (mem_size >= TS8_SIZE && mem_size / 8 < SIMPLE_CACHE_SIZE)
+ {
+ guint cell;
+
+ mem_size = (mem_size + 7) & ~0x7;
+ cell = (mem_size >> 3) - 1;
+ GSL_SPIN_LOCK (&global_memory);
+ mem = g_trash_stack_pop (simple_cache + cell);
+ GSL_SPIN_UNLOCK (&global_memory);
+ if (!mem)
+ {
+ guint8 *cache_mem = g_malloc (mem_size * PREALLOC);
+ guint i;
+
+ GSL_SPIN_LOCK (&global_memory);
+ memory_allocated += mem_size * PREALLOC;
+ for (i = 0; i < PREALLOC - 1; i++)
+ {
+ g_trash_stack_push (simple_cache + cell, cache_mem);
+ cache_mem += mem_size;
+ }
+ GSL_SPIN_UNLOCK (&global_memory);
+ mem = cache_mem;
+ }
+ }
+ else
+ {
+ mem = g_malloc (mem_size);
+ GSL_SPIN_LOCK (&global_memory);
+ memory_allocated += mem_size;
+ GSL_SPIN_UNLOCK (&global_memory);
+ }
+ return mem;
+}
+
+static inline void
+low_free (gsize mem_size,
+ gpointer mem)
+{
+ if (mem_size >= TS8_SIZE && mem_size / 8 < SIMPLE_CACHE_SIZE)
+ {
+ guint cell;
+
+ mem_size = (mem_size + 7) & ~0x7;
+ cell = (mem_size >> 3) - 1;
+ GSL_SPIN_LOCK (&global_memory);
+ g_trash_stack_push (simple_cache + cell, mem);
+ GSL_SPIN_UNLOCK (&global_memory);
+ }
+ else
+ {
+ g_free (mem);
+ GSL_SPIN_LOCK (&global_memory);
+ memory_allocated -= mem_size;
+ GSL_SPIN_UNLOCK (&global_memory);
+ }
+}
+
+gpointer
+gsl_alloc_memblock (gsize block_size)
+{
+ guint8 *cmem;
+ gsize *debug_size;
+
+ g_return_val_if_fail (block_size >= sizeof (gpointer), NULL); /* cache-link size */
+
+ cmem = low_alloc (block_size + DBG8_SIZE);
+ debug_size = (gsize*) cmem;
+ *debug_size = block_size;
+ cmem += DBG8_SIZE;
+
+ return cmem;
+}
+
+void
+gsl_free_memblock (gsize block_size,
+ gpointer mem)
+{
+ gsize *debug_size;
+ guint8 *cmem;
+
+ g_return_if_fail (mem != NULL);
+
+ cmem = mem;
+ cmem -= DBG8_SIZE;
+ debug_size = (gsize*) cmem;
+ g_return_if_fail (block_size == *debug_size);
+
+ low_free (block_size + DBG8_SIZE, cmem);
+}
+
+void
+gsl_alloc_report (void)
+{
+ guint cell, cached = 0;
+
+ GSL_SPIN_LOCK (&global_memory);
+ for (cell = 0; cell < SIMPLE_CACHE_SIZE; cell++)
+ {
+ GTrashStack *trash = simple_cache[cell];
+ guint memsize, n = 0;
+
+ while (trash)
+ {
+ n++;
+ trash = trash->next;
+ }
+
+ if (n)
+ {
+ memsize = (cell + 1) << 3;
+ g_message ("cell %4u): %u bytes in %u nodes", memsize, memsize * n, n);
+ cached += memsize * n;
+ }
+ }
+ g_message ("%lu bytes allocated from system, %u bytes unused in cache", memory_allocated, cached);
+ GSL_SPIN_UNLOCK (&global_memory);
+}
+
+gpointer
+gsl_alloc_memblock0 (gsize block_size)
+{
+ gpointer mem = gsl_alloc_memblock (block_size);
+
+ memset (mem, 0, block_size);
+
+ return mem;
+}
+
+static void
+gsl_free_node_list (gpointer mem,
+ gsize node_size)
+{
+ struct { gpointer next, data; } *tmp, *node = mem;
+
+ g_return_if_fail (node != NULL);
+ g_return_if_fail (node_size >= 2 * sizeof (gpointer));
+
+ /* FIXME: this can be optimized to an O(1) operation with T-style links in mem-caches */
+ do
+ {
+ tmp = node->next;
+
+ gsl_free_memblock (node_size, node);
+ node = tmp;
+ }
+ while (node);
+}
+
+
+/* --- ring (circular-list) --- */
+static inline GslRing*
+gsl_ring_prepend_i (GslRing *head,
+ gpointer data)
+{
+ GslRing *ring = gsl_new_struct (GslRing, 1);
+
+ ring->data = data;
+ if (!head)
+ {
+ ring->prev = ring;
+ ring->next = ring;
+ }
+ else
+ {
+ ring->prev = head->prev;
+ ring->next = head;
+ head->prev->next = ring;
+ head->prev = ring;
+ }
+ return ring;
+}
+
+GslRing*
+gsl_ring_prepend (GslRing *head,
+ gpointer data)
+{
+ return gsl_ring_prepend_i (head, data);
+}
+
+GslRing*
+gsl_ring_prepend_uniq (GslRing *head,
+ gpointer data)
+{
+ GslRing *walk;
+
+ for (walk = head; walk; walk = gsl_ring_walk (head, walk))
+ if (walk->data == data)
+ return head;
+ return gsl_ring_prepend_i (head, data);
+}
+
+GslRing*
+gsl_ring_append (GslRing *head,
+ gpointer data)
+{
+ GslRing *ring;
+
+ ring = gsl_ring_prepend_i (head, data);
+
+ return head ? head : ring;
+}
+
+GslRing*
+gsl_ring_concat (GslRing *head1,
+ GslRing *head2)
+{
+ GslRing *tail1, *tail2;
+
+ if (!head1)
+ return head2;
+ if (!head2)
+ return head1;
+ tail1 = head1->prev;
+ tail2 = head2->prev;
+ head1->prev = tail2;
+ tail2->next = head1;
+ head2->prev = tail1;
+ tail1->next = head2;
+
+ return head1;
+}
+
+GslRing*
+gsl_ring_remove_node (GslRing *head,
+ GslRing *node)
+{
+ if (!head)
+ g_return_val_if_fail (head == NULL && node == NULL, NULL);
+ if (!head || !node)
+ return NULL;
+
+ /* special case one item ring */
+ if (head->prev == head)
+ {
+ g_return_val_if_fail (node == head, head);
+
+ gsl_delete_struct (GslRing, node);
+ return NULL;
+ }
+ g_return_val_if_fail (node != node->next, head); /* node can't be a one item ring here */
+
+ node->next->prev = node->prev;
+ node->prev->next = node->next;
+ if (head == node)
+ head = node->next;
+ gsl_delete_struct (GslRing, node);
+
+ return head;
+}
+
+GslRing*
+gsl_ring_remove (GslRing *head,
+ gpointer data)
+{
+ GslRing *walk;
+
+ if (!head)
+ return NULL;
+
+ /* make tail data removal an O(1) operation */
+ if (head->prev->data == data)
+ return gsl_ring_remove_node (head, head->prev);
+
+ for (walk = head; walk; walk = gsl_ring_walk (head, walk))
+ if (walk->data == data)
+ return gsl_ring_remove_node (head, walk);
+
+ g_warning (G_STRLOC ": couldn't find data item (%p) to remove from ring (%p)", data, head);
+
+ return head;
+}
+
+guint
+gsl_ring_length (GslRing *head)
+{
+ GslRing *ring;
+ guint i = 0;
+
+ for (ring = head; ring; ring = gsl_ring_walk (head, ring))
+ i++;
+
+ return i;
+}
+
+GslRing*
+gsl_ring_find (GslRing *head,
+ gconstpointer data)
+{
+ GslRing *ring;
+
+ for (ring = head; ring; ring = gsl_ring_walk (head, ring))
+ if (ring->data == (gpointer) data)
+ return ring;
+
+ return NULL;
+}
+
+GslRing*
+gsl_ring_nth (GslRing *head,
+ guint n)
+{
+ GslRing *ring = head;
+
+ while (n-- && ring)
+ ring = gsl_ring_walk (head, ring);
+
+ return ring;
+}
+
+gpointer
+gsl_ring_nth_data (GslRing *head,
+ guint n)
+{
+ GslRing *ring = head;
+
+ while (n-- && ring)
+ ring = gsl_ring_walk (head, ring);
+
+ return ring ? ring->data : ring;
+}
+
+void
+gsl_ring_free (GslRing *head)
+{
+ if (head)
+ {
+ head->prev->next = NULL;
+ gsl_free_node_list (head, sizeof (*head));
+ }
+}
+
+gpointer
+gsl_ring_pop_head (GslRing **head_p)
+{
+ gpointer data;
+
+ g_return_val_if_fail (head_p != NULL, NULL);
+
+ if (!*head_p)
+ return NULL;
+ data = (*head_p)->data;
+ *head_p = gsl_ring_remove_node (*head_p, *head_p);
+
+ return data;
+}
+
+gpointer
+gsl_ring_pop_tail (GslRing **head_p)
+{
+ gpointer data;
+
+ g_return_val_if_fail (head_p != NULL, NULL);
+
+ if (!*head_p)
+ return NULL;
+ data = (*head_p)->prev->data;
+ *head_p = gsl_ring_remove_node (*head_p, (*head_p)->prev);
+
+ return data;
+}
+
+GslRing*
+gsl_ring_insert_sorted (GslRing *head,
+ gpointer data,
+ GCompareFunc func)
+{
+ gint cmp;
+
+ g_return_val_if_fail (func != NULL, head);
+
+ if (!head)
+ return gsl_ring_prepend (head, data);
+
+ /* typedef gint (*GCompareFunc) (gconstpointer a,
+ * gconstpointer b);
+ */
+ cmp = func (data, head->data);
+
+ if (cmp >= 0) /* insert after head */
+ {
+ GslRing *tmp, *tail = head->prev;
+
+ /* make appending an O(1) operation */
+ if (head == tail || func (data, tail->data) >= 0)
+ return gsl_ring_append (head, data);
+
+ /* walk forward while data >= tmp (skipping equal nodes) */
+ for (tmp = head->next; tmp != tail; tmp = tmp->next)
+ if (func (data, tmp->data) < 0)
+ break;
+
+ /* insert before sibling which is greater than data */
+ gsl_ring_prepend (tmp, data); /* keep current head */
+ return head;
+ }
+ else /* cmp < 0 */
+ return gsl_ring_prepend (head, data);
+}
+
+
+/* --- GslThread --- */
+typedef struct
+{
+ GslThreadFunc func;
+ gpointer data;
+ gint wpipe[2];
+ volatile gint abort;
+ guint64 awake_stamp;
+ GslDebugFlags auxlog_reporter;
+ const gchar *auxlog_section;
+} ThreadData;
+static GslMutex global_thread = { 0, };
+static GslRing *global_thread_list = NULL;
+static GslCond global_thread_cond = { 0, };
+static GslRing *awake_tdata_list = NULL;
+static ThreadData *main_thread_tdata = NULL;
+static GslThread *main_thread = NULL;
+
+static inline ThreadData*
+thread_data_from_gsl_thread (GslThread *thread)
+{
+ GThread *gthread = (GThread*) thread;
+
+ /* if gthread->data==NULL, we assume this is the main thread */
+
+ return gthread->data ? gthread->data : main_thread_tdata;
+}
+
+static gpointer
+thread_wrapper (gpointer arg)
+{
+ GslThread *self = gsl_thread_self ();
+ ThreadData *tdata = arg;
+
+ g_assert (tdata == thread_data_from_gsl_thread (gsl_thread_self ()));
+
+ GSL_SYNC_LOCK (&global_thread);
+ global_thread_list = gsl_ring_prepend (global_thread_list, self);
+ gsl_cond_broadcast (&global_thread_cond);
+ GSL_SYNC_UNLOCK (&global_thread);
+
+ tdata->func (tdata->data);
+
+ GSL_SYNC_LOCK (&global_thread);
+ global_thread_list = gsl_ring_remove (global_thread_list, self);
+ if (tdata->awake_stamp)
+ awake_tdata_list = gsl_ring_remove (awake_tdata_list, tdata);
+ gsl_cond_broadcast (&global_thread_cond);
+ GSL_SYNC_UNLOCK (&global_thread);
+
+ close (tdata->wpipe[0]);
+ tdata->wpipe[0] = -1;
+ close (tdata->wpipe[1]);
+ tdata->wpipe[1] = -1;
+ gsl_delete_struct (ThreadData, tdata);
+
+ return NULL;
+}
+
+static ThreadData*
+create_tdata (void)
+{
+ ThreadData *tdata;
+ glong d_long;
+ gint error;
+
+ tdata = gsl_new_struct0 (ThreadData, 1);
+ tdata->func = NULL;
+ tdata->data = NULL;
+ tdata->wpipe[0] = -1;
+ tdata->wpipe[1] = -1;
+ tdata->abort = FALSE;
+ tdata->auxlog_reporter = 0;
+ tdata->auxlog_section = NULL;
+ error = pipe (tdata->wpipe);
+ if (error == 0)
+ {
+ d_long = fcntl (tdata->wpipe[0], F_GETFL, 0);
+ /* g_printerr ("pipe-readfd, blocking=%ld\n", d_long & O_NONBLOCK); */
+ d_long |= O_NONBLOCK;
+ error = fcntl (tdata->wpipe[0], F_SETFL, d_long);
+ }
+ if (error == 0)
+ {
+ d_long = fcntl (tdata->wpipe[1], F_GETFL, 0);
+ /* g_printerr ("pipe-writefd, blocking=%ld\n", d_long & O_NONBLOCK); */
+ d_long |= O_NONBLOCK;
+ error = fcntl (tdata->wpipe[1], F_SETFL, d_long);
+ }
+ if (error)
+ {
+ close (tdata->wpipe[0]);
+ close (tdata->wpipe[1]);
+ gsl_delete_struct (ThreadData, tdata);
+ tdata = NULL;
+ }
+ return tdata;
+}
+
+GslThread*
+gsl_thread_new (GslThreadFunc func,
+ gpointer user_data)
+{
+ gpointer gthread = NULL;
+ ThreadData *tdata;
+ GError *gerror = NULL;
+
+ g_return_val_if_fail (func != NULL, FALSE);
+
+ tdata = create_tdata ();
+
+ if (tdata)
+ {
+ const gboolean joinable = FALSE;
+
+ /* don't dare setting joinable to TRUE, that prevents the thread's
+ * resources from being freed, since we don't offer pthread_join().
+ * so we'd just rn out of stack at some point.
+ */
+ tdata->func = func;
+ tdata->data = user_data;
+ gthread = g_thread_create_full (thread_wrapper, tdata, 0, joinable, FALSE,
+ G_THREAD_PRIORITY_NORMAL, &gerror);
+ }
+
+ if (gthread)
+ {
+ GSL_SYNC_LOCK (&global_thread);
+ while (!gsl_ring_find (global_thread_list, gthread))
+ gsl_cond_wait (&global_thread_cond, &global_thread);
+ GSL_SYNC_UNLOCK (&global_thread);
+ }
+ else
+ {
+ if (tdata)
+ {
+ close (tdata->wpipe[0]);
+ close (tdata->wpipe[1]);
+ gsl_delete_struct (ThreadData, tdata);
+ }
+ g_warning ("Failed to create thread: %s", gerror->message);
+ g_error_free (gerror);
+ }
+
+ return gthread;
+}
+
+GslThread*
+gsl_thread_self (void)
+{
+ gpointer gthread = g_thread_self ();
+
+ if (!gthread)
+ g_error ("gsl_thread_self() failed");
+
+ return gthread;
+}
+
+GslThread*
+gsl_thread_main (void)
+{
+ return main_thread;
+}
+
+guint
+gsl_threads_get_count (void)
+{
+ guint count;
+
+ GSL_SYNC_LOCK (&global_thread);
+ count = gsl_ring_length (global_thread_list);
+ GSL_SYNC_UNLOCK (&global_thread);
+
+ return count;
+}
+
+static void
+thread_wakeup_I (ThreadData *tdata)
+{
+ guint8 data = 'W';
+ gint r;
+
+ do
+ r = write (tdata->wpipe[1], &data, 1);
+ while (r < 0 && (errno == EINTR || errno == ERESTART));
+}
+
+/**
+ * gsl_thread_wakeup
+ * @thread: thread to wake up
+ * Wake up a currently sleeping thread. In practice, this
+ * function simply causes the next call to gsl_thread_sleep()
+ * within @thread to last for 0 seconds.
+ */
+void
+gsl_thread_wakeup (GslThread *thread)
+{
+ ThreadData *tdata;
+
+ g_return_if_fail (thread != NULL);
+
+ GSL_SYNC_LOCK (&global_thread);
+ g_assert (gsl_ring_find (global_thread_list, thread));
+ GSL_SYNC_UNLOCK (&global_thread);
+
+ tdata = thread_data_from_gsl_thread (thread);
+ thread_wakeup_I (tdata);
+}
+
+/**
+ * gsl_thread_abort
+ * @thread: thread to abort
+ * Abort a currently running thread. This function does not
+ * return until the thread in question terminated execution.
+ * Note that the thread handle gets invalidated with invocation
+ * of gsl_thread_abort() or gsl_thread_queue_abort().
+ */
+void
+gsl_thread_abort (GslThread *thread)
+{
+ ThreadData *tdata;
+
+ g_return_if_fail (thread != NULL);
+ g_return_if_fail (thread != main_thread);
+
+ GSL_SYNC_LOCK (&global_thread);
+ g_assert (gsl_ring_find (global_thread_list, thread));
+ GSL_SYNC_UNLOCK (&global_thread);
+
+ tdata = thread_data_from_gsl_thread (thread);
+
+ GSL_SYNC_LOCK (&global_thread);
+ tdata->abort = TRUE;
+ thread_wakeup_I (tdata);
+
+ while (gsl_ring_find (global_thread_list, thread))
+ gsl_cond_wait (&global_thread_cond, &global_thread);
+ GSL_SYNC_UNLOCK (&global_thread);
+}
+
+/**
+ * gsl_thread_queue_abort
+ * @thread: thread to abort
+ * Same as gsl_thread_abort(), but returns as soon as possible,
+ * even if thread hasn't stopped execution yet.
+ * Note that the thread handle gets invalidated with invocation
+ * of gsl_thread_abort() or gsl_thread_queue_abort().
+ */
+void
+gsl_thread_queue_abort (GslThread *thread)
+{
+ ThreadData *tdata;
+
+ g_return_if_fail (thread != NULL);
+ g_return_if_fail (thread != main_thread);
+
+ GSL_SYNC_LOCK (&global_thread);
+ g_assert (gsl_ring_find (global_thread_list, thread));
+ GSL_SYNC_UNLOCK (&global_thread);
+
+ tdata = thread_data_from_gsl_thread (thread);
+
+ GSL_SYNC_LOCK (&global_thread);
+ tdata->abort = TRUE;
+ thread_wakeup_I (tdata);
+ GSL_SYNC_UNLOCK (&global_thread);
+}
+
+/**
+ * gsl_thread_aborted
+ * @returns: %TRUE if the thread should abort execution
+ * Find out if the currently running thread should be aborted (the thread is
+ * supposed to return from its main thread function).
+ */
+gboolean
+gsl_thread_aborted (void)
+{
+ ThreadData *tdata = thread_data_from_gsl_thread (gsl_thread_self ());
+ gboolean aborted;
+
+ GSL_SYNC_LOCK (&global_thread);
+ aborted = tdata->abort != FALSE;
+ GSL_SYNC_UNLOCK (&global_thread);
+
+ return aborted;
+}
+
+/**
+ * gsl_thread_sleep
+ * @max_msec: maximum amount of milli seconds to sleep (-1 for infinite time)
+ * @returns: %TRUE if the thread should continue execution
+ * Sleep for the amount of time given. This function may get interrupted
+ * by wakeup or abort requests, it returns whether the thread is supposed
+ * to continue execution after waking up. This function also processes
+ * remaining data from the thread's poll fd.
+ */
+gboolean
+gsl_thread_sleep (glong max_msec)
+{
+ ThreadData *tdata = thread_data_from_gsl_thread (gsl_thread_self ());
+ struct pollfd pfd;
+ gint r, aborted;
+
+ pfd.fd = tdata->wpipe[0];
+ pfd.events = G_IO_IN;
+ pfd.revents = 0;
+
+ r = poll (&pfd, 1, max_msec);
+
+ if (r < 0 && errno != EINTR)
+ g_message (G_STRLOC ": poll() error: %s\n", g_strerror (errno));
+ else if (pfd.revents & G_IO_IN)
+ {
+ guint8 data[64];
+
+ do
+ r = read (tdata->wpipe[0], data, sizeof (data));
+ while ((r < 0 && (errno == EINTR || errno == ERESTART)) || r == sizeof (data));
+ }
+
+ GSL_SYNC_LOCK (&global_thread);
+ aborted = tdata->abort != FALSE;
+ GSL_SYNC_UNLOCK (&global_thread);
+
+ return !aborted;
+}
+
+/**
+ * gsl_thread_awake_after
+ * RETURNS: GPollFD for the current thread
+ * Get the GPollfd for the current thread which is used
+ * to signal thread wakeups (e.g. due to
+ * gsl_thread_abort() or gsl_thread_wakeup()).
+ */
+void
+gsl_thread_get_pollfd (GPollFD *pfd)
+{
+ ThreadData *tdata = thread_data_from_gsl_thread (gsl_thread_self ());
+
+ pfd->fd = tdata->wpipe[0];
+ pfd->events = G_IO_IN;
+ pfd->revents = 0;
+}
+
+/**
+ * gsl_thread_awake_after
+ * @tick_stamp: tick stamp update to trigger wakeup
+ * Wakeup the currently running thread after the global tick stamp
+ * (see gsl_tick_stamp()) has been updated to @tick_stamp.
+ * (If the moment of wakeup has already passed by, the thread is
+ * woken up at the next global tick stamp update.)
+ */
+void
+gsl_thread_awake_after (guint64 tick_stamp)
+{
+ ThreadData *tdata = thread_data_from_gsl_thread (gsl_thread_self ());
+
+ g_return_if_fail (tick_stamp > 0);
+
+ GSL_SYNC_LOCK (&global_thread);
+ if (!tdata->awake_stamp)
+ {
+ awake_tdata_list = gsl_ring_prepend (awake_tdata_list, tdata);
+ tdata->awake_stamp = tick_stamp;
+ }
+ else
+ tdata->awake_stamp = MIN (tdata->awake_stamp, tick_stamp);
+ GSL_SYNC_UNLOCK (&global_thread);
+}
+
+/**
+ * gsl_thread_awake_before
+ * @tick_stamp: tick stamp update to trigger wakeup
+ * Wakeup the currently running thread upon the last global tick stamp
+ * update (see gsl_tick_stamp()) that happens prior to updating the
+ * global tick stamp to @tick_stamp.
+ * (If the moment of wakeup has already passed by, the thread is
+ * woken up at the next global tick stamp update.)
+ */
+void
+gsl_thread_awake_before (guint64 tick_stamp)
+{
+ g_return_if_fail (tick_stamp > 0);
+
+ if (tick_stamp > global_tick_stamp_leaps)
+ gsl_thread_awake_after (tick_stamp - global_tick_stamp_leaps);
+ else
+ gsl_thread_awake_after (tick_stamp);
+}
+
+/**
+ * gsl_tick_stamp
+ * @RETURNS: GSL's execution tick stamp as unsigned 64bit integer
+ *
+ * Retrive the GSL global tick stamp.
+ * GSL increments its global tick stamp at certain intervals,
+ * by specific amounts (refer to gsl_engine_init() for further
+ * details). The tick stamp is a non-wrapping, unsigned 64bit
+ * integer greater than 0. Threads can schedule sleep interruptions
+ * at certain tick stamps with gsl_thread_awake_after() and
+ * gsl_thread_awake_before(). Tick stamp updating occours at
+ * GSL engine block processing boundaries, so code that can
+ * guarantee to not run across those boundaries (for instance
+ * GslProcessFunc() functions) may use the macro %GSL_TICK_STAMP
+ * to retrive the current tick in a faster manner (not involving
+ * mutex locking). See also gsl_module_tick_stamp().
+ * This function is MT-safe and may be called from any thread.
+ */
+guint64
+gsl_tick_stamp (void)
+{
+ guint64 stamp;
+
+ GSL_SYNC_LOCK (&global_thread);
+ stamp = gsl_externvar_tick_stamp;
+ GSL_SYNC_UNLOCK (&global_thread);
+
+ return stamp;
+}
+
+void
+_gsl_tick_stamp_set_leap (guint ticks)
+{
+ GSL_SYNC_LOCK (&global_thread);
+ global_tick_stamp_leaps = ticks;
+ GSL_SYNC_UNLOCK (&global_thread);
+}
+
+/**
+ * gsl_time_system
+ * @RETURNS: Current system time in micro seconds
+ *
+ * Get the current system time in micro seconds.
+ * Subsequent calls to this function do not necessarily
+ * return growing values. In fact, a second call may return
+ * a value smaller than the first call under certainsystem
+ * conditions.
+ * This function is MT-safe and may be called from any thread.
+ */
+guint64
+gsl_time_system (void)
+{
+ struct timeval tv;
+ guint64 csys_time;
+ gint error;
+
+ error = gettimeofday (&tv, NULL);
+ if (error)
+ g_error ("gettimeofday() failed: %s", g_strerror (errno));
+ csys_time = tv.tv_sec;
+ csys_time = csys_time * 1000000 + tv.tv_usec;
+
+ return csys_time;
+}
+
+/**
+ * gsl_tick_stamp_last
+ * @RETURNS: Current tick stamp and system time in micro seconds
+ *
+ * Get the system time of the last GSL global tick stamp update.
+ * This function is MT-safe and may be called from any thread.
+ */
+GslTickStampUpdate
+gsl_tick_stamp_last (void)
+{
+ GslTickStampUpdate ustamp;
+
+ GSL_SYNC_LOCK (&global_thread);
+ ustamp.tick_stamp = gsl_externvar_tick_stamp;
+ ustamp.system_time = tick_stamp_system_time;
+ GSL_SYNC_UNLOCK (&global_thread);
+
+ return ustamp;
+}
+
+void
+_gsl_tick_stamp_inc (void)
+{
+ volatile guint64 newstamp;
+ GslRing *ring;
+ guint64 systime;
+
+ g_return_if_fail (global_tick_stamp_leaps > 0);
+
+ systime = gsl_time_system ();
+ newstamp = gsl_externvar_tick_stamp + global_tick_stamp_leaps;
+
+ GSL_SYNC_LOCK (&global_thread);
+ gsl_externvar_tick_stamp = newstamp;
+ tick_stamp_system_time = systime;
+ for (ring = awake_tdata_list; ring; )
+ {
+ ThreadData *tdata = ring->data;
+
+ if (tdata->awake_stamp <= GSL_TICK_STAMP)
+ {
+ GslRing *next = gsl_ring_walk (awake_tdata_list, ring);
+
+ tdata->awake_stamp = 0;
+ awake_tdata_list = gsl_ring_remove (awake_tdata_list, tdata);
+
+ thread_wakeup_I (tdata);
+ ring = next;
+ }
+ else
+ ring = gsl_ring_walk (awake_tdata_list, ring);
+ }
+ GSL_SYNC_UNLOCK (&global_thread);
+}
+
+
+/* --- GslMutex --- */
+static gboolean is_smp_system = FALSE;
+
+static void
+default_mutex_init (GslMutex *mutex)
+{
+ g_return_if_fail (mutex != NULL);
+
+ mutex->mutex_pointer = g_mutex_new ();
+}
+
+static int
+default_mutex_trylock (GslMutex *mutex)
+{
+ return g_mutex_trylock (mutex->mutex_pointer) ? 0 : -1;
+}
+
+static void
+default_mutex_lock (GslMutex *mutex)
+{
+ /* spin locks should be held only very short times,
+ * so frequently we should succeed here
+ */
+ if (g_mutex_trylock (mutex->mutex_pointer))
+ return;
+
+ if (!is_smp_system)
+ {
+ /* on uni processor systems, there's no point in busy spinning */
+ do
+ {
+#if defined(_POSIX_PRIORITY_SCHEDULING)
+ sched_yield ();
+#endif
+ if (g_mutex_trylock (mutex->mutex_pointer))
+ return;
+ }
+ while (TRUE);
+ }
+ else
+ {
+ /* for multi processor systems, mutex_lock() is hopefully implemented
+ * via spinning. note that we can't implement spinning ourselves with
+ * mutex_trylock(), since on some architectures that'd block memory
+ * bandwith due to constant bus locks
+ */
+ g_mutex_lock (mutex->mutex_pointer);
+ }
+}
+
+static void
+default_mutex_unlock (GslMutex *mutex)
+{
+ g_mutex_unlock (mutex->mutex_pointer);
+}
+
+static void
+default_mutex_destroy (GslMutex *mutex)
+{
+ g_mutex_free (mutex->mutex_pointer);
+ memset (mutex, 0, sizeof (*mutex));
+}
+
+static void
+default_rec_mutex_init (GslRecMutex *rec_mutex)
+{
+ rec_mutex->depth = 0;
+ rec_mutex->owner = NULL;
+ gsl_mutex_init (&rec_mutex->sync_mutex);
+}
+
+static int
+default_rec_mutex_trylock (GslRecMutex *rec_mutex)
+{
+ gpointer self = gsl_thread_self ();
+
+ if (rec_mutex->owner == self)
+ {
+ g_assert (rec_mutex->depth > 0); /* paranoid */
+ rec_mutex->depth += 1;
+ return 0;
+ }
+ else
+ {
+ if (gsl_mutex_trylock (&rec_mutex->sync_mutex))
+ {
+ g_assert (rec_mutex->owner == NULL && rec_mutex->depth == 0); /* paranoid */
+ rec_mutex->owner = self;
+ rec_mutex->depth = 1;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+static void
+default_rec_mutex_lock (GslRecMutex *rec_mutex)
+{
+ gpointer self = gsl_thread_self ();
+
+ if (rec_mutex->owner == self)
+ {
+ g_assert (rec_mutex->depth > 0); /* paranoid */
+ rec_mutex->depth += 1;
+ }
+ else
+ {
+ GSL_SYNC_LOCK (&rec_mutex->sync_mutex);
+ g_assert (rec_mutex->owner == NULL && rec_mutex->depth == 0); /* paranoid */
+ rec_mutex->owner = self;
+ rec_mutex->depth = 1;
+ }
+}
+
+static void
+default_rec_mutex_unlock (GslRecMutex *rec_mutex)
+{
+ gpointer self = gsl_thread_self ();
+
+ if (rec_mutex->owner == self && rec_mutex->depth > 0)
+ {
+ rec_mutex->depth -= 1;
+ if (!rec_mutex->depth)
+ {
+ rec_mutex->owner = NULL;
+ GSL_SYNC_UNLOCK (&rec_mutex->sync_mutex);
+ }
+ }
+ else
+ g_warning ("unable to unlock recursive mutex with self %p != %p or depth %u < 1",
+ rec_mutex->owner, self, rec_mutex->depth);
+}
+
+static void
+default_rec_mutex_destroy (GslRecMutex *rec_mutex)
+{
+ if (rec_mutex->owner || rec_mutex->depth)
+ {
+ g_warning (G_STRLOC ": recursive mutex still locked during destruction");
+ return;
+ }
+ gsl_mutex_destroy (&rec_mutex->sync_mutex);
+ g_assert (rec_mutex->owner == NULL && rec_mutex->depth == 0);
+}
+
+static void
+default_cond_init (GslCond *cond)
+{
+ cond->cond_pointer = g_cond_new ();
+}
+
+static void
+default_cond_wait (GslCond *cond,
+ GslMutex *mutex)
+{
+ /* infinite wait */
+ g_cond_wait (cond->cond_pointer, mutex->mutex_pointer);
+}
+
+static void
+default_cond_signal (GslCond *cond)
+{
+ g_cond_signal (cond->cond_pointer);
+}
+
+static void
+default_cond_broadcast (GslCond *cond)
+{
+ g_cond_broadcast (cond->cond_pointer);
+}
+
+static void
+default_cond_destroy (GslCond *cond)
+{
+ g_cond_free (cond->cond_pointer);
+}
+
+static void
+default_cond_wait_timed (GslCond *cond,
+ GslMutex *mutex,
+ gulong abs_secs,
+ gulong abs_usecs)
+{
+ GTimeVal gtime;
+
+ gtime.tv_sec = abs_secs;
+ gtime.tv_usec = abs_usecs;
+ g_cond_timed_wait (cond->cond_pointer, mutex->mutex_pointer, &gtime);
+}
+
+GslMutexTable gsl_mutex_table = {
+ default_mutex_init,
+ default_mutex_lock,
+ default_mutex_trylock,
+ default_mutex_unlock,
+ default_mutex_destroy,
+ default_rec_mutex_init,
+ default_rec_mutex_lock,
+ default_rec_mutex_trylock,
+ default_rec_mutex_unlock,
+ default_rec_mutex_destroy,
+ default_cond_init,
+ default_cond_signal,
+ default_cond_broadcast,
+ default_cond_wait,
+ default_cond_wait_timed,
+ default_cond_destroy,
+};
+
+void
+gsl_cond_wait_timed (GslCond *cond,
+ GslMutex *mutex,
+ glong max_useconds)
+{
+ if (max_useconds < 0)
+ gsl_cond_wait (cond, mutex);
+ else
+ {
+ struct timeval now;
+ glong secs;
+
+ gettimeofday (&now, NULL);
+ secs = max_useconds / 1000000;
+ now.tv_sec += secs;
+ max_useconds -= secs * 1000000;
+ now.tv_usec += max_useconds;
+ if (now.tv_usec >= 1000000)
+ {
+ now.tv_usec -= 1000000;
+ now.tv_sec += 1;
+ }
+
+ /* linux on x86 with pthread has actually 10ms resolution */
+ gsl_mutex_table.cond_wait_timed (cond, mutex, now.tv_sec, now.tv_usec);
+ }
+}
+
+
+/* --- GslMessage --- */
+const gchar*
+gsl_strerror (GslErrorType error)
+{
+ switch (error)
+ {
+ case GSL_ERROR_NONE: return "Everything went well";
+ case GSL_ERROR_INTERNAL: return "Internal error (please report)";
+ case GSL_ERROR_UNKNOWN: return "Unknown error";
+ case GSL_ERROR_IO: return "I/O error";
+ case GSL_ERROR_PERMS: return "Insufficient permission";
+ case GSL_ERROR_BUSY: return "Resource currently busy";
+ case GSL_ERROR_EXISTS: return "Resource exists already";
+ case GSL_ERROR_TEMP: return "Temporary error";
+ case GSL_ERROR_EOF: return "File empty or premature EOF";
+ case GSL_ERROR_NOT_FOUND: return "Resource not found";
+ case GSL_ERROR_OPEN_FAILED: return "Open failed";
+ case GSL_ERROR_SEEK_FAILED: return "Seek failed";
+ case GSL_ERROR_READ_FAILED: return "Read failed";
+ case GSL_ERROR_WRITE_FAILED: return "Write failed";
+ case GSL_ERROR_FORMAT_INVALID: return "Invalid format";
+ case GSL_ERROR_FORMAT_UNKNOWN: return "Unknown format";
+ case GSL_ERROR_DATA_CORRUPT: return "Data corrupt";
+ case GSL_ERROR_CONTENT_GLITCH: return "Data glitch (junk) detected";
+ case GSL_ERROR_NO_RESOURCE: return "Out of memory, disk space or similar resource";
+ case GSL_ERROR_CODEC_FAILURE: return "CODEC failure";
+ default: return NULL;
+ }
+}
+
+static const GDebugKey gsl_static_debug_keys[] = {
+ { "notify", GSL_MSG_NOTIFY },
+ { "dcache", GSL_MSG_DATA_CACHE },
+ { "dhandle", GSL_MSG_DATA_HANDLE },
+ { "loader", GSL_MSG_LOADER },
+ { "osc", GSL_MSG_OSC },
+ { "engine", GSL_MSG_ENGINE },
+ { "jobs", GSL_MSG_JOBS },
+ { "fjobs", GSL_MSG_FJOBS },
+ { "sched", GSL_MSG_SCHED },
+ { "master", GSL_MSG_MASTER },
+ { "slave", GSL_MSG_SLAVE },
+};
+
+static const gchar*
+reporter_name (GslDebugFlags reporter)
+{
+ switch (reporter)
+ {
+ case GSL_MSG_NOTIFY: return "Notify";
+ case GSL_MSG_DATA_CACHE: return "DataCache";
+ case GSL_MSG_DATA_HANDLE: return "DataHandle";
+ case GSL_MSG_LOADER: return "Loader";
+ case GSL_MSG_OSC: return "Oscillator";
+ case GSL_MSG_ENGINE: return "Engine"; /* Engine */
+ case GSL_MSG_JOBS: return "Jobs"; /* Engine */
+ case GSL_MSG_FJOBS: return "FlowJobs"; /* Engine */
+ case GSL_MSG_SCHED: return "Sched"; /* Engine */
+ case GSL_MSG_MASTER: return "Master"; /* Engine */
+ case GSL_MSG_SLAVE: return "Slave"; /* Engine */
+ default: return "Custom";
+ }
+}
+
+const GDebugKey *gsl_debug_keys = gsl_static_debug_keys;
+const guint gsl_n_debug_keys = G_N_ELEMENTS (gsl_static_debug_keys);
+
+void
+gsl_message_send (GslDebugFlags reporter,
+ const gchar *section,
+ GslErrorType error,
+ const gchar *messagef,
+ ...)
+{
+ struct {
+ GslDebugFlags reporter;
+ gchar reporter_name[64];
+ gchar section[64]; /* auxillary information about reporter code portion */
+ GslErrorType error;
+ const gchar *error_str; /* gsl_strerror() of error */
+ gchar message[1024];
+ } tmsg, *msg = &tmsg;
+ gchar *string;
+ va_list args;
+
+ g_return_if_fail (messagef != NULL);
+
+ /* create message */
+ memset (msg, 0, sizeof (*msg));
+ msg->reporter = reporter;
+ strncpy (msg->reporter_name, reporter_name (msg->reporter), 63);
+ if (section)
+ strncpy (msg->section, section, 63);
+ msg->error = error;
+ msg->error_str = error ? gsl_strerror (msg->error) : NULL;
+
+ /* vsnprintf() replacement */
+ va_start (args, messagef);
+ string = g_strdup_vprintf (messagef, args);
+ va_end (args);
+ strncpy (msg->message, string, 1023);
+ g_free (string);
+
+ /* in current lack of a decent message queue, puke the message to stderr */
+ g_printerr ("GSL-%s%s%s: %s%s%s\n",
+ msg->reporter_name,
+ msg->section ? ":" : "",
+ msg->section ? msg->section : "",
+ msg->message,
+ msg->error_str ? ": " : "",
+ msg->error_str ? msg->error_str : "");
+}
+
+void
+gsl_debug_enable (GslDebugFlags dbg_flags)
+{
+ gsl_debug_flags |= dbg_flags;
+}
+
+void
+gsl_debug_disable (GslDebugFlags dbg_flags)
+{
+ gsl_debug_flags &= dbg_flags;
+}
+
+gboolean
+gsl_debug_check (GslDebugFlags dbg_flags)
+{
+ return (gsl_debug_flags & dbg_flags) != 0;
+}
+
+void
+gsl_debug (GslDebugFlags reporter,
+ const gchar *section,
+ const gchar *format,
+ ...)
+{
+ g_return_if_fail (format != NULL);
+
+ if (reporter & gsl_debug_flags)
+ {
+ va_list args;
+ gchar *string;
+
+ va_start (args, format);
+ string = g_strdup_vprintf (format, args);
+ va_end (args);
+ g_printerr ("DEBUG:GSL-%s%s%s: %s\n",
+ reporter_name (reporter),
+ section ? ":" : "",
+ section ? section : "",
+ string);
+ g_free (string);
+ }
+}
+
+void
+gsl_auxlog_push (GslDebugFlags reporter,
+ const gchar *section)
+{
+ ThreadData *tdata = thread_data_from_gsl_thread (gsl_thread_self ());
+
+ if (tdata)
+ {
+ tdata->auxlog_reporter = reporter;
+ tdata->auxlog_section = section;
+ }
+}
+
+void
+gsl_auxlog_debug (const gchar *format,
+ ...)
+{
+ ThreadData *tdata = thread_data_from_gsl_thread (gsl_thread_self ());
+ GslDebugFlags reporter = GSL_MSG_NOTIFY;
+ const gchar *section = NULL;
+ va_list args;
+ gchar *string;
+
+ if (tdata)
+ {
+ reporter = tdata->auxlog_reporter;
+ section = tdata->auxlog_section;
+ tdata->auxlog_reporter = 0;
+ tdata->auxlog_section = NULL;
+ }
+
+ g_return_if_fail (format != NULL);
+
+ va_start (args, format);
+ string = g_strdup_vprintf (format, args);
+ va_end (args);
+ gsl_debug (reporter, section, "%s", string);
+ g_free (string);
+}
+
+void
+gsl_auxlog_message (GslErrorType error,
+ const gchar *format,
+ ...)
+{
+ ThreadData *tdata = thread_data_from_gsl_thread (gsl_thread_self ());
+ GslDebugFlags reporter = GSL_MSG_NOTIFY;
+ const gchar *section = NULL;
+ va_list args;
+ gchar *string;
+
+ if (tdata)
+ {
+ reporter = tdata->auxlog_reporter;
+ section = tdata->auxlog_section;
+ tdata->auxlog_reporter = 0;
+ tdata->auxlog_section = NULL;
+ }
+
+ g_return_if_fail (format != NULL);
+
+ va_start (args, format);
+ string = g_strdup_vprintf (format, args);
+ va_end (args);
+ gsl_message_send (reporter, section, error, "%s", string);
+ g_free (string);
+}
+
+
+/* --- misc --- */
+const gchar*
+gsl_byte_order_to_string (guint byte_order)
+{
+ g_return_val_if_fail (byte_order == G_LITTLE_ENDIAN || byte_order == G_BIG_ENDIAN, NULL);
+
+ if (byte_order == G_LITTLE_ENDIAN)
+ return "little_endian";
+ if (byte_order == G_BIG_ENDIAN)
+ return "big_endian";
+
+ return NULL;
+}
+
+guint
+gsl_byte_order_from_string (const gchar *string)
+{
+ g_return_val_if_fail (string != NULL, 0);
+
+ while (*string == ' ')
+ string++;
+ if (strncasecmp (string, "little", 6) == 0)
+ return G_LITTLE_ENDIAN;
+ if (strncasecmp (string, "big", 3) == 0)
+ return G_BIG_ENDIAN;
+ return 0;
+}
+
+GslErrorType
+gsl_check_file (const gchar *file_name,
+ const gchar *mode)
+{
+ guint access_mask = 0;
+ guint check_file, check_dir, check_link;
+
+ if (strchr (mode, 'r')) /* readable */
+ access_mask |= R_OK;
+ if (strchr (mode, 'w')) /* writable */
+ access_mask |= W_OK;
+ if (strchr (mode, 'x')) /* executable */
+ access_mask |= X_OK;
+
+ if (access_mask && access (file_name, access_mask) < 0)
+ goto have_errno;
+
+ check_file = strchr (mode, 'f') != NULL; /* open as file */
+ check_dir = strchr (mode, 'd') != NULL; /* open as directory */
+ check_link = strchr (mode, 'l') != NULL; /* open as link */
+
+ if (check_file || check_dir || check_link)
+ {
+ struct stat st;
+
+ if (check_link)
+ {
+ if (lstat (file_name, &st) < 0)
+ goto have_errno;
+ }
+ else if (stat (file_name, &st) < 0)
+ goto have_errno;
+
+ if ((check_file && !S_ISREG (st.st_mode)) ||
+ (check_dir && !S_ISDIR (st.st_mode)) ||
+ (check_link && !S_ISLNK (st.st_mode)))
+ return GSL_ERROR_OPEN_FAILED;
+ }
+
+ return GSL_ERROR_NONE;
+
+ have_errno:
+ return gsl_error_from_errno (errno, GSL_ERROR_OPEN_FAILED);
+}
+
+GslErrorType
+gsl_error_from_errno (gint sys_errno,
+ GslErrorType fallback)
+{
+ switch (sys_errno)
+ {
+ case ELOOP:
+ case ENAMETOOLONG:
+ case ENOTDIR:
+ case ENOENT: return GSL_ERROR_NOT_FOUND;
+ case EROFS:
+ case EPERM:
+ case EACCES: return GSL_ERROR_PERMS;
+ case ENOMEM:
+ case ENOSPC:
+ case EFBIG:
+ case ENFILE:
+ case EMFILE: return GSL_ERROR_NO_RESOURCE;
+ case EISDIR:
+ case ESPIPE:
+ case EIO: return GSL_ERROR_IO;
+ case EEXIST: return GSL_ERROR_EXISTS;
+ case ETXTBSY:
+ case EBUSY: return GSL_ERROR_BUSY;
+ case EAGAIN:
+ case EINTR: return GSL_ERROR_TEMP;
+ case EINVAL:
+ case EFAULT:
+ case EBADF: return GSL_ERROR_INTERNAL;
+ default: return fallback;
+ }
+}
+
+
+/* --- global initialization --- */
+static guint
+get_n_processors (void)
+{
+#ifdef _SC_NPROCESSORS_ONLN
+ {
+ gint n = sysconf (_SC_NPROCESSORS_ONLN);
+
+ if (n > 0)
+ return n;
+ }
+#endif
+ return 1;
+}
+
+static const GslConfig *gsl_config = NULL;
+
+const GslConfig*
+gsl_get_config (void)
+{
+ return gsl_config;
+}
+
+#define ROUND(dblval) ((GslLong) ((dblval) + .5))
+
+void
+gsl_init (const GslConfigValue values[],
+ GslMutexTable *mtable)
+{
+ const GslConfigValue *config = values;
+ static GslConfig pconfig = { /* DEFAULTS */
+ 1, /* n_processors */
+ 2, /* wave_chunk_padding */
+ 4, /* wave_chunk_big_pad */
+ 512, /* dcache_block_size */
+ 1024 * 1024, /* dcache_cache_memory */
+ 69, /* midi_kammer_note */
+ 440, /* kammer_freq */
+ };
+
+ g_return_if_fail (gsl_config == NULL); /* assert single initialization */
+
+ /* get mutexes going first */
+ if (mtable)
+ gsl_mutex_table = *mtable;
+
+ gsl_externvar_tick_stamp = 1;
+
+ /* configure permanent config record */
+ if (config)
+ while (config->value_name)
+ {
+ if (strcmp ("wave_chunk_padding", config->value_name) == 0)
+ pconfig.wave_chunk_padding = ROUND (config->value);
+ else if (strcmp ("wave_chunk_big_pad", config->value_name) == 0)
+ pconfig.wave_chunk_big_pad = ROUND (config->value);
+ else if (strcmp ("dcache_cache_memory", config->value_name) == 0)
+ pconfig.dcache_cache_memory = ROUND (config->value);
+ else if (strcmp ("dcache_block_size", config->value_name) == 0)
+ pconfig.dcache_block_size = ROUND (config->value);
+ else if (strcmp ("midi_kammer_note", config->value_name) == 0)
+ pconfig.midi_kammer_note = ROUND (config->value);
+ else if (strcmp ("kammer_freq", config->value_name) == 0)
+ pconfig.kammer_freq = config->value;
+ config++;
+ }
+
+ /* constrain (user) config */
+ pconfig.wave_chunk_padding = MAX (1, pconfig.wave_chunk_padding);
+ pconfig.wave_chunk_big_pad = MAX (2 * pconfig.wave_chunk_padding, pconfig.wave_chunk_big_pad);
+ pconfig.dcache_block_size = MAX (2 * pconfig.wave_chunk_big_pad + sizeof (GslDataType), pconfig.dcache_block_size);
+ pconfig.dcache_block_size = gsl_alloc_upper_power2 (pconfig.dcache_block_size - 1);
+ /* pconfig.dcache_cache_memory = gsl_alloc_upper_power2 (pconfig.dcache_cache_memory); */
+
+ /* non-configurable config updates */
+ pconfig.n_processors = get_n_processors ();
+
+ /* export GSL configuration */
+ gsl_config = &pconfig;
+
+ /* initialize subsystems */
+ is_smp_system = GSL_CONFIG (n_processors) > 1;
+ gsl_mutex_init (&global_memory);
+ gsl_mutex_init (&global_thread);
+ gsl_cond_init (&global_thread_cond);
+ main_thread_tdata = create_tdata ();
+ g_assert (main_thread_tdata != NULL);
+ main_thread = gsl_thread_self ();
+ global_thread_list = gsl_ring_prepend (global_thread_list, main_thread);
+ _gsl_init_signal ();
+ _gsl_init_fd_pool ();
+ _gsl_init_data_caches ();
+ _gsl_init_engine_utils ();
+ _gsl_init_loader_gslwave ();
+ _gsl_init_loader_wav ();
+ _gsl_init_loader_oggvorbis ();
+ _gsl_init_loader_mad ();
+}
diff --git a/flow/gsl/gslcommon.h b/flow/gsl/gslcommon.h
new file mode 100644
index 0000000..6b74c77
--- /dev/null
+++ b/flow/gsl/gslcommon.h
@@ -0,0 +1,293 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001 Tim Janik
+ *
+ * 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.
+ */
+#ifndef __GSL_COMMON_H__
+#define __GSL_COMMON_H__
+
+#include <gsl/gsldefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+
+/* --- global initialization --- */
+typedef struct
+{
+ const char *value_name;
+ double value;
+} GslConfigValue;
+typedef struct
+{
+ guint n_processors;
+ /* # values to pad around wave chunk blocks per channel */
+ guint wave_chunk_padding;
+ guint wave_chunk_big_pad;
+ /* data (file) cache block size (aligned to power of 2) */
+ guint dcache_block_size;
+ /* amount of bytes to spare for memory cache */
+ guint dcache_cache_memory;
+ guint midi_kammer_note;
+ /* kammer frequency, normally 440Hz, historically 435Hz */
+ gfloat kammer_freq;
+} GslConfig;
+typedef struct _GslMutexTable GslMutexTable;
+void gsl_init (const GslConfigValue values[],
+ GslMutexTable *mtable);
+const GslConfig* gsl_get_config (void) G_GNUC_CONST;
+#define GSL_CONFIG(value) ((gsl_get_config () [0]) . value)
+
+
+/* --- memory allocation --- */
+#define gsl_new_struct(type, n) ((type*) gsl_alloc_memblock (sizeof (type) * (n)))
+#define gsl_new_struct0(type, n) ((type*) gsl_alloc_memblock0 (sizeof (type) * (n)))
+#define gsl_delete_struct(type, mem) gsl_delete_structs (type, 1, (mem))
+#ifndef __GNUC__
+# define gsl_delete_structs(type, n, mem) (gsl_free_memblock (sizeof (type) * (n), (mem)))
+#else /* provide typesafety if possible */
+# define gsl_delete_structs(type, n, mem) do { \
+ type *__typed_pointer = (mem); \
+ gsl_free_memblock (sizeof (type) * (n), __typed_pointer); \
+} while(0)
+#endif
+#define GSL_ALIGNED_SIZE(size,align) ((align) > 0 ? _GSL_INTERN_ALIGN (((gsize) (size)), ((gsize) (align))) : (gsize) (size))
+#define _GSL_INTERN_ALIGN(s, a) (((s + (a - 1)) / a) * a)
+#define GSL_STD_ALIGN (MAX (MAX (sizeof (float), sizeof (int)), sizeof (void*)))
+
+
+/* --- ring (circular-list) --- */
+struct _GslRing
+{
+ GslRing *next;
+ GslRing *prev;
+ gpointer data;
+};
+GslRing* gsl_ring_prepend (GslRing *head,
+ gpointer data);
+GslRing* gsl_ring_prepend_uniq (GslRing *head,
+ gpointer data);
+GslRing* gsl_ring_append (GslRing *head,
+ gpointer data);
+GslRing* gsl_ring_insert_sorted (GslRing *head,
+ gpointer data,
+ GCompareFunc func);
+GslRing* gsl_ring_remove_node (GslRing *head,
+ GslRing *node);
+GslRing* gsl_ring_remove (GslRing *head,
+ gpointer data);
+guint gsl_ring_length (GslRing *head);
+GslRing* gsl_ring_concat (GslRing *head1,
+ GslRing *head2);
+GslRing* gsl_ring_find (GslRing *head,
+ gconstpointer data);
+GslRing* gsl_ring_nth (GslRing *head,
+ guint n);
+gpointer gsl_ring_nth_data (GslRing *head,
+ guint n);
+gpointer gsl_ring_pop_head (GslRing **head);
+gpointer gsl_ring_pop_tail (GslRing **head);
+#define gsl_ring_push_head gsl_ring_prepend
+#define gsl_ring_push_tail gsl_ring_append
+void gsl_ring_free (GslRing *head);
+#define gsl_ring_walk(head,node) ((node) != (head)->prev ? (node)->next : NULL)
+
+
+/* --- GslMessage and debugging --- */
+typedef enum /*< skip >*/
+{
+ GSL_MSG_NOTIFY = 1 << 0,
+ GSL_MSG_DATA_CACHE = 1 << 1,
+ GSL_MSG_DATA_HANDLE = 1 << 2,
+ GSL_MSG_LOADER = 1 << 3,
+ GSL_MSG_OSC = 1 << 4,
+ GSL_MSG_ENGINE = 1 << 5,
+ GSL_MSG_JOBS = 1 << 6,
+ GSL_MSG_FJOBS = 1 << 7,
+ GSL_MSG_SCHED = 1 << 8,
+ GSL_MSG_MASTER = 1 << 9,
+ GSL_MSG_SLAVE = 1 << 10
+} GslDebugFlags;
+extern const GDebugKey *gsl_debug_keys;
+extern const guint gsl_n_debug_keys;
+void gsl_debug (GslDebugFlags reporter,
+ const gchar *section,
+ const gchar *format,
+ ...) G_GNUC_PRINTF (3, 4);
+void gsl_debug_enable (GslDebugFlags dbg_flags);
+void gsl_debug_disable (GslDebugFlags dbg_flags);
+gboolean gsl_debug_check (GslDebugFlags dbg_flags);
+void gsl_message_send (GslDebugFlags reporter,
+ const gchar *section, /* maybe NULL */
+ GslErrorType error, /* maybe 0 */
+ const gchar *messagef,
+ ...) G_GNUC_PRINTF (4, 5);
+const gchar* gsl_strerror (GslErrorType error);
+
+/* provide message/debugging macro templates, so custom messages
+ * are done as:
+ * #define FOO_DEBUG GSL_DEBUG_FUNCTION (GSL_MSG_LOADER, "FOO")
+ * FOO_DEBUG ("some debug message and number: %d", 5);
+ */
+#define GSL_DEBUG_FUNCTION(reporter, section) _GSL_DEBUG_MACRO_IMPL((reporter), (section))
+#define GSL_MESSAGE_FUNCTION(reporter, section) _GSL_MESSAGE_MACRO_IMPL((reporter), (section))
+
+
+/* --- GslThread --- */
+typedef void (*GslThreadFunc) (gpointer user_data);
+GslThread* gsl_thread_new (GslThreadFunc func,
+ gpointer user_data);
+guint gsl_threads_get_count (void);
+GslThread* gsl_thread_self (void);
+GslThread* gsl_thread_main (void);
+
+
+/* --- tick stamps --- */
+typedef struct {
+ guint64 tick_stamp;
+ guint64 system_time;
+} GslTickStampUpdate;
+guint64 gsl_tick_stamp (void);
+guint64 gsl_time_system (void);
+GslTickStampUpdate gsl_tick_stamp_last (void);
+#define GSL_TICK_STAMP (_GSL_TICK_STAMP_VAL ())
+#define GSL_MAX_TICK_STAMP (G_MAXUINT64)
+
+
+/* --- thread syncronization --- */
+gboolean gsl_thread_sleep (glong max_msec);
+gboolean gsl_thread_aborted (void);
+void gsl_thread_queue_abort (GslThread *thread);
+void gsl_thread_abort (GslThread *thread);
+void gsl_thread_wakeup (GslThread *thread);
+void gsl_thread_awake_after (guint64 tick_stamp);
+void gsl_thread_awake_before (guint64 tick_stamp);
+void gsl_thread_get_pollfd (GPollFD *pfd);
+
+
+/* --- GslMutex --- */
+#define gsl_mutex_init(mutex) (gsl_mutex_table.mutex_init (mutex))
+#define GSL_SPIN_LOCK(mutex) (gsl_mutex_table.mutex_lock (mutex))
+#define GSL_SPIN_UNLOCK(mutex) (gsl_mutex_table.mutex_unlock (mutex))
+#define GSL_SYNC_LOCK(mutex) (gsl_mutex_table.mutex_lock (mutex))
+#define GSL_SYNC_UNLOCK(mutex) (gsl_mutex_table.mutex_unlock (mutex))
+#define gsl_mutex_trylock(mutex) (!gsl_mutex_table.mutex_trylock (mutex))
+#define gsl_mutex_destroy(mutex) (gsl_mutex_table.mutex_destroy (mutex))
+#define gsl_rec_mutex_init(rmutex) (gsl_mutex_table.rec_mutex_init (rmutex))
+#define gsl_rec_mutex_lock(rmutex) (gsl_mutex_table.rec_mutex_lock (rmutex))
+#define gsl_rec_mutex_unlock(rmutex) (gsl_mutex_table.rec_mutex_unlock (rmutex))
+#define gsl_rec_mutex_trylock(rmutex) (!gsl_mutex_table.rec_mutex_trylock (rmutex))
+#define gsl_rec_mutex_destroy(rmutex) (gsl_mutex_table.rec_mutex_destroy (rmutex))
+#define gsl_cond_init(cond) (gsl_mutex_table.cond_init (cond))
+#define gsl_cond_signal(cond) (gsl_mutex_table.cond_signal (cond))
+#define gsl_cond_broadcast(cond) (gsl_mutex_table.cond_broadcast (cond))
+#define gsl_cond_wait(cond, mutex) (gsl_mutex_table.cond_wait ((cond), (mutex)))
+#define gsl_cond_destroy(cond) (gsl_mutex_table.cond_destroy (cond))
+void gsl_cond_wait_timed (GslCond *cond,
+ GslMutex *mutex,
+ glong max_useconds);
+struct _GslMutexTable
+{
+ void (*mutex_init) (GslMutex *mutex);
+ void (*mutex_lock) (GslMutex *mutex);
+ int (*mutex_trylock) (GslMutex *mutex); /* 0==has_lock */
+ void (*mutex_unlock) (GslMutex *mutex);
+ void (*mutex_destroy) (GslMutex *mutex);
+ void (*rec_mutex_init) (GslRecMutex *mutex);
+ void (*rec_mutex_lock) (GslRecMutex *mutex);
+ int (*rec_mutex_trylock) (GslRecMutex *mutex); /* 0==has_lock */
+ void (*rec_mutex_unlock) (GslRecMutex *mutex);
+ void (*rec_mutex_destroy) (GslRecMutex *mutex);
+ void (*cond_init) (GslCond *cond);
+ void (*cond_signal) (GslCond *cond);
+ void (*cond_broadcast) (GslCond *cond);
+ void (*cond_wait) (GslCond *cond,
+ GslMutex *mutex);
+ void (*cond_wait_timed) (GslCond *cond,
+ GslMutex *mutex,
+ gulong abs_secs,
+ gulong abs_usecs);
+ void (*cond_destroy) (GslCond *cond);
+};
+
+
+/* --- misc --- */
+const gchar* gsl_byte_order_to_string (guint byte_order);
+guint gsl_byte_order_from_string (const gchar *string);
+GslErrorType gsl_error_from_errno (gint sys_errno,
+ GslErrorType fallback);
+GslErrorType gsl_check_file (const gchar *file_name,
+ const gchar *mode);
+
+
+/* --- implementation details --- */
+gpointer gsl_alloc_memblock (gsize size);
+gpointer gsl_alloc_memblock0 (gsize size);
+void gsl_free_memblock (gsize size,
+ gpointer memblock);
+void gsl_alloc_report (void);
+const guint gsl_alloc_upper_power2 (const gulong number);
+void _gsl_tick_stamp_inc (void);
+void _gsl_tick_stamp_set_leap (guint ticks);
+void _gsl_init_signal (void);
+void _gsl_init_fd_pool (void);
+void _gsl_init_data_caches (void);
+void _gsl_init_engine_utils (void);
+void _gsl_init_loader_gslwave (void);
+void _gsl_init_loader_wav (void);
+void _gsl_init_loader_oggvorbis (void);
+void _gsl_init_loader_mad (void);
+#define GSL_N_IO_RETRIES (5)
+#define _GSL_TICK_STAMP_VAL() (gsl_externvar_tick_stamp + 0)
+extern volatile guint64 gsl_externvar_tick_stamp;
+extern GslMutexTable gsl_mutex_table;
+
+/* we need to provide a REPORTER and SECTION string for the debugging
+ * and message generation functions. for GCC, we also want to make use
+ * of printf style format checking with G_GNUC_PRINTF(). for the non GCC
+ * case, we push REPORTER and SECTION as thread specific data before
+ * invoking the debugging/message generation function. for the GCC case
+ * we use GNUC varargs. (using ISO varargs wouldn't provide any benefit,
+ * for one, ISO vararg support is broken with gcc-2.95 and ansi/c++, and
+ * we only need the macro magic for GCC in the first place to make use
+ * of G_GNUC_PRINTF()).
+ */
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
+#define _GSL_DEBUG_MACRO_IMPL(reporter, section) gsl_debug ((reporter), (section), _GSL_DEBUG_GCCTAIL
+#define _GSL_DEBUG_GCCTAIL(GCCARGS...) GCCARGS )
+#define _GSL_MESSAGE_MACRO_IMPL(reporter, section) gsl_message_send ((reporter), (section), _GSL_MESSGAE_GCCTAIL
+#define _GSL_MESSGAE_GCCTAIL(GCCARGS...) GCCARGS )
+#else /* non GCC, push data and invoke function */
+#define _GSL_DEBUG_MACRO_IMPL(reporter, section) (gsl_auxlog_push ((reporter), (section)), gsl_auxlog_debug)
+#define _GSL_MESSAGE_MACRO_IMPL(reporter, section) (gsl_auxlog_push ((reporter), (section)), gsl_auxlog_message)
+#endif
+/* non-GCC message helpers */
+void gsl_auxlog_push (GslDebugFlags reporter,
+ const gchar *section);
+void gsl_auxlog_debug (const gchar *format,
+ ...);
+void gsl_auxlog_message (GslErrorType error,
+ const gchar *format,
+ ...);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_COMMON_H__ */
diff --git a/flow/gsl/gslconfig.h.in b/flow/gsl/gslconfig.h.in
new file mode 100644
index 0000000..6e91bd5
--- /dev/null
+++ b/flow/gsl/gslconfig.h.in
@@ -0,0 +1,11 @@
+#define GSL_SIZEOF_PTH_MUTEX_T (@GSL_SIZEOF_PTH_MUTEX_T@)
+#define GSL_SIZEOF_PTH_COND_T (@GSL_SIZEOF_PTH_COND_T@)
+#define GSL_HAVE_MUTEXATTR_SETTYPE (@GSL_HAVE_MUTEXATTR_SETTYPE@ && \
+ GSL_SIZEOF_PTH_MUTEX_T && \
+ GSL_SIZEOF_PTH_COND_T)
+#define GSL_SIZEOF_STD_INTMAX_T (@GSL_SIZEOF_STD_INTMAX_T@)
+#define GSL_HAVE_LIBMAD (@GSL_HAVE_LIBMAD@)
+#define GSL_HAVE_OGGVORBIS (@GSL_HAVE_OGGVORBIS@)
+#define GSL_HAVE_OGGVORBIS_RC3 (@GSL_HAVE_OGGVORBIS_RC3@)
+#define GSL_USE_GSL_GLIB (@GSL_USE_GSL_GLIB@)
+#define GSL_USE_ARTS_THREADS (@GSL_USE_ARTS_THREADS@)
diff --git a/flow/gsl/gslconvert.c b/flow/gsl/gslconvert.c
new file mode 100644
index 0000000..95db568
--- /dev/null
+++ b/flow/gsl/gslconvert.c
@@ -0,0 +1,57 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001 Tim Janik
+ *
+ * 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.
+ */
+#include "gslconvert.h"
+#include <string.h>
+
+
+
+/* --- functions --- */
+gchar*
+gsl_convert_from_utf8 (const gchar *codeset,
+ const gchar *string)
+{
+ gchar *result;
+
+ g_return_val_if_fail (codeset != NULL, NULL);
+ if (!string)
+ return NULL;
+
+ result = g_convert (string, strlen (string), codeset, GSL_CODESET_UTF8, NULL, NULL, NULL);
+ if (!result)
+ result = g_strconcat ("??unknown-codeset:", codeset, "??", NULL);
+
+ return result;
+}
+
+gchar*
+gsl_convert_to_utf8 (const gchar *codeset,
+ const gchar *string)
+{
+ gchar *result;
+
+ g_return_val_if_fail (codeset != NULL, NULL);
+ if (!string)
+ return NULL;
+
+ result = g_convert (string, strlen (string), GSL_CODESET_UTF8, codeset, NULL, NULL, NULL);
+ if (!result)
+ result = g_strconcat ("??unknown-codeset:", codeset, "??", NULL);
+
+ return result;
+}
diff --git a/flow/gsl/gslconvert.h b/flow/gsl/gslconvert.h
new file mode 100644
index 0000000..10e685f
--- /dev/null
+++ b/flow/gsl/gslconvert.h
@@ -0,0 +1,43 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001 Tim Janik
+ *
+ * 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.
+ */
+#ifndef __GSL_CONVERT_H__
+#define __GSL_CONVERT_H__
+
+#include <gsl/gsldefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GSL_CODESET_8859_1 "ISO-8859-1" /* LATIN-1 */
+#define GSL_CODESET_UTF8 "UTF8" /* "ISO-10646" */
+
+gchar* gsl_convert_from_utf8 (const gchar *codeset,
+ const gchar *string);
+gchar* gsl_convert_to_utf8 (const gchar *codeset,
+ const gchar *string);
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_CONVERT_H__ */
diff --git a/flow/gsl/gsldatacache.c b/flow/gsl/gsldatacache.c
new file mode 100644
index 0000000..c1df215
--- /dev/null
+++ b/flow/gsl/gsldatacache.c
@@ -0,0 +1,633 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001-2002 Tim Janik
+ * Copyright (C) 2004 Stefan Westerfeld
+ *
+ * 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.
+ */
+#include "gsldatacache.h"
+
+#include "gslcommon.h"
+#include "gsldatahandle.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+
+
+/* --- macros --- */
+#define NODEP_INDEX(dcache, node_p) ((node_p) - (dcache)->nodes)
+#define UPPER_POWER2(n) (gsl_alloc_upper_power2 (MAX (n, 4)))
+#define CONFIG_NODE_SIZE() (gsl_get_config ()->dcache_block_size)
+#define AGE_EPSILON (3) /* must be < smallest sweep */
+#define LOW_PERSISTENCY_SWEEP (5)
+
+/* we use one global lock to protect the dcache list, the list
+ * count (length) and the number of aged (unused) nodes.
+ * also, each dcache has its own mutext to protect updates in
+ * the reference count, nodes or node data blocks.
+ * in order to avoid deadlocks, if both locks need
+ * to be held, they always have to be acquired in the order
+ * 1) global lock, 2) dcache lock.
+ * asyncronous data block filling for a new node occours without
+ * the dcache lock being held (as most calls to GslDataHandle
+ * functions).
+ * however, assignment of the newly acquired data is again
+ * protected by the dcache lock. concurrent API entries
+ * which require demand loading of such data will wait on
+ * a global condition which is always signaled once a new data
+ * block read has been completed. using one global condition
+ * is considered sufficient until shown otherwise by further
+ * profiling/debugging measures.
+ */
+
+
+/* --- prototypes --- */
+static void dcache_free (GslDataCache *dcache);
+static GslDataCacheNode* data_cache_new_node_L (GslDataCache *dcache,
+ gsize offset,
+ guint pos,
+ gboolean demand_load);
+
+
+/* --- variables --- */
+static GslMutex global_dcache_mutex = { 0, };
+static GslCond global_dcache_cond_node_filled = { 0, };
+static GslRing *global_dcache_list = NULL;
+static guint global_dcache_count = 0;
+static guint global_dcache_n_aged_nodes = 0;
+
+
+/* --- functions --- */
+void
+_gsl_init_data_caches (void)
+{
+ static gboolean initialized = FALSE;
+
+ g_assert (initialized == FALSE);
+ initialized++;
+
+ g_assert (AGE_EPSILON < LOW_PERSISTENCY_SWEEP);
+ gsl_cond_init (&global_dcache_cond_node_filled);
+ gsl_mutex_init (&global_dcache_mutex);
+}
+
+GslDataCache*
+gsl_data_cache_new (GslDataHandle *dhandle,
+ guint padding)
+{
+ guint node_size = CONFIG_NODE_SIZE () / sizeof (GslDataType);
+ GslDataCache *dcache;
+
+ g_return_val_if_fail (dhandle != NULL, NULL);
+ g_return_val_if_fail (padding > 0, NULL);
+ g_return_val_if_fail (dhandle->name != NULL, NULL);
+ g_assert (node_size == gsl_alloc_upper_power2 (node_size));
+ g_return_val_if_fail (padding < node_size / 2, NULL);
+
+ /* allocate new closed dcache if necessary */
+ dcache = gsl_new_struct (GslDataCache, 1);
+ dcache->dhandle = gsl_data_handle_ref (dhandle);
+ dcache->open_count = 0;
+ gsl_mutex_init (&dcache->mutex);
+ dcache->ref_count = 1;
+ dcache->node_size = node_size;
+ dcache->padding = padding;
+ dcache->max_age = 0;
+ dcache->low_persistency = FALSE; /* FIXME: !gsl_data_handle_needs_cache (dcache->dhandle); */
+ dcache->n_nodes = 0;
+ dcache->nodes = g_renew (GslDataCacheNode*, NULL, UPPER_POWER2 (dcache->n_nodes));
+
+ GSL_SPIN_LOCK (&global_dcache_mutex);
+ global_dcache_list = gsl_ring_append (global_dcache_list, dcache);
+ global_dcache_count++;
+ GSL_SPIN_UNLOCK (&global_dcache_mutex);
+
+ return dcache;
+}
+
+void
+gsl_data_cache_open (GslDataCache *dcache)
+{
+ g_return_if_fail (dcache != NULL);
+ g_return_if_fail (dcache->ref_count > 0);
+
+ GSL_SPIN_LOCK (&dcache->mutex);
+ if (!dcache->open_count)
+ {
+ GslErrorType error;
+
+ error = gsl_data_handle_open (dcache->dhandle);
+ if (error)
+ {
+ /* FIXME: this is pretty fatal, throw out zero blocks now? */
+ gsl_message_send (GSL_MSG_DATA_CACHE, "Open",
+ error,
+ "failed to open \"%s\": %s",
+ dcache->dhandle->name,
+ gsl_strerror (error));
+ }
+ else
+ {
+ dcache->open_count = 1;
+ dcache->ref_count++;
+ }
+ }
+ else
+ dcache->open_count++;
+ GSL_SPIN_UNLOCK (&dcache->mutex);
+}
+
+void
+gsl_data_cache_close (GslDataCache *dcache)
+{
+ gboolean need_unref;
+
+ g_return_if_fail (dcache != NULL);
+ g_return_if_fail (dcache->ref_count > 0);
+ g_return_if_fail (dcache->open_count > 0);
+
+ GSL_SPIN_LOCK (&dcache->mutex);
+ dcache->open_count--;
+ need_unref = !dcache->open_count;
+ if (!dcache->open_count)
+ gsl_data_handle_close (dcache->dhandle);
+ GSL_SPIN_UNLOCK (&dcache->mutex);
+ if (need_unref)
+ gsl_data_cache_unref (dcache);
+}
+
+GslDataCache*
+gsl_data_cache_ref (GslDataCache *dcache)
+{
+ g_return_val_if_fail (dcache != NULL, NULL);
+ g_return_val_if_fail (dcache->ref_count > 0, NULL);
+
+ /* we might get invoked with global_dcache_mutex locked */
+ GSL_SPIN_LOCK (&dcache->mutex);
+ dcache->ref_count++;
+ GSL_SPIN_UNLOCK (&dcache->mutex);
+
+ return dcache;
+}
+
+static void
+dcache_free (GslDataCache *dcache)
+{
+ guint i;
+
+ g_return_if_fail (dcache->ref_count == 0);
+ g_return_if_fail (dcache->open_count == 0);
+
+ gsl_data_handle_unref (dcache->dhandle);
+ gsl_mutex_destroy (&dcache->mutex);
+ for (i = 0; i < dcache->n_nodes; i++)
+ {
+ GslDataCacheNode *node = dcache->nodes[i];
+ guint size;
+
+ size = dcache->node_size + (dcache->padding << 1);
+ gsl_delete_structs (GslDataType, size, node->data - dcache->padding);
+ gsl_delete_struct (GslDataCacheNode, node);
+ }
+ g_free (dcache->nodes);
+ gsl_delete_struct (GslDataCache, dcache);
+}
+
+void
+gsl_data_cache_unref (GslDataCache *dcache)
+{
+ g_return_if_fail (dcache != NULL);
+ restart:
+ g_return_if_fail (dcache->ref_count > 0);
+
+ if (dcache->ref_count == 1) /* possible destruction, need global lock */
+ {
+ g_return_if_fail (dcache->open_count == 0);
+
+ GSL_SPIN_LOCK (&global_dcache_mutex);
+ GSL_SPIN_LOCK (&dcache->mutex);
+ if (dcache->ref_count != 1)
+ {
+ /* damn, some other thread trapped in, restart */
+ GSL_SPIN_UNLOCK (&dcache->mutex);
+ GSL_SPIN_UNLOCK (&global_dcache_mutex);
+ goto restart;
+ }
+ dcache->ref_count = 0;
+ global_dcache_list = gsl_ring_remove (global_dcache_list, dcache);
+ GSL_SPIN_UNLOCK (&dcache->mutex);
+ global_dcache_count--;
+ global_dcache_n_aged_nodes -= dcache->n_nodes;
+ GSL_SPIN_UNLOCK (&global_dcache_mutex);
+ dcache_free (dcache);
+ }
+ else
+ {
+ GSL_SPIN_LOCK (&dcache->mutex);
+ if (dcache->ref_count < 2)
+ {
+ /* damn, some other thread trapped in, restart */
+ GSL_SPIN_UNLOCK (&dcache->mutex);
+ goto restart;
+ }
+ dcache->ref_count--;
+ GSL_SPIN_UNLOCK (&dcache->mutex);
+ }
+}
+
+static inline GslDataCacheNode**
+data_cache_lookup_nextmost_node_L (GslDataCache *dcache,
+ gsize offset)
+{
+ if (dcache->n_nodes > 0)
+ {
+ GslDataCacheNode **check, **nodes = dcache->nodes;
+ guint n_nodes = dcache->n_nodes, node_size = dcache->node_size;
+
+ /* caller has to figure himself whether we return nextmost vs. exact match */
+ nodes -= 1;
+ do
+ {
+ register gint cmp;
+ register guint i;
+
+ i = (n_nodes + 1) >> 1;
+ check = nodes + i;
+ cmp = offset < (*check)->offset ? -1 : offset >= (*check)->offset + node_size;
+ if (cmp == 0)
+ return check; /* exact match */
+ else if (cmp > 0)
+ {
+ n_nodes -= i;
+ nodes = check;
+ }
+ else /* if (cmp < 0) */
+ n_nodes = i - 1;
+ }
+ while (n_nodes);
+
+ return check; /* nextmost */
+ }
+ return NULL;
+}
+
+static inline GslDataCacheNode*
+data_cache_new_node_L (GslDataCache *dcache,
+ gsize offset,
+ guint pos,
+ gboolean demand_load)
+{
+ GslDataCacheNode **node_p, *dnode;
+ GslDataCacheNode *left_node;
+ GslDataType *data, *node_data;
+ guint new_node_array_size, old_node_array_size = UPPER_POWER2 (dcache->n_nodes);
+ GslLong dhandle_length;
+ guint i, size;
+ gint result;
+
+ i = dcache->n_nodes++;
+ new_node_array_size = UPPER_POWER2 (dcache->n_nodes);
+ if (old_node_array_size != new_node_array_size)
+ dcache->nodes = g_renew (GslDataCacheNode*, dcache->nodes, new_node_array_size);
+ node_p = dcache->nodes + pos;
+ g_memmove (node_p + 1, node_p, (i - pos) * sizeof (*node_p));
+ dnode = gsl_new_struct (GslDataCacheNode, 1);
+ (*node_p) = dnode;
+ dnode->offset = offset & ~(dcache->node_size - 1);
+ dnode->ref_count = 1;
+ dnode->age = 0;
+ dnode->data = NULL;
+ GSL_SPIN_UNLOCK (&dcache->mutex);
+
+ size = dcache->node_size + (dcache->padding << 1);
+ data = gsl_new_struct (GslDataType, size);
+ node_data = data + dcache->padding;
+ offset = dnode->offset;
+ if (dcache->padding > offset) /* pad out bytes before data start */
+ {
+ guint short_pad = dcache->padding - offset;
+
+ memset (data, 0, short_pad * sizeof (GslDataType));
+ size -= short_pad;
+ data += short_pad;
+ offset -= (dcache->padding - short_pad); /* should always result in offset=0 */
+ }
+ else
+ offset -= dcache->padding;
+ if (!demand_load)
+ g_message (G_STRLOC ":FIXME: lazy data loading not yet supported");
+
+ /* if we have a left node, and it contains data that we need, copy it */
+ left_node = pos ? dcache->nodes[pos - 1] : NULL;
+ if (left_node)
+ {
+ guint left_node_size = dcache->node_size;
+ gint left_node_offset = left_node->offset;
+ GslDataType *left_node_data = left_node->data;
+
+ /* padding around left_node */
+ left_node_size += (dcache->padding << 1);
+ left_node_offset -= dcache->padding;
+ left_node_data -= dcache->padding;
+
+ if (offset < left_node_offset + left_node_size)
+ {
+ guint left_node_copy = left_node_offset + left_node_size - offset;
+
+ memcpy (data, left_node_data + offset - left_node_offset,
+ left_node_copy * sizeof (GslDataType));
+
+ offset += left_node_copy;
+ size -= left_node_copy;
+ data += left_node_copy;
+ }
+ }
+ dhandle_length = gsl_data_handle_length (dcache->dhandle);
+ do
+ {
+ if (offset >= dhandle_length)
+ break;
+ size = MIN (size, dhandle_length - offset);
+ result = gsl_data_handle_read (dcache->dhandle, offset, size, data);
+ if (result < 0)
+ {
+ gsl_message_send (GSL_MSG_DATA_CACHE, "ReadAhead",
+ GSL_ERROR_READ_FAILED,
+ "reading from \"%s\"", dcache->dhandle->name);
+ break;
+ }
+ else
+ {
+ offset += result;
+ size -= result;
+ data += result;
+ }
+ }
+ while (size && result > 0);
+ memset (data, 0, size * sizeof (data[0]));
+
+ GSL_SPIN_LOCK (&dcache->mutex);
+ dnode->data = node_data;
+ gsl_cond_broadcast (&global_dcache_cond_node_filled);
+
+ return dnode;
+}
+
+GslDataCacheNode*
+gsl_data_cache_ref_node (GslDataCache *dcache,
+ gsize offset,
+ GslDataCacheRequest load_request)
+{
+ GslDataCacheNode **node_p, *node;
+ guint insertion_pos;
+
+ g_return_val_if_fail (dcache != NULL, NULL);
+ g_return_val_if_fail (dcache->ref_count > 0, NULL);
+ g_return_val_if_fail (dcache->open_count > 0, NULL);
+ g_return_val_if_fail (offset < gsl_data_handle_length (dcache->dhandle), NULL);
+
+ GSL_SPIN_LOCK (&dcache->mutex);
+ node_p = data_cache_lookup_nextmost_node_L (dcache, offset);
+ if (node_p)
+ {
+ node = *node_p;
+ if (offset >= node->offset && offset < node->offset + dcache->node_size)
+ {
+ gboolean rejuvenate_node = !node->ref_count;
+
+ if (load_request == GSL_DATA_CACHE_PEEK)
+ {
+ if (node->data)
+ node->ref_count++;
+ else
+ node = NULL;
+ GSL_SPIN_UNLOCK (&dcache->mutex);
+ if (node && rejuvenate_node)
+ {
+ GSL_SPIN_LOCK (&global_dcache_mutex); /* different lock */
+ global_dcache_n_aged_nodes--;
+ GSL_SPIN_UNLOCK (&global_dcache_mutex);
+ }
+ return node;
+ }
+
+ node->ref_count++;
+ if (load_request == GSL_DATA_CACHE_DEMAND_LOAD)
+ while (!node->data)
+ gsl_cond_wait (&global_dcache_cond_node_filled, &dcache->mutex);
+ GSL_SPIN_UNLOCK (&dcache->mutex);
+ /* g_printerr ("hit: %d :%d: %d\n", node->offset, offset, node->offset + dcache->node_size); */
+
+ if (rejuvenate_node)
+ {
+ GSL_SPIN_LOCK (&global_dcache_mutex); /* different lock */
+ global_dcache_n_aged_nodes--;
+ GSL_SPIN_UNLOCK (&global_dcache_mutex);
+ }
+
+ return node; /* exact match */
+ }
+ insertion_pos = NODEP_INDEX (dcache, node_p); /* insert before neighbour */
+ if (offset > node->offset) /* insert after neighbour */
+ insertion_pos += 1;
+ /* g_printerr ("mis: %d :%d: %d\n", node->offset, offset, node->offset + dcache->node_size); */
+ }
+ else
+ insertion_pos = 0; /* insert at start */
+
+ if (load_request != GSL_DATA_CACHE_PEEK)
+ node = data_cache_new_node_L (dcache, offset, insertion_pos, load_request == GSL_DATA_CACHE_DEMAND_LOAD);
+ else
+ node = NULL;
+
+ GSL_SPIN_UNLOCK (&dcache->mutex);
+
+ return node;
+}
+
+static gboolean /* still locked */
+data_cache_free_olders_Lunlock (GslDataCache *dcache,
+ guint max_lru) /* how many lru nodes to keep */
+{
+ GslDataCacheNode **slot_p;
+ guint i, rejuvenate, size;
+ guint n_freed = 0;
+
+ g_return_val_if_fail (dcache != NULL, TRUE);
+
+ /* it doesn't make sense to free nodes below the jitter that
+ * AGE_EPSILON attempts to prevent.
+ */
+ max_lru = MAX (AGE_EPSILON, max_lru);
+ if (max_lru >= dcache->max_age)
+ return TRUE;
+
+ rejuvenate = dcache->max_age - max_lru;
+ if (0)
+ g_print ("start sweep: dcache (%p) with %u nodes, max_age: %u, rejuvenate: %u (max_lru: %u)\n",
+ dcache, dcache->n_nodes, dcache->max_age, rejuvenate, max_lru);
+ size = dcache->node_size + (dcache->padding << 1);
+ slot_p = NULL;
+ for (i = 0; i < dcache->n_nodes; i++)
+ {
+ GslDataCacheNode *node = dcache->nodes[i];
+
+ if (!node->ref_count && node->age <= rejuvenate)
+ {
+ gsl_delete_structs (GslDataType, size, node->data - dcache->padding);
+ gsl_delete_struct (GslDataCacheNode, node);
+ if (!slot_p)
+ slot_p = dcache->nodes + i;
+ n_freed++;
+ }
+ else
+ {
+ node->age -= MIN (rejuvenate, node->age);
+ if (slot_p)
+ {
+ *slot_p = node;
+ slot_p++;
+ }
+ }
+ }
+ dcache->max_age = max_lru;
+ if (slot_p)
+ dcache->n_nodes = NODEP_INDEX (dcache, slot_p);
+ GSL_SPIN_UNLOCK (&dcache->mutex);
+
+ if (n_freed)
+ {
+ GSL_SPIN_LOCK (&global_dcache_mutex);
+ global_dcache_n_aged_nodes -= n_freed;
+ GSL_SPIN_UNLOCK (&global_dcache_mutex);
+ }
+
+ if (0)
+ g_printerr ("freed %u nodes (%u bytes) remaining %u bytes\n",
+ n_freed, n_freed * CONFIG_NODE_SIZE (),
+ global_dcache_n_aged_nodes * CONFIG_NODE_SIZE ());
+ return FALSE;
+}
+
+void
+gsl_data_cache_unref_node (GslDataCache *dcache,
+ GslDataCacheNode *node)
+{
+ GslDataCacheNode **node_p;
+ gboolean check_cache;
+
+ g_return_if_fail (dcache != NULL);
+ g_return_if_fail (node != NULL);
+ g_return_if_fail (node->ref_count > 0);
+
+ GSL_SPIN_LOCK (&dcache->mutex);
+ node_p = data_cache_lookup_nextmost_node_L (dcache, node->offset);
+ g_assert (node_p && *node_p == node); /* paranoid check lookup, yeah! */
+ node->ref_count -= 1;
+ check_cache = !node->ref_count;
+ if (!node->ref_count &&
+ (node->age + AGE_EPSILON <= dcache->max_age ||
+ dcache->max_age < AGE_EPSILON))
+ node->age = ++dcache->max_age;
+ GSL_SPIN_UNLOCK (&dcache->mutex);
+
+ if (check_cache)
+ {
+ guint node_size = CONFIG_NODE_SIZE ();
+ guint cache_mem = gsl_get_config ()->dcache_cache_memory;
+ guint current_mem;
+
+ /* FIXME: cache sweeping should not be done from _unref_node for high persistency caches */
+ GSL_SPIN_LOCK (&global_dcache_mutex);
+ global_dcache_n_aged_nodes++;
+ current_mem = node_size * global_dcache_n_aged_nodes;
+ if (current_mem > cache_mem)
+ {
+ guint dcache_count, needs_unlock;
+ dcache = gsl_ring_pop_head (&global_dcache_list);
+ GSL_SPIN_LOCK (&dcache->mutex);
+ dcache->ref_count++;
+ global_dcache_list = gsl_ring_append (global_dcache_list, dcache);
+ dcache_count = global_dcache_count;
+ GSL_SPIN_UNLOCK (&global_dcache_mutex);
+ if (dcache->low_persistency)
+ needs_unlock = data_cache_free_olders_Lunlock (dcache, LOW_PERSISTENCY_SWEEP);
+ else
+ {
+ guint max_lru;
+ /* try to free the actual cache overflow from the
+ * dcache we just picked, but don't free more than
+ * 25% of its nodes yet.
+ * overflow is actual overhang + ~6% of cache size,
+ * so cache sweeps are triggered less frequently.
+ */
+ current_mem -= cache_mem; /* overhang */
+ current_mem += cache_mem >> 4; /* overflow = overhang + 6% */
+ current_mem /= node_size; /* n_nodes to free */
+ current_mem = MIN (current_mem, dcache->n_nodes);
+ max_lru = dcache->n_nodes >> 1;
+ max_lru += max_lru >> 1; /* 75% of n_nodes */
+ max_lru = MAX (max_lru, dcache->n_nodes - current_mem);
+ needs_unlock = data_cache_free_olders_Lunlock (dcache, MAX (max_lru, LOW_PERSISTENCY_SWEEP));
+ }
+ if (needs_unlock)
+ GSL_SPIN_UNLOCK (&dcache->mutex);
+ }
+ else
+ GSL_SPIN_UNLOCK (&global_dcache_mutex);
+ }
+}
+
+void
+gsl_data_cache_free_olders (GslDataCache *dcache,
+ guint max_age)
+{
+ gboolean needs_unlock;
+ g_return_if_fail (dcache != NULL);
+
+ GSL_SPIN_LOCK (&dcache->mutex);
+ needs_unlock = data_cache_free_olders_Lunlock (dcache, max_age);
+ if (needs_unlock)
+ GSL_SPIN_UNLOCK (&dcache->mutex);
+}
+
+GslDataCache*
+gsl_data_cache_from_dhandle (GslDataHandle *dhandle,
+ guint min_padding)
+{
+ GslRing *ring;
+
+ g_return_val_if_fail (dhandle != NULL, NULL);
+
+ GSL_SPIN_LOCK (&global_dcache_mutex);
+ for (ring = global_dcache_list; ring; ring = gsl_ring_walk (global_dcache_list, ring))
+ {
+ GslDataCache *dcache = ring->data;
+
+ if (dcache->dhandle == dhandle && dcache->padding >= min_padding)
+ {
+ gsl_data_cache_ref (dcache);
+ GSL_SPIN_UNLOCK (&global_dcache_mutex);
+ return dcache;
+ }
+ }
+ GSL_SPIN_UNLOCK (&global_dcache_mutex);
+
+ return gsl_data_cache_new (dhandle, min_padding);
+}
diff --git a/flow/gsl/gsldatacache.h b/flow/gsl/gsldatacache.h
new file mode 100644
index 0000000..5eb3677
--- /dev/null
+++ b/flow/gsl/gsldatacache.h
@@ -0,0 +1,87 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001 Tim Janik
+ *
+ * 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.
+ */
+#ifndef __GSL_DATA_CACHE_H__
+#define __GSL_DATA_CACHE_H__
+
+#include <gsl/gslcommon.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* --- macros --- */
+#define GSL_DATA_CACHE_NODE_SIZE(dcache) (((GslDataCache*) (dcache))->node_size)
+
+
+/* --- typedefs & structures --- */
+typedef gfloat GslDataType;
+typedef struct _GslDataCacheNode GslDataCacheNode;
+struct _GslDataCache
+{
+ GslDataHandle *dhandle;
+ guint open_count;
+ GslMutex mutex;
+ guint ref_count;
+ guint node_size; /* power of 2, const for all dcaches */
+ guint padding; /* n_values around blocks */
+ guint max_age;
+ gboolean low_persistency;
+ guint n_nodes;
+ GslDataCacheNode **nodes;
+};
+struct _GslDataCacheNode
+{
+ gsize offset;
+ guint ref_count;
+ guint age;
+ GslDataType *data; /* NULL while busy */
+};
+typedef enum
+{
+ GSL_DATA_CACHE_REQUEST = FALSE, /* node->data may be NULL and will be filled */
+ GSL_DATA_CACHE_DEMAND_LOAD = TRUE, /* blocks until node->data != NULL */
+ GSL_DATA_CACHE_PEEK = 2 /* may return NULL node, data != NULL otherwise */
+} GslDataCacheRequest;
+
+
+/* --- prototypes --- */
+GslDataCache* gsl_data_cache_new (GslDataHandle *dhandle,
+ guint padding);
+GslDataCache* gsl_data_cache_ref (GslDataCache *dcache);
+void gsl_data_cache_unref (GslDataCache *dcache);
+void gsl_data_cache_open (GslDataCache *dcache);
+void gsl_data_cache_close (GslDataCache *dcache);
+GslDataCacheNode* gsl_data_cache_ref_node (GslDataCache *dcache,
+ gsize offset,
+ GslDataCacheRequest load_request);
+void gsl_data_cache_unref_node (GslDataCache *dcache,
+ GslDataCacheNode *node);
+void gsl_data_cache_free_olders (GslDataCache *dcache,
+ guint max_age);
+GslDataCache* gsl_data_cache_from_dhandle (GslDataHandle *dhandle,
+ guint min_padding);
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_DATA_CACHE_H__ */
diff --git a/flow/gsl/gsldatahandle-lbuffer.c b/flow/gsl/gsldatahandle-lbuffer.c
new file mode 100644
index 0000000..99538bf
--- /dev/null
+++ b/flow/gsl/gsldatahandle-lbuffer.c
@@ -0,0 +1,11 @@
+
+
+typedef struct {
+ GslDataHandle dhandle;
+
+ GslLong pcm_pos;
+ guint pcm_length;
+ guint pcm_size;
+} LBufferHandle;
+
+/* ring buffer, caching the last n values read */
diff --git a/flow/gsl/gsldatahandle-mad.c b/flow/gsl/gsldatahandle-mad.c
new file mode 100644
index 0000000..fcfdd7f
--- /dev/null
+++ b/flow/gsl/gsldatahandle-mad.c
@@ -0,0 +1,711 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001-2002 Tim Janik and Stefan Westerfeld
+ *
+ * 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.
+ */
+#include <gsl/gsldatahandle-mad.h>
+
+#include "gslfilehash.h"
+#include <gsl/gsldatautils.h>
+#include <assert.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+
+#if GSL_HAVE_LIBMAD
+#include <mad.h>
+
+
+/* --- debugging and errors --- */
+#define MAD_DEBUG GSL_DEBUG_FUNCTION (GSL_MSG_DATA_HANDLE, "MAD")
+#define MAD_MSG GSL_MESSAGE_FUNCTION (GSL_MSG_DATA_HANDLE, "MAD")
+
+
+/* --- defines --- */
+#define FILE_BUFFER_SIZE (1024 * 44) /* approximately 1 second at 320 kbit */
+#define SEEK_BY_READ_AHEAD(h) (((h)->sample_rate / ((h)->frame_size * 2))) /* FIXME */
+#define MAX_CHANNELS (5)
+
+
+/* --- typedefs & structures --- */
+typedef struct
+{
+ GslDataHandle dhandle;
+
+ /* setup data */
+ guint sample_rate;
+ guint frame_size;
+ guint stream_options;
+ guint accumulate_state_frames;
+ guint skip_seek_table : 1;
+
+ /* file IO */
+ guint eof : 1;
+ GslHFile *hfile;
+ guint file_pos;
+ const gchar *error;
+
+ /* seek table */
+ GTime seek_mtime;
+ guint n_seeks;
+ guint *seeks;
+
+ /* file read buffer */
+ guint bfill;
+ guint8 buffer[FILE_BUFFER_SIZE + MAD_BUFFER_GUARD];
+
+ /* pcm housekeeping */
+ GslLong pcm_pos, pcm_length, next_pcm_pos;
+
+ /* libmad structures */
+ struct mad_stream stream;
+ struct mad_frame frame;
+ struct mad_synth synth;
+} MadHandle;
+
+
+/* --- prototypes --- */
+static GslLong dh_mad_coarse_seek (GslDataHandle *data_handle,
+ GslLong voffset);
+
+
+/* --- functions --- */
+static gboolean /* FALSE: handle->eof || errno != 0 */
+stream_read (MadHandle *handle)
+{
+ struct mad_stream *stream = &handle->stream;
+ guint l;
+
+ /* no further data to read (flag must be reset upon seeks) */
+ if (handle->eof)
+ return FALSE;
+
+ /* keep remaining data in buffer */
+ if (stream->next_frame && handle->bfill)
+ {
+ handle->bfill = handle->buffer + handle->bfill - stream->next_frame;
+ memmove (handle->buffer, stream->next_frame, handle->bfill);
+ }
+
+ /* fill buffer */
+ l = gsl_hfile_pread (handle->hfile, handle->file_pos, FILE_BUFFER_SIZE - handle->bfill, handle->buffer + handle->bfill);
+ if (l > 0)
+ {
+ handle->bfill += l;
+ handle->file_pos += l;
+ }
+ else if (l == 0)
+ {
+ handle->eof = TRUE;
+ memset (handle->buffer + handle->bfill, 0, MAD_BUFFER_GUARD);
+ handle->bfill += MAD_BUFFER_GUARD;
+ handle->file_pos += MAD_BUFFER_GUARD; /* bogus, but doesn't matter at eof */
+ }
+
+ mad_stream_buffer (stream, handle->buffer, handle->bfill);
+
+ return l < 0 ? FALSE : TRUE;
+}
+
+static gboolean
+check_frame_validity (MadHandle *handle,
+ struct mad_header *header)
+{
+ guint frame_size = MAD_NSBSAMPLES (header) * 32;
+ gchar *reason = NULL;
+
+ if (frame_size <= 0)
+ reason = "frame_size < 1";
+
+ if (handle->frame_size && handle->dhandle.setup.n_channels)
+ {
+#if 0
+ if (frame_size != handle->frame_size)
+ reason = "frame with non-standard size";
+#endif
+ if (MAD_NCHANNELS (header) != handle->dhandle.setup.n_channels)
+ reason = "frame with non-standard channel count";
+ }
+
+ if (reason)
+ {
+ MAD_DEBUG ("skipping frame: %s", reason);
+ return FALSE;
+ }
+ else
+ return TRUE;
+}
+
+static gboolean
+read_next_frame_header (MadHandle *handle)
+{
+ gboolean succeeded = TRUE;
+
+ /* fetch next frame header */
+ if (mad_header_decode (&handle->frame.header, &handle->stream) < 0)
+ {
+ if (!MAD_RECOVERABLE (handle->stream.error) ||
+ handle->stream.error == MAD_ERROR_LOSTSYNC)
+ {
+ /* read on */
+ if (!stream_read (handle))
+ {
+ handle->error = handle->eof ? NULL : g_strerror (errno);
+ return FALSE;
+ }
+ return read_next_frame_header (handle); /* retry */
+ }
+
+ if (!check_frame_validity (handle, &handle->frame.header))
+ return read_next_frame_header (handle); /* retry */
+
+ succeeded = FALSE;
+ }
+
+ handle->error = handle->stream.error ? mad_stream_errorstr (&handle->stream) : NULL;
+
+ return succeeded;
+}
+
+static gboolean /* FALSE: handle->eof || handle->error != NULL */
+pcm_frame_read (MadHandle *handle,
+ gboolean synth)
+{
+ gboolean succeeded = TRUE;
+
+ if (mad_frame_decode (&handle->frame, &handle->stream) < 0)
+ {
+ if (!MAD_RECOVERABLE (handle->stream.error) ||
+ handle->stream.error == MAD_ERROR_LOSTSYNC)
+ {
+ /* MAD_RECOVERABLE()==TRUE: frame was read, decoding failed (about to skip frame)
+ * MAD_RECOVERABLE()==FALSE: frame was not read, need data
+ * note: MAD_RECOVERABLE (MAD_ERROR_LOSTSYNC) == TRUE
+ */
+
+ /* read on */
+ if (!stream_read (handle))
+ {
+ handle->error = handle->eof ? NULL : g_strerror (errno);
+ return FALSE;
+ }
+ return pcm_frame_read (handle, synth); /* retry */
+ }
+
+ succeeded = FALSE;
+ if (synth)
+ mad_frame_mute (&handle->frame);
+ }
+
+ handle->pcm_pos = handle->next_pcm_pos;
+ handle->pcm_length = handle->frame_size;
+ handle->next_pcm_pos += handle->pcm_length;
+
+ if (synth)
+ mad_synth_frame (&handle->synth, &handle->frame);
+
+ handle->error = handle->stream.error && !succeeded ? mad_stream_errorstr (&handle->stream) : NULL;
+
+ return succeeded;
+}
+
+static guint*
+create_seek_table (MadHandle *handle,
+ guint *n_seeks_p)
+{
+ guint *seeks = NULL;
+ guint offs, n_seeks = 0;
+
+ *n_seeks_p = 0;
+ mad_synth_finish (&handle->synth);
+ mad_frame_finish (&handle->frame);
+ mad_stream_finish (&handle->stream);
+ mad_stream_init (&handle->stream);
+ mad_frame_init (&handle->frame);
+ mad_synth_init (&handle->synth);
+ mad_stream_options (&handle->stream, handle->stream_options);
+
+ offs = 0;
+ /* lseek (handle->hfile, offs, SEEK_SET) */
+ handle->eof = FALSE;
+ handle->bfill = 0;
+ handle->file_pos = 0;
+
+ do
+ {
+ while (read_next_frame_header (handle))
+ {
+ guint this_pos = handle->file_pos - handle->bfill + handle->stream.this_frame - handle->buffer;
+ guint i = n_seeks++;
+
+ if (n_seeks > 256 * 1024) /* FIXME: max_frames */
+ {
+ g_free (seeks);
+ return NULL; /* FIXME: ETOOBIG */
+ }
+
+ if (gsl_alloc_upper_power2 (n_seeks) > gsl_alloc_upper_power2 (i))
+ seeks = g_renew (guint, seeks, gsl_alloc_upper_power2 (n_seeks));
+ seeks[i] = this_pos;
+
+ if (0)
+ {
+ if (mad_frame_decode (&handle->frame, &handle->stream) < 0)
+ MAD_DEBUG ("seektable frame read failed: %s", mad_stream_errorstr (&handle->stream));
+ mad_synth_frame (&handle->synth, &handle->frame);
+ MAD_DEBUG ("frame(%u) PCM:%u => FILE:%u FDIFF:%d (%x %x %x) br:%lu time:%ld/%lu mode:%u ext:%u flags:0x%x phase:%u",
+ i, i * handle->frame_size, this_pos, this_pos - seeks[MAX (i, 1) - 1],
+ handle->stream.this_frame[0], handle->stream.this_frame[1],
+ (handle->stream.this_frame[1] >> 1) & 3,
+ handle->frame.header.bitrate,
+ handle->frame.header.duration.seconds,
+ handle->frame.header.duration.fraction,
+ handle->frame.header.mode,
+ handle->frame.header.mode_extension,
+ handle->frame.header.flags,
+ handle->synth.phase);
+ }
+ }
+
+ if (!handle->eof)
+ {
+ MAD_DEBUG ("reading seektable frame failed: %s", handle->error ? handle->error : "Unknown");
+
+ /* frame read failed for a reason other than eof */
+ g_free (seeks);
+ return NULL; /* FIXME: EIO/errno */
+ }
+ }
+ while (!handle->eof);
+
+ /* reset file offset */
+ offs = 0;
+ /* lseek (handle->hfile, offs, SEEK_SET) */
+ handle->eof = FALSE;
+ handle->file_pos = 0;
+ handle->bfill = 0;
+
+ /* shrink table */
+ seeks = g_renew (guint, seeks, n_seeks);
+ *n_seeks_p = n_seeks;
+
+ return seeks;
+}
+
+static GslErrorType
+dh_mad_open (GslDataHandle *dhandle,
+ GslDataHandleSetup *setup)
+{
+ MadHandle *handle = (MadHandle*) dhandle;
+ GslHFile *hfile;
+ GslLong n;
+ gboolean seek_invalidated = FALSE;
+
+ hfile = gsl_hfile_open (handle->dhandle.name);
+ if (!hfile)
+ return gsl_error_from_errno (errno, GSL_ERROR_OPEN_FAILED);
+ handle->hfile = hfile;
+
+ seek_invalidated |= handle->seek_mtime != hfile->mtime;
+ handle->bfill = 0;
+ handle->eof = FALSE;
+ handle->pcm_pos = 0;
+ handle->pcm_length = 0;
+ handle->next_pcm_pos = 0;
+ handle->file_pos = 0;
+ mad_stream_init (&handle->stream);
+ mad_frame_init (&handle->frame);
+ mad_synth_init (&handle->synth);
+ mad_stream_options (&handle->stream, handle->stream_options);
+
+ /* fetch first frame */
+ if (!read_next_frame_header (handle))
+ goto OPEN_FAILED;
+
+ /* get n_channels, frame size and sample rate */
+ setup->bit_depth = 24;
+ setup->n_channels = MAD_NCHANNELS (&handle->frame.header);
+ n = MAD_NSBSAMPLES (&handle->frame.header) * 32;
+ seek_invalidated |= n != handle->frame_size;
+ handle->frame_size = n;
+ handle->sample_rate = handle->frame.header.samplerate;
+ if (setup->n_channels < 1 ||
+ setup->n_channels > MAX_CHANNELS ||
+ handle->frame_size < 1 ||
+ handle->sample_rate < 1)
+ goto OPEN_FAILED;
+
+ /* seek through the stream to collect frame positions */
+ if (seek_invalidated || !handle->n_seeks)
+ {
+ handle->seek_mtime = hfile->mtime;
+ handle->n_seeks = 0;
+ g_free (handle->seeks);
+ handle->seeks = NULL;
+ if (handle->skip_seek_table)
+ {
+ /* fake seek table */
+ handle->n_seeks = 1;
+ handle->seeks = g_new (guint, handle->n_seeks);
+ handle->seeks[0] = 0;
+ }
+ else
+ {
+ handle->seeks = create_seek_table (handle, &handle->n_seeks);
+ if (!handle->seeks)
+ goto OPEN_FAILED;
+ MAD_DEBUG ("frames in seektable: %u", handle->n_seeks);
+ }
+ }
+
+ /* validate/setup handle length */
+ n = handle->n_seeks * handle->frame_size * setup->n_channels;
+ if (n > 0)
+ setup->n_values = n;
+ else
+ goto OPEN_FAILED;
+
+ if (dh_mad_coarse_seek (&handle->dhandle, 0) != 0)
+ goto OPEN_FAILED;
+
+ return GSL_ERROR_NONE;
+
+ OPEN_FAILED:
+ g_free (handle->seeks);
+ handle->seeks = NULL;
+ handle->n_seeks = 0;
+ handle->seek_mtime = -1;
+ handle->bfill = 0;
+ handle->eof = FALSE;
+ handle->pcm_pos = 0;
+ handle->pcm_length = 0;
+ handle->next_pcm_pos = 0;
+ handle->file_pos = 0;
+ mad_synth_finish (&handle->synth);
+ mad_frame_finish (&handle->frame);
+ mad_stream_finish (&handle->stream);
+ gsl_hfile_close (handle->hfile);
+ handle->hfile = NULL;
+
+ return GSL_ERROR_OPEN_FAILED;
+}
+
+static GslLong
+dh_mad_read (GslDataHandle *dhandle,
+ GslLong voffset, /* in values */
+ GslLong n_values,
+ gfloat *values)
+{
+ MadHandle *handle = (MadHandle*) dhandle;
+ GslLong pos = voffset / dhandle->setup.n_channels;
+ gboolean frame_read_ok = TRUE;
+
+ if (pos < handle->pcm_pos ||
+ pos >= handle->pcm_pos + handle->pcm_length + SEEK_BY_READ_AHEAD (handle) * handle->frame_size)
+ {
+ GslLong tmp;
+
+ /* suckage, need to do lengthy seek in file */
+ tmp = dh_mad_coarse_seek (dhandle, voffset);
+ g_assert (tmp <= voffset);
+ }
+
+ while (pos >= handle->pcm_pos + handle->pcm_length)
+ frame_read_ok = pcm_frame_read (handle, TRUE);
+
+ /* check if the last call to pcm_frame_read() failed */
+ if (!frame_read_ok)
+ {
+ if (handle->stream.error == MAD_ERROR_BADDATAPTR)
+ {
+ /* if we encounter that the inter-frame accumulated layer-III state
+ * is not complete now, we'll try to increase the amount of frames
+ * we accumulate
+ */
+ if (handle->accumulate_state_frames < 10)
+ {
+ handle->accumulate_state_frames++;
+ MAD_DEBUG ("retrying seek with accumulate_state_frames=%d",
+ handle->accumulate_state_frames);
+
+ /* force dh_mad_read to retry the seek */
+ dh_mad_coarse_seek (dhandle, 0);
+ return dh_mad_read (dhandle, voffset, n_values, values);
+ }
+ else
+ {
+ MAD_DEBUG ("synthesizing frame failed, accumulate_state_frames is already %u: %s",
+ handle->accumulate_state_frames, handle->error);
+ return -1;
+ }
+ }
+ else
+ {
+ MAD_DEBUG ("failed to synthesize frame: %s", handle->error);
+ return -1;
+ }
+ }
+
+ n_values = MIN (n_values, handle->pcm_length * dhandle->setup.n_channels);
+
+ /* interleave into output buffer */
+ if (pos >= handle->pcm_pos && pos < handle->pcm_pos + handle->pcm_length)
+ {
+ guint offset = voffset - handle->pcm_pos * dhandle->setup.n_channels;
+ guint align = offset % dhandle->setup.n_channels;
+ guint n_samples = MIN (n_values, handle->pcm_length * dhandle->setup.n_channels - offset);
+ mad_fixed_t *pcm[MAX_CHANNELS];
+ gfloat *bound = values + n_samples;
+ guint i;
+
+ offset /= dhandle->setup.n_channels;
+ for (i = 0; i < dhandle->setup.n_channels; i++)
+ pcm[i] = handle->synth.pcm.samples[i] + offset + (i < align);
+
+ for (i = align; values < bound; values++)
+ {
+ mad_fixed_t mf = *(pcm[i]++);
+
+ *values = CLAMP (mf, -MAD_F_ONE, MAD_F_ONE) * (1. / (double) MAD_F_ONE);
+ if (++i >= dhandle->setup.n_channels)
+ i = 0;
+ }
+ return n_samples;
+ }
+ else /* something went wrong here, _badly_ */
+ {
+ MAD_MSG (GSL_ERROR_READ_FAILED,
+ "pcm position screwed (pos: %lu, handle-pos: %lu), aborting read",
+ pos, handle->pcm_pos);
+ return -1;
+ }
+}
+
+static GslLong
+dh_mad_coarse_seek (GslDataHandle *dhandle,
+ GslLong voffset)
+{
+ MadHandle *handle = (MadHandle*) dhandle;
+ GslLong opos = handle->pcm_pos, pos = voffset / dhandle->setup.n_channels;
+
+ if (voffset < 0) /* pcm_tell() */
+ return handle->pcm_pos * dhandle->setup.n_channels;
+
+ if (pos < handle->pcm_pos ||
+ pos >= handle->pcm_pos + handle->pcm_length + SEEK_BY_READ_AHEAD (handle))
+ {
+ GslLong offs = pos;
+ guint i, file_pos;
+
+ /* reset decoder state */
+ mad_synth_finish (&handle->synth);
+ mad_frame_finish (&handle->frame);
+ mad_stream_finish (&handle->stream);
+ mad_stream_init (&handle->stream);
+ mad_frame_init (&handle->frame);
+ mad_synth_init (&handle->synth);
+ mad_stream_options (&handle->stream, handle->stream_options);
+
+ /* seek to some frames read ahead to accumulate layer III IDCMT state */
+ offs -= (gint) (handle->frame_size * handle->accumulate_state_frames);
+ offs = CLAMP (offs, 0, (gint) (handle->n_seeks * handle->frame_size));
+
+ /* get file position from seek table */
+ i = offs / handle->frame_size;
+ file_pos = handle->seeks[i];
+
+ /* perform file seek and adjust positions */
+ /* lseek (handle->hfile, file_pos, SEEK_SET) */
+ handle->eof = FALSE;
+ handle->bfill = 0;
+ handle->file_pos = file_pos;
+ handle->pcm_pos = i * handle->frame_size;
+ handle->pcm_length = 0;
+ handle->next_pcm_pos = handle->pcm_pos;
+
+#if 0
+ /* adapt synth phase */
+ handle->synth.phase = ((i + 1) * (handle->frame_size / 32)) % 16;
+#endif
+
+ /* accumulate state */
+ if (pos >= handle->accumulate_state_frames * handle->frame_size)
+ {
+ guint i;
+ for (i = 0; i < handle->accumulate_state_frames; i++)
+ {
+ gboolean synth = i + 1 == handle->accumulate_state_frames;
+
+ if (!pcm_frame_read (handle, synth) && handle->stream.error != MAD_ERROR_BADDATAPTR)
+ MAD_DEBUG ("COARSE-SEEK: frame read ahead (%u): failed: %s", i, handle->error);
+ }
+ }
+
+ MAD_DEBUG ("seek-done: at %lu (f:%lu) want %lu (f:%lu) got %lu (f:%lu) diff %ld (diff-requested %ld)",
+ opos, opos / handle->frame_size,
+ pos, pos / handle->frame_size,
+ handle->pcm_pos, handle->pcm_pos / handle->frame_size,
+ handle->pcm_pos - opos, pos - opos);
+ }
+
+ return handle->pcm_pos * dhandle->setup.n_channels;
+}
+
+static void
+dh_mad_close (GslDataHandle *data_handle)
+{
+ MadHandle *handle = (MadHandle*) data_handle;
+
+ handle->bfill = 0;
+ handle->eof = FALSE;
+ handle->pcm_pos = 0;
+ handle->pcm_length = 0;
+ handle->next_pcm_pos = 0;
+ handle->file_pos = 0;
+ mad_synth_finish (&handle->synth);
+ mad_frame_finish (&handle->frame);
+ mad_stream_finish (&handle->stream);
+ gsl_hfile_close (handle->hfile);
+ handle->hfile = NULL;
+}
+
+static void
+dh_mad_destroy (GslDataHandle *data_handle)
+{
+ MadHandle *handle = (MadHandle*) data_handle;
+
+ g_free (handle->seeks);
+ handle->seeks = NULL;
+ handle->n_seeks = 0;
+ gsl_data_handle_common_free (data_handle);
+ gsl_delete_struct (MadHandle, handle);
+}
+
+static GslDataHandleFuncs dh_mad_vtable = {
+ dh_mad_open,
+ dh_mad_read,
+ dh_mad_close,
+ dh_mad_destroy,
+ dh_mad_coarse_seek,
+};
+
+static GslDataHandle*
+dh_mad_new (const gchar *file_name,
+ gboolean skip_seek_keep_open)
+{
+ MadHandle *handle;
+ gboolean success;
+
+ handle = gsl_new_struct0 (MadHandle, 1);
+ success = gsl_data_handle_common_init (&handle->dhandle, file_name);
+ if (success)
+ {
+ GslErrorType error;
+
+ handle->dhandle.vtable = &dh_mad_vtable;
+ handle->sample_rate = 0;
+ handle->frame_size = 0;
+ handle->stream_options = MAD_OPTION_IGNORECRC;
+ handle->accumulate_state_frames = 0;
+ handle->eof = FALSE;
+ handle->hfile = NULL;
+ handle->file_pos = 0;
+ handle->error = NULL;
+ handle->n_seeks = 0;
+ handle->seeks = NULL;
+ handle->seek_mtime = -1;
+ handle->bfill = 0;
+ handle->pcm_pos = handle->pcm_length = handle->next_pcm_pos = 0;
+
+ /* we can only check matters upon opening
+ */
+ handle->skip_seek_table = skip_seek_keep_open != FALSE;
+ error = gsl_data_handle_open (&handle->dhandle);
+ if (!error)
+ {
+ if (!skip_seek_keep_open)
+ gsl_data_handle_close (&handle->dhandle);
+ return &handle->dhandle;
+ }
+ gsl_data_handle_unref (&handle->dhandle);
+ return NULL;
+ }
+ else
+ {
+ g_free (handle->seeks);
+ gsl_delete_struct (MadHandle, handle);
+ return NULL;
+ }
+}
+
+GslDataHandle*
+gsl_data_handle_new_mad (const gchar *file_name)
+{
+ g_return_val_if_fail (file_name != NULL, NULL);
+
+ return dh_mad_new (file_name, FALSE);
+}
+
+GslErrorType
+gsl_data_handle_mad_testopen (const gchar *file_name,
+ guint *n_channels,
+ gfloat *mix_freq)
+{
+ GslDataHandle *dhandle;
+ MadHandle *handle;
+
+ g_return_val_if_fail (file_name != NULL, GSL_ERROR_INTERNAL);
+
+ dhandle = dh_mad_new (file_name, TRUE);
+ if (!dhandle)
+ return GSL_ERROR_OPEN_FAILED;
+
+ handle = (MadHandle*) dhandle;
+ if (n_channels)
+ *n_channels = handle->dhandle.setup.n_channels;
+ if (mix_freq)
+ *mix_freq = handle->sample_rate;
+ gsl_data_handle_close (dhandle);
+ gsl_data_handle_unref (dhandle);
+
+ return GSL_ERROR_NONE;
+}
+
+#else /* !GSL_HAVE_LIBMAD */
+
+GslDataHandle*
+gsl_data_handle_new_mad (const gchar *file_name)
+{
+ return NULL;
+}
+
+GslErrorType
+gsl_data_handle_mad_testopen (const gchar *file_name,
+ guint *n_channels,
+ gfloat *mix_freq)
+{
+ return GSL_ERROR_FORMAT_UNKNOWN;
+}
+
+#endif /* !GSL_HAVE_LIBMAD */
+
+/* vim:set ts=8 sts=2 sw=2: */
diff --git a/flow/gsl/gsldatahandle-mad.h b/flow/gsl/gsldatahandle-mad.h
new file mode 100644
index 0000000..8c73ef7
--- /dev/null
+++ b/flow/gsl/gsldatahandle-mad.h
@@ -0,0 +1,42 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001-2002 Tim Janik and Stefan Westerfeld
+ *
+ * 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.
+ */
+#ifndef __GSL_DATA_HANDLE_MAD_H__
+#define __GSL_DATA_HANDLE_MAD_H__
+
+#include <gsl/gslcommon.h>
+#include <gsl/gsldatahandle.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* linear-read handle. needs buffering handle wrapper
+ */
+GslDataHandle* gsl_data_handle_new_mad (const gchar *file_name);
+GslErrorType gsl_data_handle_mad_testopen (const gchar *file_name,
+ guint *n_channels,
+ gfloat *mix_freq);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_DATA_HANDLE_MAD_H__ */
diff --git a/flow/gsl/gsldatahandle-vorbis.c b/flow/gsl/gsldatahandle-vorbis.c
new file mode 100644
index 0000000..9b84ae0
--- /dev/null
+++ b/flow/gsl/gsldatahandle-vorbis.c
@@ -0,0 +1,376 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001-2002 Tim Janik
+ *
+ * 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.
+ */
+#include "gsldatahandle-vorbis.h"
+
+#if GSL_HAVE_OGGVORBIS
+#include "gslfilehash.h"
+#include <ogg/ogg.h>
+#include <vorbis/vorbisfile.h>
+#include <errno.h>
+
+
+/* --- defines --- */
+#define MAX_CHANNELS (16) /* hard limit, eases our life somewhat */
+/* number of values to decode and throw away instead of seeking. since
+ * seeking can be quite time consuming, this should cover a good range
+ * of seek-ahead space
+ */
+#define SEEK_BY_READ_AHEAD(vhandle) (vhandle->max_block_size * 8)
+
+
+/* --- structure --- */
+typedef struct {
+ GslDataHandle dhandle;
+
+ guint stream;
+ guint n_streams;
+
+ /* live data */
+ gint64 soffset; /* our PCM start offset */
+ guint max_block_size;
+
+ /* pcm read out cache */
+ GslLong pcm_pos, pcm_length;
+ gfloat *pcm[MAX_CHANNELS];
+
+ OggVorbis_File ofile;
+} VorbisHandle;
+
+
+/* --- functions --- */
+static GslErrorType
+ov_errno_to_error (gint ov_errno,
+ GslErrorType fallback)
+{
+ switch (ov_errno)
+ {
+ case OV_EOF: return GSL_ERROR_EOF;
+ case OV_EBADLINK:
+ case OV_EBADPACKET:
+ case OV_HOLE: return GSL_ERROR_DATA_CORRUPT;
+ case OV_EREAD: return GSL_ERROR_READ_FAILED;
+ case OV_ENOSEEK: return GSL_ERROR_SEEK_FAILED;
+ case OV_EFAULT:
+ case OV_EIMPL: return GSL_ERROR_CODEC_FAILURE;
+ case OV_EINVAL: return GSL_ERROR_INTERNAL;
+ case OV_ENOTAUDIO:
+ case OV_EVERSION:
+ case OV_EBADHEADER:
+ case OV_ENOTVORBIS: return GSL_ERROR_FORMAT_INVALID;
+ case OV_FALSE:
+ default: return fallback;
+ }
+}
+
+static size_t
+rfile_read (void *ptr,
+ size_t size,
+ size_t nmemb,
+ void *datasource)
+{
+ GslRFile *rfile = datasource;
+ return gsl_rfile_read (rfile, size * nmemb, ptr);
+}
+
+static int
+rfile_seek (void *datasource,
+ ogg_int64_t offset,
+ int whence)
+{
+ GslRFile *rfile = datasource;
+ GslLong l;
+ switch (whence)
+ {
+ default:
+ case SEEK_SET:
+ l = gsl_rfile_seek_set (rfile, offset);
+ break;
+ case SEEK_CUR:
+ l = gsl_rfile_position (rfile);
+ l = gsl_rfile_seek_set (rfile, l + offset);
+ break;
+ case SEEK_END:
+ l = gsl_rfile_length (rfile);
+ l = gsl_rfile_seek_set (rfile, l + offset);
+ break;
+ }
+ return l;
+}
+
+static int
+rfile_close (void *datasource)
+{
+ GslRFile *rfile = datasource;
+ gsl_rfile_close (rfile);
+ return 0;
+}
+
+static long
+rfile_tell (void *datasource)
+{
+ GslRFile *rfile = datasource;
+ return gsl_rfile_position (rfile);
+}
+
+static ov_callbacks rfile_ov_callbacks = {
+ rfile_read,
+ rfile_seek,
+ rfile_close,
+ rfile_tell,
+};
+
+static GslErrorType
+dh_vorbis_open (GslDataHandle *data_handle,
+ GslDataHandleSetup *setup)
+{
+ VorbisHandle *vhandle = (VorbisHandle*) data_handle;
+ GslRFile *rfile;
+ vorbis_info *vi;
+ GslLong n, i;
+ gint err;
+
+#if 0
+ file = fopen (vhandle->dhandle.name, "r");
+ if (!file)
+ return gsl_error_from_errno (errno, GSL_ERROR_OPEN_FAILED);
+ err = ov_open (file, &vhandle->ofile, NULL, 0);
+ if (err < 0)
+ {
+ fclose (file);
+ return ov_errno_to_error (err, GSL_ERROR_OPEN_FAILED);
+ }
+#endif
+
+ rfile = gsl_rfile_open (vhandle->dhandle.name);
+ if (!rfile)
+ return gsl_error_from_errno (errno, GSL_ERROR_OPEN_FAILED);
+ err = ov_open_callbacks (rfile, &vhandle->ofile, NULL, 0, rfile_ov_callbacks);
+ if (err < 0)
+ {
+ gsl_rfile_close (rfile);
+ return ov_errno_to_error (err, GSL_ERROR_OPEN_FAILED);
+ }
+
+ n = ov_streams (&vhandle->ofile);
+ if (n > vhandle->stream)
+ vhandle->n_streams = n;
+ else
+ {
+ ov_clear (&vhandle->ofile); /* closes file */
+ return GSL_ERROR_OPEN_FAILED;
+ }
+
+ vhandle->soffset = 0;
+ for (i = 0; i < vhandle->stream; i++)
+ vhandle->soffset += ov_pcm_total (&vhandle->ofile, i);
+
+ n = ov_pcm_total (&vhandle->ofile, vhandle->stream);
+ vi = ov_info (&vhandle->ofile, vhandle->stream);
+ if (n > 0 && vi && vi->channels && ov_pcm_seek (&vhandle->ofile, vhandle->soffset) >= 0)
+ {
+ setup->n_channels = vi->channels;
+ setup->n_values = n * setup->n_channels;
+ setup->bit_depth = 24;
+ }
+ else
+ {
+ ov_clear (&vhandle->ofile); /* closes file */
+ return GSL_ERROR_OPEN_FAILED;
+ }
+
+ vhandle->max_block_size = vorbis_info_blocksize (vi, 0);
+ n = vorbis_info_blocksize (vi, 1);
+ vhandle->max_block_size = MAX (vhandle->max_block_size, n);
+ vhandle->pcm_pos = 0;
+ vhandle->pcm_length = 0;
+
+ return GSL_ERROR_NONE;
+}
+
+static GslLong
+dh_vorbis_coarse_seek (GslDataHandle *dhandle,
+ GslLong voffset)
+{
+ VorbisHandle *vhandle = (VorbisHandle*) dhandle;
+ GslLong opos = vhandle->pcm_pos, pos = voffset / dhandle->setup.n_channels;
+
+ if (voffset < 0)
+ return vhandle->pcm_pos * dhandle->setup.n_channels;
+
+ if (pos < vhandle->pcm_pos ||
+ pos >= vhandle->pcm_pos + vhandle->pcm_length + SEEK_BY_READ_AHEAD (vhandle))
+ {
+ gint err = ov_pcm_seek_page (&vhandle->ofile, vhandle->soffset + pos);
+
+ if (err) /* eek */
+ err = ov_pcm_seek_page (&vhandle->ofile, vhandle->soffset);
+ else
+ vhandle->pcm_pos = ov_pcm_tell (&vhandle->ofile) - vhandle->soffset;
+ if (err || vhandle->pcm_pos < 0) /* urg, we're completely screwed */
+ vhandle->pcm_pos = 0;
+ vhandle->pcm_length = 0;
+ }
+ g_printerr ("OggS-SEEK: at %lu want %lu got %lu (diff-requested %ld)\n",
+ opos, pos, vhandle->pcm_pos, pos - opos);
+
+ return vhandle->pcm_pos * dhandle->setup.n_channels;
+}
+
+static void
+read_packet (VorbisHandle *vhandle)
+{
+ gfloat **pcm = NULL;
+ gint stream_id, i;
+
+ vhandle->pcm_pos = ov_pcm_tell (&vhandle->ofile) - vhandle->soffset;
+#if GSL_HAVE_OGGVORBIS_RC3
+ vhandle->pcm_length = ov_read_float (&vhandle->ofile, &pcm, &stream_id);
+#else
+ vhandle->pcm_length = ov_read_float (&vhandle->ofile, &pcm, (~0U>>1), &stream_id);
+#endif
+ if (vhandle->pcm_pos < 0 || vhandle->pcm_length < 0 || stream_id != vhandle->stream)
+ {
+ /* urg, this is bad! */
+ dh_vorbis_coarse_seek (&vhandle->dhandle, 0);
+ }
+ else
+ for (i = 0; i < vhandle->dhandle.setup.n_channels; i++)
+ vhandle->pcm[i] = pcm[i];
+}
+
+static GslLong
+dh_vorbis_read (GslDataHandle *dhandle,
+ GslLong voffset, /* in values */
+ GslLong n_values,
+ gfloat *values)
+{
+ VorbisHandle *vhandle = (VorbisHandle*) dhandle;
+ GslLong pos = voffset / dhandle->setup.n_channels;
+
+ if (pos < vhandle->pcm_pos ||
+ pos >= vhandle->pcm_pos + vhandle->pcm_length + SEEK_BY_READ_AHEAD (vhandle))
+ {
+ GslLong tmp;
+
+ /* suckage, needs to seek in file, this takes ages */
+ tmp = dh_vorbis_coarse_seek (dhandle, voffset);
+ g_assert (tmp <= voffset);
+ }
+
+ while (pos >= vhandle->pcm_pos + vhandle->pcm_length)
+ read_packet (vhandle);
+
+ n_values = MIN (n_values, vhandle->pcm_length * dhandle->setup.n_channels);
+
+ /* interleave into output buffer */
+ if (pos >= vhandle->pcm_pos && pos < vhandle->pcm_pos + vhandle->pcm_length)
+ {
+ guint offset = voffset - vhandle->pcm_pos * dhandle->setup.n_channels;
+ guint align = offset % dhandle->setup.n_channels;
+ guint n_samples = MIN (n_values, vhandle->pcm_length * dhandle->setup.n_channels - offset);
+ gfloat *pcm[MAX_CHANNELS], *bound = values + n_samples;
+ guint i;
+
+ offset /= dhandle->setup.n_channels;
+ for (i = 0; i < dhandle->setup.n_channels; i++)
+ pcm[i] = vhandle->pcm[i] + offset + (i < align);
+
+ for (i = align; values < bound; values++)
+ {
+ gfloat f = *(pcm[i]++);
+
+ f = CLAMP (f, -1.0, 1.0);
+ *values = f;
+ if (++i >= dhandle->setup.n_channels)
+ i = 0;
+ }
+ return n_samples;
+ }
+ else /* something went wrong here, _badly_ */
+ return 0;
+}
+
+static void
+dh_vorbis_close (GslDataHandle *dhandle)
+{
+ VorbisHandle *vhandle = (VorbisHandle*) dhandle;
+
+ ov_clear (&vhandle->ofile);
+ vhandle->pcm_pos = 0;
+ vhandle->pcm_length = 0;
+}
+
+static void
+dh_vorbis_destroy (GslDataHandle *data_handle)
+{
+ VorbisHandle *vhandle = (VorbisHandle*) data_handle;
+
+ gsl_data_handle_common_free (data_handle);
+ gsl_delete_struct (VorbisHandle, vhandle);
+}
+
+static GslDataHandleFuncs dh_vorbis_vtable = {
+ dh_vorbis_open,
+ dh_vorbis_read,
+ dh_vorbis_close,
+ dh_vorbis_destroy,
+ dh_vorbis_coarse_seek,
+};
+
+GslDataHandle*
+gsl_data_handle_new_ogg_vorbis (const gchar *file_name,
+ guint lbitstream)
+{
+ VorbisHandle *vhandle;
+ gboolean success;
+
+ g_return_val_if_fail (file_name != NULL, NULL);
+
+ vhandle = gsl_new_struct0 (VorbisHandle, 1);
+ success = gsl_data_handle_common_init (&vhandle->dhandle, file_name);
+ if (success)
+ {
+ GslErrorType error;
+
+ vhandle->dhandle.vtable = &dh_vorbis_vtable;
+ vhandle->n_streams = 0;
+ vhandle->stream = lbitstream;
+
+ /* we can only check matters upon opening
+ */
+ error = gsl_data_handle_open (&vhandle->dhandle);
+ if (!error)
+ {
+ gsl_data_handle_close (&vhandle->dhandle);
+ return &vhandle->dhandle;
+ }
+ else
+ {
+ gsl_data_handle_unref (&vhandle->dhandle);
+ return NULL;
+ }
+ }
+ else
+ {
+ gsl_delete_struct (VorbisHandle, vhandle);
+ return NULL;
+ }
+}
+#endif /* GSL_HAVE_OGGVORBIS */
+
diff --git a/flow/gsl/gsldatahandle-vorbis.h b/flow/gsl/gsldatahandle-vorbis.h
new file mode 100644
index 0000000..8887923
--- /dev/null
+++ b/flow/gsl/gsldatahandle-vorbis.h
@@ -0,0 +1,41 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001-2002 Tim Janik
+ *
+ * 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.
+ */
+#ifndef __GSL_DATA_HANDLE_VORBIS_H__
+#define __GSL_DATA_HANDLE_VORBIS_H__
+
+
+#include <gsl/gslcommon.h>
+#include <gsl/gsldatahandle.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* linear-read handle! needs linbuffer handle wrapper
+ */
+GslDataHandle* gsl_data_handle_new_ogg_vorbis (const gchar *file_name,
+ guint lbitstream);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_DATA_HANDLE_VORBIS_H__ */
diff --git a/flow/gsl/gsldatahandle.c b/flow/gsl/gsldatahandle.c
new file mode 100644
index 0000000..c746ec7
--- /dev/null
+++ b/flow/gsl/gsldatahandle.c
@@ -0,0 +1,1241 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001 Tim Janik
+ *
+ * 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.
+ */
+#include "gsldatahandle.h"
+
+#include "gslcommon.h"
+#include "gsldatacache.h"
+#include "gslfilehash.h"
+
+#include <string.h>
+#include <errno.h>
+
+
+/* --- typedefs --- */
+typedef struct {
+ GslDataHandle dhandle;
+ guint n_channels;
+ guint bit_depth;
+ GslLong n_values;
+ const gfloat *values;
+ void (*free_values) (gpointer);
+} MemHandle;
+typedef struct {
+ GslDataHandle dhandle;
+ GslDataHandle *src_handle;
+} ChainHandle;
+typedef ChainHandle ReversedHandle;
+typedef struct {
+ GslDataHandle dhandle;
+ GslDataHandle *src_handle; /* mirror ChainHandle */
+ GslLong cut_offset;
+ GslLong n_cut_values;
+ GslLong tail_cut;
+} CutHandle;
+typedef struct {
+ GslDataHandle dhandle;
+ GslDataHandle *src_handle; /* mirror ChainHandle */
+ GslLong requested_paste_offset;
+ GslLong paste_offset;
+ GslLong n_paste_values;
+ guint paste_bit_depth;
+ const gfloat *paste_values;
+ void (*free_values) (gpointer);
+} InsertHandle;
+typedef struct {
+ GslDataHandle dhandle;
+ GslDataHandle *src_handle; /* mirror ChainHandle */
+ GslLong requested_first;
+ GslLong requested_last;
+ GslLong loop_start;
+ GslLong loop_width;
+} LoopHandle;
+typedef struct {
+ GslDataHandle dhandle;
+ GslDataCache *dcache;
+ guint node_size;
+} DCacheHandle;
+typedef struct {
+ GslDataHandle dhandle;
+ guint n_channels;
+ GslWaveFormatType format;
+ guint byte_order;
+ GslLong byte_offset;
+ GslLong requested_length;
+ GslHFile *hfile;
+} WaveHandle;
+
+
+/* --- standard functions --- */
+gboolean
+gsl_data_handle_common_init (GslDataHandle *dhandle,
+ const gchar *file_name)
+{
+ g_return_val_if_fail (dhandle != NULL, FALSE);
+ g_return_val_if_fail (dhandle->vtable == NULL, FALSE);
+ g_return_val_if_fail (dhandle->name == NULL, FALSE);
+ g_return_val_if_fail (dhandle->ref_count == 0, FALSE);
+
+ dhandle->name = g_strdup (file_name);
+ gsl_mutex_init (&dhandle->mutex);
+ dhandle->ref_count = 1;
+ dhandle->open_count = 0;
+ memset (&dhandle->setup, 0, sizeof (dhandle->setup));
+
+ return TRUE;
+}
+
+GslDataHandle*
+gsl_data_handle_ref (GslDataHandle *dhandle)
+{
+ g_return_val_if_fail (dhandle != NULL, NULL);
+ g_return_val_if_fail (dhandle->ref_count > 0, NULL);
+
+ GSL_SPIN_LOCK (&dhandle->mutex);
+ dhandle->ref_count++;
+ GSL_SPIN_UNLOCK (&dhandle->mutex);
+
+ return dhandle;
+}
+
+void
+gsl_data_handle_common_free (GslDataHandle *dhandle)
+{
+ g_return_if_fail (dhandle != NULL);
+ g_return_if_fail (dhandle->vtable != NULL);
+ g_return_if_fail (dhandle->ref_count == 0);
+
+ g_free (dhandle->name);
+ dhandle->name = NULL;
+ gsl_mutex_destroy (&dhandle->mutex);
+}
+
+void
+gsl_data_handle_unref (GslDataHandle *dhandle)
+{
+ gboolean destroy;
+
+ g_return_if_fail (dhandle != NULL);
+ g_return_if_fail (dhandle->ref_count > 0);
+
+ GSL_SPIN_LOCK (&dhandle->mutex);
+ dhandle->ref_count--;
+ destroy = dhandle->ref_count == 0;
+ GSL_SPIN_UNLOCK (&dhandle->mutex);
+ if (destroy)
+ {
+ g_return_if_fail (dhandle->open_count == 0);
+ dhandle->vtable->destroy (dhandle);
+ }
+}
+
+GslErrorType
+gsl_data_handle_open (GslDataHandle *dhandle)
+{
+ g_return_val_if_fail (dhandle != NULL, GSL_ERROR_INTERNAL);
+ g_return_val_if_fail (dhandle->ref_count > 0, GSL_ERROR_INTERNAL);
+
+ GSL_SPIN_LOCK (&dhandle->mutex);
+ if (dhandle->open_count == 0)
+ {
+ GslErrorType error;
+
+ memset (&dhandle->setup, 0, sizeof (dhandle->setup));
+ error = dhandle->vtable->open (dhandle, &dhandle->setup);
+ if (!error && (dhandle->setup.n_values < 0 ||
+ dhandle->setup.n_channels < 1 ||
+ dhandle->setup.bit_depth < 1))
+ {
+ g_warning ("internal error in data handle open() (%p): nv=%ld nc=%u bd=%u",
+ dhandle->vtable->open, dhandle->setup.n_values, dhandle->setup.n_channels, dhandle->setup.bit_depth);
+ dhandle->vtable->close (dhandle);
+ error = GSL_ERROR_INTERNAL;
+ }
+ if (error)
+ {
+ memset (&dhandle->setup, 0, sizeof (dhandle->setup));
+ GSL_SPIN_UNLOCK (&dhandle->mutex);
+ return error;
+ }
+ dhandle->ref_count++;
+ dhandle->open_count++;
+ }
+ else
+ dhandle->open_count++;
+ GSL_SPIN_UNLOCK (&dhandle->mutex);
+
+ return GSL_ERROR_NONE;
+}
+
+void
+gsl_data_handle_close (GslDataHandle *dhandle)
+{
+ gboolean need_unref;
+
+ g_return_if_fail (dhandle != NULL);
+ g_return_if_fail (dhandle->ref_count > 0);
+ g_return_if_fail (dhandle->open_count > 0);
+
+ GSL_SPIN_LOCK (&dhandle->mutex);
+ dhandle->open_count--;
+ need_unref = !dhandle->open_count;
+ if (!dhandle->open_count)
+ dhandle->vtable->close (dhandle);
+ GSL_SPIN_UNLOCK (&dhandle->mutex);
+ if (need_unref)
+ gsl_data_handle_unref (dhandle);
+}
+
+GslLong
+gsl_data_handle_read (GslDataHandle *dhandle,
+ GslLong value_offset,
+ GslLong n_values,
+ gfloat *values)
+{
+ GslLong l;
+
+ g_return_val_if_fail (dhandle != NULL, -1);
+ g_return_val_if_fail (dhandle->open_count > 0, -1);
+ g_return_val_if_fail (value_offset >= 0, -1);
+ if (n_values < 1)
+ return 0;
+ g_return_val_if_fail (values != NULL, -1);
+ g_return_val_if_fail (value_offset < dhandle->setup.n_values, -1);
+
+ n_values = MIN (n_values, dhandle->setup.n_values - value_offset);
+ GSL_SPIN_LOCK (&dhandle->mutex);
+ l = dhandle->vtable->read (dhandle, value_offset, n_values, values);
+ GSL_SPIN_UNLOCK (&dhandle->mutex);
+
+ return l;
+}
+
+GslLong
+gsl_data_handle_length (GslDataHandle *dhandle)
+{
+ GslLong l;
+
+ g_return_val_if_fail (dhandle != NULL, 0);
+ g_return_val_if_fail (dhandle->open_count > 0, 0);
+
+ GSL_SPIN_LOCK (&dhandle->mutex);
+ l = dhandle->open_count ? dhandle->setup.n_values : 0;
+ GSL_SPIN_UNLOCK (&dhandle->mutex);
+
+ return l;
+}
+
+guint
+gsl_data_handle_n_channels (GslDataHandle *dhandle)
+{
+ guint n;
+
+ g_return_val_if_fail (dhandle != NULL, 0);
+ g_return_val_if_fail (dhandle->open_count > 0, 0);
+
+ GSL_SPIN_LOCK (&dhandle->mutex);
+ n = dhandle->open_count ? dhandle->setup.n_channels : 0;
+ GSL_SPIN_UNLOCK (&dhandle->mutex);
+
+ return n;
+}
+
+guint
+gsl_data_handle_bit_depth (GslDataHandle *dhandle)
+{
+ guint n;
+
+ g_return_val_if_fail (dhandle != NULL, 0);
+ g_return_val_if_fail (dhandle->open_count > 0, 0);
+
+ GSL_SPIN_LOCK (&dhandle->mutex);
+ n = dhandle->open_count ? dhandle->setup.bit_depth : 0;
+ GSL_SPIN_UNLOCK (&dhandle->mutex);
+
+ return n;
+}
+
+const gchar*
+gsl_data_handle_name (GslDataHandle *dhandle)
+{
+ g_return_val_if_fail (dhandle != NULL, NULL);
+
+ return dhandle->name;
+}
+
+
+/* --- const memory handle --- */
+static GslErrorType
+mem_handle_open (GslDataHandle *dhandle,
+ GslDataHandleSetup *setup)
+{
+ MemHandle *mhandle = (MemHandle*) dhandle;
+
+ setup->n_values = mhandle->n_values;
+ setup->n_channels = mhandle->n_channels;
+ setup->bit_depth = mhandle->bit_depth;
+
+ return GSL_ERROR_NONE;
+}
+
+static void
+mem_handle_close (GslDataHandle *dhandle)
+{
+ /* MemHandle *mhandle = (MemHandle*) dhandle; */
+}
+
+static void
+mem_handle_destroy (GslDataHandle *dhandle)
+{
+ MemHandle *mhandle = (MemHandle*) dhandle;
+ void (*free_values) (gpointer) = mhandle->free_values;
+ const gfloat *mem_values = mhandle->values;
+
+ gsl_data_handle_common_free (dhandle);
+ mhandle->values = NULL;
+ mhandle->free_values = NULL;
+ gsl_delete_struct (MemHandle, mhandle);
+
+ if (free_values)
+ free_values ((gpointer) mem_values);
+}
+
+static GslLong
+mem_handle_read (GslDataHandle *dhandle,
+ GslLong voffset,
+ GslLong n_values,
+ gfloat *values)
+{
+ MemHandle *mhandle = (MemHandle*) dhandle;
+
+ g_return_val_if_fail (voffset + n_values <= mhandle->n_values, -1);
+
+ memcpy (values, mhandle->values + voffset, n_values * sizeof (values[0]));
+
+ return n_values;
+}
+
+GslDataHandle*
+gsl_data_handle_new_mem (guint n_channels,
+ guint bit_depth,
+ GslLong n_values,
+ const gfloat *values,
+ void (*free) (gpointer values))
+{
+ static GslDataHandleFuncs mem_handle_vtable = {
+ mem_handle_open,
+ mem_handle_read,
+ mem_handle_close,
+ mem_handle_destroy,
+ };
+ MemHandle *mhandle;
+ gboolean success;
+
+ g_return_val_if_fail (n_channels > 0, NULL);
+ g_return_val_if_fail (bit_depth > 0, NULL);
+ g_return_val_if_fail (n_values >= n_channels, NULL);
+ if (n_values)
+ g_return_val_if_fail (values != NULL, NULL);
+
+ mhandle = gsl_new_struct0 (MemHandle, 1);
+ success = gsl_data_handle_common_init (&mhandle->dhandle, NULL);
+ if (success)
+ {
+ mhandle->dhandle.name = g_strconcat ("// #memory /", NULL);
+ mhandle->dhandle.vtable = &mem_handle_vtable;
+ mhandle->n_channels = n_channels;
+ mhandle->bit_depth = bit_depth;
+ mhandle->n_values = n_values / mhandle->n_channels;
+ mhandle->n_values *= mhandle->n_channels;
+ mhandle->values = values;
+ mhandle->free_values = free;
+ }
+ else
+ {
+ gsl_delete_struct (MemHandle, mhandle);
+ return NULL;
+ }
+ return &mhandle->dhandle;
+}
+
+
+/* --- chain handle --- */
+static GslErrorType
+chain_handle_open (GslDataHandle *dhandle,
+ GslDataHandleSetup *setup)
+{
+ ChainHandle *chandle = (ChainHandle*) dhandle;
+ GslErrorType error;
+
+ error = gsl_data_handle_open (chandle->src_handle);
+ if (error != GSL_ERROR_NONE)
+ return error;
+ *setup = chandle->src_handle->setup;
+
+ return GSL_ERROR_NONE;
+}
+
+static void
+chain_handle_close (GslDataHandle *dhandle)
+{
+ ChainHandle *chandle = (ChainHandle*) dhandle;
+
+ gsl_data_handle_close (chandle->src_handle);
+}
+
+
+/* --- reversed handle --- */
+static void
+reverse_handle_destroy (GslDataHandle *data_handle)
+{
+ ReversedHandle *rhandle = (ReversedHandle*) data_handle;
+
+ gsl_data_handle_unref (rhandle->src_handle);
+
+ gsl_data_handle_common_free (data_handle);
+ gsl_delete_struct (ReversedHandle, rhandle);
+}
+
+static GslLong
+reverse_handle_read (GslDataHandle *dhandle,
+ GslLong voffset,
+ GslLong n_values,
+ gfloat *values)
+{
+ ReversedHandle *rhandle = (ReversedHandle*) dhandle;
+ GslLong left, new_offset = dhandle->setup.n_values - (voffset + n_values);
+ gfloat *t, *p = values;
+
+ g_assert (new_offset >= 0);
+
+ left = n_values;
+ do
+ {
+ GslLong l = gsl_data_handle_read (rhandle->src_handle, new_offset, left, p);
+
+ if (l < 0)
+ return l; /* pass on errors */
+
+ new_offset += l;
+ left -= l;
+ p += l;
+ }
+ while (left > 0);
+
+ p = values;
+ t = values + n_values - 1;
+ while (p < t)
+ {
+ gfloat v = *t;
+
+ *t-- = *p;
+ *p++ = v;
+ }
+ return n_values;
+}
+
+GslDataHandle*
+gsl_data_handle_new_reverse (GslDataHandle *src_handle)
+{
+ static GslDataHandleFuncs reverse_handle_vtable = {
+ chain_handle_open,
+ reverse_handle_read,
+ chain_handle_close,
+ reverse_handle_destroy,
+ };
+ ReversedHandle *rhandle;
+ gboolean success;
+
+ g_return_val_if_fail (src_handle != NULL, NULL);
+
+ rhandle = gsl_new_struct0 (ReversedHandle, 1);
+ success = gsl_data_handle_common_init (&rhandle->dhandle, NULL);
+ if (success)
+ {
+ rhandle->dhandle.name = g_strconcat (src_handle->name, "// #reversed /", NULL);
+ rhandle->dhandle.vtable = &reverse_handle_vtable;
+ rhandle->src_handle = gsl_data_handle_ref (src_handle);
+ }
+ else
+ {
+ gsl_delete_struct (ReversedHandle, rhandle);
+ return NULL;
+ }
+ return &rhandle->dhandle;
+}
+
+
+/* --- cut handle --- */
+static GslErrorType
+cut_handle_open (GslDataHandle *dhandle,
+ GslDataHandleSetup *setup)
+{
+ CutHandle *chandle = (CutHandle*) dhandle;
+ GslErrorType error;
+
+ error = gsl_data_handle_open (chandle->src_handle);
+ if (error != GSL_ERROR_NONE)
+ return error;
+ *setup = chandle->src_handle->setup;
+ setup->n_values -= MIN (setup->n_values, chandle->tail_cut);
+ setup->n_values -= MIN (setup->n_values, chandle->n_cut_values);
+
+ return GSL_ERROR_NONE;
+}
+
+static void
+cut_handle_destroy (GslDataHandle *data_handle)
+{
+ CutHandle *chandle = (CutHandle*) data_handle;
+
+ gsl_data_handle_unref (chandle->src_handle);
+
+ gsl_data_handle_common_free (data_handle);
+ gsl_delete_struct (CutHandle, chandle);
+}
+
+static GslLong
+cut_handle_read (GslDataHandle *dhandle,
+ GslLong voffset,
+ GslLong n_values,
+ gfloat *values)
+{
+ CutHandle *chandle = (CutHandle*) dhandle;
+ GslLong orig_n_values = n_values;
+
+ if (voffset < chandle->cut_offset)
+ {
+ GslLong l = MIN (chandle->cut_offset - voffset, n_values);
+
+ l = gsl_data_handle_read (chandle->src_handle, voffset, l, values);
+ if (l < 0)
+ return l; /* pass on errors */
+ n_values -= l;
+ values += l;
+ voffset += l;
+ }
+
+ if (voffset >= chandle->cut_offset && n_values)
+ {
+ GslLong l = gsl_data_handle_read (chandle->src_handle, voffset + chandle->n_cut_values, n_values, values);
+
+ if (l < 0 && orig_n_values == n_values)
+ return l; /* pass on errors */
+ else if (l < 0)
+ l = 0;
+
+ n_values -= l;
+ }
+
+ return orig_n_values - n_values;
+}
+
+static GslDataHandle*
+gsl_data_handle_new_translate (GslDataHandle *src_handle,
+ GslLong cut_offset,
+ GslLong n_cut_values,
+ GslLong tail_cut)
+{
+ static GslDataHandleFuncs cut_handle_vtable = {
+ cut_handle_open,
+ cut_handle_read,
+ chain_handle_close,
+ cut_handle_destroy,
+ };
+ CutHandle *chandle;
+ gboolean success;
+
+ g_return_val_if_fail (src_handle != NULL, NULL);
+ g_return_val_if_fail (cut_offset >= 0 && n_cut_values >= 0 && tail_cut >= 0, NULL);
+
+ chandle = gsl_new_struct0 (CutHandle, 1);
+ success = gsl_data_handle_common_init (&chandle->dhandle, NULL);
+ if (success)
+ {
+ chandle->dhandle.name = g_strconcat (src_handle->name, "// #translate /", NULL);
+ chandle->dhandle.vtable = &cut_handle_vtable;
+ chandle->src_handle = gsl_data_handle_ref (src_handle);
+ chandle->cut_offset = n_cut_values ? cut_offset : 0;
+ chandle->n_cut_values = n_cut_values;
+ chandle->tail_cut = tail_cut;
+ }
+ else
+ {
+ gsl_delete_struct (CutHandle, chandle);
+ return NULL;
+ }
+ return &chandle->dhandle;
+}
+
+/**
+ * gsl_data_handle_new_cut
+ * @src_handle: source GslDataHandle
+ * @cut_offset: offset of gap into @src_handle
+ * @n_cut_values: length of gap in @src_handle
+ * @RETURNS: a newly created data handle
+ *
+ * Create a new data handle containing the contents of @src_handle
+ * minus @n_cut_values at offset @cut_offset.
+ */
+GslDataHandle*
+gsl_data_handle_new_cut (GslDataHandle *src_handle,
+ GslLong cut_offset,
+ GslLong n_cut_values)
+{
+ return gsl_data_handle_new_translate (src_handle, cut_offset, n_cut_values, 0);
+}
+
+/**
+ * gsl_data_handle_new_crop
+ * @src_handle: source GslDataHandle
+ * @n_head_cut: number of values to cut at data handle head
+ * @n_tail_cut: number of values to cut at data handle tail
+ * @RETURNS: a newly created data handle
+ *
+ * Create a new data handle containing the contents of @src_handle
+ * minus @n_head_cut values at the start and @n_tail_cut values at
+ * the end.
+ */
+GslDataHandle*
+gsl_data_handle_new_crop (GslDataHandle *src_handle,
+ GslLong n_head_cut,
+ GslLong n_tail_cut)
+{
+ return gsl_data_handle_new_translate (src_handle, 0, n_head_cut, n_tail_cut);
+}
+
+
+/* --- insert handle --- */
+static GslErrorType
+insert_handle_open (GslDataHandle *dhandle,
+ GslDataHandleSetup *setup)
+{
+ InsertHandle *ihandle = (InsertHandle*) dhandle;
+ GslErrorType error;
+
+ error = gsl_data_handle_open (ihandle->src_handle);
+ if (error != GSL_ERROR_NONE)
+ return error;
+ *setup = ihandle->src_handle->setup;
+ ihandle->paste_offset = ihandle->requested_paste_offset < 0 ? setup->n_values : ihandle->requested_paste_offset;
+ if (setup->n_values < ihandle->paste_offset)
+ setup->n_values = ihandle->paste_offset + ihandle->n_paste_values;
+ else
+ setup->n_values += ihandle->n_paste_values;
+ setup->bit_depth = MAX (setup->bit_depth, ihandle->paste_bit_depth);
+
+ return GSL_ERROR_NONE;
+}
+
+static void
+insert_handle_destroy (GslDataHandle *data_handle)
+{
+ InsertHandle *ihandle = (InsertHandle*) data_handle;
+ void (*free_values) (gpointer) = ihandle->free_values;
+ const gfloat *paste_values = ihandle->paste_values;
+
+ gsl_data_handle_unref (ihandle->src_handle);
+
+ gsl_data_handle_common_free (data_handle);
+ ihandle->paste_values = NULL;
+ ihandle->free_values = NULL;
+ gsl_delete_struct (InsertHandle, ihandle);
+
+ if (free_values)
+ free_values ((gpointer) paste_values);
+}
+
+static GslLong
+insert_handle_read (GslDataHandle *data_handle,
+ GslLong voffset,
+ GslLong n_values,
+ gfloat *values)
+{
+ InsertHandle *ihandle = (InsertHandle*) data_handle;
+ GslLong l, orig_n_values = n_values;
+
+ if (voffset < ihandle->src_handle->setup.n_values &&
+ voffset < ihandle->paste_offset)
+ {
+ l = MIN (n_values, MIN (ihandle->paste_offset, ihandle->src_handle->setup.n_values) - voffset);
+ l = gsl_data_handle_read (ihandle->src_handle, voffset, l, values);
+ if (l < 0)
+ return l; /* pass on errors */
+
+ voffset += l;
+ n_values -= l;
+ values += l;
+ }
+
+ if (n_values && voffset >= ihandle->src_handle->setup.n_values && voffset < ihandle->paste_offset)
+ {
+ l = MIN (n_values, ihandle->paste_offset - voffset);
+ memset (values, 0, l * sizeof (values[0]));
+ voffset += l;
+ n_values -= l;
+ values += l;
+ }
+
+ if (n_values && voffset >= ihandle->paste_offset && voffset < ihandle->paste_offset + ihandle->n_paste_values)
+ {
+ l = MIN (n_values, ihandle->paste_offset + ihandle->n_paste_values - voffset);
+ memcpy (values, ihandle->paste_values + voffset - ihandle->paste_offset, l * sizeof (values[0]));
+ voffset += l;
+ n_values -= l;
+ values += l;
+ }
+
+ if (n_values && voffset >= ihandle->paste_offset + ihandle->n_paste_values)
+ {
+ l = gsl_data_handle_read (ihandle->src_handle, voffset - ihandle->n_paste_values, n_values, values);
+ if (l < 0 && orig_n_values == n_values)
+ return l; /* pass on errors */
+ else if (l < 0)
+ l = 0;
+ n_values -= l;
+ }
+
+ return orig_n_values - n_values;
+}
+
+GslDataHandle*
+gsl_data_handle_new_insert (GslDataHandle *src_handle,
+ guint paste_bit_depth,
+ GslLong insertion_offset,
+ GslLong n_paste_values,
+ const gfloat *paste_values,
+ void (*free) (gpointer values))
+{
+ static GslDataHandleFuncs insert_handle_vtable = {
+ insert_handle_open,
+ insert_handle_read,
+ chain_handle_close,
+ insert_handle_destroy,
+ };
+ InsertHandle *ihandle;
+ gboolean success;
+
+ g_return_val_if_fail (src_handle != NULL, NULL);
+ g_return_val_if_fail (n_paste_values >= 0, NULL);
+ if (n_paste_values)
+ g_return_val_if_fail (paste_values != NULL, NULL);
+
+ ihandle = gsl_new_struct0 (InsertHandle, 1);
+ success = gsl_data_handle_common_init (&ihandle->dhandle, NULL);
+ if (success)
+ {
+ ihandle->dhandle.name = g_strconcat (src_handle ? src_handle->name : "", "// #insert /", NULL);
+ ihandle->dhandle.vtable = &insert_handle_vtable;
+ ihandle->src_handle = gsl_data_handle_ref (src_handle);
+ ihandle->requested_paste_offset = insertion_offset;
+ ihandle->paste_offset = 0;
+ ihandle->n_paste_values = n_paste_values;
+ ihandle->paste_bit_depth = paste_bit_depth;
+ ihandle->paste_values = paste_values;
+ ihandle->free_values = free;
+ }
+ else
+ {
+ gsl_delete_struct (InsertHandle, ihandle);
+ return NULL;
+ }
+ return &ihandle->dhandle;
+}
+
+
+/* --- loop handle --- */
+static GslErrorType
+loop_handle_open (GslDataHandle *dhandle,
+ GslDataHandleSetup *setup)
+{
+ LoopHandle *lhandle = (LoopHandle*) dhandle;
+ GslErrorType error;
+
+ error = gsl_data_handle_open (lhandle->src_handle);
+ if (error != GSL_ERROR_NONE)
+ return error;
+
+ *setup = lhandle->src_handle->setup;
+ if (setup->n_values > lhandle->requested_last)
+ {
+ lhandle->loop_start = lhandle->requested_first;
+ lhandle->loop_width = lhandle->requested_last - lhandle->requested_first + 1;
+ setup->n_values = GSL_MAXLONG;
+ }
+ else /* cannot loop */
+ {
+ lhandle->loop_start = setup->n_values;
+ lhandle->loop_width = 0;
+ }
+
+ return GSL_ERROR_NONE;
+}
+
+static void
+loop_handle_destroy (GslDataHandle *data_handle)
+{
+ LoopHandle *lhandle = (LoopHandle*) data_handle;
+
+ gsl_data_handle_unref (lhandle->src_handle);
+
+ gsl_data_handle_common_free (data_handle);
+ gsl_delete_struct (LoopHandle, lhandle);
+}
+
+static GslLong
+loop_handle_read (GslDataHandle *data_handle,
+ GslLong voffset,
+ GslLong n_values,
+ gfloat *values)
+{
+ LoopHandle *lhandle = (LoopHandle*) data_handle;
+
+ if (voffset < lhandle->loop_start)
+ return gsl_data_handle_read (lhandle->src_handle, voffset,
+ MIN (lhandle->loop_start - voffset, n_values),
+ values);
+ else
+ {
+ GslLong noffset = voffset - lhandle->loop_start;
+
+ noffset %= lhandle->loop_width;
+
+ return gsl_data_handle_read (lhandle->src_handle,
+ lhandle->loop_start + noffset,
+ MIN (lhandle->loop_width - noffset, n_values),
+ values);
+ }
+}
+
+GslDataHandle*
+gsl_data_handle_new_looped (GslDataHandle *src_handle,
+ GslLong loop_first,
+ GslLong loop_last)
+{
+ static GslDataHandleFuncs loop_handle_vtable = {
+ loop_handle_open,
+ loop_handle_read,
+ chain_handle_close,
+ loop_handle_destroy,
+ };
+ LoopHandle *lhandle;
+ gboolean success;
+
+ g_return_val_if_fail (src_handle != NULL, NULL);
+ g_return_val_if_fail (loop_first >= 0, NULL);
+ g_return_val_if_fail (loop_last >= loop_first, NULL);
+
+ lhandle = gsl_new_struct0 (LoopHandle, 1);
+ success = gsl_data_handle_common_init (&lhandle->dhandle, NULL);
+ if (success)
+ {
+ lhandle->dhandle.name = g_strdup_printf ("%s// #loop(0x%lx:0x%lx) /", src_handle->name, loop_first, loop_last);
+ lhandle->dhandle.vtable = &loop_handle_vtable;
+ lhandle->src_handle = gsl_data_handle_ref (src_handle);
+ lhandle->requested_first = loop_first;
+ lhandle->requested_last = loop_last;
+ lhandle->loop_start = 0;
+ lhandle->loop_width = 0;
+ }
+ else
+ {
+ gsl_delete_struct (LoopHandle, lhandle);
+ return NULL;
+ }
+ return &lhandle->dhandle;
+}
+
+
+/* --- dcache handle --- */
+static void
+dcache_handle_destroy (GslDataHandle *data_handle)
+{
+ DCacheHandle *dhandle = (DCacheHandle*) data_handle;
+
+ gsl_data_cache_unref (dhandle->dcache);
+
+ gsl_data_handle_common_free (data_handle);
+ gsl_delete_struct (DCacheHandle, dhandle);
+}
+
+static GslErrorType
+dcache_handle_open (GslDataHandle *dhandle,
+ GslDataHandleSetup *setup)
+{
+ DCacheHandle *chandle = (DCacheHandle*) dhandle;
+ GslErrorType error;
+
+ error = gsl_data_handle_open (chandle->dcache->dhandle);
+ if (error != GSL_ERROR_NONE)
+ return error;
+ gsl_data_cache_open (chandle->dcache);
+ *setup = chandle->dcache->dhandle->setup;
+ gsl_data_handle_close (chandle->dcache->dhandle);
+
+ return GSL_ERROR_NONE;
+}
+
+static void
+dcache_handle_close (GslDataHandle *data_handle)
+{
+ DCacheHandle *dhandle = (DCacheHandle*) data_handle;
+
+ gsl_data_cache_close (dhandle->dcache);
+}
+
+static GslLong
+dcache_handle_read (GslDataHandle *data_handle,
+ GslLong voffset,
+ GslLong n_values,
+ gfloat *values)
+{
+ DCacheHandle *dhandle = (DCacheHandle*) data_handle;
+ GslDataCacheNode *node;
+
+ node = gsl_data_cache_ref_node (dhandle->dcache, voffset, TRUE);
+ voffset -= node->offset;
+ n_values = MIN (n_values, dhandle->node_size - voffset);
+ memcpy (values, node->data + voffset, sizeof (values[0]) * n_values);
+
+ return n_values;
+}
+
+GslDataHandle*
+gsl_data_handle_new_dcached (GslDataCache *dcache)
+{
+ static GslDataHandleFuncs dcache_handle_vtable = {
+ dcache_handle_open,
+ dcache_handle_read,
+ dcache_handle_close,
+ dcache_handle_destroy,
+ };
+ DCacheHandle *dhandle;
+ gboolean success;
+
+ g_return_val_if_fail (dcache != NULL, NULL);
+
+ dhandle = gsl_new_struct0 (DCacheHandle, 1);
+ success = gsl_data_handle_common_init (&dhandle->dhandle, NULL);
+ if (success)
+ {
+ dhandle->dhandle.name = g_strdup_printf ("%s// #dcache /", dcache->dhandle->name);
+ dhandle->dhandle.vtable = &dcache_handle_vtable;
+ dhandle->dcache = gsl_data_cache_ref (dcache);
+ dhandle->node_size = GSL_DATA_CACHE_NODE_SIZE (dcache) + dcache->padding;
+ }
+ else
+ {
+ gsl_delete_struct (DCacheHandle, dhandle);
+ return NULL;
+ }
+ return &dhandle->dhandle;
+}
+
+
+/* --- wave handle --- */
+static inline const guint G_GNUC_CONST
+wave_format_bit_depth (const GslWaveFormatType format)
+{
+ switch (format)
+ {
+ case GSL_WAVE_FORMAT_UNSIGNED_8:
+ case GSL_WAVE_FORMAT_SIGNED_8:
+ return 8;
+ case GSL_WAVE_FORMAT_UNSIGNED_12:
+ case GSL_WAVE_FORMAT_SIGNED_12:
+ return 12;
+ case GSL_WAVE_FORMAT_UNSIGNED_16:
+ case GSL_WAVE_FORMAT_SIGNED_16:
+ return 16;
+ case GSL_WAVE_FORMAT_FLOAT:
+ return 32;
+ default:
+ return 0;
+ }
+}
+#define wave_format_byte_width(f) ((wave_format_bit_depth (f) + 7) / 8)
+
+static void
+wave_handle_destroy (GslDataHandle *data_handle)
+{
+ WaveHandle *whandle = (WaveHandle*) data_handle;
+
+ gsl_data_handle_common_free (data_handle);
+ gsl_delete_struct (WaveHandle, whandle);
+}
+
+static GslErrorType
+wave_handle_open (GslDataHandle *data_handle,
+ GslDataHandleSetup *setup)
+{
+ WaveHandle *whandle = (WaveHandle*) data_handle;
+
+ whandle->hfile = gsl_hfile_open (whandle->dhandle.name);
+ if (!whandle->hfile)
+ return gsl_error_from_errno (errno, GSL_ERROR_OPEN_FAILED);
+ else
+ {
+ GslLong l, fwidth = wave_format_byte_width (whandle->format);
+ /* convert size into n_values, i.e. float length */
+ l = whandle->hfile->n_bytes;
+ l -= MIN (l, whandle->byte_offset);
+ if (l >= fwidth)
+ {
+ l /= fwidth;
+ if (whandle->requested_length < 0)
+ setup->n_values = l;
+ else
+ setup->n_values = MIN (l, whandle->requested_length);
+ }
+ else
+ setup->n_values = 0;
+ setup->n_channels = whandle->n_channels;
+ setup->bit_depth = wave_format_bit_depth (whandle->format);
+ return GSL_ERROR_NONE;
+ }
+}
+
+static void
+wave_handle_close (GslDataHandle *dhandle)
+{
+ WaveHandle *whandle = (WaveHandle*) dhandle;
+
+ gsl_hfile_close (whandle->hfile);
+ whandle->hfile = NULL;
+}
+
+static GslLong
+wave_handle_read (GslDataHandle *data_handle,
+ GslLong voffset,
+ GslLong n_values,
+ gfloat *values)
+{
+ WaveHandle *whandle = (WaveHandle*) data_handle;
+ gpointer buffer = values;
+ GslLong l, i, byte_offset;
+
+ byte_offset = voffset * wave_format_byte_width (whandle->format); /* float offset into bytes */
+ byte_offset += whandle->byte_offset;
+
+ switch (whandle->format)
+ {
+ guint8 *u8; gint8 *s8; guint16 *u16; guint32 *u32;
+ case GSL_WAVE_FORMAT_UNSIGNED_8:
+ u8 = buffer; u8 += n_values * 3;
+ l = gsl_hfile_pread (whandle->hfile, byte_offset, n_values, u8);
+ if (l < 1)
+ return l;
+ for (i = 0; i < l; i++)
+ {
+ int v = u8[i] - 128;
+ values[i] = v * (1. / 128.);
+ }
+ break;
+ case GSL_WAVE_FORMAT_SIGNED_8:
+ s8 = buffer; s8 += n_values * 3;
+ l = gsl_hfile_pread (whandle->hfile, byte_offset, n_values, s8);
+ if (l < 1)
+ return l;
+ for (i = 0; i < l; i++)
+ values[i] = s8[i] * (1. / 128.);
+ break;
+ case GSL_WAVE_FORMAT_SIGNED_12:
+ case GSL_WAVE_FORMAT_UNSIGNED_12:
+ case GSL_WAVE_FORMAT_SIGNED_16:
+ case GSL_WAVE_FORMAT_UNSIGNED_16:
+ u16 = buffer; u16 += n_values;
+ l = gsl_hfile_pread (whandle->hfile, byte_offset, n_values << 1, u16);
+ if (l < 2)
+ return l < 0 ? l : 0;
+ l >>= 1;
+ switch (whandle->format)
+ {
+ case GSL_WAVE_FORMAT_UNSIGNED_16:
+ if (whandle->byte_order != G_BYTE_ORDER)
+ for (i = 0; i < l; i++)
+ {
+ int v = GUINT16_SWAP_LE_BE (u16[i]); v -= 32768;
+ values[i] = v * (1. / 32768.);
+ }
+ else /* whandle->byte_order == G_BYTE_ORDER */
+ for (i = 0; i < l; i++)
+ {
+ int v = u16[i]; v -= 32768;
+ values[i] = v * (1. / 32768.);
+ }
+ break;
+ case GSL_WAVE_FORMAT_UNSIGNED_12:
+ if (whandle->byte_order != G_BYTE_ORDER)
+ for (i = 0; i < l; i++)
+ {
+ int v = GUINT16_SWAP_LE_BE (u16[i]); v &= 0x0fff; v -= 4096;
+ values[i] = v * (1. / 4096.);
+ }
+ else /* whandle->byte_order == G_BYTE_ORDER */
+ for (i = 0; i < l; i++)
+ {
+ int v = u16[i]; v &= 0x0fff; v -= 4096;
+ values[i] = v * (1. / 4096.);
+ }
+ break;
+ case GSL_WAVE_FORMAT_SIGNED_16:
+ if (whandle->byte_order != G_BYTE_ORDER)
+ for (i = 0; i < l; i++)
+ {
+ gint16 v = GUINT16_SWAP_LE_BE (u16[i]);
+ values[i] = v * (1. / 32768.);
+ }
+ else /* whandle->byte_order == G_BYTE_ORDER */
+ for (i = 0; i < l; i++)
+ {
+ gint16 v = u16[i];
+ values[i] = v * (1. / 32768.);
+ }
+ break;
+ case GSL_WAVE_FORMAT_SIGNED_12:
+ if (whandle->byte_order != G_BYTE_ORDER)
+ for (i = 0; i < l; i++)
+ {
+ gint16 v = GUINT16_SWAP_LE_BE (u16[i]);
+ values[i] = CLAMP (v, -4096, 4096) * (1. / 4096.);
+ }
+ else /* whandle->byte_order == G_BYTE_ORDER */
+ for (i = 0; i < l; i++)
+ {
+ gint16 v = u16[i];
+ values[i] = CLAMP (v, -4096, 4096) * (1. / 4096.);
+ }
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ break;
+ case GSL_WAVE_FORMAT_FLOAT:
+ u32 = buffer;
+ l = gsl_hfile_pread (whandle->hfile, byte_offset, n_values << 2, u32);
+ if (l < 4)
+ return l < 0 ? l : 0;
+ l >>= 2;
+ if (whandle->byte_order != G_BYTE_ORDER)
+ for (i = 0; i < l; i++)
+ u32[i] = GUINT32_SWAP_LE_BE (u32[i]);
+ break;
+ default:
+ l = -1;
+ g_assert_not_reached ();
+ }
+
+ return l;
+}
+
+GslDataHandle*
+gsl_wave_handle_new (const gchar *file_name,
+ guint n_channels,
+ GslWaveFormatType format,
+ guint byte_order,
+ GslLong byte_offset,
+ GslLong n_values)
+{
+ static GslDataHandleFuncs wave_handle_vtable = {
+ wave_handle_open,
+ wave_handle_read,
+ wave_handle_close,
+ wave_handle_destroy,
+ };
+ WaveHandle *whandle;
+
+ g_return_val_if_fail (file_name != NULL, NULL);
+ g_return_val_if_fail (format > GSL_WAVE_FORMAT_NONE && format < GSL_WAVE_FORMAT_LAST, NULL);
+ g_return_val_if_fail (byte_order == G_LITTLE_ENDIAN || byte_order == G_BIG_ENDIAN, NULL);
+ g_return_val_if_fail (byte_offset >= 0, NULL);
+ g_return_val_if_fail (n_channels >= 1, NULL);
+ g_return_val_if_fail (n_values >= 1 || n_values == -1, NULL);
+
+ whandle = gsl_new_struct0 (WaveHandle, 1);
+ if (gsl_data_handle_common_init (&whandle->dhandle, file_name))
+ {
+ whandle->dhandle.vtable = &wave_handle_vtable;
+ whandle->n_channels = n_channels;
+ whandle->format = format;
+ whandle->byte_order = byte_order;
+ whandle->byte_offset = byte_offset;
+ whandle->requested_length = n_values;
+ whandle->hfile = NULL;
+ return &whandle->dhandle;
+ }
+ else
+ {
+ gsl_delete_struct (WaveHandle, whandle);
+ return NULL;
+ }
+}
+
+const gchar*
+gsl_wave_format_to_string (GslWaveFormatType format)
+{
+ switch (format)
+ {
+ case GSL_WAVE_FORMAT_UNSIGNED_8: return "unsigned_8";
+ case GSL_WAVE_FORMAT_SIGNED_8: return "signed_8";
+ case GSL_WAVE_FORMAT_UNSIGNED_12: return "unsigned_12";
+ case GSL_WAVE_FORMAT_SIGNED_12: return "signed_12";
+ case GSL_WAVE_FORMAT_UNSIGNED_16: return "unsigned_16";
+ case GSL_WAVE_FORMAT_SIGNED_16: return "signed_16";
+ case GSL_WAVE_FORMAT_FLOAT: return "float";
+ case GSL_WAVE_FORMAT_NONE:
+ case GSL_WAVE_FORMAT_LAST:
+ default:
+ g_return_val_if_fail (format >= GSL_WAVE_FORMAT_UNSIGNED_8 && format <= GSL_WAVE_FORMAT_FLOAT, NULL);
+ return NULL;
+ }
+}
+
+GslWaveFormatType
+gsl_wave_format_from_string (const gchar *string)
+{
+ gboolean is_unsigned = FALSE;
+
+ g_return_val_if_fail (string != NULL, GSL_WAVE_FORMAT_NONE);
+
+ while (*string == ' ')
+ string++;
+ if (strncasecmp (string, "float", 5) == 0)
+ return GSL_WAVE_FORMAT_FLOAT;
+ if ((string[0] == 'u' || string[0] == 'U') &&
+ (string[1] == 'n' || string[1] == 'N'))
+ {
+ is_unsigned = TRUE;
+ string += 2;
+ }
+ if (strncasecmp (string, "signed", 6) != 0)
+ return GSL_WAVE_FORMAT_NONE;
+ string += 6;
+ if (string[0] != '-' && string[0] != '_')
+ return GSL_WAVE_FORMAT_NONE;
+ string += 1;
+ if (string[0] == '8')
+ return is_unsigned ? GSL_WAVE_FORMAT_UNSIGNED_8 : GSL_WAVE_FORMAT_SIGNED_8;
+ if (string[0] != '1')
+ return GSL_WAVE_FORMAT_NONE;
+ string += 1;
+ if (string[0] == '2')
+ return is_unsigned ? GSL_WAVE_FORMAT_UNSIGNED_12 : GSL_WAVE_FORMAT_SIGNED_12;
+ if (string[0] == '6')
+ return is_unsigned ? GSL_WAVE_FORMAT_UNSIGNED_16 : GSL_WAVE_FORMAT_SIGNED_16;
+ return GSL_WAVE_FORMAT_NONE;
+}
diff --git a/flow/gsl/gsldatahandle.h b/flow/gsl/gsldatahandle.h
new file mode 100644
index 0000000..d67b44f
--- /dev/null
+++ b/flow/gsl/gsldatahandle.h
@@ -0,0 +1,143 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001 Tim Janik
+ *
+ * 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.
+ */
+#ifndef __GSL_DATA_HANDLE_H__
+#define __GSL_DATA_HANDLE_H__
+
+#include <gsl/gsldefs.h>
+#include <gsl/gslcommon.h> /* GslErrorType */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* --- macros --- */
+#define GSL_DATA_HANDLE_OPENED(handle) (((GslDataHandle*) (handle))->open_count > 0)
+#define GSL_DATA_HANDLE_READ_LINEAR(handle) (((GslDataHandle*) (handle))->vtable->coarse_seek != NULL)
+
+
+/* --- typedefs & structures --- */
+typedef struct {
+ GslLong n_values;
+ guint n_channels;
+ guint bit_depth;
+} GslDataHandleSetup;
+struct _GslDataHandle
+{
+ /* constant members */
+ GslDataHandleFuncs *vtable;
+ gchar *name;
+ /* common members */
+ GslMutex mutex;
+ guint ref_count;
+ guint open_count;
+ /* opened data handle setup (open_count > 0) */
+ GslDataHandleSetup setup;
+};
+struct _GslDataHandleFuncs
+{
+ GslErrorType (*open) (GslDataHandle *data_handle,
+ GslDataHandleSetup *setup);
+ GslLong (*read) (GslDataHandle *data_handle,
+ GslLong voffset, /* in values */
+ GslLong n_values,
+ gfloat *values);
+ void (*close) (GslDataHandle *data_handle);
+ void (*destroy) (GslDataHandle *data_handle);
+ /* optional (for codecs) */
+ GslLong (*coarse_seek) (GslDataHandle *data_handle,
+ GslLong position);
+};
+
+
+
+/* --- standard functions --- */
+GslDataHandle* gsl_data_handle_ref (GslDataHandle *dhandle);
+void gsl_data_handle_unref (GslDataHandle *dhandle);
+GslErrorType gsl_data_handle_open (GslDataHandle *dhandle);
+void gsl_data_handle_close (GslDataHandle *dhandle);
+GslLong gsl_data_handle_length (GslDataHandle *data_handle);
+#define gsl_data_handle_n_values( dh) \
+ gsl_data_handle_length (dh)
+guint gsl_data_handle_n_channels (GslDataHandle *data_handle);
+guint gsl_data_handle_bit_depth (GslDataHandle *data_handle);
+const gchar* gsl_data_handle_name (GslDataHandle *data_handle);
+GslLong gsl_data_handle_read (GslDataHandle *data_handle,
+ GslLong value_offset,
+ GslLong n_values,
+ gfloat *values);
+GslDataHandle* gsl_data_handle_new_cut (GslDataHandle *src_handle,
+ GslLong cut_offset,
+ GslLong n_cut_values);
+GslDataHandle* gsl_data_handle_new_crop (GslDataHandle *src_handle,
+ GslLong n_head_cut,
+ GslLong n_tail_cut);
+GslDataHandle* gsl_data_handle_new_reverse (GslDataHandle *src_handle);
+GslDataHandle* gsl_data_handle_new_insert (GslDataHandle *src_handle,
+ guint paste_bit_depth,
+ GslLong insertion_offset,
+ GslLong n_paste_values,
+ const gfloat *paste_values,
+ void (*free) (gpointer values));
+GslDataHandle* gsl_data_handle_new_mem (guint n_channels,
+ guint bit_depth,
+ GslLong n_values,
+ const gfloat *values,
+ void (*free) (gpointer values));
+GslDataHandle* gsl_data_handle_new_dcached (GslDataCache *dcache);
+/* cheap and inefficient, testpurpose only */
+GslDataHandle* gsl_data_handle_new_looped (GslDataHandle *src_handle,
+ GslLong loop_first,
+ GslLong loop_last);
+
+
+/* --- wave specific functions --- */
+typedef enum /*< skip >*/
+{
+ GSL_WAVE_FORMAT_NONE,
+ GSL_WAVE_FORMAT_UNSIGNED_8,
+ GSL_WAVE_FORMAT_SIGNED_8,
+ GSL_WAVE_FORMAT_UNSIGNED_12,
+ GSL_WAVE_FORMAT_SIGNED_12,
+ GSL_WAVE_FORMAT_UNSIGNED_16,
+ GSL_WAVE_FORMAT_SIGNED_16,
+ GSL_WAVE_FORMAT_FLOAT,
+ GSL_WAVE_FORMAT_LAST
+} GslWaveFormatType;
+
+const gchar* gsl_wave_format_to_string (GslWaveFormatType format);
+GslWaveFormatType gsl_wave_format_from_string (const gchar *string);
+GslDataHandle* gsl_wave_handle_new (const gchar *file_name,
+ guint n_channels,
+ GslWaveFormatType format,
+ guint byte_order,
+ GslLong byte_offset,
+ GslLong n_values);
+
+
+/* --- auxillary functions --- */
+gboolean gsl_data_handle_common_init (GslDataHandle *dhandle,
+ const gchar *file_name);
+void gsl_data_handle_common_free (GslDataHandle *dhandle);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_DATA_HANDLE_H__ */
diff --git a/flow/gsl/gsldatautils.c b/flow/gsl/gsldatautils.c
new file mode 100644
index 0000000..d8c52c0
--- /dev/null
+++ b/flow/gsl/gsldatautils.c
@@ -0,0 +1,462 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001-2002 Stefan Westerfeld and Tim Janik
+ *
+ * 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.
+ */
+#include "gsldatautils.h"
+#include "gsldatacache.h"
+#include <errno.h>
+#include <unistd.h>
+
+
+#define BSIZE GSL_DATA_HANDLE_PEEK_BUFFER /* FIXME: global buffer size setting */
+
+
+/* --- functions --- */
+gfloat
+gsl_data_peek_value_f (GslDataHandle *dhandle,
+ GslLong pos,
+ GslDataPeekBuffer *peekbuf)
+{
+ if (pos < peekbuf->start || pos >= peekbuf->end)
+ {
+ GslLong dhandle_length = dhandle->setup.n_values;
+ GslLong inc, k, bsize = MIN (GSL_DATA_HANDLE_PEEK_BUFFER, dhandle_length);
+
+ g_return_val_if_fail (pos >= 0 && pos < dhandle_length, 0);
+
+ peekbuf->start = peekbuf->dir > 0 ? pos : peekbuf->dir < 0 ? pos - bsize + 1: pos - bsize / 2;
+ peekbuf->end = MIN (peekbuf->start + bsize, dhandle_length);
+ peekbuf->start = MAX (peekbuf->start, 0);
+ for (k = peekbuf->start; k < peekbuf->end; k += inc)
+ {
+ guint n_retries = 5; /* FIXME: need global retry strategy */
+
+ do
+ inc = gsl_data_handle_read (dhandle, k, peekbuf->end - k, peekbuf->data + k - peekbuf->start);
+ while (inc < 1 && n_retries-- && GSL_DATA_HANDLE_OPENED (dhandle));
+ if (inc < 1)
+ { /* pathologic */
+ peekbuf->data[k - peekbuf->start] = 0;
+ inc = 1;
+ gsl_message_send (GSL_MSG_DATA_HANDLE, "PeekBuffer",
+ GSL_ERROR_READ_FAILED, "unable to read from data handle (%p)", dhandle);
+ }
+ }
+ }
+ return peekbuf->data[pos - peekbuf->start];
+}
+
+gint /* errno */
+gsl_data_handle_dump (GslDataHandle *dhandle,
+ gint fd,
+ GslWaveFormatType format,
+ guint byte_order)
+{
+ GslLong l, offs = 0;
+
+ g_return_val_if_fail (dhandle != NULL, EINVAL);
+ g_return_val_if_fail (GSL_DATA_HANDLE_OPENED (dhandle), EINVAL);
+ g_return_val_if_fail (fd >= 0, EINVAL);
+ g_return_val_if_fail (format >= GSL_WAVE_FORMAT_UNSIGNED_8 && format <= GSL_WAVE_FORMAT_FLOAT, EINVAL);
+ g_return_val_if_fail (byte_order == G_LITTLE_ENDIAN || byte_order == G_BIG_ENDIAN, EINVAL);
+
+ l = dhandle->setup.n_values;
+ while (l)
+ {
+ GslLong retry, j, n = MIN (l, GSL_DATA_HANDLE_PEEK_BUFFER);
+ gfloat src[GSL_DATA_HANDLE_PEEK_BUFFER];
+
+ retry = GSL_N_IO_RETRIES;
+ do
+ n = gsl_data_handle_read (dhandle, offs, n, src);
+ while (n < 1 && retry--);
+ if (retry < 0)
+ return EIO;
+
+ l -= n;
+ offs += n;
+
+ n = gsl_conv_from_float_clip (format, byte_order, src, src, n);
+
+ do
+ j = write (fd, src, n);
+ while (j < 0 && errno == EINTR);
+ if (j < 0)
+ return errno ? errno : EIO;
+ }
+ return 0;
+}
+
+static void
+write_bytes (gint fd,
+ guint n_bytes,
+ const void *bytes)
+{
+ gint errold = errno;
+ guint j;
+
+ do
+ j = write (fd, bytes, n_bytes);
+ while (j < 0 && errno == EINTR);
+
+ if (!errno)
+ errno = errold;
+}
+
+static void
+write_uint32_le (gint fd,
+ guint32 val)
+{
+ val = GUINT32_TO_LE (val);
+ write_bytes (fd, 4, &val);
+}
+
+static void
+write_uint16_le (gint fd,
+ guint16 val)
+{
+ val = GUINT16_TO_LE (val);
+ write_bytes (fd, 2, &val);
+}
+
+gint /* errno */
+gsl_data_handle_dump_wav (GslDataHandle *dhandle,
+ gint fd,
+ guint n_bits,
+ guint n_channels,
+ guint sample_freq)
+{
+ guint data_length, file_length, byte_per_sample, byte_per_second;
+
+ g_return_val_if_fail (dhandle != NULL, EINVAL);
+ g_return_val_if_fail (GSL_DATA_HANDLE_OPENED (dhandle), EINVAL);
+ g_return_val_if_fail (fd >= 0, EINVAL);
+ g_return_val_if_fail (n_bits == 16 || n_bits == 8, EINVAL);
+ g_return_val_if_fail (n_channels >= 1, EINVAL);
+
+ data_length = dhandle->setup.n_values * (n_bits == 16 ? 2 : 1);
+ file_length = data_length;
+ file_length += 4 + 4; /* 'RIFF' header */
+ file_length += 4 + 4 + 2 + 2 + 4 + 4 + 2 + 2; /* 'fmt ' header */
+ file_length += 4 + 4; /* 'data' header */
+ byte_per_sample = (n_bits == 16 ? 2 : 1) * n_channels;
+ byte_per_second = byte_per_sample * sample_freq;
+
+ errno = 0;
+ write_bytes (fd, 4, "RIFF"); /* main_chunk */
+ write_uint32_le (fd, file_length);
+ write_bytes (fd, 4, "WAVE"); /* chunk_type */
+ write_bytes (fd, 4, "fmt "); /* sub_chunk */
+ write_uint32_le (fd, 16); /* sub chunk length */
+ write_uint16_le (fd, 1); /* format (1=PCM) */
+ write_uint16_le (fd, n_channels);
+ write_uint32_le (fd, sample_freq);
+ write_uint32_le (fd, byte_per_second);
+ write_uint16_le (fd, byte_per_sample);
+ write_uint16_le (fd, n_bits);
+ write_bytes (fd, 4, "data"); /* data chunk */
+ write_uint32_le (fd, data_length);
+
+ if (errno)
+ return errno;
+
+ return gsl_data_handle_dump (dhandle, fd,
+ n_bits == 16 ? GSL_WAVE_FORMAT_SIGNED_16 : GSL_WAVE_FORMAT_UNSIGNED_8,
+ G_LITTLE_ENDIAN);
+}
+
+gboolean
+gsl_data_detect_signal (GslDataHandle *handle,
+ GslLong *sigstart_p,
+ GslLong *sigend_p)
+{
+ gfloat level_0, level_1, level_2, level_3, level_4;
+ gfloat signal_threshold = 16. * 16. * 16.; /* noise level threshold */
+ GslLong k, xcheck = -1, minsamp = -1, maxsamp = -2;
+ GslDataPeekBuffer peek_buffer = { +1 /* incremental direction */, 0, };
+
+ g_return_val_if_fail (handle != NULL, FALSE);
+ g_return_val_if_fail (GSL_DATA_HANDLE_OPENED (handle), FALSE);
+ g_return_val_if_fail (sigstart_p || sigend_p, FALSE);
+
+ /* keep open */
+ gsl_data_handle_open (handle);
+
+ /* find fadein/fadeout point */
+ k = 0;
+ level_4 = gsl_data_handle_peek_value (handle, k, &peek_buffer);
+ level_4 *= 32768;
+ level_0 = level_1 = level_2 = level_3 = level_4;
+ for (; k < handle->setup.n_values; k++)
+ {
+ gfloat mean, needx, current;
+
+ current = gsl_data_handle_peek_value (handle, k, &peek_buffer) * 32768.;
+ if (xcheck < 0 && ABS (current) >= 16)
+ xcheck = k;
+ mean = (level_0 + level_1 + level_2 + level_3 + level_4) / 5;
+ needx = (ABS (level_4 + current - (level_0 + level_1 + level_2 + level_3) / 2) *
+ ABS (level_4 - mean) * ABS (current - mean));
+ /* shift */
+ level_0 = level_1; level_1 = level_2; level_2 = level_3; level_3 = level_4; level_4 = current;
+ /* aprox. noise compare */
+ if (ABS (needx) > signal_threshold)
+ {
+ if (minsamp < 0)
+ minsamp = k;
+ if (maxsamp < k)
+ maxsamp = k;
+ }
+ /* if (minsamp >= 0 && xcheck >= 0)
+ * break;
+ */
+ }
+ if (xcheck - minsamp > 0)
+ g_printerr("###################");
+ g_printerr ("active area %ld .. %ld, signal>16 at: %ld\t diff: %ld\n",minsamp,maxsamp,xcheck, xcheck-minsamp);
+
+ /* release open reference */
+ gsl_data_handle_close (handle);
+
+ if (sigstart_p)
+ *sigstart_p = minsamp;
+ if (sigend_p)
+ *sigend_p = MAX (-1, maxsamp);
+
+ return maxsamp >= minsamp;
+}
+
+GslLong
+gsl_data_find_sample (GslDataHandle *dhandle,
+ gfloat min_value,
+ gfloat max_value,
+ GslLong start_offset,
+ gint direction)
+{
+ GslDataPeekBuffer peekbuf = { 0, 0, 0, };
+ GslLong i;
+
+ g_return_val_if_fail (dhandle != NULL, -1);
+ g_return_val_if_fail (direction == -1 || direction == +1, -1);
+
+ if (gsl_data_handle_open (dhandle) != GSL_ERROR_NONE ||
+ start_offset >= dhandle->setup.n_values)
+ return -1;
+
+ if (start_offset < 0)
+ start_offset = dhandle->setup.n_values - 1;
+
+ peekbuf.dir = direction;
+ if (min_value <= max_value)
+ for (i = start_offset; i < dhandle->setup.n_values && i >= 0; i += direction)
+ {
+ gfloat val = gsl_data_handle_peek_value (dhandle, i, &peekbuf);
+
+ /* g_print ("(%lu): %f <= %f <= %f\n", i, min_value, val, max_value); */
+ if (val >= min_value && val <= max_value)
+ break;
+ }
+ else
+ for (i = start_offset; i < dhandle->setup.n_values && i >= 0; i += direction)
+ {
+ gfloat val = gsl_data_handle_peek_value (dhandle, i, &peekbuf);
+
+ /* g_print ("(%lu): %f > %f || %f < %f\n", i, val, max_value, val, min_value); */
+ if (val > min_value || val < max_value)
+ break;
+ }
+
+ gsl_data_handle_close (dhandle);
+
+ return i >= dhandle->setup.n_values ? -1: i;
+}
+
+static inline gdouble
+tailmatch_score_loop (GslDataHandle *shandle,
+ GslDataHandle *dhandle,
+ GslLong start,
+ gdouble worst_score)
+{
+ GslLong l, length = MIN (shandle->setup.n_values, dhandle->setup.n_values);
+ gfloat v1[GSL_DATA_HANDLE_PEEK_BUFFER], v2[GSL_DATA_HANDLE_PEEK_BUFFER];
+ gdouble score = 0;
+
+ g_assert (start < length);
+
+ for (l = start; l < length; )
+ {
+ GslLong b = MIN (GSL_DATA_HANDLE_PEEK_BUFFER, length - l);
+
+ b = gsl_data_handle_read (shandle, l, b, v1);
+ b = gsl_data_handle_read (dhandle, l, b, v2);
+ g_assert (b >= 1);
+ l += b;
+
+ while (b--)
+ score += (v1[b] - v2[b]) * (v1[b] - v2[b]);
+
+ /* for performance, prematurely abort */
+ if (score > worst_score)
+ break;
+ }
+ return score;
+}
+
+gboolean
+gsl_data_find_tailmatch (GslDataHandle *dhandle,
+ const GslLoopSpec *lspec,
+ GslLong *loop_start_p,
+ GslLong *loop_end_p)
+{
+ GslDataHandle *shandle;
+ GslDataCache *dcache;
+ GslLong length, offset, l, lsize, pcount, start = 0, end = 0;
+ gdouble pbound, pval, best_score = GSL_MAXLONG;
+
+ g_return_val_if_fail (dhandle != NULL, FALSE);
+ g_return_val_if_fail (lspec != NULL, FALSE);
+ g_return_val_if_fail (loop_start_p != NULL, FALSE);
+ g_return_val_if_fail (loop_end_p != NULL, FALSE);
+ g_return_val_if_fail (lspec->head_skip >= 0, FALSE);
+ g_return_val_if_fail (lspec->tail_cut >= 0, FALSE);
+ g_return_val_if_fail (lspec->min_loop >= 1, FALSE);
+ g_return_val_if_fail (lspec->max_loop >= lspec->min_loop, FALSE);
+ g_return_val_if_fail (lspec->tail_cut >= lspec->max_loop, FALSE);
+
+ if (gsl_data_handle_open (dhandle) != GSL_ERROR_NONE)
+ return FALSE;
+ length = dhandle->setup.n_values;
+ if (lspec->head_skip < length)
+ {
+ gsl_data_handle_close (dhandle);
+ return FALSE;
+ }
+ offset = lspec->head_skip;
+ length -= offset;
+ if (lspec->tail_cut < length)
+ {
+ gsl_data_handle_close (dhandle);
+ return FALSE;
+ }
+ length -= lspec->tail_cut;
+ if (lspec->max_loop <= length)
+ {
+ gsl_data_handle_close (dhandle);
+ return FALSE;
+ }
+
+ dcache = gsl_data_cache_new (dhandle, 1);
+ shandle = gsl_data_handle_new_dcached (dcache);
+ gsl_data_cache_unref (dcache);
+ gsl_data_handle_open (shandle);
+ gsl_data_handle_close (dhandle);
+ gsl_data_handle_unref (shandle);
+ /* at this point, we just hold one open() count on shandle */
+
+ pbound = (lspec->max_loop - lspec->min_loop + 1.);
+ pbound *= length / 100.;
+ pval = 0;
+ pcount = 100;
+
+ for (lsize = lspec->min_loop; lsize <= lspec->max_loop; lsize++)
+ {
+ for (l = length - lsize; l >= 0; l--)
+ {
+ GslDataHandle *lhandle = gsl_data_handle_new_looped (shandle, offset + l, offset + l + lsize - 1);
+ gdouble score;
+
+ gsl_data_handle_open (lhandle);
+ score = tailmatch_score_loop (shandle, lhandle, offset + l, best_score);
+ gsl_data_handle_close (lhandle);
+ gsl_data_handle_unref (lhandle);
+
+ if (score < best_score)
+ {
+ start = offset + l;
+ end = offset + l + lsize - 1;
+ g_print ("\nimproved: %f < %f: [0x%lx..0x%lx] (%lu)\n", score, best_score, start, end, lsize);
+ best_score = score;
+ }
+ else
+ break;
+ }
+ if (!pcount--)
+ {
+ pcount = 100;
+ pval = lsize - lspec->min_loop;
+ pbound = (lspec->max_loop - lspec->min_loop + 1.);
+ g_print ("\rprocessed: %f%% \r", pval / pbound);
+ }
+ }
+ gsl_data_handle_close (shandle);
+
+ g_print ("\nhalted: %f: [0x%lx..0x%lx] (%lu)\n", best_score, start, end, end - start + 1);
+
+ *loop_start_p = start;
+ *loop_end_p = end;
+
+ return TRUE;
+}
+
+/**
+ * gsl_data_find_block
+ * @handle: an open GslDataHandle
+ * @n_values: amount of values to look for
+ * @values: values to find
+ * @epsilon: maximum difference upon comparisons
+ * @RETURNS: position of values in data handle or -1
+ *
+ * Find the position of a block of values within a
+ * data handle, where all values compare to the reference
+ * values with a delta smaller than epsilon.
+ */
+GslLong
+gsl_data_find_block (GslDataHandle *handle,
+ guint n_values,
+ const gfloat *values,
+ gfloat epsilon)
+{
+ GslDataPeekBuffer pbuf = { +1 /* random access: 0 */ };
+ guint i;
+
+ g_return_val_if_fail (handle != NULL, -1);
+ g_return_val_if_fail (GSL_DATA_HANDLE_OPENED (handle), -1);
+
+ if (n_values < 1)
+ return -1;
+ else
+ g_return_val_if_fail (values != NULL, -1);
+
+ for (i = 0; i < handle->setup.n_values; i++)
+ {
+ guint j;
+
+ if (n_values > handle->setup.n_values - i)
+ return -1;
+
+ for (j = 0; j < n_values; j++)
+ {
+ if (fabs (values[j] - gsl_data_handle_peek_value (handle, i + j, &pbuf)) >= epsilon)
+ break;
+ }
+ if (j >= n_values)
+ return i;
+ }
+ return -1;
+}
+
+/* vim:set ts=8 sts=2 sw=2: */
diff --git a/flow/gsl/gsldatautils.h b/flow/gsl/gsldatautils.h
new file mode 100644
index 0000000..0dea8c9
--- /dev/null
+++ b/flow/gsl/gsldatautils.h
@@ -0,0 +1,909 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001-2002 Stefan Westerfeld and Tim Janik
+ *
+ * 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.
+ */
+#ifndef __GSL_DATA_UTILS_H__
+#define __GSL_DATA_UTILS_H__
+
+#include <gsl/gslmath.h>
+#include <gsl/gsldatahandle.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* --- structures --- */
+#define GSL_DATA_HANDLE_PEEK_BUFFER (8192)
+typedef struct
+{
+ gint dir; /* initialize direction to -1 or +1 (or 0 for random access) */
+ GslLong start; /* initialize to 0 */
+ GslLong end; /* initialize to 0 */
+ gfloat data[GSL_DATA_HANDLE_PEEK_BUFFER];
+} GslDataPeekBuffer;
+typedef struct
+{
+ GslLong head_skip; /* FIXME: remove this */
+ GslLong tail_cut;
+ GslLong min_loop;
+ GslLong max_loop;
+} GslLoopSpec; /* rename this to ...Data... */
+
+
+/* --- data utils --- */
+gboolean gsl_data_detect_signal (GslDataHandle *handle,
+ GslLong *sigstart,
+ GslLong *sigend);
+GslLong gsl_data_find_sample (GslDataHandle *dhandle,
+ gfloat min_value,
+ gfloat max_value,
+ GslLong start_offset,
+ gint direction);
+gboolean gsl_data_find_tailmatch (GslDataHandle *dhandle,
+ const GslLoopSpec *lspec,
+ GslLong *loop_start_p,
+ GslLong *loop_end_p);
+GslLong gsl_data_find_block (GslDataHandle *handle,
+ guint n_values,
+ const gfloat *values,
+ gfloat epsilon);
+
+
+/* --- data handle utils --- */
+static inline gfloat gsl_data_handle_peek_value (GslDataHandle *dhandle,
+ GslLong position,
+ GslDataPeekBuffer *peekbuf);
+gint /* errno */ gsl_data_handle_dump (GslDataHandle *dhandle,
+ gint fd,
+ GslWaveFormatType format,
+ guint byte_order);
+gint /* errno */ gsl_data_handle_dump_wav (GslDataHandle *dhandle,
+ gint fd,
+ guint n_bits,
+ guint n_channels,
+ guint sample_freq);
+
+
+/* --- conversion utils --- */
+static inline guint gsl_conv_from_float (GslWaveFormatType format,
+ guint byte_order,
+ const gfloat *src,
+ gpointer dest,
+ guint n_values);
+static inline guint gsl_conv_from_float_clip (GslWaveFormatType format,
+ guint byte_order,
+ const gfloat *src,
+ gpointer dest,
+ guint n_values);
+static inline void gsl_conv_to_float (GslWaveFormatType format,
+ guint byte_order,
+ gconstpointer src,
+ gfloat *dest,
+ guint n_values);
+static inline guint gsl_conv_from_double (GslWaveFormatType format,
+ guint byte_order,
+ const gdouble *src,
+ gpointer dest,
+ guint n_values);
+static inline guint gsl_conv_from_double_clip (GslWaveFormatType format,
+ guint byte_order,
+ const gdouble *src,
+ gpointer dest,
+ guint n_values);
+static inline void gsl_conv_to_double (GslWaveFormatType format,
+ guint byte_order,
+ gconstpointer src,
+ gdouble *dest,
+ guint n_values);
+
+
+
+/* --- misc implementations --- */
+gfloat gsl_data_peek_value_f (GslDataHandle *dhandle,
+ GslLong pos,
+ GslDataPeekBuffer *peekbuf);
+
+static inline gfloat
+gsl_data_handle_peek_value (GslDataHandle *dhandle,
+ GslLong position,
+ GslDataPeekBuffer *peekbuf)
+{
+ return (position >= peekbuf->start && position < peekbuf->end ?
+ peekbuf->data[position - peekbuf->start] :
+ gsl_data_peek_value_f (dhandle, position, peekbuf));
+}
+
+#define GSL_CONV_FORMAT(format, endian_flag) (((endian_flag) << 16) | ((format) & 0xffff))
+
+static inline guint /* returns number of bytes used in dest */
+gsl_conv_from_float (GslWaveFormatType format,
+ guint byte_order,
+ const gfloat *src,
+ gpointer dest,
+ guint n_values)
+{
+ gint8 *i8 = (gint8*) dest;
+ guint8 *u8 = (guint8*) dest;
+ gint16 *i16 = (gint16*) dest;
+ guint16 *u16 = (guint16*) dest;
+ guint32 *u32dest = (guint32*) dest;
+ const gfloat *bound = src + n_values;
+ guint32 *u32src = (guint32*) src, *u32bound = (guint32*) bound;
+
+ if (!n_values)
+ return 0;
+
+ switch (GSL_CONV_FORMAT (format, byte_order == G_BYTE_ORDER))
+ {
+ GslFpuState fpu;
+ gfloat v;
+ gint16 vi16;
+ guint16 vu16;
+ guint32 vu32;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER):
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ *u8++ = *src++ * 128. + 128.5;
+ while (src < bound);
+ return n_values;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER):
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER):
+ gsl_fpu_setround (&fpu);
+ do
+ {
+ v = *src++;
+ v *= 128.;
+ *i8++ = gsl_ftoi (v);
+ }
+ while (src < bound);
+ gsl_fpu_restore (fpu);
+ return n_values;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER):
+ do
+ *u16++ = *src++ * 2048. + 2048.5;
+ while (src < bound);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ {
+ vu16 = *src++ * 2048. + 2048.5;
+ *u16++ = GUINT16_SWAP_LE_BE (vu16);
+ }
+ while (src < bound);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER):
+ gsl_fpu_setround (&fpu);
+ do
+ {
+ v = *src++;
+ v *= 2048.;
+ *i16++ = gsl_ftoi (v);
+ }
+ while (src < bound);
+ gsl_fpu_restore (fpu);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER):
+ gsl_fpu_setround (&fpu);
+ do
+ {
+ v = *src++;
+ v *= 2048.;
+ vi16 = gsl_ftoi (v);
+ *i16++ = GUINT16_SWAP_LE_BE (vi16);
+ }
+ while (src < bound);
+ gsl_fpu_restore (fpu);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER):
+ do
+ *u16++ = *src++ * 32768. + 32768.5;
+ while (src < bound);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ {
+ vu16 = *src++ * 32768. + 32768.5;
+ *u16++ = GUINT16_SWAP_LE_BE (vu16);
+ }
+ while (src < bound);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER):
+ gsl_fpu_setround (&fpu);
+ do
+ {
+ v = *src++;
+ v *= 32768.;
+ *i16++ = gsl_ftoi (v);
+ }
+ while (src < bound);
+ gsl_fpu_restore (fpu);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER):
+ gsl_fpu_setround (&fpu);
+ do
+ {
+ v = *src++;
+ v *= 32768.;
+ vi16 = gsl_ftoi (v);
+ *i16++ = GUINT16_SWAP_LE_BE (vi16);
+ }
+ while (src < bound);
+ gsl_fpu_restore (fpu);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER == G_BYTE_ORDER):
+ return n_values << 2;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ {
+ vu32 = *u32src++;
+ *u32dest++ = GUINT32_SWAP_LE_BE (vu32);
+ }
+ while (u32src < u32bound);
+ return n_values << 2;
+ default:
+ g_assert_not_reached ();
+ return 0;
+ }
+}
+
+static inline guint /* returns number of bytes used in dest */
+gsl_conv_from_float_clip (GslWaveFormatType format,
+ guint byte_order,
+ const gfloat *src,
+ gpointer dest,
+ guint n_values)
+{
+ gint8 *i8 = (gint8*) dest;
+ guint8 *u8 = (guint8*) dest;
+ gint16 *i16 = (gint16*) dest;
+ guint16 *u16 = (guint16*) dest;
+ guint32 *u32dest = (guint32*) dest;
+ const gfloat *bound = src + n_values;
+ guint32 *u32src = (guint32*) src, *u32bound = (guint32*) bound;
+
+ if (!n_values)
+ return 0;
+
+ switch (GSL_CONV_FORMAT (format, byte_order == G_BYTE_ORDER))
+ {
+ GslFpuState fpu;
+ gfloat v;
+ guint32 vu32;
+ gint32 vi32;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER):
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ {
+ vi32 = *src++ * 128. + 128.5;
+ *u8++ = CLAMP (vi32, 0, 255);
+ }
+ while (src < bound);
+ return n_values;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER):
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER):
+ gsl_fpu_setround (&fpu);
+ do
+ {
+ v = *src++;
+ v *= 128.;
+ vi32 = gsl_ftoi (v);
+ *i8++ = CLAMP (vi32, -128, 127);
+ }
+ while (src < bound);
+ gsl_fpu_restore (fpu);
+ return n_values;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER):
+ do
+ {
+ vi32 = *src++ * 2048. + 2048.5;
+ *u16++ = CLAMP (vi32, 0, 4095);
+ }
+ while (src < bound);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ {
+ vi32 = *src++ * 2048. + 2048.5;
+ vi32 = CLAMP (vi32, 0, 4095);
+ *u16++ = GUINT16_SWAP_LE_BE (vi32);
+ }
+ while (src < bound);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER):
+ gsl_fpu_setround (&fpu);
+ do
+ {
+ v = *src++;
+ v *= 2048.;
+ vi32 = gsl_ftoi (v);
+ *i16++ = CLAMP (vi32, -2048, 2047);
+ }
+ while (src < bound);
+ gsl_fpu_restore (fpu);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER):
+ gsl_fpu_setround (&fpu);
+ do
+ {
+ v = *src++;
+ v *= 2048.;
+ vi32 = gsl_ftoi (v);
+ vi32 = CLAMP (vi32, -2048, 2047);
+ *i16++ = GUINT16_SWAP_LE_BE (vi32);
+ }
+ while (src < bound);
+ gsl_fpu_restore (fpu);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER):
+ do
+ {
+ vi32 = *src++ * 32768. + 32768.5;
+ *u16++ = CLAMP (vi32, 0, 65535);
+ }
+ while (src < bound);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ {
+ vi32 = *src++ * 32768. + 32768.5;
+ vi32 = CLAMP (vi32, 0, 65535);
+ *u16++ = GUINT16_SWAP_LE_BE (vi32);
+ }
+ while (src < bound);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER):
+ gsl_fpu_setround (&fpu);
+ do
+ {
+ v = *src++;
+ v *= 32768.;
+ vi32 = gsl_ftoi (v);
+ vi32 = CLAMP (vi32, -32768, 32767);
+ *i16++ = vi32;
+ }
+ while (src < bound);
+ gsl_fpu_restore (fpu);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER):
+ gsl_fpu_setround (&fpu);
+ do
+ {
+ v = *src++;
+ v *= 32768.;
+ vi32 = gsl_ftoi (v);
+ vi32 = CLAMP (vi32, -32768, 32767);
+ *i16++ = GUINT16_SWAP_LE_BE (vi32);
+ }
+ while (src < bound);
+ gsl_fpu_restore (fpu);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER == G_BYTE_ORDER):
+ return n_values << 2;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ {
+ vu32 = *u32src++;
+ *u32dest++ = GUINT32_SWAP_LE_BE (vu32);
+ }
+ while (u32src < u32bound);
+ return n_values << 2;
+ default:
+ g_assert_not_reached ();
+ return 0;
+ }
+}
+
+static inline void
+gsl_conv_to_float (GslWaveFormatType format,
+ guint byte_order,
+ gconstpointer src,
+ gfloat *dest,
+ guint n_values)
+{
+ guint8 *u8 = (guint8*) src;
+ gint8 *i8 = (gint8*) src;
+ guint16 *u16 = (guint16*) src;
+ gint16 *i16 = (gint16*) src;
+ guint32 *u32src = (guint32*) src;
+ gfloat *bound = dest + n_values;
+ guint32 *u32dest = (guint32*) dest, *u32bound = (guint32*) bound;
+
+ if (!n_values)
+ return;
+
+ switch (GSL_CONV_FORMAT (format, byte_order == G_BYTE_ORDER))
+ {
+ gint16 vi16;
+ guint16 vu16;
+ guint32 vu32;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER):
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ *dest++ = (*u8++ - 128) * (1. / 128.);
+ while (dest < bound);
+ break;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER):
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ *dest++ = *i8++ * (1. / 128.);
+ while (dest < bound);
+ break;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER):
+ do
+ *dest++ = ((*u16++ & 0x0fff) - 2048) * (1. / 2048.);
+ while (dest < bound);
+ break;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ {
+ vu16 = *u16++;
+ *dest++ = ((GUINT16_SWAP_LE_BE (vu16) & 0x0fff) - 2048) * (1. / 2048.);
+ }
+ while (dest < bound);
+ break;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER):
+ do
+ {
+ vi16 = *i16++;
+ *dest++ = CLAMP (vi16, -2048, 2048) * (1. / 2048.);
+ }
+ while (dest < bound);
+ break;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ {
+ vi16 = *i16++;
+ vi16 = GUINT16_SWAP_LE_BE (vi16);
+ *dest++ = CLAMP (vi16, -2048, 2048) * (1. / 2048.);
+ }
+ while (dest < bound);
+ break;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER):
+ do
+ *dest++ = (*u16++ - 32768) * (1. / 32768.);
+ while (dest < bound);
+ break;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ {
+ vu16 = *u16++;
+ *dest++ = (GUINT16_SWAP_LE_BE (vu16) - 32768) * (1. / 32768.);
+ }
+ while (dest < bound);
+ break;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER):
+ do
+ *dest++ = *i16++ * (1. / 32768.);
+ while (dest < bound);
+ break;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ {
+ vi16 = *i16++;
+ *dest++ = GUINT16_SWAP_LE_BE (vi16) * (1. / 32768.);
+ }
+ while (dest < bound);
+ break;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER == G_BYTE_ORDER):
+ break;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ {
+ vu32 = *u32src++;
+ *u32dest++ = GUINT32_SWAP_LE_BE (vu32);
+ }
+ while (u32dest < u32bound);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+/* same as above with s/float/double */
+static inline guint /* returns number of bytes used in dest */
+gsl_conv_from_double (GslWaveFormatType format,
+ guint byte_order,
+ const gdouble *src,
+ gpointer dest,
+ guint n_values)
+{
+ gint8 *i8 = (gint8*) dest;
+ guint8 *u8 = (guint8*) dest;
+ gint16 *i16 = (gint16*) dest;
+ guint16 *u16 = (guint16*) dest;
+ guint32 *u32dest = (guint32*) dest;
+ const gdouble *bound = src + n_values;
+ guint32 *u32src = (guint32*) src, *u32bound = (guint32*) bound;
+
+ if (!n_values)
+ return 0;
+
+ switch (GSL_CONV_FORMAT (format, byte_order == G_BYTE_ORDER))
+ {
+ GslFpuState fpu;
+ gdouble v;
+ gint16 vi16;
+ guint16 vu16;
+ guint32 vu32;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER):
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ *u8++ = *src++ * 128. + 128.5;
+ while (src < bound);
+ return n_values;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER):
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER):
+ gsl_fpu_setround (&fpu);
+ do
+ {
+ v = *src++;
+ v *= 128.;
+ *i8++ = gsl_ftoi (v);
+ }
+ while (src < bound);
+ gsl_fpu_restore (fpu);
+ return n_values;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER):
+ do
+ *u16++ = *src++ * 2048. + 2048.5;
+ while (src < bound);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ {
+ vu16 = *src++ * 2048. + 2048.5;
+ *u16++ = GUINT16_SWAP_LE_BE (vu16);
+ }
+ while (src < bound);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER):
+ gsl_fpu_setround (&fpu);
+ do
+ {
+ v = *src++;
+ v *= 2048.;
+ *i16++ = gsl_ftoi (v);
+ }
+ while (src < bound);
+ gsl_fpu_restore (fpu);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER):
+ gsl_fpu_setround (&fpu);
+ do
+ {
+ v = *src++;
+ v *= 2048.;
+ vi16 = gsl_ftoi (v);
+ *i16++ = GUINT16_SWAP_LE_BE (vi16);
+ }
+ while (src < bound);
+ gsl_fpu_restore (fpu);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER):
+ do
+ *u16++ = *src++ * 32768. + 32768.5;
+ while (src < bound);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ {
+ vu16 = *src++ * 32768. + 32768.5;
+ *u16++ = GUINT16_SWAP_LE_BE (vu16);
+ }
+ while (src < bound);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER):
+ gsl_fpu_setround (&fpu);
+ do
+ {
+ v = *src++;
+ v *= 32768.;
+ *i16++ = gsl_ftoi (v);
+ }
+ while (src < bound);
+ gsl_fpu_restore (fpu);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER):
+ gsl_fpu_setround (&fpu);
+ do
+ {
+ v = *src++;
+ v *= 32768.;
+ vi16 = gsl_ftoi (v);
+ *i16++ = GUINT16_SWAP_LE_BE (vi16);
+ }
+ while (src < bound);
+ gsl_fpu_restore (fpu);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER == G_BYTE_ORDER):
+ return n_values << 2;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ {
+ vu32 = *u32src++;
+ *u32dest++ = GUINT32_SWAP_LE_BE (vu32);
+ }
+ while (u32src < u32bound);
+ return n_values << 2;
+ default:
+ g_assert_not_reached ();
+ return 0;
+ }
+}
+
+static inline guint /* returns number of bytes used in dest */
+gsl_conv_from_double_clip (GslWaveFormatType format,
+ guint byte_order,
+ const gdouble *src,
+ gpointer dest,
+ guint n_values)
+{
+ gint8 *i8 = (gint8*) dest;
+ guint8 *u8 = (guint8*) dest;
+ gint16 *i16 = (gint16*) dest;
+ guint16 *u16 = (guint16*) dest;
+ guint32 *u32dest = (guint32*) dest;
+ const gdouble *bound = src + n_values;
+ guint32 *u32src = (guint32*) src, *u32bound = (guint32*) bound;
+
+ if (!n_values)
+ return 0;
+
+ switch (GSL_CONV_FORMAT (format, byte_order == G_BYTE_ORDER))
+ {
+ GslFpuState fpu;
+ gdouble v;
+ guint32 vu32;
+ gint32 vi32;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER):
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ {
+ vi32 = *src++ * 128. + 128.5;
+ *u8++ = CLAMP (vi32, 0, 255);
+ }
+ while (src < bound);
+ return n_values;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER):
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER):
+ gsl_fpu_setround (&fpu);
+ do
+ {
+ v = *src++;
+ v *= 128.;
+ vi32 = gsl_ftoi (v);
+ *i8++ = CLAMP (vi32, -128, 127);
+ }
+ while (src < bound);
+ gsl_fpu_restore (fpu);
+ return n_values;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER):
+ do
+ {
+ vi32 = *src++ * 2048. + 2048.5;
+ *u16++ = CLAMP (vi32, 0, 4095);
+ }
+ while (src < bound);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ {
+ vi32 = *src++ * 2048. + 2048.5;
+ vi32 = CLAMP (vi32, 0, 4095);
+ *u16++ = GUINT16_SWAP_LE_BE (vi32);
+ }
+ while (src < bound);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER):
+ gsl_fpu_setround (&fpu);
+ do
+ {
+ v = *src++;
+ v *= 2048.;
+ vi32 = gsl_ftoi (v);
+ *i16++ = CLAMP (vi32, -2048, 2047);
+ }
+ while (src < bound);
+ gsl_fpu_restore (fpu);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER):
+ gsl_fpu_setround (&fpu);
+ do
+ {
+ v = *src++;
+ v *= 2048.;
+ vi32 = gsl_ftoi (v);
+ vi32 = CLAMP (vi32, -2048, 2047);
+ *i16++ = GUINT16_SWAP_LE_BE (vi32);
+ }
+ while (src < bound);
+ gsl_fpu_restore (fpu);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER):
+ do
+ {
+ vi32 = *src++ * 32768. + 32768.5;
+ *u16++ = CLAMP (vi32, 0, 65535);
+ }
+ while (src < bound);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ {
+ vi32 = *src++ * 32768. + 32768.5;
+ vi32 = CLAMP (vi32, 0, 65535);
+ *u16++ = GUINT16_SWAP_LE_BE (vi32);
+ }
+ while (src < bound);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER):
+ gsl_fpu_setround (&fpu);
+ do
+ {
+ v = *src++;
+ v *= 32768.;
+ vi32 = gsl_ftoi (v);
+ vi32 = CLAMP (vi32, -32768, 32767);
+ *i16++ = vi32;
+ }
+ while (src < bound);
+ gsl_fpu_restore (fpu);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER):
+ gsl_fpu_setround (&fpu);
+ do
+ {
+ v = *src++;
+ v *= 32768.;
+ vi32 = gsl_ftoi (v);
+ vi32 = CLAMP (vi32, -32768, 32767);
+ *i16++ = GUINT16_SWAP_LE_BE (vi32);
+ }
+ while (src < bound);
+ gsl_fpu_restore (fpu);
+ return n_values << 1;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER == G_BYTE_ORDER):
+ return n_values << 2;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ {
+ vu32 = *u32src++;
+ *u32dest++ = GUINT32_SWAP_LE_BE (vu32);
+ }
+ while (u32src < u32bound);
+ return n_values << 2;
+ default:
+ g_assert_not_reached ();
+ return 0;
+ }
+}
+
+static inline void
+gsl_conv_to_double (GslWaveFormatType format,
+ guint byte_order,
+ gconstpointer src,
+ gdouble *dest,
+ guint n_values)
+{
+ guint8 *u8 = (guint8*) src;
+ gint8 *i8 = (gint8*) src;
+ guint16 *u16 = (guint16*) src;
+ gint16 *i16 = (gint16*) src;
+ guint32 *u32src = (guint32*) src;
+ gdouble *bound = dest + n_values;
+ guint32 *u32dest = (guint32*) dest, *u32bound = (guint32*) bound;
+
+ if (!n_values)
+ return;
+
+ switch (GSL_CONV_FORMAT (format, byte_order == G_BYTE_ORDER))
+ {
+ gint16 vi16;
+ guint16 vu16;
+ guint32 vu32;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER):
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ *dest++ = (*u8++ - 128) * (1. / 128.);
+ while (dest < bound);
+ break;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER):
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ *dest++ = *i8++ * (1. / 128.);
+ while (dest < bound);
+ break;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER):
+ do
+ *dest++ = ((*u16++ & 0x0fff) - 2048) * (1. / 2048.);
+ while (dest < bound);
+ break;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ {
+ vu16 = *u16++;
+ *dest++ = ((GUINT16_SWAP_LE_BE (vu16) & 0x0fff) - 2048) * (1. / 2048.);
+ }
+ while (dest < bound);
+ break;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER):
+ do
+ {
+ vi16 = *i16++;
+ *dest++ = CLAMP (vi16, -2048, 2048) * (1. / 2048.);
+ }
+ while (dest < bound);
+ break;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ {
+ vi16 = *i16++;
+ vi16 = GUINT16_SWAP_LE_BE (vi16);
+ *dest++ = CLAMP (vi16, -2048, 2048) * (1. / 2048.);
+ }
+ while (dest < bound);
+ break;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER):
+ do
+ *dest++ = (*u16++ - 32768) * (1. / 32768.);
+ while (dest < bound);
+ break;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ {
+ vu16 = *u16++;
+ *dest++ = (GUINT16_SWAP_LE_BE (vu16) - 32768) * (1. / 32768.);
+ }
+ while (dest < bound);
+ break;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER):
+ do
+ *dest++ = *i16++ * (1. / 32768.);
+ while (dest < bound);
+ break;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ {
+ vi16 = *i16++;
+ *dest++ = GUINT16_SWAP_LE_BE (vi16) * (1. / 32768.);
+ }
+ while (dest < bound);
+ break;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER == G_BYTE_ORDER):
+ break;
+ case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER != G_BYTE_ORDER):
+ do
+ {
+ vu32 = *u32src++;
+ *u32dest++ = GUINT32_SWAP_LE_BE (vu32);
+ }
+ while (u32dest < u32bound);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_DATA_UTILS_H__ */
+
+/* vim:set ts=8 sts=2 sw=2: */
diff --git a/flow/gsl/gsldefs.h b/flow/gsl/gsldefs.h
new file mode 100644
index 0000000..d610e9c
--- /dev/null
+++ b/flow/gsl/gsldefs.h
@@ -0,0 +1,136 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001 Stefan Westerfeld and Tim Janik
+ *
+ * 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.
+ */
+#ifndef __GSL_DEFS_H__
+#define __GSL_DEFS_H__
+
+/* configure checks */
+#include <gsl/gslconfig.h>
+#include <glib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* --- forward decls --- */
+typedef struct _GslMagic GslMagic;
+typedef struct _GslClass GslClass;
+typedef struct _GslComplex GslComplex;
+typedef struct _GslDataCache GslDataCache;
+typedef struct _GslDataHandle GslDataHandle;
+typedef struct _GslDataHandleFuncs GslDataHandleFuncs;
+typedef struct _GslGlueContext GslGlueContext;
+typedef struct _GslJob GslJob;
+typedef struct _GslModule GslModule;
+typedef struct _GslIStream GslIStream;
+typedef struct _GslJStream GslJStream;
+typedef struct _GslLoader GslLoader;
+typedef struct _GslOStream GslOStream;
+typedef struct _GslThread GslThread;
+typedef struct _GslTrans GslTrans;
+typedef struct _GslWaveChunk GslWaveChunk;
+typedef struct _GslWaveChunkBlock GslWaveChunkBlock;
+typedef struct _GslRecMutex GslRecMutex;
+typedef struct _GslRing GslRing;
+typedef union _GslCond GslCond;
+typedef union _GslMutex GslMutex;
+/* ssize_t/off_t type used within Gsl */
+typedef glong GslLong;
+#define GSL_MAXLONG G_MAXLONG
+
+
+/* --- GSL errors --- */
+typedef enum /*< skip >*/
+{
+ GSL_ERROR_NONE,
+ GSL_ERROR_INTERNAL,
+ GSL_ERROR_UNKNOWN,
+ /* I/O errors */
+ GSL_ERROR_IO,
+ GSL_ERROR_PERMS,
+ GSL_ERROR_BUSY,
+ GSL_ERROR_EXISTS,
+ GSL_ERROR_TEMP,
+ GSL_ERROR_EOF,
+#define GSL_ERROR_FILE_EMPTY GSL_ERROR_EOF
+ GSL_ERROR_NOT_FOUND,
+ GSL_ERROR_OPEN_FAILED,
+ GSL_ERROR_SEEK_FAILED,
+ GSL_ERROR_READ_FAILED,
+ GSL_ERROR_WRITE_FAILED,
+ /* content errors */
+ GSL_ERROR_FORMAT_INVALID,
+ GSL_ERROR_FORMAT_UNKNOWN,
+ GSL_ERROR_DATA_CORRUPT,
+ GSL_ERROR_CONTENT_GLITCH,
+ /* miscellaneous errors */
+ GSL_ERROR_NO_RESOURCE,
+ GSL_ERROR_CODEC_FAILURE,
+ GSL_ERROR_LAST /* administrative */
+} GslErrorType;
+
+
+/* --- functions --- */
+typedef void (*GslAccessFunc) (GslModule *module,
+ gpointer data);
+typedef void (*GslFreeFunc) (gpointer data);
+typedef void (*GslModuleFreeFunc) (gpointer data,
+ const GslClass *klass);
+
+
+#if defined (BSE_COMPILATION) || defined (BSE_PLUGIN_FALLBACK) \
+ || (GSL_USE_GSL_GLIB) || defined (GSL_EXTENSIONS)
+# define if_expect(cond) if (GSL_GCC_EXPECT (cond))
+# define if_reject(cond) if (GSL_GCC_REJECT (cond))
+#endif
+
+
+/* --- implementation details --- */
+#define GSL_ENGINE_MAX_POLLFDS (128)
+union _GslCond
+{
+ gpointer cond_pointer;
+ guint8 cond_dummy[MAX (8, GSL_SIZEOF_PTH_COND_T)];
+};
+union _GslMutex
+{
+ gpointer mutex_pointer;
+ guint8 mutex_dummy[MAX (8, GSL_SIZEOF_PTH_MUTEX_T)];
+};
+struct _GslRecMutex
+{
+ GslMutex sync_mutex;
+ gpointer owner;
+ guint depth;
+};
+#if __GNUC__ >= 3 && defined __OPTIMIZE__
+# define GSL_GCC_EXPECT(cond) (__builtin_expect ((cond) != 0, 1))
+# define GSL_GCC_REJECT(cond) (__builtin_expect ((cond) != 0, 0))
+#else
+# define GSL_GCC_EXPECT(cond) cond
+# define GSL_GCC_REJECT(cond) cond
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_DEFS_H__ */
+
+/* vim:set ts=8 sw=2 sts=2: */
diff --git a/flow/gsl/gslengine.c b/flow/gsl/gslengine.c
new file mode 100644
index 0000000..65ee620
--- /dev/null
+++ b/flow/gsl/gslengine.c
@@ -0,0 +1,753 @@
+/* GSL Engine - Flow module operation engine
+ * Copyright (C) 2001 Tim Janik
+ *
+ * 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.
+ */
+#include "gslengine.h"
+
+#include "gslcommon.h"
+#include "gslopnode.h"
+#include "gslopmaster.h"
+
+
+/* --- prototypes --- */
+static void wakeup_master (void);
+
+
+/* --- UserThread --- */
+GslModule*
+gsl_module_new (const GslClass *klass,
+ gpointer user_data)
+{
+ EngineNode *node;
+ guint i;
+
+ g_return_val_if_fail (klass != NULL, NULL);
+ g_return_val_if_fail (klass->process != NULL || klass->process_defer != NULL, NULL);
+ if (klass->process_defer)
+ {
+ g_warning ("%s: Delay cycle processing not yet implemented", G_STRLOC);
+ return NULL;
+ }
+
+ node = gsl_new_struct0 (EngineNode, 1);
+
+ /* setup GslModule */
+ node->module.klass = klass;
+ node->module.user_data = user_data;
+ node->module.istreams = klass->n_istreams ? gsl_new_struct0 (GslIStream, ENGINE_NODE_N_ISTREAMS (node)) : NULL;
+ node->module.jstreams = klass->n_jstreams ? gsl_new_struct0 (GslJStream, ENGINE_NODE_N_JSTREAMS (node)) : NULL;
+ node->module.ostreams = _engine_alloc_ostreams (ENGINE_NODE_N_OSTREAMS (node));
+
+ /* setup EngineNode */
+ node->inputs = ENGINE_NODE_N_ISTREAMS (node) ? gsl_new_struct0 (EngineInput, ENGINE_NODE_N_ISTREAMS (node)) : NULL;
+ node->jinputs = ENGINE_NODE_N_JSTREAMS (node) ? gsl_new_struct0 (EngineJInput*, ENGINE_NODE_N_JSTREAMS (node)) : NULL;
+ node->outputs = ENGINE_NODE_N_OSTREAMS (node) ? gsl_new_struct0 (EngineOutput, ENGINE_NODE_N_OSTREAMS (node)) : NULL;
+ node->output_nodes = NULL;
+ node->integrated = FALSE;
+ gsl_rec_mutex_init (&node->rec_mutex);
+ for (i = 0; i < ENGINE_NODE_N_OSTREAMS (node); i++)
+ {
+ node->outputs[i].buffer = node->module.ostreams[i].values;
+ node->module.ostreams[i].sub_sample_pattern = gsl_engine_sub_sample_test (node->module.ostreams[i].values);
+ }
+ node->flow_jobs = NULL;
+ node->fjob_first = NULL;
+ node->fjob_last = NULL;
+
+ return &node->module;
+}
+
+/**
+ * gsl_module_tick_stamp
+ * @module: a GSL engine module
+ * @RETURNS: the module's tick stamp, indicating its process status
+ *
+ * Any thread may call this function on a valid engine module.
+ * The module specific tick stamp is updated to gsl_tick_stamp() +
+ * @n_values every time its GslProcessFunc() function was
+ * called. See also gsl_tick_stamp().
+ */
+guint64
+gsl_module_tick_stamp (GslModule *module)
+{
+ g_return_val_if_fail (module != NULL, 0);
+
+ return ENGINE_NODE (module)->counter;
+}
+
+/**
+ * gsl_job_integrate
+ * @module: The module to integrate
+ * @Returns: New job suitable for gsl_trans_add()
+ *
+ * Create a new transaction job to integrate @module into the engine.
+ */
+GslJob*
+gsl_job_integrate (GslModule *module)
+{
+ GslJob *job;
+
+ g_return_val_if_fail (module != NULL, NULL);
+
+ job = gsl_new_struct0 (GslJob, 1);
+ job->job_id = ENGINE_JOB_INTEGRATE;
+ job->data.node = ENGINE_NODE (module);
+
+ return job;
+}
+
+/**
+ * gsl_job_discard
+ * @module: The module to discard
+ * @Returns: New job suitable for gsl_trans_add()
+ *
+ * Create a new transaction job which removes @module from the
+ * engine and destroys it.
+ */
+GslJob*
+gsl_job_discard (GslModule *module)
+{
+ GslJob *job;
+
+ g_return_val_if_fail (module != NULL, NULL);
+
+ job = gsl_new_struct0 (GslJob, 1);
+ job->job_id = ENGINE_JOB_DISCARD;
+ job->data.node = ENGINE_NODE (module);
+
+ return job;
+}
+
+/**
+ * gsl_job_connect
+ * @src_module: Module with output stream
+ * @src_ostream: Index of output stream of @src_module
+ * @dest_module: Module with unconnected input stream
+ * @dest_istream: Index of input stream of @dest_module
+ * @Returns: New job suitable for gsl_trans_add()
+ *
+ * Create a new transaction job which connects the output stream @src_ostream
+ * of module @src_module to the input stream @dest_istream of module @dest_module
+ * (it is an error if the input stream is already connected by the time the job
+ * is executed).
+ */
+GslJob*
+gsl_job_connect (GslModule *src_module,
+ guint src_ostream,
+ GslModule *dest_module,
+ guint dest_istream)
+{
+ GslJob *job;
+
+ g_return_val_if_fail (src_module != NULL, NULL);
+ g_return_val_if_fail (src_ostream < src_module->klass->n_ostreams, NULL);
+ g_return_val_if_fail (dest_module != NULL, NULL);
+ g_return_val_if_fail (dest_istream < dest_module->klass->n_istreams, NULL);
+
+ job = gsl_new_struct0 (GslJob, 1);
+ job->job_id = ENGINE_JOB_ICONNECT;
+ job->data.connection.dest_node = ENGINE_NODE (dest_module);
+ job->data.connection.dest_ijstream = dest_istream;
+ job->data.connection.src_node = ENGINE_NODE (src_module);
+ job->data.connection.src_ostream = src_ostream;
+
+ return job;
+}
+
+GslJob*
+gsl_job_jconnect (GslModule *src_module,
+ guint src_ostream,
+ GslModule *dest_module,
+ guint dest_jstream)
+{
+ GslJob *job;
+
+ g_return_val_if_fail (src_module != NULL, NULL);
+ g_return_val_if_fail (src_ostream < src_module->klass->n_ostreams, NULL);
+ g_return_val_if_fail (dest_module != NULL, NULL);
+ g_return_val_if_fail (dest_jstream < dest_module->klass->n_jstreams, NULL);
+
+ job = gsl_new_struct0 (GslJob, 1);
+ job->job_id = ENGINE_JOB_JCONNECT;
+ job->data.connection.dest_node = ENGINE_NODE (dest_module);
+ job->data.connection.dest_ijstream = dest_jstream;
+ job->data.connection.src_node = ENGINE_NODE (src_module);
+ job->data.connection.src_ostream = src_ostream;
+
+ return job;
+}
+
+/**
+ * gsl_job_disconnect
+ * @dest_module: Module with connected input stream
+ * @dest_istream: Index of input stream of @dest_module
+ * @Returns: New job suitable for gsl_trans_add()
+ *
+ * Create a new transaction job which causes the input stream @dest_istream
+ * of @dest_module to be disconnected (it is an error if the input stream isn't
+ * connected by the time the job is executed).
+ */
+GslJob*
+gsl_job_disconnect (GslModule *dest_module,
+ guint dest_istream)
+{
+ GslJob *job;
+
+ g_return_val_if_fail (dest_module != NULL, NULL);
+ g_return_val_if_fail (dest_istream < dest_module->klass->n_istreams, NULL);
+
+ job = gsl_new_struct0 (GslJob, 1);
+ job->job_id = ENGINE_JOB_IDISCONNECT;
+ job->data.connection.dest_node = ENGINE_NODE (dest_module);
+ job->data.connection.dest_ijstream = dest_istream;
+ job->data.connection.src_node = NULL;
+ job->data.connection.src_ostream = ~0;
+
+ return job;
+}
+
+GslJob*
+gsl_job_jdisconnect (GslModule *dest_module,
+ guint dest_jstream,
+ GslModule *src_module,
+ guint src_ostream)
+{
+ GslJob *job;
+
+ g_return_val_if_fail (dest_module != NULL, NULL);
+ g_return_val_if_fail (dest_jstream < dest_module->klass->n_jstreams, NULL);
+ g_return_val_if_fail (src_module != NULL, NULL);
+ g_return_val_if_fail (src_ostream < src_module->klass->n_ostreams, NULL);
+
+ job = gsl_new_struct0 (GslJob, 1);
+ job->job_id = ENGINE_JOB_JDISCONNECT;
+ job->data.connection.dest_node = ENGINE_NODE (dest_module);
+ job->data.connection.dest_ijstream = dest_jstream;
+ job->data.connection.src_node = ENGINE_NODE (src_module);
+ job->data.connection.src_ostream = src_ostream;
+
+ return job;
+}
+
+GslJob*
+gsl_job_set_consumer (GslModule *module,
+ gboolean is_toplevel_consumer)
+{
+ GslJob *job;
+
+ g_return_val_if_fail (module != NULL, NULL);
+
+ job = gsl_new_struct0 (GslJob, 1);
+ job->job_id = is_toplevel_consumer ? ENGINE_JOB_SET_CONSUMER : ENGINE_JOB_UNSET_CONSUMER;
+ job->data.node = ENGINE_NODE (module);
+
+ return job;
+}
+
+/**
+ * GslAccessFunc
+ * @module: Module to operate on
+ * @data: Accessor data
+ *
+ * The GslAccessFunc is a user supplied callback function which can access
+ * a module in times it is not processing. Accessors are usually used to
+ * either read out a module's current state, or to modify its state. An
+ * accessor may only operate on the @data and the @module passed
+ * in to it.
+ */
+/**
+ * gsl_job_access
+ * @module: The module to access
+ * @access_func: The accessor function
+ * @data: Data passed in to the accessor
+ * @free_func: Function to free @data
+ * @Returns: New job suitable for gsl_trans_add()
+ *
+ * Create a new transaction job which will invoke @access_func
+ * on @module with @data when the transaction queue is processed
+ * to modify the module's state.
+ */
+GslJob*
+gsl_job_access (GslModule *module,
+ GslAccessFunc access_func,
+ gpointer data,
+ GslFreeFunc free_func)
+{
+ GslJob *job;
+
+ g_return_val_if_fail (module != NULL, NULL);
+ g_return_val_if_fail (access_func != NULL, NULL);
+
+ job = gsl_new_struct0 (GslJob, 1);
+ job->job_id = ENGINE_JOB_ACCESS;
+ job->data.access.node = ENGINE_NODE (module);
+ job->data.access.access_func = access_func;
+ job->data.access.data = data;
+ job->data.access.free_func = free_func;
+
+ return job;
+}
+
+/**
+ * gsl_flow_job_access
+ */
+GslJob*
+gsl_flow_job_access (GslModule *module,
+ guint64 tick_stamp,
+ GslAccessFunc access_func,
+ gpointer data,
+ GslFreeFunc free_func)
+{
+ GslJob *job;
+ EngineFlowJob *fjob;
+
+ g_return_val_if_fail (module != NULL, NULL);
+ g_return_val_if_fail (access_func != NULL, NULL);
+
+ fjob = (EngineFlowJob*) gsl_new_struct0 (EngineFlowJobAccess, 1);
+ fjob->fjob_id = ENGINE_FLOW_JOB_ACCESS;
+ fjob->any.tick_stamp = tick_stamp;
+ fjob->access.access_func = access_func;
+ fjob->access.data = data;
+ fjob->access.free_func = free_func;
+
+ job = gsl_new_struct0 (GslJob, 1);
+ job->job_id = ENGINE_JOB_FLOW_JOB;
+ job->data.flow_job.node = ENGINE_NODE (module);
+ job->data.flow_job.fjob = fjob;
+
+ return job;
+}
+
+GslJob*
+gsl_flow_job_suspend (GslModule *module,
+ guint64 tick_stamp)
+{
+ GslJob *job;
+ EngineFlowJob *fjob;
+
+ g_return_val_if_fail (module != NULL, NULL);
+
+ fjob = (EngineFlowJob*) gsl_new_struct0 (EngineFlowJobAny, 1);
+ fjob->fjob_id = ENGINE_FLOW_JOB_SUSPEND;
+ fjob->any.tick_stamp = tick_stamp;
+
+ job = gsl_new_struct0 (GslJob, 1);
+ job->job_id = ENGINE_JOB_FLOW_JOB;
+ job->data.flow_job.node = ENGINE_NODE (module);
+ job->data.flow_job.fjob = fjob;
+
+ return job;
+}
+
+GslJob*
+gsl_flow_job_resume (GslModule *module,
+ guint64 tick_stamp)
+{
+ GslJob *job;
+ EngineFlowJob *fjob;
+
+ g_return_val_if_fail (module != NULL, NULL);
+
+ fjob = (EngineFlowJob*) gsl_new_struct0 (EngineFlowJobAny, 1);
+ fjob->fjob_id = ENGINE_FLOW_JOB_RESUME;
+ fjob->any.tick_stamp = tick_stamp;
+
+ job = gsl_new_struct0 (GslJob, 1);
+ job->job_id = ENGINE_JOB_FLOW_JOB;
+ job->data.flow_job.node = ENGINE_NODE (module);
+ job->data.flow_job.fjob = fjob;
+
+ return job;
+}
+
+/**
+ * GslPollFunc
+ * @data: Data of poll function
+ * @n_values: Minimum number of values the engine wants to process
+ * @timeout_p: Location of timeout value
+ * @n_fds: Number of file descriptors used for polling
+ * @fds: File descriptors to be used for polling
+ * @revents_filled: Indicates whether @fds actually have their ->revents field filled with valid data.
+ * @Returns: A boolean value indicating whether the engine should process data right now
+ *
+ * The GslPollFunc is a user supplied callback function which can be hooked into the
+ * GSL engine. The engine uses the poll functions to determine whether processing of
+ * @n_values in its module network is necessary.
+ * In order for the poll functions to react to extern events, such as device driver
+ * status changes, the engine will poll(2) the @fds of the poll function and invoke
+ * the callback with @revents_filled==%TRUE if any of its @fds changed state.
+ * The callback may also be invoked at other random times with @revents_filled=%FALSE.
+ * It is supposed to return %TRUE if network processing is currently necessary, and
+ * %FALSE if not.
+ * If %FALSE is returned, @timeout_p may be filled with the number of milliseconds
+ * the engine should use for polling at maximum.
+ */
+/**
+ * gsl_job_add_poll
+ * @poll_func: Poll function to add
+ * @data: Data of poll function
+ * @free_func: Function to free @data
+ * @n_fds: Number of poll file descriptors
+ * @fds: File descriptors to select(2) or poll(2) on
+ * @Returns: New job suitable for gsl_trans_add()
+ *
+ * Create a new transaction job which adds a poll function
+ * to the engine. The poll function is used by the engine to
+ * determine whether processing is currently necessary.
+ */
+GslJob*
+gsl_job_add_poll (GslPollFunc poll_func,
+ gpointer data,
+ GslFreeFunc free_func,
+ guint n_fds,
+ const GPollFD *fds)
+{
+ GslJob *job;
+
+ g_return_val_if_fail (poll_func != NULL, NULL);
+ if (n_fds)
+ g_return_val_if_fail (fds != NULL, NULL);
+
+ job = gsl_new_struct0 (GslJob, 1);
+ job->job_id = ENGINE_JOB_ADD_POLL;
+ job->data.poll.poll_func = poll_func;
+ job->data.poll.data = data;
+ job->data.poll.n_fds = n_fds;
+ job->data.poll.fds = g_memdup (fds, sizeof (fds[0]) * n_fds);
+
+ return job;
+}
+
+/**
+ * gsl_job_remove_poll
+ * @poll_func: Poll function to remove
+ * @data: Data of poll function
+ * @Returns: New job suitable for gsl_trans_add()
+ *
+ * Create a new transaction job which removes a previously inserted poll
+ * function from the engine.
+ */
+GslJob*
+gsl_job_remove_poll (GslPollFunc poll_func,
+ gpointer data)
+{
+ GslJob *job;
+
+ g_return_val_if_fail (poll_func != NULL, NULL);
+
+ job = gsl_new_struct0 (GslJob, 1);
+ job->job_id = ENGINE_JOB_REMOVE_POLL;
+ job->data.poll.poll_func = poll_func;
+ job->data.poll.data = data;
+ job->data.poll.free_func = NULL;
+ job->data.poll.fds = NULL;
+
+ return job;
+}
+
+/**
+ * gsl_job_debug
+ * @debug: Debug message
+ * @Returns: New job suitable for gsl_trans_add()
+ *
+ * Create a new transaction job which issues @debug message when
+ * the job is executed. This function is meant for debugging purposes
+ * during development phase only and shouldn't be used in production code.
+ */
+GslJob*
+gsl_job_debug (const gchar *debug)
+{
+ GslJob *job;
+
+ g_return_val_if_fail (debug != NULL, NULL);
+
+ job = gsl_new_struct0 (GslJob, 1);
+ job->job_id = ENGINE_JOB_DEBUG;
+ job->data.debug = g_strdup (debug);
+
+ return job;
+}
+
+/**
+ * gsl_trans_open
+ * @Returns: Newly opened empty transaction
+ *
+ * Open up a new transaction to commit jobs to the GSL engine.
+ * This function may cause garbage collection (see
+ * gsl_engine_garbage_collect()).
+ */
+GslTrans*
+gsl_trans_open (void)
+{
+ GslTrans *trans;
+
+ gsl_engine_garbage_collect ();
+
+ trans = gsl_new_struct0 (GslTrans, 1);
+
+ trans->jobs_head = NULL;
+ trans->jobs_tail = NULL;
+ trans->comitted = FALSE;
+ trans->cqt_next = NULL;
+
+ return trans;
+}
+
+/**
+ * gsl_trans_add
+ * @trans: Opened transaction
+ * @job: Job to add
+ *
+ * Append a job to an opened transaction.
+ */
+void
+gsl_trans_add (GslTrans *trans,
+ GslJob *job)
+{
+ g_return_if_fail (trans != NULL);
+ g_return_if_fail (trans->comitted == FALSE);
+ g_return_if_fail (job != NULL);
+ g_return_if_fail (job->next == NULL);
+
+ if (trans->jobs_tail)
+ trans->jobs_tail->next = job;
+ else
+ trans->jobs_head = job;
+ trans->jobs_tail = job;
+}
+
+/**
+ * gsl_trans_commit
+ * @trans: Opened transaction
+ *
+ * Close the transaction and commit it to the engine. The engine
+ * will execute the jobs contained in this transaction as soon as
+ * it has completed its current processing cycle. The jobs will be
+ * executed in the exact order they were added to the transaction.
+ */
+void
+gsl_trans_commit (GslTrans *trans)
+{
+ g_return_if_fail (trans != NULL);
+ g_return_if_fail (trans->comitted == FALSE);
+ g_return_if_fail (trans->cqt_next == NULL);
+
+ if (trans->jobs_head)
+ {
+ trans->comitted = TRUE;
+ _engine_enqueue_trans (trans);
+ wakeup_master ();
+ }
+ else
+ gsl_trans_dismiss (trans);
+}
+
+/**
+ * gsl_trans_dismiss
+ * @trans: Opened transaction
+ *
+ * Close and discard the transaction, destroy all jobs currently
+ * contained in it and do not execute them.
+ * This function may cause garbage collection (see
+ * gsl_engine_garbage_collect()).
+ */
+void
+gsl_trans_dismiss (GslTrans *trans)
+{
+ g_return_if_fail (trans != NULL);
+ g_return_if_fail (trans->comitted == FALSE);
+ g_return_if_fail (trans->cqt_next == NULL);
+
+ _engine_free_trans (trans);
+
+ gsl_engine_garbage_collect ();
+}
+
+/**
+ * gsl_transact
+ * @job: First job
+ * @...: %NULL terminated job list
+ *
+ * Convenience function which openes up a new transaction,
+ * collects the %NULL terminated job list passed to the function,
+ * and commits the transaction.
+ */
+void
+gsl_transact (GslJob *job,
+ ...)
+{
+ GslTrans *trans = gsl_trans_open ();
+ va_list var_args;
+
+ va_start (var_args, job);
+ while (job)
+ {
+ gsl_trans_add (trans, job);
+ job = va_arg (var_args, GslJob*);
+ }
+ va_end (var_args);
+ gsl_trans_commit (trans);
+}
+
+
+/* --- initialization --- */
+static void
+slave (gpointer data)
+{
+ gboolean run = TRUE;
+
+ while (run)
+ {
+ GslTrans *trans = gsl_trans_open ();
+ gchar *str = g_strdup_printf ("SLAVE(%p): idle", g_thread_self ());
+
+ gsl_trans_add (trans, gsl_job_debug (str));
+ g_free (str);
+ gsl_trans_add (trans, gsl_job_debug ("string2"));
+ gsl_trans_commit (trans);
+
+ trans = gsl_trans_open ();
+ gsl_trans_add (trans, gsl_job_debug ("trans2"));
+ gsl_trans_commit (trans);
+
+ g_usleep (1000*500);
+ }
+}
+
+/* --- setup & trigger --- */
+static gboolean gsl_engine_initialized = FALSE;
+static gboolean gsl_engine_threaded = FALSE;
+static GslThread *master_thread = NULL;
+guint gsl_externvar_bsize = 0;
+guint gsl_externvar_sample_freq = 0;
+guint gsl_externvar_sub_sample_mask = 0;
+guint gsl_externvar_sub_sample_steps = 0;
+
+/**
+ * gsl_engine_init
+ * @block_size: number of values to process block wise
+ *
+ * Initialize the GSL engine, this function must be called prior to
+ * any other engine related function and can only be invoked once.
+ * The @block_size determines the amount by which the global tick
+ * stamp (see gsl_tick_stamp()) is updated every time the whole
+ * module network completed processing @block_size values.
+ */
+void
+gsl_engine_init (gboolean run_threaded,
+ guint block_size,
+ guint sample_freq,
+ guint sub_sample_mask)
+{
+ g_return_if_fail (gsl_engine_initialized == FALSE);
+ g_return_if_fail (block_size > 0 && block_size <= GSL_STREAM_MAX_VALUES);
+ g_return_if_fail (sample_freq > 0);
+ g_return_if_fail (sub_sample_mask < block_size);
+ g_return_if_fail ((sub_sample_mask & (sub_sample_mask + 1)) == 0); /* power of 2 */
+
+ gsl_engine_initialized = TRUE;
+ gsl_engine_threaded = run_threaded;
+ gsl_externvar_bsize = block_size;
+ gsl_externvar_sample_freq = sample_freq;
+ gsl_externvar_sub_sample_mask = sub_sample_mask << 2; /* shift out sizeof (float) alignment */
+ gsl_externvar_sub_sample_steps = sub_sample_mask + 1;
+ _gsl_tick_stamp_set_leap (block_size);
+
+ ENG_DEBUG ("initialization: threaded=%s", gsl_engine_threaded ? "TRUE" : "FALSE");
+
+ if (gsl_engine_threaded)
+ {
+ if (!g_thread_supported ()) g_thread_init (NULL);
+ master_thread = gsl_thread_new (_engine_master_thread, NULL);
+ if (0)
+ gsl_thread_new (slave, NULL);
+ }
+}
+
+static void
+wakeup_master (void)
+{
+ if (master_thread)
+ gsl_thread_wakeup (master_thread);
+}
+
+gboolean
+gsl_engine_prepare (GslEngineLoop *loop)
+{
+ g_return_val_if_fail (loop != NULL, FALSE);
+ g_return_val_if_fail (gsl_engine_initialized == TRUE, FALSE);
+
+ if (!gsl_engine_threaded)
+ return _engine_master_prepare (loop);
+ else
+ {
+ loop->timeout = -1;
+ loop->fds_changed = FALSE;
+ loop->n_fds = 0;
+ loop->revents_filled = FALSE;
+ return FALSE;
+ }
+}
+
+gboolean
+gsl_engine_check (const GslEngineLoop *loop)
+{
+ g_return_val_if_fail (loop != NULL, FALSE);
+ if (loop->n_fds)
+ g_return_val_if_fail (loop->revents_filled == TRUE, FALSE);
+
+ if (!gsl_engine_threaded)
+ return _engine_master_check (loop);
+ else
+ return FALSE;
+}
+
+void
+gsl_engine_dispatch (void)
+{
+ g_return_if_fail (gsl_engine_initialized == TRUE);
+
+ if (!gsl_engine_threaded)
+ _engine_master_dispatch ();
+}
+
+/**
+ * gsl_engine_wait_on_trans
+ *
+ * Wait until all pending transactions have been processed
+ * by the GSL Engine.
+ * This function may cause garbage collection (see
+ * gsl_engine_garbage_collect()).
+ */
+void
+gsl_engine_wait_on_trans (void)
+{
+ g_return_if_fail (gsl_engine_initialized == TRUE);
+
+ /* non-threaded */
+ if (!gsl_engine_threaded)
+ _engine_master_dispatch_jobs ();
+
+ /* threaded */
+ _engine_wait_on_trans ();
+
+ /* call all free() functions */
+ gsl_engine_garbage_collect ();
+}
+
+/* vim:set ts=8 sts=2 sw=2: */
diff --git a/flow/gsl/gslengine.h b/flow/gsl/gslengine.h
new file mode 100644
index 0000000..34f8f80
--- /dev/null
+++ b/flow/gsl/gslengine.h
@@ -0,0 +1,206 @@
+/* GSL Engine - Flow module operation engine
+ * Copyright (C) 2001 Tim Janik
+ *
+ * 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.
+ */
+#ifndef __GSL_ENGINE_H__
+#define __GSL_ENGINE_H__
+
+#include <gsl/gsldefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+
+/* --- constants --- */
+#define GSL_STREAM_MAX_VALUES (8192 /* power of 2, <= 16384 */) /* FIXME */
+#define GSL_MODULE_N_OSTREAMS(module) ((module)->klass->n_ostreams)
+#define GSL_MODULE_N_ISTREAMS(module) ((module)->klass->n_istreams)
+#define GSL_MODULE_N_JSTREAMS(module) ((module)->klass->n_jstreams)
+#define GSL_MODULE_ISTREAM(module, stream) ((module)->istreams[(stream)])
+#define GSL_MODULE_JSTREAM(module, stream) ((module)->jstreams[(stream)])
+#define GSL_MODULE_OSTREAM(module, stream) ((module)->ostreams[(stream)])
+#define GSL_MODULE_IBUFFER(module, stream) (GSL_MODULE_ISTREAM ((module), (stream)).values)
+#define GSL_MODULE_JBUFFER(module, stream, con) (GSL_MODULE_JSTREAM ((module), (stream)).values[con])
+#define GSL_MODULE_OBUFFER(module, stream) (GSL_MODULE_OSTREAM ((module), (stream)).values)
+
+
+/* --- typedefs --- */
+typedef gboolean (*GslPollFunc) (gpointer data,
+ guint n_values,
+ glong *timeout_p,
+ guint n_fds,
+ const GPollFD *fds,
+ gboolean revents_filled);
+typedef void (*GslProcessFunc) (GslModule *module,
+ guint n_values);
+typedef guint (*GslProcessDeferFunc) (GslModule *module,
+ guint n_ivalues,
+ guint n_ovalues);
+typedef void (*GslReconnectFunc) (GslModule *module);
+/* gsldefs.h:
+ * typedef void (*GslAccessFunc) (GslModule *module,
+ * gpointer data);
+ * typedef void (*GslFreeFunc) (gpointer data);
+ * typedef void (*GslModuleFreeFunc) (gpointer data,
+ * const GslClass *klass);
+ */
+typedef enum /*< skip >*/
+{
+ GSL_COST_NORMAL = 0,
+ GSL_COST_CHEAP = 1 << 0,
+ GSL_COST_EXPENSIVE = 1 << 1
+} GslModuleFlags;
+/* class, filled out by user */
+struct _GslClass
+{
+ guint n_istreams;
+ guint n_jstreams;
+ guint n_ostreams;
+ GslProcessFunc process; /* EngineThread */
+ GslProcessDeferFunc process_defer; /* EngineThread */
+ GslReconnectFunc reconnect; /* EngineThread */
+ GslModuleFreeFunc free; /* UserThread */
+ GslModuleFlags mflags;
+};
+/* module, constructed by engine */
+struct _GslModule
+{
+ const GslClass *klass;
+ gpointer user_data;
+ GslIStream *istreams; /* input streams */
+ GslJStream *jstreams; /* joint (multiconnect) input streams */
+ GslOStream *ostreams; /* output streams */
+};
+/* streams, constructed by engine */
+struct _GslJStream
+{
+ const gfloat **values;
+ guint n_connections;
+ guint reserved : 16;
+};
+struct _GslIStream
+{
+ const gfloat *values;
+ guint reserved : 16;
+ guint connected : 1;
+};
+struct _GslOStream
+{
+ gfloat *values;
+ guint sub_sample_pattern : 16;
+ guint connected : 1;
+};
+
+
+/* --- interface (UserThread functions) --- */
+GslModule* gsl_module_new (const GslClass *klass,
+ gpointer user_data);
+guint64 gsl_module_tick_stamp (GslModule *module);
+GslJob* gsl_job_connect (GslModule *src_module,
+ guint src_ostream,
+ GslModule *dest_module,
+ guint dest_istream);
+GslJob* gsl_job_jconnect (GslModule *src_module,
+ guint src_ostream,
+ GslModule *dest_module,
+ guint dest_jstream);
+GslJob* gsl_job_disconnect (GslModule *dest_module,
+ guint dest_istream);
+GslJob* gsl_job_jdisconnect (GslModule *dest_module,
+ guint dest_jstream,
+ GslModule *src_module,
+ guint src_ostream);
+GslJob* gsl_job_integrate (GslModule *module);
+GslJob* gsl_job_discard (GslModule *module);
+GslJob* gsl_job_access (GslModule *module,
+ GslAccessFunc access_func, /* EngineThread */
+ gpointer data,
+ GslFreeFunc free_func); /* UserThread */
+GslJob* gsl_job_set_consumer (GslModule *module,
+ gboolean is_toplevel_consumer);
+GslJob* gsl_job_debug (const gchar *debug);
+GslJob* gsl_job_add_poll (GslPollFunc poll_func,
+ gpointer data,
+ GslFreeFunc free_func,
+ guint n_fds,
+ const GPollFD *fds);
+GslJob* gsl_job_remove_poll (GslPollFunc poll_func,
+ gpointer data);
+GslTrans* gsl_trans_open (void);
+void gsl_trans_add (GslTrans *trans,
+ GslJob *job);
+void gsl_trans_commit (GslTrans *trans);
+void gsl_trans_dismiss (GslTrans *trans);
+void gsl_transact (GslJob *job,
+ ...);
+GslJob* gsl_flow_job_access (GslModule *module,
+ guint64 tick_stamp,
+ GslAccessFunc access_func, /* EngineThread */
+ gpointer data,
+ GslFreeFunc free_func); /* UserThread */
+GslJob* gsl_flow_job_suspend (GslModule *module,
+ guint64 tick_stamp);
+GslJob* gsl_flow_job_resume (GslModule *module,
+ guint64 tick_stamp);
+
+
+/* --- module utilities --- */
+gfloat* gsl_engine_const_values (gfloat value);
+
+
+/* --- initialization & main loop --- */
+void gsl_engine_init (gboolean threaded,
+ guint block_size,
+ guint sample_freq,
+ guint sub_sample_mask);
+typedef struct
+{
+ glong timeout;
+ gboolean fds_changed;
+ guint n_fds;
+ GPollFD *fds;
+ gboolean revents_filled;
+} GslEngineLoop;
+gboolean gsl_engine_prepare (GslEngineLoop *loop);
+gboolean gsl_engine_check (const GslEngineLoop *loop);
+void gsl_engine_dispatch (void);
+
+
+/* --- miscellaneous --- */
+void gsl_engine_garbage_collect (void);
+void gsl_engine_wait_on_trans (void);
+#define gsl_engine_block_size() ((const guint) gsl_externvar_bsize + 0)
+#define gsl_engine_sample_freq() ((const guint) gsl_externvar_sample_freq + 0)
+#define gsl_engine_sub_sample_mask() ((const guint) gsl_externvar_sub_sample_mask + 0)
+#define gsl_engine_sub_sample_steps() ((const guint) gsl_externvar_sub_sample_steps + 0)
+#define gsl_engine_sub_sample_test(ptr) (((guint) (ptr)) & gsl_engine_sub_sample_mask ())
+#define GSL_SUB_SAMPLE_MATCH(ptr,sspatrn) (gsl_engine_sub_sample_test (ptr) == (sspatrn))
+
+
+/*< private >*/
+extern guint gsl_externvar_bsize;
+extern guint gsl_externvar_sample_freq;
+extern guint gsl_externvar_sub_sample_mask;
+extern guint gsl_externvar_sub_sample_steps;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_ENGINE_H__ */
diff --git a/flow/gsl/gslfft.c b/flow/gsl/gslfft.c
new file mode 100644
index 0000000..48f56ef
--- /dev/null
+++ b/flow/gsl/gslfft.c
@@ -0,0 +1,9052 @@
+#include "gslfft.h"
+#include <math.h>
+
+#define BUTTERFLY_XY(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,Wre,Wim) { \
+ register double T1re, T1im, T2re, T2im; \
+ T1re = X2re * Wre; \
+ T1im = X2im * Wre; \
+ T2re = X2im * Wim; \
+ T2im = X2re * Wim; \
+ T1re -= T2re; \
+ T1im += T2im; \
+ T2re = X1re - T1re; \
+ T2im = X1im - T1im; \
+ Y1re = X1re + T1re; \
+ Y1im = X1im + T1im; \
+ Y2re = T2re; \
+ Y2im = T2im; \
+}
+#define BUTTERFLY_Yx(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,Wre,Wim) { \
+ register double T1re, T1im, T2re, T2im; \
+ T1re = X2re * Wim; \
+ T1im = X2im * Wim; \
+ T2re = X2im * Wre; \
+ T2im = X2re * Wre; \
+ T1re += T2re; \
+ T1im -= T2im; \
+ T2re = X1re + T1re; \
+ T2im = X1im + T1im; \
+ Y1re = X1re - T1re; \
+ Y1im = X1im - T1im; \
+ Y2re = T2re; \
+ Y2im = T2im; \
+}
+#define BUTTERFLY_yX(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,Wre,Wim) { \
+ register double T1re, T1im, T2re, T2im; \
+ T1re = X2re * Wim; \
+ T1im = X2im * Wim; \
+ T2re = X2im * Wre; \
+ T2im = X2re * Wre; \
+ T1re += T2re; \
+ T1im -= T2im; \
+ T2re = X1re - T1re; \
+ T2im = X1im - T1im; \
+ Y1re = X1re + T1re; \
+ Y1im = X1im + T1im; \
+ Y2re = T2re; \
+ Y2im = T2im; \
+}
+#define BUTTERFLY_10(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,_1,_2) { \
+ register double T2re, T2im; \
+ T2re = X1re - X2re; \
+ T2im = X1im - X2im; \
+ Y1re = X1re + X2re; \
+ Y1im = X1im + X2im; \
+ Y2re = T2re; \
+ Y2im = T2im; \
+}
+#define BUTTERFLY_01(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,_1,_2) { \
+ register double T2re, T2im; \
+ T2re = X1re + X2im; \
+ T2im = X1im - X2re; \
+ Y1re = X1re - X2im; \
+ Y1im = X1im + X2re; \
+ Y2re = T2re; \
+ Y2im = T2im; \
+}
+#define BUTTERFLY_0m(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,_1,_2) { \
+ register double T2re, T2im; \
+ T2re = X1re - X2im; \
+ T2im = X1im + X2re; \
+ Y1re = X1re + X2im; \
+ Y1im = X1im - X2re; \
+ Y2re = T2re; \
+ Y2im = T2im; \
+}
+#define BUTTERFLY_XX(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,Wre,_2) { \
+ register double T1re, T1im, T2re, T2im; \
+ T1re = X2re * Wre; \
+ T1im = X2im * Wre; \
+ T2re = T1im; \
+ T2im = T1re; \
+ T1re -= T2re; \
+ T1im += T2im; \
+ T2re = X1re - T1re; \
+ T2im = X1im - T1im; \
+ Y1re = X1re + T1re; \
+ Y1im = X1im + T1im; \
+ Y2re = T2re; \
+ Y2im = T2im; \
+}
+#define BUTTERFLY_yY(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,Wre,_2) { \
+ register double T1re, T1im, T2re, T2im; \
+ T1re = X2re * Wre; \
+ T1im = X2im * Wre; \
+ T2re = T1im; \
+ T2im = T1re; \
+ T1re += T2re; \
+ T1im -= T2im; \
+ T2re = X1re - T1re; \
+ T2im = X1im - T1im; \
+ Y1re = X1re + T1re; \
+ Y1im = X1im + T1im; \
+ Y2re = T2re; \
+ Y2im = T2im; \
+}
+#define BUTTERFLY_10scale(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,S) { \
+ register double T2re, T2im; \
+ T2re = X1re - X2re; \
+ T2im = X1im - X2im; \
+ Y1re = X1re + X2re; \
+ Y1im = X1im + X2im; \
+ Y2re = T2re * S; \
+ Y2im = T2im * S; \
+ Y1re *= S; \
+ Y1im *= S; \
+}
+
+#define WMULTIPLY(Wre,Wim,Dre,Dim) { \
+ register double T1re, T1im, T2re, T2im; \
+ T1re = Wre * Dre; \
+ T1im = Wim * Dre; \
+ T2re = Wim * Dim; \
+ T2im = Wre * Dim; \
+ T1re -= T2re; \
+ T1im += T2im; \
+ Wre += T1re; \
+ Wim += T1im; \
+}
+static inline void
+bitreverse_fft2analysis (const unsigned int n,
+ const double *X,
+ double *Y)
+{
+ const unsigned int n2 = n >> 1, n1 = n + n2, max = n >> 2;
+ unsigned int i, r;
+
+ BUTTERFLY_10 (X[0], X[1],
+ X[n], X[n + 1],
+ Y[0], Y[1],
+ Y[2], Y[3],
+ __1, __0);
+ BUTTERFLY_10 (X[n2], X[n2 + 1],
+ X[n1], X[n1 + 1],
+ Y[4], Y[5],
+ Y[6], Y[7],
+ __1, __0);
+ for (i = 1, r = 0; i < max; i++)
+ {
+ unsigned int k, j = n >> 1;
+
+ while (r >= j)
+ {
+ r -= j;
+ j >>= 1;
+ }
+ r |= j;
+
+ k = r >> 1;
+ j = i << 3;
+ BUTTERFLY_10 (X[k], X[k + 1],
+ X[k + n], X[k + n + 1],
+ Y[j], Y[j + 1],
+ Y[j + 2], Y[j + 3],
+ __1, __0);
+ k += n2;
+ j += 4;
+ BUTTERFLY_10 (X[k], X[k + 1],
+ X[k + n], X[k + n + 1],
+ Y[j], Y[j + 1],
+ Y[j + 2], Y[j + 3],
+ __1, __0);
+ }
+}
+static inline void
+bitreverse_fft2synthesis (const unsigned int n,
+ const double *X,
+ double *Y)
+{
+ const unsigned int n2 = n >> 1, n1 = n + n2, max = n >> 2;
+ unsigned int i, r;
+ double scale = n;
+
+ scale = 1.0 / scale;
+ BUTTERFLY_10scale (X[0], X[1],
+ X[n], X[n + 1],
+ Y[0], Y[1],
+ Y[2], Y[3],
+ scale);
+ BUTTERFLY_10scale (X[n2], X[n2 + 1],
+ X[n1], X[n1 + 1],
+ Y[4], Y[5],
+ Y[6], Y[7],
+ scale);
+ for (i = 1, r = 0; i < max; i++)
+ {
+ unsigned int k, j = n >> 1;
+
+ while (r >= j)
+ {
+ r -= j;
+ j >>= 1;
+ }
+ r |= j;
+
+ k = r >> 1;
+ j = i << 3;
+ BUTTERFLY_10scale (X[k], X[k + 1],
+ X[k + n], X[k + n + 1],
+ Y[j], Y[j + 1],
+ Y[j + 2], Y[j + 3],
+ scale);
+ k += n2;
+ j += 4;
+ BUTTERFLY_10scale (X[k], X[k + 1],
+ X[k + n], X[k + n + 1],
+ Y[j], Y[j + 1],
+ Y[j + 2], Y[j + 3],
+ scale);
+ }
+}
+/**
+ ** Generated data (by gsl-genfft 2 F)
+ **/
+static void
+gsl_power2_fft2analysis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform 1 times fft2 */
+ BUTTERFLY_10 (X[0], X[0 + 1],
+ X[2], X[2 + 1],
+ Y[0], Y[0 + 1],
+ Y[2], Y[2 + 1],
+ __1, __0);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 4 S F)
+ **/
+static void
+gsl_power2_fft4analysis_skip2 (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* skipping 2 times fft2 */
+
+ /* perform 1 times fft4 */
+ BUTTERFLY_10 (Y[0], /* W0 */
+ Y[0 + 1],
+ Y[4],
+ Y[4 + 1],
+ Y[0],
+ Y[0 + 1],
+ Y[4],
+ Y[4 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_01 (Y[2], /* W1 */
+ Y[2 + 1],
+ Y[6],
+ Y[6 + 1],
+ Y[2],
+ Y[2 + 1],
+ Y[6],
+ Y[6 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 4 F X)
+ **/
+static void
+gsl_power2_fft4analysis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform 2 times fft2 */
+ BUTTERFLY_10 (X[0], X[0 + 1],
+ X[4], X[4 + 1],
+ Y[0], Y[0 + 1],
+ Y[2], Y[2 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[2], X[2 + 1],
+ X[6], X[6 + 1],
+ Y[4], Y[4 + 1],
+ Y[6], Y[6 + 1],
+ __1, __0);
+
+ /* perform 1 times fft4 */
+ gsl_power2_fft4analysis_skip2 (X, Y);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 8 S F F)
+ **/
+static void
+gsl_power2_fft8analysis_skip2 (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* skipping 4 times fft2 */
+
+ /* perform 2 times fft4 */
+ BUTTERFLY_10 (Y[0], /* W0 */
+ Y[0 + 1],
+ Y[4],
+ Y[4 + 1],
+ Y[0],
+ Y[0 + 1],
+ Y[4],
+ Y[4 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[8], /* W0 */
+ Y[8 + 1],
+ Y[12],
+ Y[12 + 1],
+ Y[8],
+ Y[8 + 1],
+ Y[12],
+ Y[12 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_01 (Y[2], /* W2 */
+ Y[2 + 1],
+ Y[6],
+ Y[6 + 1],
+ Y[2],
+ Y[2 + 1],
+ Y[6],
+ Y[6 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_01 (Y[10], /* W2 */
+ Y[10 + 1],
+ Y[14],
+ Y[14 + 1],
+ Y[10],
+ Y[10 + 1],
+ Y[14],
+ Y[14 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+
+ /* perform 1 times fft8 */
+ BUTTERFLY_10 (Y[0], /* W0 */
+ Y[0 + 1],
+ Y[8],
+ Y[8 + 1],
+ Y[0],
+ Y[0 + 1],
+ Y[8],
+ Y[8 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XX (Y[2], /* W1 */
+ Y[2 + 1],
+ Y[10],
+ Y[10 + 1],
+ Y[2],
+ Y[2 + 1],
+ Y[10],
+ Y[10 + 1],
+ (double) +0.707106781186548, (double) +0.707106781186547);
+ BUTTERFLY_01 (Y[4], /* W2 */
+ Y[4 + 1],
+ Y[12],
+ Y[12 + 1],
+ Y[4],
+ Y[4 + 1],
+ Y[12],
+ Y[12 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_yY (Y[6], /* W3 */
+ Y[6 + 1],
+ Y[14],
+ Y[14 + 1],
+ Y[6],
+ Y[6 + 1],
+ Y[14],
+ Y[14 + 1],
+ (double) -0.707106781186547, (double) +0.707106781186548);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 8 F S X)
+ **/
+static void
+gsl_power2_fft8analysis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform 4 times fft2 */
+ BUTTERFLY_10 (X[0], X[0 + 1],
+ X[8], X[8 + 1],
+ Y[0], Y[0 + 1],
+ Y[2], Y[2 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[4], X[4 + 1],
+ X[12], X[12 + 1],
+ Y[4], Y[4 + 1],
+ Y[6], Y[6 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[2], X[2 + 1],
+ X[10], X[10 + 1],
+ Y[8], Y[8 + 1],
+ Y[10], Y[10 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[6], X[6 + 1],
+ X[14], X[14 + 1],
+ Y[12], Y[12 + 1],
+ Y[14], Y[14 + 1],
+ __1, __0);
+
+ /* skipping 2 times fft4 */
+
+ /* perform 1 times fft8 */
+ gsl_power2_fft8analysis_skip2 (X, Y);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 16 S F F F)
+ **/
+static void
+gsl_power2_fft16analysis_skip2 (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* skipping 8 times fft2 */
+
+ /* perform 4 times fft4 */
+ BUTTERFLY_10 (Y[0], /* W0 */
+ Y[0 + 1],
+ Y[4],
+ Y[4 + 1],
+ Y[0],
+ Y[0 + 1],
+ Y[4],
+ Y[4 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[8], /* W0 */
+ Y[8 + 1],
+ Y[12],
+ Y[12 + 1],
+ Y[8],
+ Y[8 + 1],
+ Y[12],
+ Y[12 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[16], /* W0 */
+ Y[16 + 1],
+ Y[20],
+ Y[20 + 1],
+ Y[16],
+ Y[16 + 1],
+ Y[20],
+ Y[20 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[24], /* W0 */
+ Y[24 + 1],
+ Y[28],
+ Y[28 + 1],
+ Y[24],
+ Y[24 + 1],
+ Y[28],
+ Y[28 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_01 (Y[2], /* W4 */
+ Y[2 + 1],
+ Y[6],
+ Y[6 + 1],
+ Y[2],
+ Y[2 + 1],
+ Y[6],
+ Y[6 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_01 (Y[10], /* W4 */
+ Y[10 + 1],
+ Y[14],
+ Y[14 + 1],
+ Y[10],
+ Y[10 + 1],
+ Y[14],
+ Y[14 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_01 (Y[18], /* W4 */
+ Y[18 + 1],
+ Y[22],
+ Y[22 + 1],
+ Y[18],
+ Y[18 + 1],
+ Y[22],
+ Y[22 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_01 (Y[26], /* W4 */
+ Y[26 + 1],
+ Y[30],
+ Y[30 + 1],
+ Y[26],
+ Y[26 + 1],
+ Y[30],
+ Y[30 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+
+ /* perform 2 times fft8 */
+ BUTTERFLY_10 (Y[0], /* W0 */
+ Y[0 + 1],
+ Y[8],
+ Y[8 + 1],
+ Y[0],
+ Y[0 + 1],
+ Y[8],
+ Y[8 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[16], /* W0 */
+ Y[16 + 1],
+ Y[24],
+ Y[24 + 1],
+ Y[16],
+ Y[16 + 1],
+ Y[24],
+ Y[24 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XX (Y[2], /* W2 */
+ Y[2 + 1],
+ Y[10],
+ Y[10 + 1],
+ Y[2],
+ Y[2 + 1],
+ Y[10],
+ Y[10 + 1],
+ (double) +0.707106781186548, (double) +0.707106781186547);
+ BUTTERFLY_XX (Y[18], /* W2 */
+ Y[18 + 1],
+ Y[26],
+ Y[26 + 1],
+ Y[18],
+ Y[18 + 1],
+ Y[26],
+ Y[26 + 1],
+ (double) +0.707106781186548, (double) +0.707106781186547);
+ BUTTERFLY_01 (Y[4], /* W4 */
+ Y[4 + 1],
+ Y[12],
+ Y[12 + 1],
+ Y[4],
+ Y[4 + 1],
+ Y[12],
+ Y[12 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_01 (Y[20], /* W4 */
+ Y[20 + 1],
+ Y[28],
+ Y[28 + 1],
+ Y[20],
+ Y[20 + 1],
+ Y[28],
+ Y[28 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_yY (Y[6], /* W6 */
+ Y[6 + 1],
+ Y[14],
+ Y[14 + 1],
+ Y[6],
+ Y[6 + 1],
+ Y[14],
+ Y[14 + 1],
+ (double) -0.707106781186547, (double) +0.707106781186548);
+ BUTTERFLY_yY (Y[22], /* W6 */
+ Y[22 + 1],
+ Y[30],
+ Y[30 + 1],
+ Y[22],
+ Y[22 + 1],
+ Y[30],
+ Y[30 + 1],
+ (double) -0.707106781186547, (double) +0.707106781186548);
+
+ /* perform 1 times fft16 */
+ BUTTERFLY_10 (Y[0], /* W0 */
+ Y[0 + 1],
+ Y[16],
+ Y[16 + 1],
+ Y[0],
+ Y[0 + 1],
+ Y[16],
+ Y[16 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XY (Y[2], /* W1 */
+ Y[2 + 1],
+ Y[18],
+ Y[18 + 1],
+ Y[2],
+ Y[2 + 1],
+ Y[18],
+ Y[18 + 1],
+ (double) +0.923879532511287, (double) +0.382683432365090);
+ BUTTERFLY_XX (Y[4], /* W2 */
+ Y[4 + 1],
+ Y[20],
+ Y[20 + 1],
+ Y[4],
+ Y[4 + 1],
+ Y[20],
+ Y[20 + 1],
+ (double) +0.707106781186548, (double) +0.707106781186547);
+ BUTTERFLY_XY (Y[6], /* W3 */
+ Y[6 + 1],
+ Y[22],
+ Y[22 + 1],
+ Y[6],
+ Y[6 + 1],
+ Y[22],
+ Y[22 + 1],
+ (double) +0.382683432365090, (double) +0.923879532511287);
+ BUTTERFLY_01 (Y[8], /* W4 */
+ Y[8 + 1],
+ Y[24],
+ Y[24 + 1],
+ Y[8],
+ Y[8 + 1],
+ Y[24],
+ Y[24 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_XY (Y[10], /* W5 */
+ Y[10 + 1],
+ Y[26],
+ Y[26 + 1],
+ Y[10],
+ Y[10 + 1],
+ Y[26],
+ Y[26 + 1],
+ (double) -0.382683432365090, (double) +0.923879532511287);
+ BUTTERFLY_yY (Y[12], /* W6 */
+ Y[12 + 1],
+ Y[28],
+ Y[28 + 1],
+ Y[12],
+ Y[12 + 1],
+ Y[28],
+ Y[28 + 1],
+ (double) -0.707106781186547, (double) +0.707106781186548);
+ BUTTERFLY_XY (Y[14], /* W7 */
+ Y[14 + 1],
+ Y[30],
+ Y[30 + 1],
+ Y[14],
+ Y[14 + 1],
+ Y[30],
+ Y[30 + 1],
+ (double) -0.923879532511287, (double) +0.382683432365090);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 16 F S S X)
+ **/
+static void
+gsl_power2_fft16analysis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform 8 times fft2 */
+ BUTTERFLY_10 (X[0], X[0 + 1],
+ X[16], X[16 + 1],
+ Y[0], Y[0 + 1],
+ Y[2], Y[2 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[8], X[8 + 1],
+ X[24], X[24 + 1],
+ Y[4], Y[4 + 1],
+ Y[6], Y[6 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[4], X[4 + 1],
+ X[20], X[20 + 1],
+ Y[8], Y[8 + 1],
+ Y[10], Y[10 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[12], X[12 + 1],
+ X[28], X[28 + 1],
+ Y[12], Y[12 + 1],
+ Y[14], Y[14 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[2], X[2 + 1],
+ X[18], X[18 + 1],
+ Y[16], Y[16 + 1],
+ Y[18], Y[18 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[10], X[10 + 1],
+ X[26], X[26 + 1],
+ Y[20], Y[20 + 1],
+ Y[22], Y[22 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[6], X[6 + 1],
+ X[22], X[22 + 1],
+ Y[24], Y[24 + 1],
+ Y[26], Y[26 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[14], X[14 + 1],
+ X[30], X[30 + 1],
+ Y[28], Y[28 + 1],
+ Y[30], Y[30 + 1],
+ __1, __0);
+
+ /* skipping 4 times fft4 */
+
+ /* skipping 2 times fft8 */
+
+ /* perform 1 times fft16 */
+ gsl_power2_fft16analysis_skip2 (X, Y);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 32 S F F F F)
+ **/
+static void
+gsl_power2_fft32analysis_skip2 (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* skipping 16 times fft2 */
+
+ /* perform 8 times fft4 */
+ BUTTERFLY_10 (Y[0], /* W0 */
+ Y[0 + 1],
+ Y[4],
+ Y[4 + 1],
+ Y[0],
+ Y[0 + 1],
+ Y[4],
+ Y[4 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[8], /* W0 */
+ Y[8 + 1],
+ Y[12],
+ Y[12 + 1],
+ Y[8],
+ Y[8 + 1],
+ Y[12],
+ Y[12 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[16], /* W0 */
+ Y[16 + 1],
+ Y[20],
+ Y[20 + 1],
+ Y[16],
+ Y[16 + 1],
+ Y[20],
+ Y[20 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[24], /* W0 */
+ Y[24 + 1],
+ Y[28],
+ Y[28 + 1],
+ Y[24],
+ Y[24 + 1],
+ Y[28],
+ Y[28 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[32], /* W0 */
+ Y[32 + 1],
+ Y[36],
+ Y[36 + 1],
+ Y[32],
+ Y[32 + 1],
+ Y[36],
+ Y[36 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[40], /* W0 */
+ Y[40 + 1],
+ Y[44],
+ Y[44 + 1],
+ Y[40],
+ Y[40 + 1],
+ Y[44],
+ Y[44 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[48], /* W0 */
+ Y[48 + 1],
+ Y[52],
+ Y[52 + 1],
+ Y[48],
+ Y[48 + 1],
+ Y[52],
+ Y[52 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[56], /* W0 */
+ Y[56 + 1],
+ Y[60],
+ Y[60 + 1],
+ Y[56],
+ Y[56 + 1],
+ Y[60],
+ Y[60 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_01 (Y[2], /* W8 */
+ Y[2 + 1],
+ Y[6],
+ Y[6 + 1],
+ Y[2],
+ Y[2 + 1],
+ Y[6],
+ Y[6 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_01 (Y[10], /* W8 */
+ Y[10 + 1],
+ Y[14],
+ Y[14 + 1],
+ Y[10],
+ Y[10 + 1],
+ Y[14],
+ Y[14 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_01 (Y[18], /* W8 */
+ Y[18 + 1],
+ Y[22],
+ Y[22 + 1],
+ Y[18],
+ Y[18 + 1],
+ Y[22],
+ Y[22 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_01 (Y[26], /* W8 */
+ Y[26 + 1],
+ Y[30],
+ Y[30 + 1],
+ Y[26],
+ Y[26 + 1],
+ Y[30],
+ Y[30 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_01 (Y[34], /* W8 */
+ Y[34 + 1],
+ Y[38],
+ Y[38 + 1],
+ Y[34],
+ Y[34 + 1],
+ Y[38],
+ Y[38 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_01 (Y[42], /* W8 */
+ Y[42 + 1],
+ Y[46],
+ Y[46 + 1],
+ Y[42],
+ Y[42 + 1],
+ Y[46],
+ Y[46 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_01 (Y[50], /* W8 */
+ Y[50 + 1],
+ Y[54],
+ Y[54 + 1],
+ Y[50],
+ Y[50 + 1],
+ Y[54],
+ Y[54 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_01 (Y[58], /* W8 */
+ Y[58 + 1],
+ Y[62],
+ Y[62 + 1],
+ Y[58],
+ Y[58 + 1],
+ Y[62],
+ Y[62 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+
+ /* perform 4 times fft8 */
+ BUTTERFLY_10 (Y[0], /* W0 */
+ Y[0 + 1],
+ Y[8],
+ Y[8 + 1],
+ Y[0],
+ Y[0 + 1],
+ Y[8],
+ Y[8 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[16], /* W0 */
+ Y[16 + 1],
+ Y[24],
+ Y[24 + 1],
+ Y[16],
+ Y[16 + 1],
+ Y[24],
+ Y[24 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[32], /* W0 */
+ Y[32 + 1],
+ Y[40],
+ Y[40 + 1],
+ Y[32],
+ Y[32 + 1],
+ Y[40],
+ Y[40 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[48], /* W0 */
+ Y[48 + 1],
+ Y[56],
+ Y[56 + 1],
+ Y[48],
+ Y[48 + 1],
+ Y[56],
+ Y[56 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XX (Y[2], /* W4 */
+ Y[2 + 1],
+ Y[10],
+ Y[10 + 1],
+ Y[2],
+ Y[2 + 1],
+ Y[10],
+ Y[10 + 1],
+ (double) +0.707106781186548, (double) +0.707106781186547);
+ BUTTERFLY_XX (Y[18], /* W4 */
+ Y[18 + 1],
+ Y[26],
+ Y[26 + 1],
+ Y[18],
+ Y[18 + 1],
+ Y[26],
+ Y[26 + 1],
+ (double) +0.707106781186548, (double) +0.707106781186547);
+ BUTTERFLY_XX (Y[34], /* W4 */
+ Y[34 + 1],
+ Y[42],
+ Y[42 + 1],
+ Y[34],
+ Y[34 + 1],
+ Y[42],
+ Y[42 + 1],
+ (double) +0.707106781186548, (double) +0.707106781186547);
+ BUTTERFLY_XX (Y[50], /* W4 */
+ Y[50 + 1],
+ Y[58],
+ Y[58 + 1],
+ Y[50],
+ Y[50 + 1],
+ Y[58],
+ Y[58 + 1],
+ (double) +0.707106781186548, (double) +0.707106781186547);
+ BUTTERFLY_01 (Y[4], /* W8 */
+ Y[4 + 1],
+ Y[12],
+ Y[12 + 1],
+ Y[4],
+ Y[4 + 1],
+ Y[12],
+ Y[12 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_01 (Y[20], /* W8 */
+ Y[20 + 1],
+ Y[28],
+ Y[28 + 1],
+ Y[20],
+ Y[20 + 1],
+ Y[28],
+ Y[28 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_01 (Y[36], /* W8 */
+ Y[36 + 1],
+ Y[44],
+ Y[44 + 1],
+ Y[36],
+ Y[36 + 1],
+ Y[44],
+ Y[44 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_01 (Y[52], /* W8 */
+ Y[52 + 1],
+ Y[60],
+ Y[60 + 1],
+ Y[52],
+ Y[52 + 1],
+ Y[60],
+ Y[60 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_yY (Y[6], /* W12 */
+ Y[6 + 1],
+ Y[14],
+ Y[14 + 1],
+ Y[6],
+ Y[6 + 1],
+ Y[14],
+ Y[14 + 1],
+ (double) -0.707106781186547, (double) +0.707106781186548);
+ BUTTERFLY_yY (Y[22], /* W12 */
+ Y[22 + 1],
+ Y[30],
+ Y[30 + 1],
+ Y[22],
+ Y[22 + 1],
+ Y[30],
+ Y[30 + 1],
+ (double) -0.707106781186547, (double) +0.707106781186548);
+ BUTTERFLY_yY (Y[38], /* W12 */
+ Y[38 + 1],
+ Y[46],
+ Y[46 + 1],
+ Y[38],
+ Y[38 + 1],
+ Y[46],
+ Y[46 + 1],
+ (double) -0.707106781186547, (double) +0.707106781186548);
+ BUTTERFLY_yY (Y[54], /* W12 */
+ Y[54 + 1],
+ Y[62],
+ Y[62 + 1],
+ Y[54],
+ Y[54 + 1],
+ Y[62],
+ Y[62 + 1],
+ (double) -0.707106781186547, (double) +0.707106781186548);
+
+ /* perform 2 times fft16 */
+ BUTTERFLY_10 (Y[0], /* W0 */
+ Y[0 + 1],
+ Y[16],
+ Y[16 + 1],
+ Y[0],
+ Y[0 + 1],
+ Y[16],
+ Y[16 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[32], /* W0 */
+ Y[32 + 1],
+ Y[48],
+ Y[48 + 1],
+ Y[32],
+ Y[32 + 1],
+ Y[48],
+ Y[48 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XY (Y[2], /* W2 */
+ Y[2 + 1],
+ Y[18],
+ Y[18 + 1],
+ Y[2],
+ Y[2 + 1],
+ Y[18],
+ Y[18 + 1],
+ (double) +0.923879532511287, (double) +0.382683432365090);
+ BUTTERFLY_XY (Y[34], /* W2 */
+ Y[34 + 1],
+ Y[50],
+ Y[50 + 1],
+ Y[34],
+ Y[34 + 1],
+ Y[50],
+ Y[50 + 1],
+ (double) +0.923879532511287, (double) +0.382683432365090);
+ BUTTERFLY_XX (Y[4], /* W4 */
+ Y[4 + 1],
+ Y[20],
+ Y[20 + 1],
+ Y[4],
+ Y[4 + 1],
+ Y[20],
+ Y[20 + 1],
+ (double) +0.707106781186548, (double) +0.707106781186547);
+ BUTTERFLY_XX (Y[36], /* W4 */
+ Y[36 + 1],
+ Y[52],
+ Y[52 + 1],
+ Y[36],
+ Y[36 + 1],
+ Y[52],
+ Y[52 + 1],
+ (double) +0.707106781186548, (double) +0.707106781186547);
+ BUTTERFLY_XY (Y[6], /* W6 */
+ Y[6 + 1],
+ Y[22],
+ Y[22 + 1],
+ Y[6],
+ Y[6 + 1],
+ Y[22],
+ Y[22 + 1],
+ (double) +0.382683432365090, (double) +0.923879532511287);
+ BUTTERFLY_XY (Y[38], /* W6 */
+ Y[38 + 1],
+ Y[54],
+ Y[54 + 1],
+ Y[38],
+ Y[38 + 1],
+ Y[54],
+ Y[54 + 1],
+ (double) +0.382683432365090, (double) +0.923879532511287);
+ BUTTERFLY_01 (Y[8], /* W8 */
+ Y[8 + 1],
+ Y[24],
+ Y[24 + 1],
+ Y[8],
+ Y[8 + 1],
+ Y[24],
+ Y[24 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_01 (Y[40], /* W8 */
+ Y[40 + 1],
+ Y[56],
+ Y[56 + 1],
+ Y[40],
+ Y[40 + 1],
+ Y[56],
+ Y[56 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_XY (Y[10], /* W10 */
+ Y[10 + 1],
+ Y[26],
+ Y[26 + 1],
+ Y[10],
+ Y[10 + 1],
+ Y[26],
+ Y[26 + 1],
+ (double) -0.382683432365090, (double) +0.923879532511287);
+ BUTTERFLY_XY (Y[42], /* W10 */
+ Y[42 + 1],
+ Y[58],
+ Y[58 + 1],
+ Y[42],
+ Y[42 + 1],
+ Y[58],
+ Y[58 + 1],
+ (double) -0.382683432365090, (double) +0.923879532511287);
+ BUTTERFLY_yY (Y[12], /* W12 */
+ Y[12 + 1],
+ Y[28],
+ Y[28 + 1],
+ Y[12],
+ Y[12 + 1],
+ Y[28],
+ Y[28 + 1],
+ (double) -0.707106781186547, (double) +0.707106781186548);
+ BUTTERFLY_yY (Y[44], /* W12 */
+ Y[44 + 1],
+ Y[60],
+ Y[60 + 1],
+ Y[44],
+ Y[44 + 1],
+ Y[60],
+ Y[60 + 1],
+ (double) -0.707106781186547, (double) +0.707106781186548);
+ BUTTERFLY_XY (Y[14], /* W14 */
+ Y[14 + 1],
+ Y[30],
+ Y[30 + 1],
+ Y[14],
+ Y[14 + 1],
+ Y[30],
+ Y[30 + 1],
+ (double) -0.923879532511287, (double) +0.382683432365090);
+ BUTTERFLY_XY (Y[46], /* W14 */
+ Y[46 + 1],
+ Y[62],
+ Y[62 + 1],
+ Y[46],
+ Y[46 + 1],
+ Y[62],
+ Y[62 + 1],
+ (double) -0.923879532511287, (double) +0.382683432365090);
+
+ /* perform 1 times fft32 */
+ BUTTERFLY_10 (Y[0], /* W0 */
+ Y[0 + 1],
+ Y[32],
+ Y[32 + 1],
+ Y[0],
+ Y[0 + 1],
+ Y[32],
+ Y[32 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XY (Y[2], /* W1 */
+ Y[2 + 1],
+ Y[34],
+ Y[34 + 1],
+ Y[2],
+ Y[2 + 1],
+ Y[34],
+ Y[34 + 1],
+ (double) +0.980785280403230, (double) +0.195090322016128);
+ BUTTERFLY_XY (Y[4], /* W2 */
+ Y[4 + 1],
+ Y[36],
+ Y[36 + 1],
+ Y[4],
+ Y[4 + 1],
+ Y[36],
+ Y[36 + 1],
+ (double) +0.923879532511287, (double) +0.382683432365090);
+ BUTTERFLY_XY (Y[6], /* W3 */
+ Y[6 + 1],
+ Y[38],
+ Y[38 + 1],
+ Y[6],
+ Y[6 + 1],
+ Y[38],
+ Y[38 + 1],
+ (double) +0.831469612302545, (double) +0.555570233019602);
+ BUTTERFLY_XX (Y[8], /* W4 */
+ Y[8 + 1],
+ Y[40],
+ Y[40 + 1],
+ Y[8],
+ Y[8 + 1],
+ Y[40],
+ Y[40 + 1],
+ (double) +0.707106781186548, (double) +0.707106781186547);
+ BUTTERFLY_XY (Y[10], /* W5 */
+ Y[10 + 1],
+ Y[42],
+ Y[42 + 1],
+ Y[10],
+ Y[10 + 1],
+ Y[42],
+ Y[42 + 1],
+ (double) +0.555570233019602, (double) +0.831469612302545);
+ BUTTERFLY_XY (Y[12], /* W6 */
+ Y[12 + 1],
+ Y[44],
+ Y[44 + 1],
+ Y[12],
+ Y[12 + 1],
+ Y[44],
+ Y[44 + 1],
+ (double) +0.382683432365090, (double) +0.923879532511287);
+ BUTTERFLY_XY (Y[14], /* W7 */
+ Y[14 + 1],
+ Y[46],
+ Y[46 + 1],
+ Y[14],
+ Y[14 + 1],
+ Y[46],
+ Y[46 + 1],
+ (double) +0.195090322016128, (double) +0.980785280403230);
+ BUTTERFLY_01 (Y[16], /* W8 */
+ Y[16 + 1],
+ Y[48],
+ Y[48 + 1],
+ Y[16],
+ Y[16 + 1],
+ Y[48],
+ Y[48 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_XY (Y[18], /* W9 */
+ Y[18 + 1],
+ Y[50],
+ Y[50 + 1],
+ Y[18],
+ Y[18 + 1],
+ Y[50],
+ Y[50 + 1],
+ (double) -0.195090322016128, (double) +0.980785280403230);
+ BUTTERFLY_XY (Y[20], /* W10 */
+ Y[20 + 1],
+ Y[52],
+ Y[52 + 1],
+ Y[20],
+ Y[20 + 1],
+ Y[52],
+ Y[52 + 1],
+ (double) -0.382683432365090, (double) +0.923879532511287);
+ BUTTERFLY_XY (Y[22], /* W11 */
+ Y[22 + 1],
+ Y[54],
+ Y[54 + 1],
+ Y[22],
+ Y[22 + 1],
+ Y[54],
+ Y[54 + 1],
+ (double) -0.555570233019602, (double) +0.831469612302545);
+ BUTTERFLY_yY (Y[24], /* W12 */
+ Y[24 + 1],
+ Y[56],
+ Y[56 + 1],
+ Y[24],
+ Y[24 + 1],
+ Y[56],
+ Y[56 + 1],
+ (double) -0.707106781186547, (double) +0.707106781186548);
+ BUTTERFLY_XY (Y[26], /* W13 */
+ Y[26 + 1],
+ Y[58],
+ Y[58 + 1],
+ Y[26],
+ Y[26 + 1],
+ Y[58],
+ Y[58 + 1],
+ (double) -0.831469612302545, (double) +0.555570233019602);
+ BUTTERFLY_XY (Y[28], /* W14 */
+ Y[28 + 1],
+ Y[60],
+ Y[60 + 1],
+ Y[28],
+ Y[28 + 1],
+ Y[60],
+ Y[60 + 1],
+ (double) -0.923879532511287, (double) +0.382683432365090);
+ BUTTERFLY_XY (Y[30], /* W15 */
+ Y[30 + 1],
+ Y[62],
+ Y[62 + 1],
+ Y[30],
+ Y[30 + 1],
+ Y[62],
+ Y[62 + 1],
+ (double) -0.980785280403230, (double) +0.195090322016129);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 32 F S S S X)
+ **/
+static void
+gsl_power2_fft32analysis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform 16 times fft2 */
+ BUTTERFLY_10 (X[0], X[0 + 1],
+ X[32], X[32 + 1],
+ Y[0], Y[0 + 1],
+ Y[2], Y[2 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[16], X[16 + 1],
+ X[48], X[48 + 1],
+ Y[4], Y[4 + 1],
+ Y[6], Y[6 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[8], X[8 + 1],
+ X[40], X[40 + 1],
+ Y[8], Y[8 + 1],
+ Y[10], Y[10 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[24], X[24 + 1],
+ X[56], X[56 + 1],
+ Y[12], Y[12 + 1],
+ Y[14], Y[14 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[4], X[4 + 1],
+ X[36], X[36 + 1],
+ Y[16], Y[16 + 1],
+ Y[18], Y[18 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[20], X[20 + 1],
+ X[52], X[52 + 1],
+ Y[20], Y[20 + 1],
+ Y[22], Y[22 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[12], X[12 + 1],
+ X[44], X[44 + 1],
+ Y[24], Y[24 + 1],
+ Y[26], Y[26 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[28], X[28 + 1],
+ X[60], X[60 + 1],
+ Y[28], Y[28 + 1],
+ Y[30], Y[30 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[2], X[2 + 1],
+ X[34], X[34 + 1],
+ Y[32], Y[32 + 1],
+ Y[34], Y[34 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[18], X[18 + 1],
+ X[50], X[50 + 1],
+ Y[36], Y[36 + 1],
+ Y[38], Y[38 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[10], X[10 + 1],
+ X[42], X[42 + 1],
+ Y[40], Y[40 + 1],
+ Y[42], Y[42 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[26], X[26 + 1],
+ X[58], X[58 + 1],
+ Y[44], Y[44 + 1],
+ Y[46], Y[46 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[6], X[6 + 1],
+ X[38], X[38 + 1],
+ Y[48], Y[48 + 1],
+ Y[50], Y[50 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[22], X[22 + 1],
+ X[54], X[54 + 1],
+ Y[52], Y[52 + 1],
+ Y[54], Y[54 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[14], X[14 + 1],
+ X[46], X[46 + 1],
+ Y[56], Y[56 + 1],
+ Y[58], Y[58 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[30], X[30 + 1],
+ X[62], X[62 + 1],
+ Y[60], Y[60 + 1],
+ Y[62], Y[62 + 1],
+ __1, __0);
+
+ /* skipping 8 times fft4 */
+
+ /* skipping 4 times fft8 */
+
+ /* skipping 2 times fft16 */
+
+ /* perform 1 times fft32 */
+ gsl_power2_fft32analysis_skip2 (X, Y);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 64 S R R R R F)
+ **/
+static void
+gsl_power2_fft64analysis_skip2 (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* skipping 32 times fft2 */
+
+ /* perform 16 times fft4 */
+ for (block = 0; block < 128; block += 8) {
+ BUTTERFLY_10 (Y[block + 0], /* W0 */
+ Y[block + 0 + 1],
+ Y[block + 4],
+ Y[block + 4 + 1],
+ Y[block + 0],
+ Y[block + 0 + 1],
+ Y[block + 4],
+ Y[block + 4 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_01 (Y[block + 2], /* W16 */
+ Y[block + 2 + 1],
+ Y[block + 6],
+ Y[block + 6 + 1],
+ Y[block + 2],
+ Y[block + 2 + 1],
+ Y[block + 6],
+ Y[block + 6 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ }
+
+ /* perform 8 times fft8 */
+ for (block = 0; block < 128; block += 16) {
+ BUTTERFLY_10 (Y[block + 0], /* W0 */
+ Y[block + 0 + 1],
+ Y[block + 8],
+ Y[block + 8 + 1],
+ Y[block + 0],
+ Y[block + 0 + 1],
+ Y[block + 8],
+ Y[block + 8 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XX (Y[block + 2], /* W8 */
+ Y[block + 2 + 1],
+ Y[block + 10],
+ Y[block + 10 + 1],
+ Y[block + 2],
+ Y[block + 2 + 1],
+ Y[block + 10],
+ Y[block + 10 + 1],
+ (double) +0.707106781186548, (double) +0.707106781186547);
+ BUTTERFLY_01 (Y[block + 4], /* W16 */
+ Y[block + 4 + 1],
+ Y[block + 12],
+ Y[block + 12 + 1],
+ Y[block + 4],
+ Y[block + 4 + 1],
+ Y[block + 12],
+ Y[block + 12 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_yY (Y[block + 6], /* W24 */
+ Y[block + 6 + 1],
+ Y[block + 14],
+ Y[block + 14 + 1],
+ Y[block + 6],
+ Y[block + 6 + 1],
+ Y[block + 14],
+ Y[block + 14 + 1],
+ (double) -0.707106781186547, (double) +0.707106781186548);
+ }
+
+ /* perform 4 times fft16 */
+ for (block = 0; block < 128; block += 32) {
+ BUTTERFLY_10 (Y[block + 0], /* W0 */
+ Y[block + 0 + 1],
+ Y[block + 16],
+ Y[block + 16 + 1],
+ Y[block + 0],
+ Y[block + 0 + 1],
+ Y[block + 16],
+ Y[block + 16 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XY (Y[block + 2], /* W4 */
+ Y[block + 2 + 1],
+ Y[block + 18],
+ Y[block + 18 + 1],
+ Y[block + 2],
+ Y[block + 2 + 1],
+ Y[block + 18],
+ Y[block + 18 + 1],
+ (double) +0.923879532511287, (double) +0.382683432365090);
+ BUTTERFLY_XX (Y[block + 4], /* W8 */
+ Y[block + 4 + 1],
+ Y[block + 20],
+ Y[block + 20 + 1],
+ Y[block + 4],
+ Y[block + 4 + 1],
+ Y[block + 20],
+ Y[block + 20 + 1],
+ (double) +0.707106781186548, (double) +0.707106781186547);
+ BUTTERFLY_XY (Y[block + 6], /* W12 */
+ Y[block + 6 + 1],
+ Y[block + 22],
+ Y[block + 22 + 1],
+ Y[block + 6],
+ Y[block + 6 + 1],
+ Y[block + 22],
+ Y[block + 22 + 1],
+ (double) +0.382683432365090, (double) +0.923879532511287);
+ BUTTERFLY_01 (Y[block + 8], /* W16 */
+ Y[block + 8 + 1],
+ Y[block + 24],
+ Y[block + 24 + 1],
+ Y[block + 8],
+ Y[block + 8 + 1],
+ Y[block + 24],
+ Y[block + 24 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_XY (Y[block + 10], /* W20 */
+ Y[block + 10 + 1],
+ Y[block + 26],
+ Y[block + 26 + 1],
+ Y[block + 10],
+ Y[block + 10 + 1],
+ Y[block + 26],
+ Y[block + 26 + 1],
+ (double) -0.382683432365090, (double) +0.923879532511287);
+ BUTTERFLY_yY (Y[block + 12], /* W24 */
+ Y[block + 12 + 1],
+ Y[block + 28],
+ Y[block + 28 + 1],
+ Y[block + 12],
+ Y[block + 12 + 1],
+ Y[block + 28],
+ Y[block + 28 + 1],
+ (double) -0.707106781186547, (double) +0.707106781186548);
+ BUTTERFLY_XY (Y[block + 14], /* W28 */
+ Y[block + 14 + 1],
+ Y[block + 30],
+ Y[block + 30 + 1],
+ Y[block + 14],
+ Y[block + 14 + 1],
+ Y[block + 30],
+ Y[block + 30 + 1],
+ (double) -0.923879532511287, (double) +0.382683432365090);
+ }
+
+ /* perform 2 times fft32 */
+ for (block = 0; block < 128; block += 64) {
+ BUTTERFLY_10 (Y[block + 0], /* W0 */
+ Y[block + 0 + 1],
+ Y[block + 32],
+ Y[block + 32 + 1],
+ Y[block + 0],
+ Y[block + 0 + 1],
+ Y[block + 32],
+ Y[block + 32 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XY (Y[block + 2], /* W2 */
+ Y[block + 2 + 1],
+ Y[block + 34],
+ Y[block + 34 + 1],
+ Y[block + 2],
+ Y[block + 2 + 1],
+ Y[block + 34],
+ Y[block + 34 + 1],
+ (double) +0.980785280403230, (double) +0.195090322016128);
+ BUTTERFLY_XY (Y[block + 4], /* W4 */
+ Y[block + 4 + 1],
+ Y[block + 36],
+ Y[block + 36 + 1],
+ Y[block + 4],
+ Y[block + 4 + 1],
+ Y[block + 36],
+ Y[block + 36 + 1],
+ (double) +0.923879532511287, (double) +0.382683432365090);
+ BUTTERFLY_XY (Y[block + 6], /* W6 */
+ Y[block + 6 + 1],
+ Y[block + 38],
+ Y[block + 38 + 1],
+ Y[block + 6],
+ Y[block + 6 + 1],
+ Y[block + 38],
+ Y[block + 38 + 1],
+ (double) +0.831469612302545, (double) +0.555570233019602);
+ BUTTERFLY_XX (Y[block + 8], /* W8 */
+ Y[block + 8 + 1],
+ Y[block + 40],
+ Y[block + 40 + 1],
+ Y[block + 8],
+ Y[block + 8 + 1],
+ Y[block + 40],
+ Y[block + 40 + 1],
+ (double) +0.707106781186548, (double) +0.707106781186547);
+ BUTTERFLY_XY (Y[block + 10], /* W10 */
+ Y[block + 10 + 1],
+ Y[block + 42],
+ Y[block + 42 + 1],
+ Y[block + 10],
+ Y[block + 10 + 1],
+ Y[block + 42],
+ Y[block + 42 + 1],
+ (double) +0.555570233019602, (double) +0.831469612302545);
+ BUTTERFLY_XY (Y[block + 12], /* W12 */
+ Y[block + 12 + 1],
+ Y[block + 44],
+ Y[block + 44 + 1],
+ Y[block + 12],
+ Y[block + 12 + 1],
+ Y[block + 44],
+ Y[block + 44 + 1],
+ (double) +0.382683432365090, (double) +0.923879532511287);
+ BUTTERFLY_XY (Y[block + 14], /* W14 */
+ Y[block + 14 + 1],
+ Y[block + 46],
+ Y[block + 46 + 1],
+ Y[block + 14],
+ Y[block + 14 + 1],
+ Y[block + 46],
+ Y[block + 46 + 1],
+ (double) +0.195090322016128, (double) +0.980785280403230);
+ BUTTERFLY_01 (Y[block + 16], /* W16 */
+ Y[block + 16 + 1],
+ Y[block + 48],
+ Y[block + 48 + 1],
+ Y[block + 16],
+ Y[block + 16 + 1],
+ Y[block + 48],
+ Y[block + 48 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_XY (Y[block + 18], /* W18 */
+ Y[block + 18 + 1],
+ Y[block + 50],
+ Y[block + 50 + 1],
+ Y[block + 18],
+ Y[block + 18 + 1],
+ Y[block + 50],
+ Y[block + 50 + 1],
+ (double) -0.195090322016128, (double) +0.980785280403230);
+ BUTTERFLY_XY (Y[block + 20], /* W20 */
+ Y[block + 20 + 1],
+ Y[block + 52],
+ Y[block + 52 + 1],
+ Y[block + 20],
+ Y[block + 20 + 1],
+ Y[block + 52],
+ Y[block + 52 + 1],
+ (double) -0.382683432365090, (double) +0.923879532511287);
+ BUTTERFLY_XY (Y[block + 22], /* W22 */
+ Y[block + 22 + 1],
+ Y[block + 54],
+ Y[block + 54 + 1],
+ Y[block + 22],
+ Y[block + 22 + 1],
+ Y[block + 54],
+ Y[block + 54 + 1],
+ (double) -0.555570233019602, (double) +0.831469612302545);
+ BUTTERFLY_yY (Y[block + 24], /* W24 */
+ Y[block + 24 + 1],
+ Y[block + 56],
+ Y[block + 56 + 1],
+ Y[block + 24],
+ Y[block + 24 + 1],
+ Y[block + 56],
+ Y[block + 56 + 1],
+ (double) -0.707106781186547, (double) +0.707106781186548);
+ BUTTERFLY_XY (Y[block + 26], /* W26 */
+ Y[block + 26 + 1],
+ Y[block + 58],
+ Y[block + 58 + 1],
+ Y[block + 26],
+ Y[block + 26 + 1],
+ Y[block + 58],
+ Y[block + 58 + 1],
+ (double) -0.831469612302545, (double) +0.555570233019602);
+ BUTTERFLY_XY (Y[block + 28], /* W28 */
+ Y[block + 28 + 1],
+ Y[block + 60],
+ Y[block + 60 + 1],
+ Y[block + 28],
+ Y[block + 28 + 1],
+ Y[block + 60],
+ Y[block + 60 + 1],
+ (double) -0.923879532511287, (double) +0.382683432365090);
+ BUTTERFLY_XY (Y[block + 30], /* W30 */
+ Y[block + 30 + 1],
+ Y[block + 62],
+ Y[block + 62 + 1],
+ Y[block + 30],
+ Y[block + 30 + 1],
+ Y[block + 62],
+ Y[block + 62 + 1],
+ (double) -0.980785280403230, (double) +0.195090322016129);
+ }
+
+ /* perform 1 times fft64 */
+ BUTTERFLY_10 (Y[0], /* W0 */
+ Y[0 + 1],
+ Y[64],
+ Y[64 + 1],
+ Y[0],
+ Y[0 + 1],
+ Y[64],
+ Y[64 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XY (Y[2], /* W1 */
+ Y[2 + 1],
+ Y[66],
+ Y[66 + 1],
+ Y[2],
+ Y[2 + 1],
+ Y[66],
+ Y[66 + 1],
+ (double) +0.995184726672197, (double) +0.098017140329561);
+ BUTTERFLY_XY (Y[4], /* W2 */
+ Y[4 + 1],
+ Y[68],
+ Y[68 + 1],
+ Y[4],
+ Y[4 + 1],
+ Y[68],
+ Y[68 + 1],
+ (double) +0.980785280403230, (double) +0.195090322016128);
+ BUTTERFLY_XY (Y[6], /* W3 */
+ Y[6 + 1],
+ Y[70],
+ Y[70 + 1],
+ Y[6],
+ Y[6 + 1],
+ Y[70],
+ Y[70 + 1],
+ (double) +0.956940335732209, (double) +0.290284677254462);
+ BUTTERFLY_XY (Y[8], /* W4 */
+ Y[8 + 1],
+ Y[72],
+ Y[72 + 1],
+ Y[8],
+ Y[8 + 1],
+ Y[72],
+ Y[72 + 1],
+ (double) +0.923879532511287, (double) +0.382683432365090);
+ BUTTERFLY_XY (Y[10], /* W5 */
+ Y[10 + 1],
+ Y[74],
+ Y[74 + 1],
+ Y[10],
+ Y[10 + 1],
+ Y[74],
+ Y[74 + 1],
+ (double) +0.881921264348355, (double) +0.471396736825998);
+ BUTTERFLY_XY (Y[12], /* W6 */
+ Y[12 + 1],
+ Y[76],
+ Y[76 + 1],
+ Y[12],
+ Y[12 + 1],
+ Y[76],
+ Y[76 + 1],
+ (double) +0.831469612302545, (double) +0.555570233019602);
+ BUTTERFLY_XY (Y[14], /* W7 */
+ Y[14 + 1],
+ Y[78],
+ Y[78 + 1],
+ Y[14],
+ Y[14 + 1],
+ Y[78],
+ Y[78 + 1],
+ (double) +0.773010453362737, (double) +0.634393284163645);
+ BUTTERFLY_XX (Y[16], /* W8 */
+ Y[16 + 1],
+ Y[80],
+ Y[80 + 1],
+ Y[16],
+ Y[16 + 1],
+ Y[80],
+ Y[80 + 1],
+ (double) +0.707106781186548, (double) +0.707106781186547);
+ BUTTERFLY_XY (Y[18], /* W9 */
+ Y[18 + 1],
+ Y[82],
+ Y[82 + 1],
+ Y[18],
+ Y[18 + 1],
+ Y[82],
+ Y[82 + 1],
+ (double) +0.634393284163645, (double) +0.773010453362737);
+ BUTTERFLY_XY (Y[20], /* W10 */
+ Y[20 + 1],
+ Y[84],
+ Y[84 + 1],
+ Y[20],
+ Y[20 + 1],
+ Y[84],
+ Y[84 + 1],
+ (double) +0.555570233019602, (double) +0.831469612302545);
+ BUTTERFLY_XY (Y[22], /* W11 */
+ Y[22 + 1],
+ Y[86],
+ Y[86 + 1],
+ Y[22],
+ Y[22 + 1],
+ Y[86],
+ Y[86 + 1],
+ (double) +0.471396736825998, (double) +0.881921264348355);
+ BUTTERFLY_XY (Y[24], /* W12 */
+ Y[24 + 1],
+ Y[88],
+ Y[88 + 1],
+ Y[24],
+ Y[24 + 1],
+ Y[88],
+ Y[88 + 1],
+ (double) +0.382683432365090, (double) +0.923879532511287);
+ BUTTERFLY_XY (Y[26], /* W13 */
+ Y[26 + 1],
+ Y[90],
+ Y[90 + 1],
+ Y[26],
+ Y[26 + 1],
+ Y[90],
+ Y[90 + 1],
+ (double) +0.290284677254462, (double) +0.956940335732209);
+ BUTTERFLY_XY (Y[28], /* W14 */
+ Y[28 + 1],
+ Y[92],
+ Y[92 + 1],
+ Y[28],
+ Y[28 + 1],
+ Y[92],
+ Y[92 + 1],
+ (double) +0.195090322016128, (double) +0.980785280403230);
+ BUTTERFLY_XY (Y[30], /* W15 */
+ Y[30 + 1],
+ Y[94],
+ Y[94 + 1],
+ Y[30],
+ Y[30 + 1],
+ Y[94],
+ Y[94 + 1],
+ (double) +0.098017140329561, (double) +0.995184726672197);
+ BUTTERFLY_01 (Y[32], /* W16 */
+ Y[32 + 1],
+ Y[96],
+ Y[96 + 1],
+ Y[32],
+ Y[32 + 1],
+ Y[96],
+ Y[96 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_XY (Y[34], /* W17 */
+ Y[34 + 1],
+ Y[98],
+ Y[98 + 1],
+ Y[34],
+ Y[34 + 1],
+ Y[98],
+ Y[98 + 1],
+ (double) -0.098017140329561, (double) +0.995184726672197);
+ BUTTERFLY_XY (Y[36], /* W18 */
+ Y[36 + 1],
+ Y[100],
+ Y[100 + 1],
+ Y[36],
+ Y[36 + 1],
+ Y[100],
+ Y[100 + 1],
+ (double) -0.195090322016128, (double) +0.980785280403230);
+ BUTTERFLY_XY (Y[38], /* W19 */
+ Y[38 + 1],
+ Y[102],
+ Y[102 + 1],
+ Y[38],
+ Y[38 + 1],
+ Y[102],
+ Y[102 + 1],
+ (double) -0.290284677254462, (double) +0.956940335732209);
+ BUTTERFLY_XY (Y[40], /* W20 */
+ Y[40 + 1],
+ Y[104],
+ Y[104 + 1],
+ Y[40],
+ Y[40 + 1],
+ Y[104],
+ Y[104 + 1],
+ (double) -0.382683432365090, (double) +0.923879532511287);
+ BUTTERFLY_XY (Y[42], /* W21 */
+ Y[42 + 1],
+ Y[106],
+ Y[106 + 1],
+ Y[42],
+ Y[42 + 1],
+ Y[106],
+ Y[106 + 1],
+ (double) -0.471396736825998, (double) +0.881921264348355);
+ BUTTERFLY_XY (Y[44], /* W22 */
+ Y[44 + 1],
+ Y[108],
+ Y[108 + 1],
+ Y[44],
+ Y[44 + 1],
+ Y[108],
+ Y[108 + 1],
+ (double) -0.555570233019602, (double) +0.831469612302545);
+ BUTTERFLY_XY (Y[46], /* W23 */
+ Y[46 + 1],
+ Y[110],
+ Y[110 + 1],
+ Y[46],
+ Y[46 + 1],
+ Y[110],
+ Y[110 + 1],
+ (double) -0.634393284163645, (double) +0.773010453362737);
+ BUTTERFLY_yY (Y[48], /* W24 */
+ Y[48 + 1],
+ Y[112],
+ Y[112 + 1],
+ Y[48],
+ Y[48 + 1],
+ Y[112],
+ Y[112 + 1],
+ (double) -0.707106781186547, (double) +0.707106781186548);
+ BUTTERFLY_XY (Y[50], /* W25 */
+ Y[50 + 1],
+ Y[114],
+ Y[114 + 1],
+ Y[50],
+ Y[50 + 1],
+ Y[114],
+ Y[114 + 1],
+ (double) -0.773010453362737, (double) +0.634393284163645);
+ BUTTERFLY_XY (Y[52], /* W26 */
+ Y[52 + 1],
+ Y[116],
+ Y[116 + 1],
+ Y[52],
+ Y[52 + 1],
+ Y[116],
+ Y[116 + 1],
+ (double) -0.831469612302545, (double) +0.555570233019602);
+ BUTTERFLY_XY (Y[54], /* W27 */
+ Y[54 + 1],
+ Y[118],
+ Y[118 + 1],
+ Y[54],
+ Y[54 + 1],
+ Y[118],
+ Y[118 + 1],
+ (double) -0.881921264348355, (double) +0.471396736825998);
+ BUTTERFLY_XY (Y[56], /* W28 */
+ Y[56 + 1],
+ Y[120],
+ Y[120 + 1],
+ Y[56],
+ Y[56 + 1],
+ Y[120],
+ Y[120 + 1],
+ (double) -0.923879532511287, (double) +0.382683432365090);
+ BUTTERFLY_XY (Y[58], /* W29 */
+ Y[58 + 1],
+ Y[122],
+ Y[122 + 1],
+ Y[58],
+ Y[58 + 1],
+ Y[122],
+ Y[122 + 1],
+ (double) -0.956940335732209, (double) +0.290284677254462);
+ BUTTERFLY_XY (Y[60], /* W30 */
+ Y[60 + 1],
+ Y[124],
+ Y[124 + 1],
+ Y[60],
+ Y[60 + 1],
+ Y[124],
+ Y[124 + 1],
+ (double) -0.980785280403230, (double) +0.195090322016129);
+ BUTTERFLY_XY (Y[62], /* W31 */
+ Y[62 + 1],
+ Y[126],
+ Y[126 + 1],
+ Y[62],
+ Y[62 + 1],
+ Y[126],
+ Y[126 + 1],
+ (double) -0.995184726672197, (double) +0.098017140329561);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 64 F S S S S X)
+ **/
+static void
+gsl_power2_fft64analysis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform 32 times fft2 */
+ BUTTERFLY_10 (X[0], X[0 + 1],
+ X[64], X[64 + 1],
+ Y[0], Y[0 + 1],
+ Y[2], Y[2 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[32], X[32 + 1],
+ X[96], X[96 + 1],
+ Y[4], Y[4 + 1],
+ Y[6], Y[6 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[16], X[16 + 1],
+ X[80], X[80 + 1],
+ Y[8], Y[8 + 1],
+ Y[10], Y[10 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[48], X[48 + 1],
+ X[112], X[112 + 1],
+ Y[12], Y[12 + 1],
+ Y[14], Y[14 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[8], X[8 + 1],
+ X[72], X[72 + 1],
+ Y[16], Y[16 + 1],
+ Y[18], Y[18 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[40], X[40 + 1],
+ X[104], X[104 + 1],
+ Y[20], Y[20 + 1],
+ Y[22], Y[22 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[24], X[24 + 1],
+ X[88], X[88 + 1],
+ Y[24], Y[24 + 1],
+ Y[26], Y[26 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[56], X[56 + 1],
+ X[120], X[120 + 1],
+ Y[28], Y[28 + 1],
+ Y[30], Y[30 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[4], X[4 + 1],
+ X[68], X[68 + 1],
+ Y[32], Y[32 + 1],
+ Y[34], Y[34 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[36], X[36 + 1],
+ X[100], X[100 + 1],
+ Y[36], Y[36 + 1],
+ Y[38], Y[38 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[20], X[20 + 1],
+ X[84], X[84 + 1],
+ Y[40], Y[40 + 1],
+ Y[42], Y[42 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[52], X[52 + 1],
+ X[116], X[116 + 1],
+ Y[44], Y[44 + 1],
+ Y[46], Y[46 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[12], X[12 + 1],
+ X[76], X[76 + 1],
+ Y[48], Y[48 + 1],
+ Y[50], Y[50 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[44], X[44 + 1],
+ X[108], X[108 + 1],
+ Y[52], Y[52 + 1],
+ Y[54], Y[54 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[28], X[28 + 1],
+ X[92], X[92 + 1],
+ Y[56], Y[56 + 1],
+ Y[58], Y[58 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[60], X[60 + 1],
+ X[124], X[124 + 1],
+ Y[60], Y[60 + 1],
+ Y[62], Y[62 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[2], X[2 + 1],
+ X[66], X[66 + 1],
+ Y[64], Y[64 + 1],
+ Y[66], Y[66 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[34], X[34 + 1],
+ X[98], X[98 + 1],
+ Y[68], Y[68 + 1],
+ Y[70], Y[70 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[18], X[18 + 1],
+ X[82], X[82 + 1],
+ Y[72], Y[72 + 1],
+ Y[74], Y[74 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[50], X[50 + 1],
+ X[114], X[114 + 1],
+ Y[76], Y[76 + 1],
+ Y[78], Y[78 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[10], X[10 + 1],
+ X[74], X[74 + 1],
+ Y[80], Y[80 + 1],
+ Y[82], Y[82 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[42], X[42 + 1],
+ X[106], X[106 + 1],
+ Y[84], Y[84 + 1],
+ Y[86], Y[86 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[26], X[26 + 1],
+ X[90], X[90 + 1],
+ Y[88], Y[88 + 1],
+ Y[90], Y[90 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[58], X[58 + 1],
+ X[122], X[122 + 1],
+ Y[92], Y[92 + 1],
+ Y[94], Y[94 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[6], X[6 + 1],
+ X[70], X[70 + 1],
+ Y[96], Y[96 + 1],
+ Y[98], Y[98 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[38], X[38 + 1],
+ X[102], X[102 + 1],
+ Y[100], Y[100 + 1],
+ Y[102], Y[102 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[22], X[22 + 1],
+ X[86], X[86 + 1],
+ Y[104], Y[104 + 1],
+ Y[106], Y[106 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[54], X[54 + 1],
+ X[118], X[118 + 1],
+ Y[108], Y[108 + 1],
+ Y[110], Y[110 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[14], X[14 + 1],
+ X[78], X[78 + 1],
+ Y[112], Y[112 + 1],
+ Y[114], Y[114 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[46], X[46 + 1],
+ X[110], X[110 + 1],
+ Y[116], Y[116 + 1],
+ Y[118], Y[118 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[30], X[30 + 1],
+ X[94], X[94 + 1],
+ Y[120], Y[120 + 1],
+ Y[122], Y[122 + 1],
+ __1, __0);
+ BUTTERFLY_10 (X[62], X[62 + 1],
+ X[126], X[126 + 1],
+ Y[124], Y[124 + 1],
+ Y[126], Y[126 + 1],
+ __1, __0);
+
+ /* skipping 16 times fft4 */
+
+ /* skipping 8 times fft8 */
+
+ /* skipping 4 times fft16 */
+
+ /* skipping 2 times fft32 */
+
+ /* perform 1 times fft64 */
+ gsl_power2_fft64analysis_skip2 (X, Y);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 128 S R R R R R F)
+ **/
+static void
+gsl_power2_fft128analysis_skip2 (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* skipping 64 times fft2 */
+
+ /* perform 32 times fft4 */
+ for (block = 0; block < 256; block += 8) {
+ BUTTERFLY_10 (Y[block + 0], /* W0 */
+ Y[block + 0 + 1],
+ Y[block + 4],
+ Y[block + 4 + 1],
+ Y[block + 0],
+ Y[block + 0 + 1],
+ Y[block + 4],
+ Y[block + 4 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_01 (Y[block + 2], /* W32 */
+ Y[block + 2 + 1],
+ Y[block + 6],
+ Y[block + 6 + 1],
+ Y[block + 2],
+ Y[block + 2 + 1],
+ Y[block + 6],
+ Y[block + 6 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ }
+
+ /* perform 16 times fft8 */
+ for (block = 0; block < 256; block += 16) {
+ BUTTERFLY_10 (Y[block + 0], /* W0 */
+ Y[block + 0 + 1],
+ Y[block + 8],
+ Y[block + 8 + 1],
+ Y[block + 0],
+ Y[block + 0 + 1],
+ Y[block + 8],
+ Y[block + 8 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XX (Y[block + 2], /* W16 */
+ Y[block + 2 + 1],
+ Y[block + 10],
+ Y[block + 10 + 1],
+ Y[block + 2],
+ Y[block + 2 + 1],
+ Y[block + 10],
+ Y[block + 10 + 1],
+ (double) +0.707106781186548, (double) +0.707106781186547);
+ BUTTERFLY_01 (Y[block + 4], /* W32 */
+ Y[block + 4 + 1],
+ Y[block + 12],
+ Y[block + 12 + 1],
+ Y[block + 4],
+ Y[block + 4 + 1],
+ Y[block + 12],
+ Y[block + 12 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_yY (Y[block + 6], /* W48 */
+ Y[block + 6 + 1],
+ Y[block + 14],
+ Y[block + 14 + 1],
+ Y[block + 6],
+ Y[block + 6 + 1],
+ Y[block + 14],
+ Y[block + 14 + 1],
+ (double) -0.707106781186547, (double) +0.707106781186548);
+ }
+
+ /* perform 8 times fft16 */
+ for (block = 0; block < 256; block += 32) {
+ BUTTERFLY_10 (Y[block + 0], /* W0 */
+ Y[block + 0 + 1],
+ Y[block + 16],
+ Y[block + 16 + 1],
+ Y[block + 0],
+ Y[block + 0 + 1],
+ Y[block + 16],
+ Y[block + 16 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XY (Y[block + 2], /* W8 */
+ Y[block + 2 + 1],
+ Y[block + 18],
+ Y[block + 18 + 1],
+ Y[block + 2],
+ Y[block + 2 + 1],
+ Y[block + 18],
+ Y[block + 18 + 1],
+ (double) +0.923879532511287, (double) +0.382683432365090);
+ BUTTERFLY_XX (Y[block + 4], /* W16 */
+ Y[block + 4 + 1],
+ Y[block + 20],
+ Y[block + 20 + 1],
+ Y[block + 4],
+ Y[block + 4 + 1],
+ Y[block + 20],
+ Y[block + 20 + 1],
+ (double) +0.707106781186548, (double) +0.707106781186547);
+ BUTTERFLY_XY (Y[block + 6], /* W24 */
+ Y[block + 6 + 1],
+ Y[block + 22],
+ Y[block + 22 + 1],
+ Y[block + 6],
+ Y[block + 6 + 1],
+ Y[block + 22],
+ Y[block + 22 + 1],
+ (double) +0.382683432365090, (double) +0.923879532511287);
+ BUTTERFLY_01 (Y[block + 8], /* W32 */
+ Y[block + 8 + 1],
+ Y[block + 24],
+ Y[block + 24 + 1],
+ Y[block + 8],
+ Y[block + 8 + 1],
+ Y[block + 24],
+ Y[block + 24 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_XY (Y[block + 10], /* W40 */
+ Y[block + 10 + 1],
+ Y[block + 26],
+ Y[block + 26 + 1],
+ Y[block + 10],
+ Y[block + 10 + 1],
+ Y[block + 26],
+ Y[block + 26 + 1],
+ (double) -0.382683432365090, (double) +0.923879532511287);
+ BUTTERFLY_yY (Y[block + 12], /* W48 */
+ Y[block + 12 + 1],
+ Y[block + 28],
+ Y[block + 28 + 1],
+ Y[block + 12],
+ Y[block + 12 + 1],
+ Y[block + 28],
+ Y[block + 28 + 1],
+ (double) -0.707106781186547, (double) +0.707106781186548);
+ BUTTERFLY_XY (Y[block + 14], /* W56 */
+ Y[block + 14 + 1],
+ Y[block + 30],
+ Y[block + 30 + 1],
+ Y[block + 14],
+ Y[block + 14 + 1],
+ Y[block + 30],
+ Y[block + 30 + 1],
+ (double) -0.923879532511287, (double) +0.382683432365090);
+ }
+
+ /* perform 4 times fft32 */
+ for (block = 0; block < 256; block += 64) {
+ BUTTERFLY_10 (Y[block + 0], /* W0 */
+ Y[block + 0 + 1],
+ Y[block + 32],
+ Y[block + 32 + 1],
+ Y[block + 0],
+ Y[block + 0 + 1],
+ Y[block + 32],
+ Y[block + 32 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XY (Y[block + 2], /* W4 */
+ Y[block + 2 + 1],
+ Y[block + 34],
+ Y[block + 34 + 1],
+ Y[block + 2],
+ Y[block + 2 + 1],
+ Y[block + 34],
+ Y[block + 34 + 1],
+ (double) +0.980785280403230, (double) +0.195090322016128);
+ BUTTERFLY_XY (Y[block + 4], /* W8 */
+ Y[block + 4 + 1],
+ Y[block + 36],
+ Y[block + 36 + 1],
+ Y[block + 4],
+ Y[block + 4 + 1],
+ Y[block + 36],
+ Y[block + 36 + 1],
+ (double) +0.923879532511287, (double) +0.382683432365090);
+ BUTTERFLY_XY (Y[block + 6], /* W12 */
+ Y[block + 6 + 1],
+ Y[block + 38],
+ Y[block + 38 + 1],
+ Y[block + 6],
+ Y[block + 6 + 1],
+ Y[block + 38],
+ Y[block + 38 + 1],
+ (double) +0.831469612302545, (double) +0.555570233019602);
+ BUTTERFLY_XX (Y[block + 8], /* W16 */
+ Y[block + 8 + 1],
+ Y[block + 40],
+ Y[block + 40 + 1],
+ Y[block + 8],
+ Y[block + 8 + 1],
+ Y[block + 40],
+ Y[block + 40 + 1],
+ (double) +0.707106781186548, (double) +0.707106781186547);
+ BUTTERFLY_XY (Y[block + 10], /* W20 */
+ Y[block + 10 + 1],
+ Y[block + 42],
+ Y[block + 42 + 1],
+ Y[block + 10],
+ Y[block + 10 + 1],
+ Y[block + 42],
+ Y[block + 42 + 1],
+ (double) +0.555570233019602, (double) +0.831469612302545);
+ BUTTERFLY_XY (Y[block + 12], /* W24 */
+ Y[block + 12 + 1],
+ Y[block + 44],
+ Y[block + 44 + 1],
+ Y[block + 12],
+ Y[block + 12 + 1],
+ Y[block + 44],
+ Y[block + 44 + 1],
+ (double) +0.382683432365090, (double) +0.923879532511287);
+ BUTTERFLY_XY (Y[block + 14], /* W28 */
+ Y[block + 14 + 1],
+ Y[block + 46],
+ Y[block + 46 + 1],
+ Y[block + 14],
+ Y[block + 14 + 1],
+ Y[block + 46],
+ Y[block + 46 + 1],
+ (double) +0.195090322016128, (double) +0.980785280403230);
+ BUTTERFLY_01 (Y[block + 16], /* W32 */
+ Y[block + 16 + 1],
+ Y[block + 48],
+ Y[block + 48 + 1],
+ Y[block + 16],
+ Y[block + 16 + 1],
+ Y[block + 48],
+ Y[block + 48 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_XY (Y[block + 18], /* W36 */
+ Y[block + 18 + 1],
+ Y[block + 50],
+ Y[block + 50 + 1],
+ Y[block + 18],
+ Y[block + 18 + 1],
+ Y[block + 50],
+ Y[block + 50 + 1],
+ (double) -0.195090322016128, (double) +0.980785280403230);
+ BUTTERFLY_XY (Y[block + 20], /* W40 */
+ Y[block + 20 + 1],
+ Y[block + 52],
+ Y[block + 52 + 1],
+ Y[block + 20],
+ Y[block + 20 + 1],
+ Y[block + 52],
+ Y[block + 52 + 1],
+ (double) -0.382683432365090, (double) +0.923879532511287);
+ BUTTERFLY_XY (Y[block + 22], /* W44 */
+ Y[block + 22 + 1],
+ Y[block + 54],
+ Y[block + 54 + 1],
+ Y[block + 22],
+ Y[block + 22 + 1],
+ Y[block + 54],
+ Y[block + 54 + 1],
+ (double) -0.555570233019602, (double) +0.831469612302545);
+ BUTTERFLY_yY (Y[block + 24], /* W48 */
+ Y[block + 24 + 1],
+ Y[block + 56],
+ Y[block + 56 + 1],
+ Y[block + 24],
+ Y[block + 24 + 1],
+ Y[block + 56],
+ Y[block + 56 + 1],
+ (double) -0.707106781186547, (double) +0.707106781186548);
+ BUTTERFLY_XY (Y[block + 26], /* W52 */
+ Y[block + 26 + 1],
+ Y[block + 58],
+ Y[block + 58 + 1],
+ Y[block + 26],
+ Y[block + 26 + 1],
+ Y[block + 58],
+ Y[block + 58 + 1],
+ (double) -0.831469612302545, (double) +0.555570233019602);
+ BUTTERFLY_XY (Y[block + 28], /* W56 */
+ Y[block + 28 + 1],
+ Y[block + 60],
+ Y[block + 60 + 1],
+ Y[block + 28],
+ Y[block + 28 + 1],
+ Y[block + 60],
+ Y[block + 60 + 1],
+ (double) -0.923879532511287, (double) +0.382683432365090);
+ BUTTERFLY_XY (Y[block + 30], /* W60 */
+ Y[block + 30 + 1],
+ Y[block + 62],
+ Y[block + 62 + 1],
+ Y[block + 30],
+ Y[block + 30 + 1],
+ Y[block + 62],
+ Y[block + 62 + 1],
+ (double) -0.980785280403230, (double) +0.195090322016129);
+ }
+
+ /* perform 2 times fft64 */
+ for (block = 0; block < 256; block += 128) {
+ BUTTERFLY_10 (Y[block + 0], /* W0 */
+ Y[block + 0 + 1],
+ Y[block + 64],
+ Y[block + 64 + 1],
+ Y[block + 0],
+ Y[block + 0 + 1],
+ Y[block + 64],
+ Y[block + 64 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XY (Y[block + 2], /* W2 */
+ Y[block + 2 + 1],
+ Y[block + 66],
+ Y[block + 66 + 1],
+ Y[block + 2],
+ Y[block + 2 + 1],
+ Y[block + 66],
+ Y[block + 66 + 1],
+ (double) +0.995184726672197, (double) +0.098017140329561);
+ BUTTERFLY_XY (Y[block + 4], /* W4 */
+ Y[block + 4 + 1],
+ Y[block + 68],
+ Y[block + 68 + 1],
+ Y[block + 4],
+ Y[block + 4 + 1],
+ Y[block + 68],
+ Y[block + 68 + 1],
+ (double) +0.980785280403230, (double) +0.195090322016128);
+ BUTTERFLY_XY (Y[block + 6], /* W6 */
+ Y[block + 6 + 1],
+ Y[block + 70],
+ Y[block + 70 + 1],
+ Y[block + 6],
+ Y[block + 6 + 1],
+ Y[block + 70],
+ Y[block + 70 + 1],
+ (double) +0.956940335732209, (double) +0.290284677254462);
+ BUTTERFLY_XY (Y[block + 8], /* W8 */
+ Y[block + 8 + 1],
+ Y[block + 72],
+ Y[block + 72 + 1],
+ Y[block + 8],
+ Y[block + 8 + 1],
+ Y[block + 72],
+ Y[block + 72 + 1],
+ (double) +0.923879532511287, (double) +0.382683432365090);
+ BUTTERFLY_XY (Y[block + 10], /* W10 */
+ Y[block + 10 + 1],
+ Y[block + 74],
+ Y[block + 74 + 1],
+ Y[block + 10],
+ Y[block + 10 + 1],
+ Y[block + 74],
+ Y[block + 74 + 1],
+ (double) +0.881921264348355, (double) +0.471396736825998);
+ BUTTERFLY_XY (Y[block + 12], /* W12 */
+ Y[block + 12 + 1],
+ Y[block + 76],
+ Y[block + 76 + 1],
+ Y[block + 12],
+ Y[block + 12 + 1],
+ Y[block + 76],
+ Y[block + 76 + 1],
+ (double) +0.831469612302545, (double) +0.555570233019602);
+ BUTTERFLY_XY (Y[block + 14], /* W14 */
+ Y[block + 14 + 1],
+ Y[block + 78],
+ Y[block + 78 + 1],
+ Y[block + 14],
+ Y[block + 14 + 1],
+ Y[block + 78],
+ Y[block + 78 + 1],
+ (double) +0.773010453362737, (double) +0.634393284163645);
+ BUTTERFLY_XX (Y[block + 16], /* W16 */
+ Y[block + 16 + 1],
+ Y[block + 80],
+ Y[block + 80 + 1],
+ Y[block + 16],
+ Y[block + 16 + 1],
+ Y[block + 80],
+ Y[block + 80 + 1],
+ (double) +0.707106781186548, (double) +0.707106781186547);
+ BUTTERFLY_XY (Y[block + 18], /* W18 */
+ Y[block + 18 + 1],
+ Y[block + 82],
+ Y[block + 82 + 1],
+ Y[block + 18],
+ Y[block + 18 + 1],
+ Y[block + 82],
+ Y[block + 82 + 1],
+ (double) +0.634393284163645, (double) +0.773010453362737);
+ BUTTERFLY_XY (Y[block + 20], /* W20 */
+ Y[block + 20 + 1],
+ Y[block + 84],
+ Y[block + 84 + 1],
+ Y[block + 20],
+ Y[block + 20 + 1],
+ Y[block + 84],
+ Y[block + 84 + 1],
+ (double) +0.555570233019602, (double) +0.831469612302545);
+ BUTTERFLY_XY (Y[block + 22], /* W22 */
+ Y[block + 22 + 1],
+ Y[block + 86],
+ Y[block + 86 + 1],
+ Y[block + 22],
+ Y[block + 22 + 1],
+ Y[block + 86],
+ Y[block + 86 + 1],
+ (double) +0.471396736825998, (double) +0.881921264348355);
+ BUTTERFLY_XY (Y[block + 24], /* W24 */
+ Y[block + 24 + 1],
+ Y[block + 88],
+ Y[block + 88 + 1],
+ Y[block + 24],
+ Y[block + 24 + 1],
+ Y[block + 88],
+ Y[block + 88 + 1],
+ (double) +0.382683432365090, (double) +0.923879532511287);
+ BUTTERFLY_XY (Y[block + 26], /* W26 */
+ Y[block + 26 + 1],
+ Y[block + 90],
+ Y[block + 90 + 1],
+ Y[block + 26],
+ Y[block + 26 + 1],
+ Y[block + 90],
+ Y[block + 90 + 1],
+ (double) +0.290284677254462, (double) +0.956940335732209);
+ BUTTERFLY_XY (Y[block + 28], /* W28 */
+ Y[block + 28 + 1],
+ Y[block + 92],
+ Y[block + 92 + 1],
+ Y[block + 28],
+ Y[block + 28 + 1],
+ Y[block + 92],
+ Y[block + 92 + 1],
+ (double) +0.195090322016128, (double) +0.980785280403230);
+ BUTTERFLY_XY (Y[block + 30], /* W30 */
+ Y[block + 30 + 1],
+ Y[block + 94],
+ Y[block + 94 + 1],
+ Y[block + 30],
+ Y[block + 30 + 1],
+ Y[block + 94],
+ Y[block + 94 + 1],
+ (double) +0.098017140329561, (double) +0.995184726672197);
+ BUTTERFLY_01 (Y[block + 32], /* W32 */
+ Y[block + 32 + 1],
+ Y[block + 96],
+ Y[block + 96 + 1],
+ Y[block + 32],
+ Y[block + 32 + 1],
+ Y[block + 96],
+ Y[block + 96 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_XY (Y[block + 34], /* W34 */
+ Y[block + 34 + 1],
+ Y[block + 98],
+ Y[block + 98 + 1],
+ Y[block + 34],
+ Y[block + 34 + 1],
+ Y[block + 98],
+ Y[block + 98 + 1],
+ (double) -0.098017140329561, (double) +0.995184726672197);
+ BUTTERFLY_XY (Y[block + 36], /* W36 */
+ Y[block + 36 + 1],
+ Y[block + 100],
+ Y[block + 100 + 1],
+ Y[block + 36],
+ Y[block + 36 + 1],
+ Y[block + 100],
+ Y[block + 100 + 1],
+ (double) -0.195090322016128, (double) +0.980785280403230);
+ BUTTERFLY_XY (Y[block + 38], /* W38 */
+ Y[block + 38 + 1],
+ Y[block + 102],
+ Y[block + 102 + 1],
+ Y[block + 38],
+ Y[block + 38 + 1],
+ Y[block + 102],
+ Y[block + 102 + 1],
+ (double) -0.290284677254462, (double) +0.956940335732209);
+ BUTTERFLY_XY (Y[block + 40], /* W40 */
+ Y[block + 40 + 1],
+ Y[block + 104],
+ Y[block + 104 + 1],
+ Y[block + 40],
+ Y[block + 40 + 1],
+ Y[block + 104],
+ Y[block + 104 + 1],
+ (double) -0.382683432365090, (double) +0.923879532511287);
+ BUTTERFLY_XY (Y[block + 42], /* W42 */
+ Y[block + 42 + 1],
+ Y[block + 106],
+ Y[block + 106 + 1],
+ Y[block + 42],
+ Y[block + 42 + 1],
+ Y[block + 106],
+ Y[block + 106 + 1],
+ (double) -0.471396736825998, (double) +0.881921264348355);
+ BUTTERFLY_XY (Y[block + 44], /* W44 */
+ Y[block + 44 + 1],
+ Y[block + 108],
+ Y[block + 108 + 1],
+ Y[block + 44],
+ Y[block + 44 + 1],
+ Y[block + 108],
+ Y[block + 108 + 1],
+ (double) -0.555570233019602, (double) +0.831469612302545);
+ BUTTERFLY_XY (Y[block + 46], /* W46 */
+ Y[block + 46 + 1],
+ Y[block + 110],
+ Y[block + 110 + 1],
+ Y[block + 46],
+ Y[block + 46 + 1],
+ Y[block + 110],
+ Y[block + 110 + 1],
+ (double) -0.634393284163645, (double) +0.773010453362737);
+ BUTTERFLY_yY (Y[block + 48], /* W48 */
+ Y[block + 48 + 1],
+ Y[block + 112],
+ Y[block + 112 + 1],
+ Y[block + 48],
+ Y[block + 48 + 1],
+ Y[block + 112],
+ Y[block + 112 + 1],
+ (double) -0.707106781186547, (double) +0.707106781186548);
+ BUTTERFLY_XY (Y[block + 50], /* W50 */
+ Y[block + 50 + 1],
+ Y[block + 114],
+ Y[block + 114 + 1],
+ Y[block + 50],
+ Y[block + 50 + 1],
+ Y[block + 114],
+ Y[block + 114 + 1],
+ (double) -0.773010453362737, (double) +0.634393284163645);
+ BUTTERFLY_XY (Y[block + 52], /* W52 */
+ Y[block + 52 + 1],
+ Y[block + 116],
+ Y[block + 116 + 1],
+ Y[block + 52],
+ Y[block + 52 + 1],
+ Y[block + 116],
+ Y[block + 116 + 1],
+ (double) -0.831469612302545, (double) +0.555570233019602);
+ BUTTERFLY_XY (Y[block + 54], /* W54 */
+ Y[block + 54 + 1],
+ Y[block + 118],
+ Y[block + 118 + 1],
+ Y[block + 54],
+ Y[block + 54 + 1],
+ Y[block + 118],
+ Y[block + 118 + 1],
+ (double) -0.881921264348355, (double) +0.471396736825998);
+ BUTTERFLY_XY (Y[block + 56], /* W56 */
+ Y[block + 56 + 1],
+ Y[block + 120],
+ Y[block + 120 + 1],
+ Y[block + 56],
+ Y[block + 56 + 1],
+ Y[block + 120],
+ Y[block + 120 + 1],
+ (double) -0.923879532511287, (double) +0.382683432365090);
+ BUTTERFLY_XY (Y[block + 58], /* W58 */
+ Y[block + 58 + 1],
+ Y[block + 122],
+ Y[block + 122 + 1],
+ Y[block + 58],
+ Y[block + 58 + 1],
+ Y[block + 122],
+ Y[block + 122 + 1],
+ (double) -0.956940335732209, (double) +0.290284677254462);
+ BUTTERFLY_XY (Y[block + 60], /* W60 */
+ Y[block + 60 + 1],
+ Y[block + 124],
+ Y[block + 124 + 1],
+ Y[block + 60],
+ Y[block + 60 + 1],
+ Y[block + 124],
+ Y[block + 124 + 1],
+ (double) -0.980785280403230, (double) +0.195090322016129);
+ BUTTERFLY_XY (Y[block + 62], /* W62 */
+ Y[block + 62 + 1],
+ Y[block + 126],
+ Y[block + 126 + 1],
+ Y[block + 62],
+ Y[block + 62 + 1],
+ Y[block + 126],
+ Y[block + 126 + 1],
+ (double) -0.995184726672197, (double) +0.098017140329561);
+ }
+
+ /* perform 1 times fft128 */
+ BUTTERFLY_10 (Y[0], /* W0 */
+ Y[0 + 1],
+ Y[128],
+ Y[128 + 1],
+ Y[0],
+ Y[0 + 1],
+ Y[128],
+ Y[128 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XY (Y[2], /* W1 */
+ Y[2 + 1],
+ Y[130],
+ Y[130 + 1],
+ Y[2],
+ Y[2 + 1],
+ Y[130],
+ Y[130 + 1],
+ (double) +0.998795456205172, (double) +0.049067674327418);
+ BUTTERFLY_XY (Y[4], /* W2 */
+ Y[4 + 1],
+ Y[132],
+ Y[132 + 1],
+ Y[4],
+ Y[4 + 1],
+ Y[132],
+ Y[132 + 1],
+ (double) +0.995184726672197, (double) +0.098017140329561);
+ BUTTERFLY_XY (Y[6], /* W3 */
+ Y[6 + 1],
+ Y[134],
+ Y[134 + 1],
+ Y[6],
+ Y[6 + 1],
+ Y[134],
+ Y[134 + 1],
+ (double) +0.989176509964781, (double) +0.146730474455362);
+ BUTTERFLY_XY (Y[8], /* W4 */
+ Y[8 + 1],
+ Y[136],
+ Y[136 + 1],
+ Y[8],
+ Y[8 + 1],
+ Y[136],
+ Y[136 + 1],
+ (double) +0.980785280403230, (double) +0.195090322016128);
+ BUTTERFLY_XY (Y[10], /* W5 */
+ Y[10 + 1],
+ Y[138],
+ Y[138 + 1],
+ Y[10],
+ Y[10 + 1],
+ Y[138],
+ Y[138 + 1],
+ (double) +0.970031253194544, (double) +0.242980179903264);
+ BUTTERFLY_XY (Y[12], /* W6 */
+ Y[12 + 1],
+ Y[140],
+ Y[140 + 1],
+ Y[12],
+ Y[12 + 1],
+ Y[140],
+ Y[140 + 1],
+ (double) +0.956940335732209, (double) +0.290284677254462);
+ BUTTERFLY_XY (Y[14], /* W7 */
+ Y[14 + 1],
+ Y[142],
+ Y[142 + 1],
+ Y[14],
+ Y[14 + 1],
+ Y[142],
+ Y[142 + 1],
+ (double) +0.941544065183021, (double) +0.336889853392220);
+ BUTTERFLY_XY (Y[16], /* W8 */
+ Y[16 + 1],
+ Y[144],
+ Y[144 + 1],
+ Y[16],
+ Y[16 + 1],
+ Y[144],
+ Y[144 + 1],
+ (double) +0.923879532511287, (double) +0.382683432365090);
+ BUTTERFLY_XY (Y[18], /* W9 */
+ Y[18 + 1],
+ Y[146],
+ Y[146 + 1],
+ Y[18],
+ Y[18 + 1],
+ Y[146],
+ Y[146 + 1],
+ (double) +0.903989293123443, (double) +0.427555093430282);
+ BUTTERFLY_XY (Y[20], /* W10 */
+ Y[20 + 1],
+ Y[148],
+ Y[148 + 1],
+ Y[20],
+ Y[20 + 1],
+ Y[148],
+ Y[148 + 1],
+ (double) +0.881921264348355, (double) +0.471396736825998);
+ BUTTERFLY_XY (Y[22], /* W11 */
+ Y[22 + 1],
+ Y[150],
+ Y[150 + 1],
+ Y[22],
+ Y[22 + 1],
+ Y[150],
+ Y[150 + 1],
+ (double) +0.857728610000272, (double) +0.514102744193222);
+ BUTTERFLY_XY (Y[24], /* W12 */
+ Y[24 + 1],
+ Y[152],
+ Y[152 + 1],
+ Y[24],
+ Y[24 + 1],
+ Y[152],
+ Y[152 + 1],
+ (double) +0.831469612302545, (double) +0.555570233019602);
+ BUTTERFLY_XY (Y[26], /* W13 */
+ Y[26 + 1],
+ Y[154],
+ Y[154 + 1],
+ Y[26],
+ Y[26 + 1],
+ Y[154],
+ Y[154 + 1],
+ (double) +0.803207531480645, (double) +0.595699304492433);
+ BUTTERFLY_XY (Y[28], /* W14 */
+ Y[28 + 1],
+ Y[156],
+ Y[156 + 1],
+ Y[28],
+ Y[28 + 1],
+ Y[156],
+ Y[156 + 1],
+ (double) +0.773010453362737, (double) +0.634393284163645);
+ BUTTERFLY_XY (Y[30], /* W15 */
+ Y[30 + 1],
+ Y[158],
+ Y[158 + 1],
+ Y[30],
+ Y[30 + 1],
+ Y[158],
+ Y[158 + 1],
+ (double) +0.740951125354959, (double) +0.671558954847018);
+ BUTTERFLY_XX (Y[32], /* W16 */
+ Y[32 + 1],
+ Y[160],
+ Y[160 + 1],
+ Y[32],
+ Y[32 + 1],
+ Y[160],
+ Y[160 + 1],
+ (double) +0.707106781186548, (double) +0.707106781186547);
+ BUTTERFLY_XY (Y[34], /* W17 */
+ Y[34 + 1],
+ Y[162],
+ Y[162 + 1],
+ Y[34],
+ Y[34 + 1],
+ Y[162],
+ Y[162 + 1],
+ (double) +0.671558954847018, (double) +0.740951125354959);
+ BUTTERFLY_XY (Y[36], /* W18 */
+ Y[36 + 1],
+ Y[164],
+ Y[164 + 1],
+ Y[36],
+ Y[36 + 1],
+ Y[164],
+ Y[164 + 1],
+ (double) +0.634393284163645, (double) +0.773010453362737);
+ BUTTERFLY_XY (Y[38], /* W19 */
+ Y[38 + 1],
+ Y[166],
+ Y[166 + 1],
+ Y[38],
+ Y[38 + 1],
+ Y[166],
+ Y[166 + 1],
+ (double) +0.595699304492433, (double) +0.803207531480645);
+ BUTTERFLY_XY (Y[40], /* W20 */
+ Y[40 + 1],
+ Y[168],
+ Y[168 + 1],
+ Y[40],
+ Y[40 + 1],
+ Y[168],
+ Y[168 + 1],
+ (double) +0.555570233019602, (double) +0.831469612302545);
+ BUTTERFLY_XY (Y[42], /* W21 */
+ Y[42 + 1],
+ Y[170],
+ Y[170 + 1],
+ Y[42],
+ Y[42 + 1],
+ Y[170],
+ Y[170 + 1],
+ (double) +0.514102744193222, (double) +0.857728610000272);
+ BUTTERFLY_XY (Y[44], /* W22 */
+ Y[44 + 1],
+ Y[172],
+ Y[172 + 1],
+ Y[44],
+ Y[44 + 1],
+ Y[172],
+ Y[172 + 1],
+ (double) +0.471396736825998, (double) +0.881921264348355);
+ BUTTERFLY_XY (Y[46], /* W23 */
+ Y[46 + 1],
+ Y[174],
+ Y[174 + 1],
+ Y[46],
+ Y[46 + 1],
+ Y[174],
+ Y[174 + 1],
+ (double) +0.427555093430282, (double) +0.903989293123443);
+ BUTTERFLY_XY (Y[48], /* W24 */
+ Y[48 + 1],
+ Y[176],
+ Y[176 + 1],
+ Y[48],
+ Y[48 + 1],
+ Y[176],
+ Y[176 + 1],
+ (double) +0.382683432365090, (double) +0.923879532511287);
+ BUTTERFLY_XY (Y[50], /* W25 */
+ Y[50 + 1],
+ Y[178],
+ Y[178 + 1],
+ Y[50],
+ Y[50 + 1],
+ Y[178],
+ Y[178 + 1],
+ (double) +0.336889853392220, (double) +0.941544065183021);
+ BUTTERFLY_XY (Y[52], /* W26 */
+ Y[52 + 1],
+ Y[180],
+ Y[180 + 1],
+ Y[52],
+ Y[52 + 1],
+ Y[180],
+ Y[180 + 1],
+ (double) +0.290284677254462, (double) +0.956940335732209);
+ BUTTERFLY_XY (Y[54], /* W27 */
+ Y[54 + 1],
+ Y[182],
+ Y[182 + 1],
+ Y[54],
+ Y[54 + 1],
+ Y[182],
+ Y[182 + 1],
+ (double) +0.242980179903264, (double) +0.970031253194544);
+ BUTTERFLY_XY (Y[56], /* W28 */
+ Y[56 + 1],
+ Y[184],
+ Y[184 + 1],
+ Y[56],
+ Y[56 + 1],
+ Y[184],
+ Y[184 + 1],
+ (double) +0.195090322016128, (double) +0.980785280403230);
+ BUTTERFLY_XY (Y[58], /* W29 */
+ Y[58 + 1],
+ Y[186],
+ Y[186 + 1],
+ Y[58],
+ Y[58 + 1],
+ Y[186],
+ Y[186 + 1],
+ (double) +0.146730474455362, (double) +0.989176509964781);
+ BUTTERFLY_XY (Y[60], /* W30 */
+ Y[60 + 1],
+ Y[188],
+ Y[188 + 1],
+ Y[60],
+ Y[60 + 1],
+ Y[188],
+ Y[188 + 1],
+ (double) +0.098017140329561, (double) +0.995184726672197);
+ BUTTERFLY_XY (Y[62], /* W31 */
+ Y[62 + 1],
+ Y[190],
+ Y[190 + 1],
+ Y[62],
+ Y[62 + 1],
+ Y[190],
+ Y[190 + 1],
+ (double) +0.049067674327418, (double) +0.998795456205172);
+ BUTTERFLY_01 (Y[64], /* W32 */
+ Y[64 + 1],
+ Y[192],
+ Y[192 + 1],
+ Y[64],
+ Y[64 + 1],
+ Y[192],
+ Y[192 + 1],
+ (double) +0.000000000000000, (double) +1.000000000000000);
+ BUTTERFLY_XY (Y[66], /* W33 */
+ Y[66 + 1],
+ Y[194],
+ Y[194 + 1],
+ Y[66],
+ Y[66 + 1],
+ Y[194],
+ Y[194 + 1],
+ (double) -0.049067674327418, (double) +0.998795456205172);
+ BUTTERFLY_XY (Y[68], /* W34 */
+ Y[68 + 1],
+ Y[196],
+ Y[196 + 1],
+ Y[68],
+ Y[68 + 1],
+ Y[196],
+ Y[196 + 1],
+ (double) -0.098017140329561, (double) +0.995184726672197);
+ BUTTERFLY_XY (Y[70], /* W35 */
+ Y[70 + 1],
+ Y[198],
+ Y[198 + 1],
+ Y[70],
+ Y[70 + 1],
+ Y[198],
+ Y[198 + 1],
+ (double) -0.146730474455362, (double) +0.989176509964781);
+ BUTTERFLY_XY (Y[72], /* W36 */
+ Y[72 + 1],
+ Y[200],
+ Y[200 + 1],
+ Y[72],
+ Y[72 + 1],
+ Y[200],
+ Y[200 + 1],
+ (double) -0.195090322016128, (double) +0.980785280403230);
+ BUTTERFLY_XY (Y[74], /* W37 */
+ Y[74 + 1],
+ Y[202],
+ Y[202 + 1],
+ Y[74],
+ Y[74 + 1],
+ Y[202],
+ Y[202 + 1],
+ (double) -0.242980179903264, (double) +0.970031253194544);
+ BUTTERFLY_XY (Y[76], /* W38 */
+ Y[76 + 1],
+ Y[204],
+ Y[204 + 1],
+ Y[76],
+ Y[76 + 1],
+ Y[204],
+ Y[204 + 1],
+ (double) -0.290284677254462, (double) +0.956940335732209);
+ BUTTERFLY_XY (Y[78], /* W39 */
+ Y[78 + 1],
+ Y[206],
+ Y[206 + 1],
+ Y[78],
+ Y[78 + 1],
+ Y[206],
+ Y[206 + 1],
+ (double) -0.336889853392220, (double) +0.941544065183021);
+ BUTTERFLY_XY (Y[80], /* W40 */
+ Y[80 + 1],
+ Y[208],
+ Y[208 + 1],
+ Y[80],
+ Y[80 + 1],
+ Y[208],
+ Y[208 + 1],
+ (double) -0.382683432365090, (double) +0.923879532511287);
+ BUTTERFLY_XY (Y[82], /* W41 */
+ Y[82 + 1],
+ Y[210],
+ Y[210 + 1],
+ Y[82],
+ Y[82 + 1],
+ Y[210],
+ Y[210 + 1],
+ (double) -0.427555093430282, (double) +0.903989293123443);
+ BUTTERFLY_XY (Y[84], /* W42 */
+ Y[84 + 1],
+ Y[212],
+ Y[212 + 1],
+ Y[84],
+ Y[84 + 1],
+ Y[212],
+ Y[212 + 1],
+ (double) -0.471396736825998, (double) +0.881921264348355);
+ BUTTERFLY_XY (Y[86], /* W43 */
+ Y[86 + 1],
+ Y[214],
+ Y[214 + 1],
+ Y[86],
+ Y[86 + 1],
+ Y[214],
+ Y[214 + 1],
+ (double) -0.514102744193222, (double) +0.857728610000272);
+ BUTTERFLY_XY (Y[88], /* W44 */
+ Y[88 + 1],
+ Y[216],
+ Y[216 + 1],
+ Y[88],
+ Y[88 + 1],
+ Y[216],
+ Y[216 + 1],
+ (double) -0.555570233019602, (double) +0.831469612302545);
+ BUTTERFLY_XY (Y[90], /* W45 */
+ Y[90 + 1],
+ Y[218],
+ Y[218 + 1],
+ Y[90],
+ Y[90 + 1],
+ Y[218],
+ Y[218 + 1],
+ (double) -0.595699304492433, (double) +0.803207531480645);
+ BUTTERFLY_XY (Y[92], /* W46 */
+ Y[92 + 1],
+ Y[220],
+ Y[220 + 1],
+ Y[92],
+ Y[92 + 1],
+ Y[220],
+ Y[220 + 1],
+ (double) -0.634393284163645, (double) +0.773010453362737);
+ BUTTERFLY_XY (Y[94], /* W47 */
+ Y[94 + 1],
+ Y[222],
+ Y[222 + 1],
+ Y[94],
+ Y[94 + 1],
+ Y[222],
+ Y[222 + 1],
+ (double) -0.671558954847018, (double) +0.740951125354959);
+ BUTTERFLY_yY (Y[96], /* W48 */
+ Y[96 + 1],
+ Y[224],
+ Y[224 + 1],
+ Y[96],
+ Y[96 + 1],
+ Y[224],
+ Y[224 + 1],
+ (double) -0.707106781186547, (double) +0.707106781186548);
+ BUTTERFLY_XY (Y[98], /* W49 */
+ Y[98 + 1],
+ Y[226],
+ Y[226 + 1],
+ Y[98],
+ Y[98 + 1],
+ Y[226],
+ Y[226 + 1],
+ (double) -0.740951125354959, (double) +0.671558954847019);
+ BUTTERFLY_XY (Y[100], /* W50 */
+ Y[100 + 1],
+ Y[228],
+ Y[228 + 1],
+ Y[100],
+ Y[100 + 1],
+ Y[228],
+ Y[228 + 1],
+ (double) -0.773010453362737, (double) +0.634393284163645);
+ BUTTERFLY_XY (Y[102], /* W51 */
+ Y[102 + 1],
+ Y[230],
+ Y[230 + 1],
+ Y[102],
+ Y[102 + 1],
+ Y[230],
+ Y[230 + 1],
+ (double) -0.803207531480645, (double) +0.595699304492433);
+ BUTTERFLY_XY (Y[104], /* W52 */
+ Y[104 + 1],
+ Y[232],
+ Y[232 + 1],
+ Y[104],
+ Y[104 + 1],
+ Y[232],
+ Y[232 + 1],
+ (double) -0.831469612302545, (double) +0.555570233019602);
+ BUTTERFLY_XY (Y[106], /* W53 */
+ Y[106 + 1],
+ Y[234],
+ Y[234 + 1],
+ Y[106],
+ Y[106 + 1],
+ Y[234],
+ Y[234 + 1],
+ (double) -0.857728610000272, (double) +0.514102744193222);
+ BUTTERFLY_XY (Y[108], /* W54 */
+ Y[108 + 1],
+ Y[236],
+ Y[236 + 1],
+ Y[108],
+ Y[108 + 1],
+ Y[236],
+ Y[236 + 1],
+ (double) -0.881921264348355, (double) +0.471396736825998);
+ BUTTERFLY_XY (Y[110], /* W55 */
+ Y[110 + 1],
+ Y[238],
+ Y[238 + 1],
+ Y[110],
+ Y[110 + 1],
+ Y[238],
+ Y[238 + 1],
+ (double) -0.903989293123443, (double) +0.427555093430282);
+ BUTTERFLY_XY (Y[112], /* W56 */
+ Y[112 + 1],
+ Y[240],
+ Y[240 + 1],
+ Y[112],
+ Y[112 + 1],
+ Y[240],
+ Y[240 + 1],
+ (double) -0.923879532511287, (double) +0.382683432365090);
+ BUTTERFLY_XY (Y[114], /* W57 */
+ Y[114 + 1],
+ Y[242],
+ Y[242 + 1],
+ Y[114],
+ Y[114 + 1],
+ Y[242],
+ Y[242 + 1],
+ (double) -0.941544065183021, (double) +0.336889853392220);
+ BUTTERFLY_XY (Y[116], /* W58 */
+ Y[116 + 1],
+ Y[244],
+ Y[244 + 1],
+ Y[116],
+ Y[116 + 1],
+ Y[244],
+ Y[244 + 1],
+ (double) -0.956940335732209, (double) +0.290284677254462);
+ BUTTERFLY_XY (Y[118], /* W59 */
+ Y[118 + 1],
+ Y[246],
+ Y[246 + 1],
+ Y[118],
+ Y[118 + 1],
+ Y[246],
+ Y[246 + 1],
+ (double) -0.970031253194544, (double) +0.242980179903264);
+ BUTTERFLY_XY (Y[120], /* W60 */
+ Y[120 + 1],
+ Y[248],
+ Y[248 + 1],
+ Y[120],
+ Y[120 + 1],
+ Y[248],
+ Y[248 + 1],
+ (double) -0.980785280403230, (double) +0.195090322016129);
+ BUTTERFLY_XY (Y[122], /* W61 */
+ Y[122 + 1],
+ Y[250],
+ Y[250 + 1],
+ Y[122],
+ Y[122 + 1],
+ Y[250],
+ Y[250 + 1],
+ (double) -0.989176509964781, (double) +0.146730474455362);
+ BUTTERFLY_XY (Y[124], /* W62 */
+ Y[124 + 1],
+ Y[252],
+ Y[252 + 1],
+ Y[124],
+ Y[124 + 1],
+ Y[252],
+ Y[252 + 1],
+ (double) -0.995184726672197, (double) +0.098017140329561);
+ BUTTERFLY_XY (Y[126], /* W63 */
+ Y[126 + 1],
+ Y[254],
+ Y[254 + 1],
+ Y[126],
+ Y[126 + 1],
+ Y[254],
+ Y[254 + 1],
+ (double) -0.998795456205172, (double) +0.049067674327418);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 128 L S S S S S X)
+ **/
+static void
+gsl_power2_fft128analysis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform fft2 and bitreverse input */
+ bitreverse_fft2analysis (128, X, Y);
+
+ /* skipping 32 times fft4 */
+
+ /* skipping 16 times fft8 */
+
+ /* skipping 8 times fft16 */
+
+ /* skipping 4 times fft32 */
+
+ /* skipping 2 times fft64 */
+
+ /* perform 1 times fft128 */
+ gsl_power2_fft128analysis_skip2 (X, Y);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 256 S S S S S S X T)
+ **/
+static void
+gsl_power2_fft256analysis_skip2 (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* skipping 128 times fft2 */
+
+ /* skipping 64 times fft4 */
+
+ /* skipping 32 times fft8 */
+
+ /* skipping 16 times fft16 */
+
+ /* skipping 8 times fft32 */
+
+ /* skipping 4 times fft64 */
+
+ /* perform 2 times fft128 */
+ gsl_power2_fft128analysis_skip2 (X, Y);
+ gsl_power2_fft128analysis_skip2 (X + 256, Y + 256);
+
+ /* perform 1 times fft256 */
+ {
+ static const double Wconst256[] = {
+ +0.999698818696204, +0.024541228522912,
+ +0.998795456205172, +0.049067674327418,
+ +0.997290456678690, +0.073564563599667,
+ +0.995184726672197, +0.098017140329561,
+ +0.992479534598710, +0.122410675199216,
+ +0.989176509964781, +0.146730474455362,
+ +0.985277642388941, +0.170961888760301,
+ +0.980785280403230, +0.195090322016128,
+ +0.975702130038529, +0.219101240156870,
+ +0.970031253194544, +0.242980179903264,
+ +0.963776065795440, +0.266712757474898,
+ +0.956940335732209, +0.290284677254462,
+ +0.949528180593037, +0.313681740398892,
+ +0.941544065183021, +0.336889853392220,
+ +0.932992798834739, +0.359895036534988,
+ +0.923879532511287, +0.382683432365090,
+ +0.914209755703531, +0.405241314004990,
+ +0.903989293123443, +0.427555093430282,
+ +0.893224301195515, +0.449611329654607,
+ +0.881921264348355, +0.471396736825998,
+ +0.870086991108711, +0.492898192229784,
+ +0.857728610000272, +0.514102744193222,
+ +0.844853565249707, +0.534997619887097,
+ +0.831469612302545, +0.555570233019602,
+ +0.817584813151584, +0.575808191417845,
+ +0.803207531480645, +0.595699304492433,
+ +0.788346427626606, +0.615231590580627,
+ +0.773010453362737, +0.634393284163645,
+ +0.757208846506485, +0.653172842953777,
+ +0.740951125354959, +0.671558954847018,
+ +0.724247082951467, +0.689540544737067,
+ +0.707106781186548, +0.707106781186547,
+ +0.689540544737067, +0.724247082951467,
+ +0.671558954847018, +0.740951125354959,
+ +0.653172842953777, +0.757208846506484,
+ +0.634393284163645, +0.773010453362737,
+ +0.615231590580627, +0.788346427626606,
+ +0.595699304492433, +0.803207531480645,
+ +0.575808191417845, +0.817584813151584,
+ +0.555570233019602, +0.831469612302545,
+ +0.534997619887097, +0.844853565249707,
+ +0.514102744193222, +0.857728610000272,
+ +0.492898192229784, +0.870086991108711,
+ +0.471396736825998, +0.881921264348355,
+ +0.449611329654607, +0.893224301195515,
+ +0.427555093430282, +0.903989293123443,
+ +0.405241314004990, +0.914209755703531,
+ +0.382683432365090, +0.923879532511287,
+ +0.359895036534988, +0.932992798834739,
+ +0.336889853392220, +0.941544065183021,
+ +0.313681740398892, +0.949528180593037,
+ +0.290284677254462, +0.956940335732209,
+ +0.266712757474898, +0.963776065795440,
+ +0.242980179903264, +0.970031253194544,
+ +0.219101240156870, +0.975702130038529,
+ +0.195090322016128, +0.980785280403230,
+ +0.170961888760301, +0.985277642388941,
+ +0.146730474455362, +0.989176509964781,
+ +0.122410675199216, +0.992479534598710,
+ +0.098017140329561, +0.995184726672197,
+ +0.073564563599667, +0.997290456678690,
+ +0.049067674327418, +0.998795456205172,
+ +0.024541228522912, +0.999698818696204,
+ };
+ const double *W = Wconst256 - 2;
+ double *Z = Y + 128;
+ for (offset = 0; offset < 512; offset += 512) {
+ BUTTERFLY_10 (Y[offset], Y[offset + 1],
+ Y[offset + 256], Y[offset + 256 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 256], Y[offset + 256 + 1],
+ __1, __0);
+ BUTTERFLY_01 (Z[offset], Z[offset + 1],
+ Z[offset + 256], Z[offset + 256 + 1],
+ Z[offset], Z[offset + 1],
+ Z[offset + 256], Z[offset + 256 + 1],
+ __0, __1);
+ }
+ for (butterfly = 2; butterfly < 128; butterfly += 2) {
+ Wre = W[butterfly]; Wim = W[butterfly + 1];
+ for (block = 0; block < 512; block += 512) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 256], Y[offset + 256 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 256], Y[offset + 256 + 1],
+ Wre, Wim);
+ BUTTERFLY_Yx (Z[offset], Z[offset + 1],
+ Z[offset + 256], Z[offset + 256 + 1],
+ Z[offset], Z[offset + 1],
+ Z[offset + 256], Z[offset + 256 + 1],
+ Wre, Wim);
+ }
+ }
+ }
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 256 L S S S S S S X)
+ **/
+static void
+gsl_power2_fft256analysis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform fft2 and bitreverse input */
+ bitreverse_fft2analysis (256, X, Y);
+
+ /* skipping 64 times fft4 */
+
+ /* skipping 32 times fft8 */
+
+ /* skipping 16 times fft16 */
+
+ /* skipping 8 times fft32 */
+
+ /* skipping 4 times fft64 */
+
+ /* skipping 2 times fft128 */
+
+ /* perform 1 times fft256 */
+ gsl_power2_fft256analysis_skip2 (X, Y);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 512 S S S S S S X T T)
+ **/
+static void
+gsl_power2_fft512analysis_skip2 (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* skipping 256 times fft2 */
+
+ /* skipping 128 times fft4 */
+
+ /* skipping 64 times fft8 */
+
+ /* skipping 32 times fft16 */
+
+ /* skipping 16 times fft32 */
+
+ /* skipping 8 times fft64 */
+
+ /* perform 4 times fft128 */
+ gsl_power2_fft128analysis_skip2 (X, Y);
+ gsl_power2_fft128analysis_skip2 (X + 256, Y + 256);
+ gsl_power2_fft128analysis_skip2 (X + 512, Y + 512);
+ gsl_power2_fft128analysis_skip2 (X + 768, Y + 768);
+
+ /* perform 2 times fft256 */
+ {
+ static const double Wconst256[] = {
+ +0.999698818696204, +0.024541228522912,
+ +0.998795456205172, +0.049067674327418,
+ +0.997290456678690, +0.073564563599667,
+ +0.995184726672197, +0.098017140329561,
+ +0.992479534598710, +0.122410675199216,
+ +0.989176509964781, +0.146730474455362,
+ +0.985277642388941, +0.170961888760301,
+ +0.980785280403230, +0.195090322016128,
+ +0.975702130038529, +0.219101240156870,
+ +0.970031253194544, +0.242980179903264,
+ +0.963776065795440, +0.266712757474898,
+ +0.956940335732209, +0.290284677254462,
+ +0.949528180593037, +0.313681740398892,
+ +0.941544065183021, +0.336889853392220,
+ +0.932992798834739, +0.359895036534988,
+ +0.923879532511287, +0.382683432365090,
+ +0.914209755703531, +0.405241314004990,
+ +0.903989293123443, +0.427555093430282,
+ +0.893224301195515, +0.449611329654607,
+ +0.881921264348355, +0.471396736825998,
+ +0.870086991108711, +0.492898192229784,
+ +0.857728610000272, +0.514102744193222,
+ +0.844853565249707, +0.534997619887097,
+ +0.831469612302545, +0.555570233019602,
+ +0.817584813151584, +0.575808191417845,
+ +0.803207531480645, +0.595699304492433,
+ +0.788346427626606, +0.615231590580627,
+ +0.773010453362737, +0.634393284163645,
+ +0.757208846506485, +0.653172842953777,
+ +0.740951125354959, +0.671558954847018,
+ +0.724247082951467, +0.689540544737067,
+ +0.707106781186548, +0.707106781186547,
+ +0.689540544737067, +0.724247082951467,
+ +0.671558954847018, +0.740951125354959,
+ +0.653172842953777, +0.757208846506484,
+ +0.634393284163645, +0.773010453362737,
+ +0.615231590580627, +0.788346427626606,
+ +0.595699304492433, +0.803207531480645,
+ +0.575808191417845, +0.817584813151584,
+ +0.555570233019602, +0.831469612302545,
+ +0.534997619887097, +0.844853565249707,
+ +0.514102744193222, +0.857728610000272,
+ +0.492898192229784, +0.870086991108711,
+ +0.471396736825998, +0.881921264348355,
+ +0.449611329654607, +0.893224301195515,
+ +0.427555093430282, +0.903989293123443,
+ +0.405241314004990, +0.914209755703531,
+ +0.382683432365090, +0.923879532511287,
+ +0.359895036534988, +0.932992798834739,
+ +0.336889853392220, +0.941544065183021,
+ +0.313681740398892, +0.949528180593037,
+ +0.290284677254462, +0.956940335732209,
+ +0.266712757474898, +0.963776065795440,
+ +0.242980179903264, +0.970031253194544,
+ +0.219101240156870, +0.975702130038529,
+ +0.195090322016128, +0.980785280403230,
+ +0.170961888760301, +0.985277642388941,
+ +0.146730474455362, +0.989176509964781,
+ +0.122410675199216, +0.992479534598710,
+ +0.098017140329561, +0.995184726672197,
+ +0.073564563599667, +0.997290456678690,
+ +0.049067674327418, +0.998795456205172,
+ +0.024541228522912, +0.999698818696204,
+ };
+ const double *W = Wconst256 - 2;
+ double *Z = Y + 128;
+ for (offset = 0; offset < 1024; offset += 512) {
+ BUTTERFLY_10 (Y[offset], Y[offset + 1],
+ Y[offset + 256], Y[offset + 256 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 256], Y[offset + 256 + 1],
+ __1, __0);
+ BUTTERFLY_01 (Z[offset], Z[offset + 1],
+ Z[offset + 256], Z[offset + 256 + 1],
+ Z[offset], Z[offset + 1],
+ Z[offset + 256], Z[offset + 256 + 1],
+ __0, __1);
+ }
+ for (butterfly = 2; butterfly < 128; butterfly += 2) {
+ Wre = W[butterfly]; Wim = W[butterfly + 1];
+ for (block = 0; block < 1024; block += 512) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 256], Y[offset + 256 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 256], Y[offset + 256 + 1],
+ Wre, Wim);
+ BUTTERFLY_Yx (Z[offset], Z[offset + 1],
+ Z[offset + 256], Z[offset + 256 + 1],
+ Z[offset], Z[offset + 1],
+ Z[offset + 256], Z[offset + 256 + 1],
+ Wre, Wim);
+ }
+ }
+ }
+
+ /* perform 1 times fft512 */
+ {
+ static const double Wconst512[] = {
+ +0.999924701839145, +0.012271538285720,
+ +0.999698818696204, +0.024541228522912,
+ +0.999322384588350, +0.036807222941359,
+ +0.998795456205172, +0.049067674327418,
+ +0.998118112900149, +0.061320736302209,
+ +0.997290456678690, +0.073564563599667,
+ +0.996312612182778, +0.085797312344440,
+ +0.995184726672197, +0.098017140329561,
+ +0.993906970002356, +0.110222207293883,
+ +0.992479534598710, +0.122410675199216,
+ +0.990902635427780, +0.134580708507126,
+ +0.989176509964781, +0.146730474455362,
+ +0.987301418157858, +0.158858143333861,
+ +0.985277642388941, +0.170961888760301,
+ +0.983105487431216, +0.183039887955141,
+ +0.980785280403230, +0.195090322016128,
+ +0.978317370719628, +0.207111376192219,
+ +0.975702130038529, +0.219101240156870,
+ +0.972939952205560, +0.231058108280671,
+ +0.970031253194544, +0.242980179903264,
+ +0.966976471044852, +0.254865659604515,
+ +0.963776065795440, +0.266712757474898,
+ +0.960430519415566, +0.278519689385053,
+ +0.956940335732209, +0.290284677254462,
+ +0.953306040354194, +0.302005949319228,
+ +0.949528180593037, +0.313681740398892,
+ +0.945607325380521, +0.325310292162263,
+ +0.941544065183021, +0.336889853392220,
+ +0.937339011912575, +0.348418680249435,
+ +0.932992798834739, +0.359895036534988,
+ +0.928506080473216, +0.371317193951838,
+ +0.923879532511287, +0.382683432365090,
+ +0.919113851690058, +0.393992040061048,
+ +0.914209755703531, +0.405241314004990,
+ +0.909167983090522, +0.416429560097637,
+ +0.903989293123443, +0.427555093430282,
+ +0.898674465693954, +0.438616238538528,
+ +0.893224301195515, +0.449611329654607,
+ +0.887639620402854, +0.460538710958240,
+ +0.881921264348355, +0.471396736825998,
+ +0.876070094195407, +0.482183772079123,
+ +0.870086991108711, +0.492898192229784,
+ +0.863972856121587, +0.503538383725718,
+ +0.857728610000272, +0.514102744193222,
+ +0.851355193105265, +0.524589682678469,
+ +0.844853565249707, +0.534997619887097,
+ +0.838224705554838, +0.545324988422046,
+ +0.831469612302545, +0.555570233019602,
+ +0.824589302785025, +0.565731810783613,
+ +0.817584813151584, +0.575808191417845,
+ +0.810457198252595, +0.585797857456439,
+ +0.803207531480645, +0.595699304492433,
+ +0.795836904608884, +0.605511041404326,
+ +0.788346427626606, +0.615231590580627,
+ +0.780737228572094, +0.624859488142386,
+ +0.773010453362737, +0.634393284163645,
+ +0.765167265622459, +0.643831542889791,
+ +0.757208846506485, +0.653172842953777,
+ +0.749136394523459, +0.662415777590172,
+ +0.740951125354959, +0.671558954847018,
+ +0.732654271672413, +0.680600997795453,
+ +0.724247082951467, +0.689540544737067,
+ +0.715730825283819, +0.698376249408973,
+ +0.707106781186548, +0.707106781186547,
+ +0.698376249408973, +0.715730825283819,
+ +0.689540544737067, +0.724247082951467,
+ +0.680600997795453, +0.732654271672413,
+ +0.671558954847018, +0.740951125354959,
+ +0.662415777590172, +0.749136394523459,
+ +0.653172842953777, +0.757208846506484,
+ +0.643831542889791, +0.765167265622459,
+ +0.634393284163645, +0.773010453362737,
+ +0.624859488142386, +0.780737228572094,
+ +0.615231590580627, +0.788346427626606,
+ +0.605511041404326, +0.795836904608883,
+ +0.595699304492433, +0.803207531480645,
+ +0.585797857456439, +0.810457198252595,
+ +0.575808191417845, +0.817584813151584,
+ +0.565731810783613, +0.824589302785025,
+ +0.555570233019602, +0.831469612302545,
+ +0.545324988422046, +0.838224705554838,
+ +0.534997619887097, +0.844853565249707,
+ +0.524589682678469, +0.851355193105265,
+ +0.514102744193222, +0.857728610000272,
+ +0.503538383725718, +0.863972856121587,
+ +0.492898192229784, +0.870086991108711,
+ +0.482183772079123, +0.876070094195407,
+ +0.471396736825998, +0.881921264348355,
+ +0.460538710958240, +0.887639620402854,
+ +0.449611329654607, +0.893224301195515,
+ +0.438616238538528, +0.898674465693954,
+ +0.427555093430282, +0.903989293123443,
+ +0.416429560097637, +0.909167983090522,
+ +0.405241314004990, +0.914209755703531,
+ +0.393992040061048, +0.919113851690058,
+ +0.382683432365090, +0.923879532511287,
+ +0.371317193951838, +0.928506080473215,
+ +0.359895036534988, +0.932992798834739,
+ +0.348418680249435, +0.937339011912575,
+ +0.336889853392220, +0.941544065183021,
+ +0.325310292162263, +0.945607325380521,
+ +0.313681740398892, +0.949528180593037,
+ +0.302005949319228, +0.953306040354194,
+ +0.290284677254462, +0.956940335732209,
+ +0.278519689385053, +0.960430519415566,
+ +0.266712757474898, +0.963776065795440,
+ +0.254865659604515, +0.966976471044852,
+ +0.242980179903264, +0.970031253194544,
+ +0.231058108280671, +0.972939952205560,
+ +0.219101240156870, +0.975702130038529,
+ +0.207111376192219, +0.978317370719628,
+ +0.195090322016128, +0.980785280403230,
+ +0.183039887955141, +0.983105487431216,
+ +0.170961888760301, +0.985277642388941,
+ +0.158858143333861, +0.987301418157858,
+ +0.146730474455362, +0.989176509964781,
+ +0.134580708507126, +0.990902635427780,
+ +0.122410675199216, +0.992479534598710,
+ +0.110222207293883, +0.993906970002356,
+ +0.098017140329561, +0.995184726672197,
+ +0.085797312344440, +0.996312612182778,
+ +0.073564563599667, +0.997290456678690,
+ +0.061320736302209, +0.998118112900149,
+ +0.049067674327418, +0.998795456205172,
+ +0.036807222941359, +0.999322384588350,
+ +0.024541228522912, +0.999698818696204,
+ +0.012271538285720, +0.999924701839145,
+ };
+ const double *W = Wconst512 - 2;
+ double *Z = Y + 256;
+ for (offset = 0; offset < 1024; offset += 1024) {
+ BUTTERFLY_10 (Y[offset], Y[offset + 1],
+ Y[offset + 512], Y[offset + 512 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 512], Y[offset + 512 + 1],
+ __1, __0);
+ BUTTERFLY_01 (Z[offset], Z[offset + 1],
+ Z[offset + 512], Z[offset + 512 + 1],
+ Z[offset], Z[offset + 1],
+ Z[offset + 512], Z[offset + 512 + 1],
+ __0, __1);
+ }
+ for (butterfly = 2; butterfly < 256; butterfly += 2) {
+ Wre = W[butterfly]; Wim = W[butterfly + 1];
+ for (block = 0; block < 1024; block += 1024) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 512], Y[offset + 512 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 512], Y[offset + 512 + 1],
+ Wre, Wim);
+ BUTTERFLY_Yx (Z[offset], Z[offset + 1],
+ Z[offset + 512], Z[offset + 512 + 1],
+ Z[offset], Z[offset + 1],
+ Z[offset + 512], Z[offset + 512 + 1],
+ Wre, Wim);
+ }
+ }
+ }
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 512 L S S S S S S S X)
+ **/
+static void
+gsl_power2_fft512analysis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform fft2 and bitreverse input */
+ bitreverse_fft2analysis (512, X, Y);
+
+ /* skipping 128 times fft4 */
+
+ /* skipping 64 times fft8 */
+
+ /* skipping 32 times fft16 */
+
+ /* skipping 16 times fft32 */
+
+ /* skipping 8 times fft64 */
+
+ /* skipping 4 times fft128 */
+
+ /* skipping 2 times fft256 */
+
+ /* perform 1 times fft512 */
+ gsl_power2_fft512analysis_skip2 (X, Y);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 1024 S S S S S S S S X L)
+ **/
+static void
+gsl_power2_fft1024analysis_skip2 (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* skipping 512 times fft2 */
+
+ /* skipping 256 times fft4 */
+
+ /* skipping 128 times fft8 */
+
+ /* skipping 64 times fft16 */
+
+ /* skipping 32 times fft32 */
+
+ /* skipping 16 times fft64 */
+
+ /* skipping 8 times fft128 */
+
+ /* skipping 4 times fft256 */
+
+ /* perform 2 times fft512 */
+ gsl_power2_fft512analysis_skip2 (X, Y);
+ gsl_power2_fft512analysis_skip2 (X + 1024, Y + 1024);
+
+ /* perform 1 times fft1024 */
+ for (offset = 0; offset < 2048; offset += 2048) {
+ BUTTERFLY_10 (Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ __1, __0);
+ }
+ Wre = +0.999981175282601; Wim = +0.006135884649154;
+ for (butterfly = 2; butterfly < 512; butterfly += 2) {
+ for (block = 0; block < 2048; block += 2048) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, -0.000018824717399, +0.006135884649154);
+ }
+ for (offset = 512; offset < 2048; offset += 2048) {
+ BUTTERFLY_01 (Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ __0, __1);
+ }
+ Wre = -0.006135884649154; Wim = +0.999981175282601;
+ for (butterfly = 514; butterfly < 1024; butterfly += 2) {
+ for (block = 0; block < 2048; block += 2048) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, -0.000018824717399, +0.006135884649154);
+ }
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 1024 L S S S S S S S S X)
+ **/
+static void
+gsl_power2_fft1024analysis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform fft2 and bitreverse input */
+ bitreverse_fft2analysis (1024, X, Y);
+
+ /* skipping 256 times fft4 */
+
+ /* skipping 128 times fft8 */
+
+ /* skipping 64 times fft16 */
+
+ /* skipping 32 times fft32 */
+
+ /* skipping 16 times fft64 */
+
+ /* skipping 8 times fft128 */
+
+ /* skipping 4 times fft256 */
+
+ /* skipping 2 times fft512 */
+
+ /* perform 1 times fft1024 */
+ gsl_power2_fft1024analysis_skip2 (X, Y);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 2048 S S S S S S S S X L L)
+ **/
+static void
+gsl_power2_fft2048analysis_skip2 (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* skipping 1024 times fft2 */
+
+ /* skipping 512 times fft4 */
+
+ /* skipping 256 times fft8 */
+
+ /* skipping 128 times fft16 */
+
+ /* skipping 64 times fft32 */
+
+ /* skipping 32 times fft64 */
+
+ /* skipping 16 times fft128 */
+
+ /* skipping 8 times fft256 */
+
+ /* perform 4 times fft512 */
+ gsl_power2_fft512analysis_skip2 (X, Y);
+ gsl_power2_fft512analysis_skip2 (X + 1024, Y + 1024);
+ gsl_power2_fft512analysis_skip2 (X + 2048, Y + 2048);
+ gsl_power2_fft512analysis_skip2 (X + 3072, Y + 3072);
+
+ /* perform 2 times fft1024 */
+ for (offset = 0; offset < 4096; offset += 2048) {
+ BUTTERFLY_10 (Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ __1, __0);
+ }
+ Wre = +0.999981175282601; Wim = +0.006135884649154;
+ for (butterfly = 2; butterfly < 512; butterfly += 2) {
+ for (block = 0; block < 4096; block += 2048) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, -0.000018824717399, +0.006135884649154);
+ }
+ for (offset = 512; offset < 4096; offset += 2048) {
+ BUTTERFLY_01 (Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ __0, __1);
+ }
+ Wre = -0.006135884649154; Wim = +0.999981175282601;
+ for (butterfly = 514; butterfly < 1024; butterfly += 2) {
+ for (block = 0; block < 4096; block += 2048) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, -0.000018824717399, +0.006135884649154);
+ }
+
+ /* perform 1 times fft2048 */
+ for (offset = 0; offset < 4096; offset += 4096) {
+ BUTTERFLY_10 (Y[offset], Y[offset + 1],
+ Y[offset + 2048], Y[offset + 2048 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 2048], Y[offset + 2048 + 1],
+ __1, __0);
+ }
+ Wre = +0.999995293809576; Wim = +0.003067956762966;
+ for (butterfly = 2; butterfly < 1024; butterfly += 2) {
+ for (block = 0; block < 4096; block += 4096) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 2048], Y[offset + 2048 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 2048], Y[offset + 2048 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, -0.000004706190424, +0.003067956762966);
+ }
+ for (offset = 1024; offset < 4096; offset += 4096) {
+ BUTTERFLY_01 (Y[offset], Y[offset + 1],
+ Y[offset + 2048], Y[offset + 2048 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 2048], Y[offset + 2048 + 1],
+ __0, __1);
+ }
+ Wre = -0.003067956762966; Wim = +0.999995293809576;
+ for (butterfly = 1026; butterfly < 2048; butterfly += 2) {
+ for (block = 0; block < 4096; block += 4096) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 2048], Y[offset + 2048 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 2048], Y[offset + 2048 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, -0.000004706190424, +0.003067956762966);
+ }
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 2048 L S S S S S S S S S X)
+ **/
+static void
+gsl_power2_fft2048analysis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform fft2 and bitreverse input */
+ bitreverse_fft2analysis (2048, X, Y);
+
+ /* skipping 512 times fft4 */
+
+ /* skipping 256 times fft8 */
+
+ /* skipping 128 times fft16 */
+
+ /* skipping 64 times fft32 */
+
+ /* skipping 32 times fft64 */
+
+ /* skipping 16 times fft128 */
+
+ /* skipping 8 times fft256 */
+
+ /* skipping 4 times fft512 */
+
+ /* skipping 2 times fft1024 */
+
+ /* perform 1 times fft2048 */
+ gsl_power2_fft2048analysis_skip2 (X, Y);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 4096 S S S S S S S S S S X L)
+ **/
+static void
+gsl_power2_fft4096analysis_skip2 (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* skipping 2048 times fft2 */
+
+ /* skipping 1024 times fft4 */
+
+ /* skipping 512 times fft8 */
+
+ /* skipping 256 times fft16 */
+
+ /* skipping 128 times fft32 */
+
+ /* skipping 64 times fft64 */
+
+ /* skipping 32 times fft128 */
+
+ /* skipping 16 times fft256 */
+
+ /* skipping 8 times fft512 */
+
+ /* skipping 4 times fft1024 */
+
+ /* perform 2 times fft2048 */
+ gsl_power2_fft2048analysis_skip2 (X, Y);
+ gsl_power2_fft2048analysis_skip2 (X + 4096, Y + 4096);
+
+ /* perform 1 times fft4096 */
+ for (offset = 0; offset < 8192; offset += 8192) {
+ BUTTERFLY_10 (Y[offset], Y[offset + 1],
+ Y[offset + 4096], Y[offset + 4096 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 4096], Y[offset + 4096 + 1],
+ __1, __0);
+ }
+ Wre = +0.999998823451702; Wim = +0.001533980186285;
+ for (butterfly = 2; butterfly < 2048; butterfly += 2) {
+ for (block = 0; block < 8192; block += 8192) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 4096], Y[offset + 4096 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 4096], Y[offset + 4096 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, -0.000001176548298, +0.001533980186285);
+ }
+ for (offset = 2048; offset < 8192; offset += 8192) {
+ BUTTERFLY_01 (Y[offset], Y[offset + 1],
+ Y[offset + 4096], Y[offset + 4096 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 4096], Y[offset + 4096 + 1],
+ __0, __1);
+ }
+ Wre = -0.001533980186285; Wim = +0.999998823451702;
+ for (butterfly = 2050; butterfly < 4096; butterfly += 2) {
+ for (block = 0; block < 8192; block += 8192) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 4096], Y[offset + 4096 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 4096], Y[offset + 4096 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, -0.000001176548298, +0.001533980186285);
+ }
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 4096 L S S S S S S S S S S X)
+ **/
+static void
+gsl_power2_fft4096analysis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform fft2 and bitreverse input */
+ bitreverse_fft2analysis (4096, X, Y);
+
+ /* skipping 1024 times fft4 */
+
+ /* skipping 512 times fft8 */
+
+ /* skipping 256 times fft16 */
+
+ /* skipping 128 times fft32 */
+
+ /* skipping 64 times fft64 */
+
+ /* skipping 32 times fft128 */
+
+ /* skipping 16 times fft256 */
+
+ /* skipping 8 times fft512 */
+
+ /* skipping 4 times fft1024 */
+
+ /* skipping 2 times fft2048 */
+
+ /* perform 1 times fft4096 */
+ gsl_power2_fft4096analysis_skip2 (X, Y);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 8192 S S S S S S S S S S S X L)
+ **/
+static void
+gsl_power2_fft8192analysis_skip2 (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* skipping 4096 times fft2 */
+
+ /* skipping 2048 times fft4 */
+
+ /* skipping 1024 times fft8 */
+
+ /* skipping 512 times fft16 */
+
+ /* skipping 256 times fft32 */
+
+ /* skipping 128 times fft64 */
+
+ /* skipping 64 times fft128 */
+
+ /* skipping 32 times fft256 */
+
+ /* skipping 16 times fft512 */
+
+ /* skipping 8 times fft1024 */
+
+ /* skipping 4 times fft2048 */
+
+ /* perform 2 times fft4096 */
+ gsl_power2_fft4096analysis_skip2 (X, Y);
+ gsl_power2_fft4096analysis_skip2 (X + 8192, Y + 8192);
+
+ /* perform 1 times fft8192 */
+ for (offset = 0; offset < 16384; offset += 16384) {
+ BUTTERFLY_10 (Y[offset], Y[offset + 1],
+ Y[offset + 8192], Y[offset + 8192 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 8192], Y[offset + 8192 + 1],
+ __1, __0);
+ }
+ Wre = +0.999999705862882; Wim = +0.000766990318743;
+ for (butterfly = 2; butterfly < 4096; butterfly += 2) {
+ for (block = 0; block < 16384; block += 16384) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 8192], Y[offset + 8192 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 8192], Y[offset + 8192 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, -0.000000294137118, +0.000766990318743);
+ }
+ for (offset = 4096; offset < 16384; offset += 16384) {
+ BUTTERFLY_01 (Y[offset], Y[offset + 1],
+ Y[offset + 8192], Y[offset + 8192 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 8192], Y[offset + 8192 + 1],
+ __0, __1);
+ }
+ Wre = -0.000766990318743; Wim = +0.999999705862882;
+ for (butterfly = 4098; butterfly < 8192; butterfly += 2) {
+ for (block = 0; block < 16384; block += 16384) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 8192], Y[offset + 8192 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 8192], Y[offset + 8192 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, -0.000000294137118, +0.000766990318743);
+ }
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 8192 L S S S S S S S S S S S X)
+ **/
+static void
+gsl_power2_fft8192analysis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform fft2 and bitreverse input */
+ bitreverse_fft2analysis (8192, X, Y);
+
+ /* skipping 2048 times fft4 */
+
+ /* skipping 1024 times fft8 */
+
+ /* skipping 512 times fft16 */
+
+ /* skipping 256 times fft32 */
+
+ /* skipping 128 times fft64 */
+
+ /* skipping 64 times fft128 */
+
+ /* skipping 32 times fft256 */
+
+ /* skipping 16 times fft512 */
+
+ /* skipping 8 times fft1024 */
+
+ /* skipping 4 times fft2048 */
+
+ /* skipping 2 times fft4096 */
+
+ /* perform 1 times fft8192 */
+ gsl_power2_fft8192analysis_skip2 (X, Y);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 2 F)
+ **/
+static void
+gsl_power2_fft2synthesis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform 1 times fft2 */
+ BUTTERFLY_10scale (X[0], X[0 + 1],
+ X[2], X[2 + 1],
+ Y[0], Y[0 + 1],
+ Y[2], Y[2 + 1],
+ 1.0 / (double) 2);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 4 S F)
+ **/
+static void
+gsl_power2_fft4synthesis_skip2 (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* skipping 2 times fft2 */
+
+ /* perform 1 times fft4 */
+ BUTTERFLY_10 (Y[0], /* W0 */
+ Y[0 + 1],
+ Y[4],
+ Y[4 + 1],
+ Y[0],
+ Y[0 + 1],
+ Y[4],
+ Y[4 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_0m (Y[2], /* W1 */
+ Y[2 + 1],
+ Y[6],
+ Y[6 + 1],
+ Y[2],
+ Y[2 + 1],
+ Y[6],
+ Y[6 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 4 F X)
+ **/
+static void
+gsl_power2_fft4synthesis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform 2 times fft2 */
+ BUTTERFLY_10scale (X[0], X[0 + 1],
+ X[4], X[4 + 1],
+ Y[0], Y[0 + 1],
+ Y[2], Y[2 + 1],
+ 1.0 / (double) 4);
+ BUTTERFLY_10scale (X[2], X[2 + 1],
+ X[6], X[6 + 1],
+ Y[4], Y[4 + 1],
+ Y[6], Y[6 + 1],
+ 1.0 / (double) 4);
+
+ /* perform 1 times fft4 */
+ gsl_power2_fft4synthesis_skip2 (X, Y);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 8 S F F)
+ **/
+static void
+gsl_power2_fft8synthesis_skip2 (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* skipping 4 times fft2 */
+
+ /* perform 2 times fft4 */
+ BUTTERFLY_10 (Y[0], /* W0 */
+ Y[0 + 1],
+ Y[4],
+ Y[4 + 1],
+ Y[0],
+ Y[0 + 1],
+ Y[4],
+ Y[4 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[8], /* W0 */
+ Y[8 + 1],
+ Y[12],
+ Y[12 + 1],
+ Y[8],
+ Y[8 + 1],
+ Y[12],
+ Y[12 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_0m (Y[2], /* W2 */
+ Y[2 + 1],
+ Y[6],
+ Y[6 + 1],
+ Y[2],
+ Y[2 + 1],
+ Y[6],
+ Y[6 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_0m (Y[10], /* W2 */
+ Y[10 + 1],
+ Y[14],
+ Y[14 + 1],
+ Y[10],
+ Y[10 + 1],
+ Y[14],
+ Y[14 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+
+ /* perform 1 times fft8 */
+ BUTTERFLY_10 (Y[0], /* W0 */
+ Y[0 + 1],
+ Y[8],
+ Y[8 + 1],
+ Y[0],
+ Y[0 + 1],
+ Y[8],
+ Y[8 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_yY (Y[2], /* W1 */
+ Y[2 + 1],
+ Y[10],
+ Y[10 + 1],
+ Y[2],
+ Y[2 + 1],
+ Y[10],
+ Y[10 + 1],
+ (double) +0.707106781186548, (double) -0.707106781186547);
+ BUTTERFLY_0m (Y[4], /* W2 */
+ Y[4 + 1],
+ Y[12],
+ Y[12 + 1],
+ Y[4],
+ Y[4 + 1],
+ Y[12],
+ Y[12 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_XX (Y[6], /* W3 */
+ Y[6 + 1],
+ Y[14],
+ Y[14 + 1],
+ Y[6],
+ Y[6 + 1],
+ Y[14],
+ Y[14 + 1],
+ (double) -0.707106781186547, (double) -0.707106781186548);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 8 F S X)
+ **/
+static void
+gsl_power2_fft8synthesis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform 4 times fft2 */
+ BUTTERFLY_10scale (X[0], X[0 + 1],
+ X[8], X[8 + 1],
+ Y[0], Y[0 + 1],
+ Y[2], Y[2 + 1],
+ 1.0 / (double) 8);
+ BUTTERFLY_10scale (X[4], X[4 + 1],
+ X[12], X[12 + 1],
+ Y[4], Y[4 + 1],
+ Y[6], Y[6 + 1],
+ 1.0 / (double) 8);
+ BUTTERFLY_10scale (X[2], X[2 + 1],
+ X[10], X[10 + 1],
+ Y[8], Y[8 + 1],
+ Y[10], Y[10 + 1],
+ 1.0 / (double) 8);
+ BUTTERFLY_10scale (X[6], X[6 + 1],
+ X[14], X[14 + 1],
+ Y[12], Y[12 + 1],
+ Y[14], Y[14 + 1],
+ 1.0 / (double) 8);
+
+ /* skipping 2 times fft4 */
+
+ /* perform 1 times fft8 */
+ gsl_power2_fft8synthesis_skip2 (X, Y);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 16 S F F F)
+ **/
+static void
+gsl_power2_fft16synthesis_skip2 (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* skipping 8 times fft2 */
+
+ /* perform 4 times fft4 */
+ BUTTERFLY_10 (Y[0], /* W0 */
+ Y[0 + 1],
+ Y[4],
+ Y[4 + 1],
+ Y[0],
+ Y[0 + 1],
+ Y[4],
+ Y[4 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[8], /* W0 */
+ Y[8 + 1],
+ Y[12],
+ Y[12 + 1],
+ Y[8],
+ Y[8 + 1],
+ Y[12],
+ Y[12 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[16], /* W0 */
+ Y[16 + 1],
+ Y[20],
+ Y[20 + 1],
+ Y[16],
+ Y[16 + 1],
+ Y[20],
+ Y[20 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[24], /* W0 */
+ Y[24 + 1],
+ Y[28],
+ Y[28 + 1],
+ Y[24],
+ Y[24 + 1],
+ Y[28],
+ Y[28 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_0m (Y[2], /* W4 */
+ Y[2 + 1],
+ Y[6],
+ Y[6 + 1],
+ Y[2],
+ Y[2 + 1],
+ Y[6],
+ Y[6 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_0m (Y[10], /* W4 */
+ Y[10 + 1],
+ Y[14],
+ Y[14 + 1],
+ Y[10],
+ Y[10 + 1],
+ Y[14],
+ Y[14 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_0m (Y[18], /* W4 */
+ Y[18 + 1],
+ Y[22],
+ Y[22 + 1],
+ Y[18],
+ Y[18 + 1],
+ Y[22],
+ Y[22 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_0m (Y[26], /* W4 */
+ Y[26 + 1],
+ Y[30],
+ Y[30 + 1],
+ Y[26],
+ Y[26 + 1],
+ Y[30],
+ Y[30 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+
+ /* perform 2 times fft8 */
+ BUTTERFLY_10 (Y[0], /* W0 */
+ Y[0 + 1],
+ Y[8],
+ Y[8 + 1],
+ Y[0],
+ Y[0 + 1],
+ Y[8],
+ Y[8 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[16], /* W0 */
+ Y[16 + 1],
+ Y[24],
+ Y[24 + 1],
+ Y[16],
+ Y[16 + 1],
+ Y[24],
+ Y[24 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_yY (Y[2], /* W2 */
+ Y[2 + 1],
+ Y[10],
+ Y[10 + 1],
+ Y[2],
+ Y[2 + 1],
+ Y[10],
+ Y[10 + 1],
+ (double) +0.707106781186548, (double) -0.707106781186547);
+ BUTTERFLY_yY (Y[18], /* W2 */
+ Y[18 + 1],
+ Y[26],
+ Y[26 + 1],
+ Y[18],
+ Y[18 + 1],
+ Y[26],
+ Y[26 + 1],
+ (double) +0.707106781186548, (double) -0.707106781186547);
+ BUTTERFLY_0m (Y[4], /* W4 */
+ Y[4 + 1],
+ Y[12],
+ Y[12 + 1],
+ Y[4],
+ Y[4 + 1],
+ Y[12],
+ Y[12 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_0m (Y[20], /* W4 */
+ Y[20 + 1],
+ Y[28],
+ Y[28 + 1],
+ Y[20],
+ Y[20 + 1],
+ Y[28],
+ Y[28 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_XX (Y[6], /* W6 */
+ Y[6 + 1],
+ Y[14],
+ Y[14 + 1],
+ Y[6],
+ Y[6 + 1],
+ Y[14],
+ Y[14 + 1],
+ (double) -0.707106781186547, (double) -0.707106781186548);
+ BUTTERFLY_XX (Y[22], /* W6 */
+ Y[22 + 1],
+ Y[30],
+ Y[30 + 1],
+ Y[22],
+ Y[22 + 1],
+ Y[30],
+ Y[30 + 1],
+ (double) -0.707106781186547, (double) -0.707106781186548);
+
+ /* perform 1 times fft16 */
+ BUTTERFLY_10 (Y[0], /* W0 */
+ Y[0 + 1],
+ Y[16],
+ Y[16 + 1],
+ Y[0],
+ Y[0 + 1],
+ Y[16],
+ Y[16 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XY (Y[2], /* W1 */
+ Y[2 + 1],
+ Y[18],
+ Y[18 + 1],
+ Y[2],
+ Y[2 + 1],
+ Y[18],
+ Y[18 + 1],
+ (double) +0.923879532511287, (double) -0.382683432365090);
+ BUTTERFLY_yY (Y[4], /* W2 */
+ Y[4 + 1],
+ Y[20],
+ Y[20 + 1],
+ Y[4],
+ Y[4 + 1],
+ Y[20],
+ Y[20 + 1],
+ (double) +0.707106781186548, (double) -0.707106781186547);
+ BUTTERFLY_XY (Y[6], /* W3 */
+ Y[6 + 1],
+ Y[22],
+ Y[22 + 1],
+ Y[6],
+ Y[6 + 1],
+ Y[22],
+ Y[22 + 1],
+ (double) +0.382683432365090, (double) -0.923879532511287);
+ BUTTERFLY_0m (Y[8], /* W4 */
+ Y[8 + 1],
+ Y[24],
+ Y[24 + 1],
+ Y[8],
+ Y[8 + 1],
+ Y[24],
+ Y[24 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_XY (Y[10], /* W5 */
+ Y[10 + 1],
+ Y[26],
+ Y[26 + 1],
+ Y[10],
+ Y[10 + 1],
+ Y[26],
+ Y[26 + 1],
+ (double) -0.382683432365090, (double) -0.923879532511287);
+ BUTTERFLY_XX (Y[12], /* W6 */
+ Y[12 + 1],
+ Y[28],
+ Y[28 + 1],
+ Y[12],
+ Y[12 + 1],
+ Y[28],
+ Y[28 + 1],
+ (double) -0.707106781186547, (double) -0.707106781186548);
+ BUTTERFLY_XY (Y[14], /* W7 */
+ Y[14 + 1],
+ Y[30],
+ Y[30 + 1],
+ Y[14],
+ Y[14 + 1],
+ Y[30],
+ Y[30 + 1],
+ (double) -0.923879532511287, (double) -0.382683432365090);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 16 F S S X)
+ **/
+static void
+gsl_power2_fft16synthesis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform 8 times fft2 */
+ BUTTERFLY_10scale (X[0], X[0 + 1],
+ X[16], X[16 + 1],
+ Y[0], Y[0 + 1],
+ Y[2], Y[2 + 1],
+ 1.0 / (double) 16);
+ BUTTERFLY_10scale (X[8], X[8 + 1],
+ X[24], X[24 + 1],
+ Y[4], Y[4 + 1],
+ Y[6], Y[6 + 1],
+ 1.0 / (double) 16);
+ BUTTERFLY_10scale (X[4], X[4 + 1],
+ X[20], X[20 + 1],
+ Y[8], Y[8 + 1],
+ Y[10], Y[10 + 1],
+ 1.0 / (double) 16);
+ BUTTERFLY_10scale (X[12], X[12 + 1],
+ X[28], X[28 + 1],
+ Y[12], Y[12 + 1],
+ Y[14], Y[14 + 1],
+ 1.0 / (double) 16);
+ BUTTERFLY_10scale (X[2], X[2 + 1],
+ X[18], X[18 + 1],
+ Y[16], Y[16 + 1],
+ Y[18], Y[18 + 1],
+ 1.0 / (double) 16);
+ BUTTERFLY_10scale (X[10], X[10 + 1],
+ X[26], X[26 + 1],
+ Y[20], Y[20 + 1],
+ Y[22], Y[22 + 1],
+ 1.0 / (double) 16);
+ BUTTERFLY_10scale (X[6], X[6 + 1],
+ X[22], X[22 + 1],
+ Y[24], Y[24 + 1],
+ Y[26], Y[26 + 1],
+ 1.0 / (double) 16);
+ BUTTERFLY_10scale (X[14], X[14 + 1],
+ X[30], X[30 + 1],
+ Y[28], Y[28 + 1],
+ Y[30], Y[30 + 1],
+ 1.0 / (double) 16);
+
+ /* skipping 4 times fft4 */
+
+ /* skipping 2 times fft8 */
+
+ /* perform 1 times fft16 */
+ gsl_power2_fft16synthesis_skip2 (X, Y);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 32 S F F F F)
+ **/
+static void
+gsl_power2_fft32synthesis_skip2 (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* skipping 16 times fft2 */
+
+ /* perform 8 times fft4 */
+ BUTTERFLY_10 (Y[0], /* W0 */
+ Y[0 + 1],
+ Y[4],
+ Y[4 + 1],
+ Y[0],
+ Y[0 + 1],
+ Y[4],
+ Y[4 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[8], /* W0 */
+ Y[8 + 1],
+ Y[12],
+ Y[12 + 1],
+ Y[8],
+ Y[8 + 1],
+ Y[12],
+ Y[12 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[16], /* W0 */
+ Y[16 + 1],
+ Y[20],
+ Y[20 + 1],
+ Y[16],
+ Y[16 + 1],
+ Y[20],
+ Y[20 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[24], /* W0 */
+ Y[24 + 1],
+ Y[28],
+ Y[28 + 1],
+ Y[24],
+ Y[24 + 1],
+ Y[28],
+ Y[28 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[32], /* W0 */
+ Y[32 + 1],
+ Y[36],
+ Y[36 + 1],
+ Y[32],
+ Y[32 + 1],
+ Y[36],
+ Y[36 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[40], /* W0 */
+ Y[40 + 1],
+ Y[44],
+ Y[44 + 1],
+ Y[40],
+ Y[40 + 1],
+ Y[44],
+ Y[44 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[48], /* W0 */
+ Y[48 + 1],
+ Y[52],
+ Y[52 + 1],
+ Y[48],
+ Y[48 + 1],
+ Y[52],
+ Y[52 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[56], /* W0 */
+ Y[56 + 1],
+ Y[60],
+ Y[60 + 1],
+ Y[56],
+ Y[56 + 1],
+ Y[60],
+ Y[60 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_0m (Y[2], /* W8 */
+ Y[2 + 1],
+ Y[6],
+ Y[6 + 1],
+ Y[2],
+ Y[2 + 1],
+ Y[6],
+ Y[6 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_0m (Y[10], /* W8 */
+ Y[10 + 1],
+ Y[14],
+ Y[14 + 1],
+ Y[10],
+ Y[10 + 1],
+ Y[14],
+ Y[14 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_0m (Y[18], /* W8 */
+ Y[18 + 1],
+ Y[22],
+ Y[22 + 1],
+ Y[18],
+ Y[18 + 1],
+ Y[22],
+ Y[22 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_0m (Y[26], /* W8 */
+ Y[26 + 1],
+ Y[30],
+ Y[30 + 1],
+ Y[26],
+ Y[26 + 1],
+ Y[30],
+ Y[30 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_0m (Y[34], /* W8 */
+ Y[34 + 1],
+ Y[38],
+ Y[38 + 1],
+ Y[34],
+ Y[34 + 1],
+ Y[38],
+ Y[38 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_0m (Y[42], /* W8 */
+ Y[42 + 1],
+ Y[46],
+ Y[46 + 1],
+ Y[42],
+ Y[42 + 1],
+ Y[46],
+ Y[46 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_0m (Y[50], /* W8 */
+ Y[50 + 1],
+ Y[54],
+ Y[54 + 1],
+ Y[50],
+ Y[50 + 1],
+ Y[54],
+ Y[54 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_0m (Y[58], /* W8 */
+ Y[58 + 1],
+ Y[62],
+ Y[62 + 1],
+ Y[58],
+ Y[58 + 1],
+ Y[62],
+ Y[62 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+
+ /* perform 4 times fft8 */
+ BUTTERFLY_10 (Y[0], /* W0 */
+ Y[0 + 1],
+ Y[8],
+ Y[8 + 1],
+ Y[0],
+ Y[0 + 1],
+ Y[8],
+ Y[8 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[16], /* W0 */
+ Y[16 + 1],
+ Y[24],
+ Y[24 + 1],
+ Y[16],
+ Y[16 + 1],
+ Y[24],
+ Y[24 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[32], /* W0 */
+ Y[32 + 1],
+ Y[40],
+ Y[40 + 1],
+ Y[32],
+ Y[32 + 1],
+ Y[40],
+ Y[40 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[48], /* W0 */
+ Y[48 + 1],
+ Y[56],
+ Y[56 + 1],
+ Y[48],
+ Y[48 + 1],
+ Y[56],
+ Y[56 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_yY (Y[2], /* W4 */
+ Y[2 + 1],
+ Y[10],
+ Y[10 + 1],
+ Y[2],
+ Y[2 + 1],
+ Y[10],
+ Y[10 + 1],
+ (double) +0.707106781186548, (double) -0.707106781186547);
+ BUTTERFLY_yY (Y[18], /* W4 */
+ Y[18 + 1],
+ Y[26],
+ Y[26 + 1],
+ Y[18],
+ Y[18 + 1],
+ Y[26],
+ Y[26 + 1],
+ (double) +0.707106781186548, (double) -0.707106781186547);
+ BUTTERFLY_yY (Y[34], /* W4 */
+ Y[34 + 1],
+ Y[42],
+ Y[42 + 1],
+ Y[34],
+ Y[34 + 1],
+ Y[42],
+ Y[42 + 1],
+ (double) +0.707106781186548, (double) -0.707106781186547);
+ BUTTERFLY_yY (Y[50], /* W4 */
+ Y[50 + 1],
+ Y[58],
+ Y[58 + 1],
+ Y[50],
+ Y[50 + 1],
+ Y[58],
+ Y[58 + 1],
+ (double) +0.707106781186548, (double) -0.707106781186547);
+ BUTTERFLY_0m (Y[4], /* W8 */
+ Y[4 + 1],
+ Y[12],
+ Y[12 + 1],
+ Y[4],
+ Y[4 + 1],
+ Y[12],
+ Y[12 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_0m (Y[20], /* W8 */
+ Y[20 + 1],
+ Y[28],
+ Y[28 + 1],
+ Y[20],
+ Y[20 + 1],
+ Y[28],
+ Y[28 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_0m (Y[36], /* W8 */
+ Y[36 + 1],
+ Y[44],
+ Y[44 + 1],
+ Y[36],
+ Y[36 + 1],
+ Y[44],
+ Y[44 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_0m (Y[52], /* W8 */
+ Y[52 + 1],
+ Y[60],
+ Y[60 + 1],
+ Y[52],
+ Y[52 + 1],
+ Y[60],
+ Y[60 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_XX (Y[6], /* W12 */
+ Y[6 + 1],
+ Y[14],
+ Y[14 + 1],
+ Y[6],
+ Y[6 + 1],
+ Y[14],
+ Y[14 + 1],
+ (double) -0.707106781186547, (double) -0.707106781186548);
+ BUTTERFLY_XX (Y[22], /* W12 */
+ Y[22 + 1],
+ Y[30],
+ Y[30 + 1],
+ Y[22],
+ Y[22 + 1],
+ Y[30],
+ Y[30 + 1],
+ (double) -0.707106781186547, (double) -0.707106781186548);
+ BUTTERFLY_XX (Y[38], /* W12 */
+ Y[38 + 1],
+ Y[46],
+ Y[46 + 1],
+ Y[38],
+ Y[38 + 1],
+ Y[46],
+ Y[46 + 1],
+ (double) -0.707106781186547, (double) -0.707106781186548);
+ BUTTERFLY_XX (Y[54], /* W12 */
+ Y[54 + 1],
+ Y[62],
+ Y[62 + 1],
+ Y[54],
+ Y[54 + 1],
+ Y[62],
+ Y[62 + 1],
+ (double) -0.707106781186547, (double) -0.707106781186548);
+
+ /* perform 2 times fft16 */
+ BUTTERFLY_10 (Y[0], /* W0 */
+ Y[0 + 1],
+ Y[16],
+ Y[16 + 1],
+ Y[0],
+ Y[0 + 1],
+ Y[16],
+ Y[16 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_10 (Y[32], /* W0 */
+ Y[32 + 1],
+ Y[48],
+ Y[48 + 1],
+ Y[32],
+ Y[32 + 1],
+ Y[48],
+ Y[48 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XY (Y[2], /* W2 */
+ Y[2 + 1],
+ Y[18],
+ Y[18 + 1],
+ Y[2],
+ Y[2 + 1],
+ Y[18],
+ Y[18 + 1],
+ (double) +0.923879532511287, (double) -0.382683432365090);
+ BUTTERFLY_XY (Y[34], /* W2 */
+ Y[34 + 1],
+ Y[50],
+ Y[50 + 1],
+ Y[34],
+ Y[34 + 1],
+ Y[50],
+ Y[50 + 1],
+ (double) +0.923879532511287, (double) -0.382683432365090);
+ BUTTERFLY_yY (Y[4], /* W4 */
+ Y[4 + 1],
+ Y[20],
+ Y[20 + 1],
+ Y[4],
+ Y[4 + 1],
+ Y[20],
+ Y[20 + 1],
+ (double) +0.707106781186548, (double) -0.707106781186547);
+ BUTTERFLY_yY (Y[36], /* W4 */
+ Y[36 + 1],
+ Y[52],
+ Y[52 + 1],
+ Y[36],
+ Y[36 + 1],
+ Y[52],
+ Y[52 + 1],
+ (double) +0.707106781186548, (double) -0.707106781186547);
+ BUTTERFLY_XY (Y[6], /* W6 */
+ Y[6 + 1],
+ Y[22],
+ Y[22 + 1],
+ Y[6],
+ Y[6 + 1],
+ Y[22],
+ Y[22 + 1],
+ (double) +0.382683432365090, (double) -0.923879532511287);
+ BUTTERFLY_XY (Y[38], /* W6 */
+ Y[38 + 1],
+ Y[54],
+ Y[54 + 1],
+ Y[38],
+ Y[38 + 1],
+ Y[54],
+ Y[54 + 1],
+ (double) +0.382683432365090, (double) -0.923879532511287);
+ BUTTERFLY_0m (Y[8], /* W8 */
+ Y[8 + 1],
+ Y[24],
+ Y[24 + 1],
+ Y[8],
+ Y[8 + 1],
+ Y[24],
+ Y[24 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_0m (Y[40], /* W8 */
+ Y[40 + 1],
+ Y[56],
+ Y[56 + 1],
+ Y[40],
+ Y[40 + 1],
+ Y[56],
+ Y[56 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_XY (Y[10], /* W10 */
+ Y[10 + 1],
+ Y[26],
+ Y[26 + 1],
+ Y[10],
+ Y[10 + 1],
+ Y[26],
+ Y[26 + 1],
+ (double) -0.382683432365090, (double) -0.923879532511287);
+ BUTTERFLY_XY (Y[42], /* W10 */
+ Y[42 + 1],
+ Y[58],
+ Y[58 + 1],
+ Y[42],
+ Y[42 + 1],
+ Y[58],
+ Y[58 + 1],
+ (double) -0.382683432365090, (double) -0.923879532511287);
+ BUTTERFLY_XX (Y[12], /* W12 */
+ Y[12 + 1],
+ Y[28],
+ Y[28 + 1],
+ Y[12],
+ Y[12 + 1],
+ Y[28],
+ Y[28 + 1],
+ (double) -0.707106781186547, (double) -0.707106781186548);
+ BUTTERFLY_XX (Y[44], /* W12 */
+ Y[44 + 1],
+ Y[60],
+ Y[60 + 1],
+ Y[44],
+ Y[44 + 1],
+ Y[60],
+ Y[60 + 1],
+ (double) -0.707106781186547, (double) -0.707106781186548);
+ BUTTERFLY_XY (Y[14], /* W14 */
+ Y[14 + 1],
+ Y[30],
+ Y[30 + 1],
+ Y[14],
+ Y[14 + 1],
+ Y[30],
+ Y[30 + 1],
+ (double) -0.923879532511287, (double) -0.382683432365090);
+ BUTTERFLY_XY (Y[46], /* W14 */
+ Y[46 + 1],
+ Y[62],
+ Y[62 + 1],
+ Y[46],
+ Y[46 + 1],
+ Y[62],
+ Y[62 + 1],
+ (double) -0.923879532511287, (double) -0.382683432365090);
+
+ /* perform 1 times fft32 */
+ BUTTERFLY_10 (Y[0], /* W0 */
+ Y[0 + 1],
+ Y[32],
+ Y[32 + 1],
+ Y[0],
+ Y[0 + 1],
+ Y[32],
+ Y[32 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XY (Y[2], /* W1 */
+ Y[2 + 1],
+ Y[34],
+ Y[34 + 1],
+ Y[2],
+ Y[2 + 1],
+ Y[34],
+ Y[34 + 1],
+ (double) +0.980785280403230, (double) -0.195090322016128);
+ BUTTERFLY_XY (Y[4], /* W2 */
+ Y[4 + 1],
+ Y[36],
+ Y[36 + 1],
+ Y[4],
+ Y[4 + 1],
+ Y[36],
+ Y[36 + 1],
+ (double) +0.923879532511287, (double) -0.382683432365090);
+ BUTTERFLY_XY (Y[6], /* W3 */
+ Y[6 + 1],
+ Y[38],
+ Y[38 + 1],
+ Y[6],
+ Y[6 + 1],
+ Y[38],
+ Y[38 + 1],
+ (double) +0.831469612302545, (double) -0.555570233019602);
+ BUTTERFLY_yY (Y[8], /* W4 */
+ Y[8 + 1],
+ Y[40],
+ Y[40 + 1],
+ Y[8],
+ Y[8 + 1],
+ Y[40],
+ Y[40 + 1],
+ (double) +0.707106781186548, (double) -0.707106781186547);
+ BUTTERFLY_XY (Y[10], /* W5 */
+ Y[10 + 1],
+ Y[42],
+ Y[42 + 1],
+ Y[10],
+ Y[10 + 1],
+ Y[42],
+ Y[42 + 1],
+ (double) +0.555570233019602, (double) -0.831469612302545);
+ BUTTERFLY_XY (Y[12], /* W6 */
+ Y[12 + 1],
+ Y[44],
+ Y[44 + 1],
+ Y[12],
+ Y[12 + 1],
+ Y[44],
+ Y[44 + 1],
+ (double) +0.382683432365090, (double) -0.923879532511287);
+ BUTTERFLY_XY (Y[14], /* W7 */
+ Y[14 + 1],
+ Y[46],
+ Y[46 + 1],
+ Y[14],
+ Y[14 + 1],
+ Y[46],
+ Y[46 + 1],
+ (double) +0.195090322016128, (double) -0.980785280403230);
+ BUTTERFLY_0m (Y[16], /* W8 */
+ Y[16 + 1],
+ Y[48],
+ Y[48 + 1],
+ Y[16],
+ Y[16 + 1],
+ Y[48],
+ Y[48 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_XY (Y[18], /* W9 */
+ Y[18 + 1],
+ Y[50],
+ Y[50 + 1],
+ Y[18],
+ Y[18 + 1],
+ Y[50],
+ Y[50 + 1],
+ (double) -0.195090322016128, (double) -0.980785280403230);
+ BUTTERFLY_XY (Y[20], /* W10 */
+ Y[20 + 1],
+ Y[52],
+ Y[52 + 1],
+ Y[20],
+ Y[20 + 1],
+ Y[52],
+ Y[52 + 1],
+ (double) -0.382683432365090, (double) -0.923879532511287);
+ BUTTERFLY_XY (Y[22], /* W11 */
+ Y[22 + 1],
+ Y[54],
+ Y[54 + 1],
+ Y[22],
+ Y[22 + 1],
+ Y[54],
+ Y[54 + 1],
+ (double) -0.555570233019602, (double) -0.831469612302545);
+ BUTTERFLY_XX (Y[24], /* W12 */
+ Y[24 + 1],
+ Y[56],
+ Y[56 + 1],
+ Y[24],
+ Y[24 + 1],
+ Y[56],
+ Y[56 + 1],
+ (double) -0.707106781186547, (double) -0.707106781186548);
+ BUTTERFLY_XY (Y[26], /* W13 */
+ Y[26 + 1],
+ Y[58],
+ Y[58 + 1],
+ Y[26],
+ Y[26 + 1],
+ Y[58],
+ Y[58 + 1],
+ (double) -0.831469612302545, (double) -0.555570233019602);
+ BUTTERFLY_XY (Y[28], /* W14 */
+ Y[28 + 1],
+ Y[60],
+ Y[60 + 1],
+ Y[28],
+ Y[28 + 1],
+ Y[60],
+ Y[60 + 1],
+ (double) -0.923879532511287, (double) -0.382683432365090);
+ BUTTERFLY_XY (Y[30], /* W15 */
+ Y[30 + 1],
+ Y[62],
+ Y[62 + 1],
+ Y[30],
+ Y[30 + 1],
+ Y[62],
+ Y[62 + 1],
+ (double) -0.980785280403230, (double) -0.195090322016129);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 32 F S S S X)
+ **/
+static void
+gsl_power2_fft32synthesis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform 16 times fft2 */
+ BUTTERFLY_10scale (X[0], X[0 + 1],
+ X[32], X[32 + 1],
+ Y[0], Y[0 + 1],
+ Y[2], Y[2 + 1],
+ 1.0 / (double) 32);
+ BUTTERFLY_10scale (X[16], X[16 + 1],
+ X[48], X[48 + 1],
+ Y[4], Y[4 + 1],
+ Y[6], Y[6 + 1],
+ 1.0 / (double) 32);
+ BUTTERFLY_10scale (X[8], X[8 + 1],
+ X[40], X[40 + 1],
+ Y[8], Y[8 + 1],
+ Y[10], Y[10 + 1],
+ 1.0 / (double) 32);
+ BUTTERFLY_10scale (X[24], X[24 + 1],
+ X[56], X[56 + 1],
+ Y[12], Y[12 + 1],
+ Y[14], Y[14 + 1],
+ 1.0 / (double) 32);
+ BUTTERFLY_10scale (X[4], X[4 + 1],
+ X[36], X[36 + 1],
+ Y[16], Y[16 + 1],
+ Y[18], Y[18 + 1],
+ 1.0 / (double) 32);
+ BUTTERFLY_10scale (X[20], X[20 + 1],
+ X[52], X[52 + 1],
+ Y[20], Y[20 + 1],
+ Y[22], Y[22 + 1],
+ 1.0 / (double) 32);
+ BUTTERFLY_10scale (X[12], X[12 + 1],
+ X[44], X[44 + 1],
+ Y[24], Y[24 + 1],
+ Y[26], Y[26 + 1],
+ 1.0 / (double) 32);
+ BUTTERFLY_10scale (X[28], X[28 + 1],
+ X[60], X[60 + 1],
+ Y[28], Y[28 + 1],
+ Y[30], Y[30 + 1],
+ 1.0 / (double) 32);
+ BUTTERFLY_10scale (X[2], X[2 + 1],
+ X[34], X[34 + 1],
+ Y[32], Y[32 + 1],
+ Y[34], Y[34 + 1],
+ 1.0 / (double) 32);
+ BUTTERFLY_10scale (X[18], X[18 + 1],
+ X[50], X[50 + 1],
+ Y[36], Y[36 + 1],
+ Y[38], Y[38 + 1],
+ 1.0 / (double) 32);
+ BUTTERFLY_10scale (X[10], X[10 + 1],
+ X[42], X[42 + 1],
+ Y[40], Y[40 + 1],
+ Y[42], Y[42 + 1],
+ 1.0 / (double) 32);
+ BUTTERFLY_10scale (X[26], X[26 + 1],
+ X[58], X[58 + 1],
+ Y[44], Y[44 + 1],
+ Y[46], Y[46 + 1],
+ 1.0 / (double) 32);
+ BUTTERFLY_10scale (X[6], X[6 + 1],
+ X[38], X[38 + 1],
+ Y[48], Y[48 + 1],
+ Y[50], Y[50 + 1],
+ 1.0 / (double) 32);
+ BUTTERFLY_10scale (X[22], X[22 + 1],
+ X[54], X[54 + 1],
+ Y[52], Y[52 + 1],
+ Y[54], Y[54 + 1],
+ 1.0 / (double) 32);
+ BUTTERFLY_10scale (X[14], X[14 + 1],
+ X[46], X[46 + 1],
+ Y[56], Y[56 + 1],
+ Y[58], Y[58 + 1],
+ 1.0 / (double) 32);
+ BUTTERFLY_10scale (X[30], X[30 + 1],
+ X[62], X[62 + 1],
+ Y[60], Y[60 + 1],
+ Y[62], Y[62 + 1],
+ 1.0 / (double) 32);
+
+ /* skipping 8 times fft4 */
+
+ /* skipping 4 times fft8 */
+
+ /* skipping 2 times fft16 */
+
+ /* perform 1 times fft32 */
+ gsl_power2_fft32synthesis_skip2 (X, Y);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 64 S R R R R F)
+ **/
+static void
+gsl_power2_fft64synthesis_skip2 (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* skipping 32 times fft2 */
+
+ /* perform 16 times fft4 */
+ for (block = 0; block < 128; block += 8) {
+ BUTTERFLY_10 (Y[block + 0], /* W0 */
+ Y[block + 0 + 1],
+ Y[block + 4],
+ Y[block + 4 + 1],
+ Y[block + 0],
+ Y[block + 0 + 1],
+ Y[block + 4],
+ Y[block + 4 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_0m (Y[block + 2], /* W16 */
+ Y[block + 2 + 1],
+ Y[block + 6],
+ Y[block + 6 + 1],
+ Y[block + 2],
+ Y[block + 2 + 1],
+ Y[block + 6],
+ Y[block + 6 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ }
+
+ /* perform 8 times fft8 */
+ for (block = 0; block < 128; block += 16) {
+ BUTTERFLY_10 (Y[block + 0], /* W0 */
+ Y[block + 0 + 1],
+ Y[block + 8],
+ Y[block + 8 + 1],
+ Y[block + 0],
+ Y[block + 0 + 1],
+ Y[block + 8],
+ Y[block + 8 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_yY (Y[block + 2], /* W8 */
+ Y[block + 2 + 1],
+ Y[block + 10],
+ Y[block + 10 + 1],
+ Y[block + 2],
+ Y[block + 2 + 1],
+ Y[block + 10],
+ Y[block + 10 + 1],
+ (double) +0.707106781186548, (double) -0.707106781186547);
+ BUTTERFLY_0m (Y[block + 4], /* W16 */
+ Y[block + 4 + 1],
+ Y[block + 12],
+ Y[block + 12 + 1],
+ Y[block + 4],
+ Y[block + 4 + 1],
+ Y[block + 12],
+ Y[block + 12 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_XX (Y[block + 6], /* W24 */
+ Y[block + 6 + 1],
+ Y[block + 14],
+ Y[block + 14 + 1],
+ Y[block + 6],
+ Y[block + 6 + 1],
+ Y[block + 14],
+ Y[block + 14 + 1],
+ (double) -0.707106781186547, (double) -0.707106781186548);
+ }
+
+ /* perform 4 times fft16 */
+ for (block = 0; block < 128; block += 32) {
+ BUTTERFLY_10 (Y[block + 0], /* W0 */
+ Y[block + 0 + 1],
+ Y[block + 16],
+ Y[block + 16 + 1],
+ Y[block + 0],
+ Y[block + 0 + 1],
+ Y[block + 16],
+ Y[block + 16 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XY (Y[block + 2], /* W4 */
+ Y[block + 2 + 1],
+ Y[block + 18],
+ Y[block + 18 + 1],
+ Y[block + 2],
+ Y[block + 2 + 1],
+ Y[block + 18],
+ Y[block + 18 + 1],
+ (double) +0.923879532511287, (double) -0.382683432365090);
+ BUTTERFLY_yY (Y[block + 4], /* W8 */
+ Y[block + 4 + 1],
+ Y[block + 20],
+ Y[block + 20 + 1],
+ Y[block + 4],
+ Y[block + 4 + 1],
+ Y[block + 20],
+ Y[block + 20 + 1],
+ (double) +0.707106781186548, (double) -0.707106781186547);
+ BUTTERFLY_XY (Y[block + 6], /* W12 */
+ Y[block + 6 + 1],
+ Y[block + 22],
+ Y[block + 22 + 1],
+ Y[block + 6],
+ Y[block + 6 + 1],
+ Y[block + 22],
+ Y[block + 22 + 1],
+ (double) +0.382683432365090, (double) -0.923879532511287);
+ BUTTERFLY_0m (Y[block + 8], /* W16 */
+ Y[block + 8 + 1],
+ Y[block + 24],
+ Y[block + 24 + 1],
+ Y[block + 8],
+ Y[block + 8 + 1],
+ Y[block + 24],
+ Y[block + 24 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_XY (Y[block + 10], /* W20 */
+ Y[block + 10 + 1],
+ Y[block + 26],
+ Y[block + 26 + 1],
+ Y[block + 10],
+ Y[block + 10 + 1],
+ Y[block + 26],
+ Y[block + 26 + 1],
+ (double) -0.382683432365090, (double) -0.923879532511287);
+ BUTTERFLY_XX (Y[block + 12], /* W24 */
+ Y[block + 12 + 1],
+ Y[block + 28],
+ Y[block + 28 + 1],
+ Y[block + 12],
+ Y[block + 12 + 1],
+ Y[block + 28],
+ Y[block + 28 + 1],
+ (double) -0.707106781186547, (double) -0.707106781186548);
+ BUTTERFLY_XY (Y[block + 14], /* W28 */
+ Y[block + 14 + 1],
+ Y[block + 30],
+ Y[block + 30 + 1],
+ Y[block + 14],
+ Y[block + 14 + 1],
+ Y[block + 30],
+ Y[block + 30 + 1],
+ (double) -0.923879532511287, (double) -0.382683432365090);
+ }
+
+ /* perform 2 times fft32 */
+ for (block = 0; block < 128; block += 64) {
+ BUTTERFLY_10 (Y[block + 0], /* W0 */
+ Y[block + 0 + 1],
+ Y[block + 32],
+ Y[block + 32 + 1],
+ Y[block + 0],
+ Y[block + 0 + 1],
+ Y[block + 32],
+ Y[block + 32 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XY (Y[block + 2], /* W2 */
+ Y[block + 2 + 1],
+ Y[block + 34],
+ Y[block + 34 + 1],
+ Y[block + 2],
+ Y[block + 2 + 1],
+ Y[block + 34],
+ Y[block + 34 + 1],
+ (double) +0.980785280403230, (double) -0.195090322016128);
+ BUTTERFLY_XY (Y[block + 4], /* W4 */
+ Y[block + 4 + 1],
+ Y[block + 36],
+ Y[block + 36 + 1],
+ Y[block + 4],
+ Y[block + 4 + 1],
+ Y[block + 36],
+ Y[block + 36 + 1],
+ (double) +0.923879532511287, (double) -0.382683432365090);
+ BUTTERFLY_XY (Y[block + 6], /* W6 */
+ Y[block + 6 + 1],
+ Y[block + 38],
+ Y[block + 38 + 1],
+ Y[block + 6],
+ Y[block + 6 + 1],
+ Y[block + 38],
+ Y[block + 38 + 1],
+ (double) +0.831469612302545, (double) -0.555570233019602);
+ BUTTERFLY_yY (Y[block + 8], /* W8 */
+ Y[block + 8 + 1],
+ Y[block + 40],
+ Y[block + 40 + 1],
+ Y[block + 8],
+ Y[block + 8 + 1],
+ Y[block + 40],
+ Y[block + 40 + 1],
+ (double) +0.707106781186548, (double) -0.707106781186547);
+ BUTTERFLY_XY (Y[block + 10], /* W10 */
+ Y[block + 10 + 1],
+ Y[block + 42],
+ Y[block + 42 + 1],
+ Y[block + 10],
+ Y[block + 10 + 1],
+ Y[block + 42],
+ Y[block + 42 + 1],
+ (double) +0.555570233019602, (double) -0.831469612302545);
+ BUTTERFLY_XY (Y[block + 12], /* W12 */
+ Y[block + 12 + 1],
+ Y[block + 44],
+ Y[block + 44 + 1],
+ Y[block + 12],
+ Y[block + 12 + 1],
+ Y[block + 44],
+ Y[block + 44 + 1],
+ (double) +0.382683432365090, (double) -0.923879532511287);
+ BUTTERFLY_XY (Y[block + 14], /* W14 */
+ Y[block + 14 + 1],
+ Y[block + 46],
+ Y[block + 46 + 1],
+ Y[block + 14],
+ Y[block + 14 + 1],
+ Y[block + 46],
+ Y[block + 46 + 1],
+ (double) +0.195090322016128, (double) -0.980785280403230);
+ BUTTERFLY_0m (Y[block + 16], /* W16 */
+ Y[block + 16 + 1],
+ Y[block + 48],
+ Y[block + 48 + 1],
+ Y[block + 16],
+ Y[block + 16 + 1],
+ Y[block + 48],
+ Y[block + 48 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_XY (Y[block + 18], /* W18 */
+ Y[block + 18 + 1],
+ Y[block + 50],
+ Y[block + 50 + 1],
+ Y[block + 18],
+ Y[block + 18 + 1],
+ Y[block + 50],
+ Y[block + 50 + 1],
+ (double) -0.195090322016128, (double) -0.980785280403230);
+ BUTTERFLY_XY (Y[block + 20], /* W20 */
+ Y[block + 20 + 1],
+ Y[block + 52],
+ Y[block + 52 + 1],
+ Y[block + 20],
+ Y[block + 20 + 1],
+ Y[block + 52],
+ Y[block + 52 + 1],
+ (double) -0.382683432365090, (double) -0.923879532511287);
+ BUTTERFLY_XY (Y[block + 22], /* W22 */
+ Y[block + 22 + 1],
+ Y[block + 54],
+ Y[block + 54 + 1],
+ Y[block + 22],
+ Y[block + 22 + 1],
+ Y[block + 54],
+ Y[block + 54 + 1],
+ (double) -0.555570233019602, (double) -0.831469612302545);
+ BUTTERFLY_XX (Y[block + 24], /* W24 */
+ Y[block + 24 + 1],
+ Y[block + 56],
+ Y[block + 56 + 1],
+ Y[block + 24],
+ Y[block + 24 + 1],
+ Y[block + 56],
+ Y[block + 56 + 1],
+ (double) -0.707106781186547, (double) -0.707106781186548);
+ BUTTERFLY_XY (Y[block + 26], /* W26 */
+ Y[block + 26 + 1],
+ Y[block + 58],
+ Y[block + 58 + 1],
+ Y[block + 26],
+ Y[block + 26 + 1],
+ Y[block + 58],
+ Y[block + 58 + 1],
+ (double) -0.831469612302545, (double) -0.555570233019602);
+ BUTTERFLY_XY (Y[block + 28], /* W28 */
+ Y[block + 28 + 1],
+ Y[block + 60],
+ Y[block + 60 + 1],
+ Y[block + 28],
+ Y[block + 28 + 1],
+ Y[block + 60],
+ Y[block + 60 + 1],
+ (double) -0.923879532511287, (double) -0.382683432365090);
+ BUTTERFLY_XY (Y[block + 30], /* W30 */
+ Y[block + 30 + 1],
+ Y[block + 62],
+ Y[block + 62 + 1],
+ Y[block + 30],
+ Y[block + 30 + 1],
+ Y[block + 62],
+ Y[block + 62 + 1],
+ (double) -0.980785280403230, (double) -0.195090322016129);
+ }
+
+ /* perform 1 times fft64 */
+ BUTTERFLY_10 (Y[0], /* W0 */
+ Y[0 + 1],
+ Y[64],
+ Y[64 + 1],
+ Y[0],
+ Y[0 + 1],
+ Y[64],
+ Y[64 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XY (Y[2], /* W1 */
+ Y[2 + 1],
+ Y[66],
+ Y[66 + 1],
+ Y[2],
+ Y[2 + 1],
+ Y[66],
+ Y[66 + 1],
+ (double) +0.995184726672197, (double) -0.098017140329561);
+ BUTTERFLY_XY (Y[4], /* W2 */
+ Y[4 + 1],
+ Y[68],
+ Y[68 + 1],
+ Y[4],
+ Y[4 + 1],
+ Y[68],
+ Y[68 + 1],
+ (double) +0.980785280403230, (double) -0.195090322016128);
+ BUTTERFLY_XY (Y[6], /* W3 */
+ Y[6 + 1],
+ Y[70],
+ Y[70 + 1],
+ Y[6],
+ Y[6 + 1],
+ Y[70],
+ Y[70 + 1],
+ (double) +0.956940335732209, (double) -0.290284677254462);
+ BUTTERFLY_XY (Y[8], /* W4 */
+ Y[8 + 1],
+ Y[72],
+ Y[72 + 1],
+ Y[8],
+ Y[8 + 1],
+ Y[72],
+ Y[72 + 1],
+ (double) +0.923879532511287, (double) -0.382683432365090);
+ BUTTERFLY_XY (Y[10], /* W5 */
+ Y[10 + 1],
+ Y[74],
+ Y[74 + 1],
+ Y[10],
+ Y[10 + 1],
+ Y[74],
+ Y[74 + 1],
+ (double) +0.881921264348355, (double) -0.471396736825998);
+ BUTTERFLY_XY (Y[12], /* W6 */
+ Y[12 + 1],
+ Y[76],
+ Y[76 + 1],
+ Y[12],
+ Y[12 + 1],
+ Y[76],
+ Y[76 + 1],
+ (double) +0.831469612302545, (double) -0.555570233019602);
+ BUTTERFLY_XY (Y[14], /* W7 */
+ Y[14 + 1],
+ Y[78],
+ Y[78 + 1],
+ Y[14],
+ Y[14 + 1],
+ Y[78],
+ Y[78 + 1],
+ (double) +0.773010453362737, (double) -0.634393284163645);
+ BUTTERFLY_yY (Y[16], /* W8 */
+ Y[16 + 1],
+ Y[80],
+ Y[80 + 1],
+ Y[16],
+ Y[16 + 1],
+ Y[80],
+ Y[80 + 1],
+ (double) +0.707106781186548, (double) -0.707106781186547);
+ BUTTERFLY_XY (Y[18], /* W9 */
+ Y[18 + 1],
+ Y[82],
+ Y[82 + 1],
+ Y[18],
+ Y[18 + 1],
+ Y[82],
+ Y[82 + 1],
+ (double) +0.634393284163645, (double) -0.773010453362737);
+ BUTTERFLY_XY (Y[20], /* W10 */
+ Y[20 + 1],
+ Y[84],
+ Y[84 + 1],
+ Y[20],
+ Y[20 + 1],
+ Y[84],
+ Y[84 + 1],
+ (double) +0.555570233019602, (double) -0.831469612302545);
+ BUTTERFLY_XY (Y[22], /* W11 */
+ Y[22 + 1],
+ Y[86],
+ Y[86 + 1],
+ Y[22],
+ Y[22 + 1],
+ Y[86],
+ Y[86 + 1],
+ (double) +0.471396736825998, (double) -0.881921264348355);
+ BUTTERFLY_XY (Y[24], /* W12 */
+ Y[24 + 1],
+ Y[88],
+ Y[88 + 1],
+ Y[24],
+ Y[24 + 1],
+ Y[88],
+ Y[88 + 1],
+ (double) +0.382683432365090, (double) -0.923879532511287);
+ BUTTERFLY_XY (Y[26], /* W13 */
+ Y[26 + 1],
+ Y[90],
+ Y[90 + 1],
+ Y[26],
+ Y[26 + 1],
+ Y[90],
+ Y[90 + 1],
+ (double) +0.290284677254462, (double) -0.956940335732209);
+ BUTTERFLY_XY (Y[28], /* W14 */
+ Y[28 + 1],
+ Y[92],
+ Y[92 + 1],
+ Y[28],
+ Y[28 + 1],
+ Y[92],
+ Y[92 + 1],
+ (double) +0.195090322016128, (double) -0.980785280403230);
+ BUTTERFLY_XY (Y[30], /* W15 */
+ Y[30 + 1],
+ Y[94],
+ Y[94 + 1],
+ Y[30],
+ Y[30 + 1],
+ Y[94],
+ Y[94 + 1],
+ (double) +0.098017140329561, (double) -0.995184726672197);
+ BUTTERFLY_0m (Y[32], /* W16 */
+ Y[32 + 1],
+ Y[96],
+ Y[96 + 1],
+ Y[32],
+ Y[32 + 1],
+ Y[96],
+ Y[96 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_XY (Y[34], /* W17 */
+ Y[34 + 1],
+ Y[98],
+ Y[98 + 1],
+ Y[34],
+ Y[34 + 1],
+ Y[98],
+ Y[98 + 1],
+ (double) -0.098017140329561, (double) -0.995184726672197);
+ BUTTERFLY_XY (Y[36], /* W18 */
+ Y[36 + 1],
+ Y[100],
+ Y[100 + 1],
+ Y[36],
+ Y[36 + 1],
+ Y[100],
+ Y[100 + 1],
+ (double) -0.195090322016128, (double) -0.980785280403230);
+ BUTTERFLY_XY (Y[38], /* W19 */
+ Y[38 + 1],
+ Y[102],
+ Y[102 + 1],
+ Y[38],
+ Y[38 + 1],
+ Y[102],
+ Y[102 + 1],
+ (double) -0.290284677254462, (double) -0.956940335732209);
+ BUTTERFLY_XY (Y[40], /* W20 */
+ Y[40 + 1],
+ Y[104],
+ Y[104 + 1],
+ Y[40],
+ Y[40 + 1],
+ Y[104],
+ Y[104 + 1],
+ (double) -0.382683432365090, (double) -0.923879532511287);
+ BUTTERFLY_XY (Y[42], /* W21 */
+ Y[42 + 1],
+ Y[106],
+ Y[106 + 1],
+ Y[42],
+ Y[42 + 1],
+ Y[106],
+ Y[106 + 1],
+ (double) -0.471396736825998, (double) -0.881921264348355);
+ BUTTERFLY_XY (Y[44], /* W22 */
+ Y[44 + 1],
+ Y[108],
+ Y[108 + 1],
+ Y[44],
+ Y[44 + 1],
+ Y[108],
+ Y[108 + 1],
+ (double) -0.555570233019602, (double) -0.831469612302545);
+ BUTTERFLY_XY (Y[46], /* W23 */
+ Y[46 + 1],
+ Y[110],
+ Y[110 + 1],
+ Y[46],
+ Y[46 + 1],
+ Y[110],
+ Y[110 + 1],
+ (double) -0.634393284163645, (double) -0.773010453362737);
+ BUTTERFLY_XX (Y[48], /* W24 */
+ Y[48 + 1],
+ Y[112],
+ Y[112 + 1],
+ Y[48],
+ Y[48 + 1],
+ Y[112],
+ Y[112 + 1],
+ (double) -0.707106781186547, (double) -0.707106781186548);
+ BUTTERFLY_XY (Y[50], /* W25 */
+ Y[50 + 1],
+ Y[114],
+ Y[114 + 1],
+ Y[50],
+ Y[50 + 1],
+ Y[114],
+ Y[114 + 1],
+ (double) -0.773010453362737, (double) -0.634393284163645);
+ BUTTERFLY_XY (Y[52], /* W26 */
+ Y[52 + 1],
+ Y[116],
+ Y[116 + 1],
+ Y[52],
+ Y[52 + 1],
+ Y[116],
+ Y[116 + 1],
+ (double) -0.831469612302545, (double) -0.555570233019602);
+ BUTTERFLY_XY (Y[54], /* W27 */
+ Y[54 + 1],
+ Y[118],
+ Y[118 + 1],
+ Y[54],
+ Y[54 + 1],
+ Y[118],
+ Y[118 + 1],
+ (double) -0.881921264348355, (double) -0.471396736825998);
+ BUTTERFLY_XY (Y[56], /* W28 */
+ Y[56 + 1],
+ Y[120],
+ Y[120 + 1],
+ Y[56],
+ Y[56 + 1],
+ Y[120],
+ Y[120 + 1],
+ (double) -0.923879532511287, (double) -0.382683432365090);
+ BUTTERFLY_XY (Y[58], /* W29 */
+ Y[58 + 1],
+ Y[122],
+ Y[122 + 1],
+ Y[58],
+ Y[58 + 1],
+ Y[122],
+ Y[122 + 1],
+ (double) -0.956940335732209, (double) -0.290284677254462);
+ BUTTERFLY_XY (Y[60], /* W30 */
+ Y[60 + 1],
+ Y[124],
+ Y[124 + 1],
+ Y[60],
+ Y[60 + 1],
+ Y[124],
+ Y[124 + 1],
+ (double) -0.980785280403230, (double) -0.195090322016129);
+ BUTTERFLY_XY (Y[62], /* W31 */
+ Y[62 + 1],
+ Y[126],
+ Y[126 + 1],
+ Y[62],
+ Y[62 + 1],
+ Y[126],
+ Y[126 + 1],
+ (double) -0.995184726672197, (double) -0.098017140329561);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 64 F S S S S X)
+ **/
+static void
+gsl_power2_fft64synthesis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform 32 times fft2 */
+ BUTTERFLY_10scale (X[0], X[0 + 1],
+ X[64], X[64 + 1],
+ Y[0], Y[0 + 1],
+ Y[2], Y[2 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[32], X[32 + 1],
+ X[96], X[96 + 1],
+ Y[4], Y[4 + 1],
+ Y[6], Y[6 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[16], X[16 + 1],
+ X[80], X[80 + 1],
+ Y[8], Y[8 + 1],
+ Y[10], Y[10 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[48], X[48 + 1],
+ X[112], X[112 + 1],
+ Y[12], Y[12 + 1],
+ Y[14], Y[14 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[8], X[8 + 1],
+ X[72], X[72 + 1],
+ Y[16], Y[16 + 1],
+ Y[18], Y[18 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[40], X[40 + 1],
+ X[104], X[104 + 1],
+ Y[20], Y[20 + 1],
+ Y[22], Y[22 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[24], X[24 + 1],
+ X[88], X[88 + 1],
+ Y[24], Y[24 + 1],
+ Y[26], Y[26 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[56], X[56 + 1],
+ X[120], X[120 + 1],
+ Y[28], Y[28 + 1],
+ Y[30], Y[30 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[4], X[4 + 1],
+ X[68], X[68 + 1],
+ Y[32], Y[32 + 1],
+ Y[34], Y[34 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[36], X[36 + 1],
+ X[100], X[100 + 1],
+ Y[36], Y[36 + 1],
+ Y[38], Y[38 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[20], X[20 + 1],
+ X[84], X[84 + 1],
+ Y[40], Y[40 + 1],
+ Y[42], Y[42 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[52], X[52 + 1],
+ X[116], X[116 + 1],
+ Y[44], Y[44 + 1],
+ Y[46], Y[46 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[12], X[12 + 1],
+ X[76], X[76 + 1],
+ Y[48], Y[48 + 1],
+ Y[50], Y[50 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[44], X[44 + 1],
+ X[108], X[108 + 1],
+ Y[52], Y[52 + 1],
+ Y[54], Y[54 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[28], X[28 + 1],
+ X[92], X[92 + 1],
+ Y[56], Y[56 + 1],
+ Y[58], Y[58 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[60], X[60 + 1],
+ X[124], X[124 + 1],
+ Y[60], Y[60 + 1],
+ Y[62], Y[62 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[2], X[2 + 1],
+ X[66], X[66 + 1],
+ Y[64], Y[64 + 1],
+ Y[66], Y[66 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[34], X[34 + 1],
+ X[98], X[98 + 1],
+ Y[68], Y[68 + 1],
+ Y[70], Y[70 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[18], X[18 + 1],
+ X[82], X[82 + 1],
+ Y[72], Y[72 + 1],
+ Y[74], Y[74 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[50], X[50 + 1],
+ X[114], X[114 + 1],
+ Y[76], Y[76 + 1],
+ Y[78], Y[78 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[10], X[10 + 1],
+ X[74], X[74 + 1],
+ Y[80], Y[80 + 1],
+ Y[82], Y[82 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[42], X[42 + 1],
+ X[106], X[106 + 1],
+ Y[84], Y[84 + 1],
+ Y[86], Y[86 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[26], X[26 + 1],
+ X[90], X[90 + 1],
+ Y[88], Y[88 + 1],
+ Y[90], Y[90 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[58], X[58 + 1],
+ X[122], X[122 + 1],
+ Y[92], Y[92 + 1],
+ Y[94], Y[94 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[6], X[6 + 1],
+ X[70], X[70 + 1],
+ Y[96], Y[96 + 1],
+ Y[98], Y[98 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[38], X[38 + 1],
+ X[102], X[102 + 1],
+ Y[100], Y[100 + 1],
+ Y[102], Y[102 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[22], X[22 + 1],
+ X[86], X[86 + 1],
+ Y[104], Y[104 + 1],
+ Y[106], Y[106 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[54], X[54 + 1],
+ X[118], X[118 + 1],
+ Y[108], Y[108 + 1],
+ Y[110], Y[110 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[14], X[14 + 1],
+ X[78], X[78 + 1],
+ Y[112], Y[112 + 1],
+ Y[114], Y[114 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[46], X[46 + 1],
+ X[110], X[110 + 1],
+ Y[116], Y[116 + 1],
+ Y[118], Y[118 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[30], X[30 + 1],
+ X[94], X[94 + 1],
+ Y[120], Y[120 + 1],
+ Y[122], Y[122 + 1],
+ 1.0 / (double) 64);
+ BUTTERFLY_10scale (X[62], X[62 + 1],
+ X[126], X[126 + 1],
+ Y[124], Y[124 + 1],
+ Y[126], Y[126 + 1],
+ 1.0 / (double) 64);
+
+ /* skipping 16 times fft4 */
+
+ /* skipping 8 times fft8 */
+
+ /* skipping 4 times fft16 */
+
+ /* skipping 2 times fft32 */
+
+ /* perform 1 times fft64 */
+ gsl_power2_fft64synthesis_skip2 (X, Y);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 128 S R R R R R F)
+ **/
+static void
+gsl_power2_fft128synthesis_skip2 (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* skipping 64 times fft2 */
+
+ /* perform 32 times fft4 */
+ for (block = 0; block < 256; block += 8) {
+ BUTTERFLY_10 (Y[block + 0], /* W0 */
+ Y[block + 0 + 1],
+ Y[block + 4],
+ Y[block + 4 + 1],
+ Y[block + 0],
+ Y[block + 0 + 1],
+ Y[block + 4],
+ Y[block + 4 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_0m (Y[block + 2], /* W32 */
+ Y[block + 2 + 1],
+ Y[block + 6],
+ Y[block + 6 + 1],
+ Y[block + 2],
+ Y[block + 2 + 1],
+ Y[block + 6],
+ Y[block + 6 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ }
+
+ /* perform 16 times fft8 */
+ for (block = 0; block < 256; block += 16) {
+ BUTTERFLY_10 (Y[block + 0], /* W0 */
+ Y[block + 0 + 1],
+ Y[block + 8],
+ Y[block + 8 + 1],
+ Y[block + 0],
+ Y[block + 0 + 1],
+ Y[block + 8],
+ Y[block + 8 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_yY (Y[block + 2], /* W16 */
+ Y[block + 2 + 1],
+ Y[block + 10],
+ Y[block + 10 + 1],
+ Y[block + 2],
+ Y[block + 2 + 1],
+ Y[block + 10],
+ Y[block + 10 + 1],
+ (double) +0.707106781186548, (double) -0.707106781186547);
+ BUTTERFLY_0m (Y[block + 4], /* W32 */
+ Y[block + 4 + 1],
+ Y[block + 12],
+ Y[block + 12 + 1],
+ Y[block + 4],
+ Y[block + 4 + 1],
+ Y[block + 12],
+ Y[block + 12 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_XX (Y[block + 6], /* W48 */
+ Y[block + 6 + 1],
+ Y[block + 14],
+ Y[block + 14 + 1],
+ Y[block + 6],
+ Y[block + 6 + 1],
+ Y[block + 14],
+ Y[block + 14 + 1],
+ (double) -0.707106781186547, (double) -0.707106781186548);
+ }
+
+ /* perform 8 times fft16 */
+ for (block = 0; block < 256; block += 32) {
+ BUTTERFLY_10 (Y[block + 0], /* W0 */
+ Y[block + 0 + 1],
+ Y[block + 16],
+ Y[block + 16 + 1],
+ Y[block + 0],
+ Y[block + 0 + 1],
+ Y[block + 16],
+ Y[block + 16 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XY (Y[block + 2], /* W8 */
+ Y[block + 2 + 1],
+ Y[block + 18],
+ Y[block + 18 + 1],
+ Y[block + 2],
+ Y[block + 2 + 1],
+ Y[block + 18],
+ Y[block + 18 + 1],
+ (double) +0.923879532511287, (double) -0.382683432365090);
+ BUTTERFLY_yY (Y[block + 4], /* W16 */
+ Y[block + 4 + 1],
+ Y[block + 20],
+ Y[block + 20 + 1],
+ Y[block + 4],
+ Y[block + 4 + 1],
+ Y[block + 20],
+ Y[block + 20 + 1],
+ (double) +0.707106781186548, (double) -0.707106781186547);
+ BUTTERFLY_XY (Y[block + 6], /* W24 */
+ Y[block + 6 + 1],
+ Y[block + 22],
+ Y[block + 22 + 1],
+ Y[block + 6],
+ Y[block + 6 + 1],
+ Y[block + 22],
+ Y[block + 22 + 1],
+ (double) +0.382683432365090, (double) -0.923879532511287);
+ BUTTERFLY_0m (Y[block + 8], /* W32 */
+ Y[block + 8 + 1],
+ Y[block + 24],
+ Y[block + 24 + 1],
+ Y[block + 8],
+ Y[block + 8 + 1],
+ Y[block + 24],
+ Y[block + 24 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_XY (Y[block + 10], /* W40 */
+ Y[block + 10 + 1],
+ Y[block + 26],
+ Y[block + 26 + 1],
+ Y[block + 10],
+ Y[block + 10 + 1],
+ Y[block + 26],
+ Y[block + 26 + 1],
+ (double) -0.382683432365090, (double) -0.923879532511287);
+ BUTTERFLY_XX (Y[block + 12], /* W48 */
+ Y[block + 12 + 1],
+ Y[block + 28],
+ Y[block + 28 + 1],
+ Y[block + 12],
+ Y[block + 12 + 1],
+ Y[block + 28],
+ Y[block + 28 + 1],
+ (double) -0.707106781186547, (double) -0.707106781186548);
+ BUTTERFLY_XY (Y[block + 14], /* W56 */
+ Y[block + 14 + 1],
+ Y[block + 30],
+ Y[block + 30 + 1],
+ Y[block + 14],
+ Y[block + 14 + 1],
+ Y[block + 30],
+ Y[block + 30 + 1],
+ (double) -0.923879532511287, (double) -0.382683432365090);
+ }
+
+ /* perform 4 times fft32 */
+ for (block = 0; block < 256; block += 64) {
+ BUTTERFLY_10 (Y[block + 0], /* W0 */
+ Y[block + 0 + 1],
+ Y[block + 32],
+ Y[block + 32 + 1],
+ Y[block + 0],
+ Y[block + 0 + 1],
+ Y[block + 32],
+ Y[block + 32 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XY (Y[block + 2], /* W4 */
+ Y[block + 2 + 1],
+ Y[block + 34],
+ Y[block + 34 + 1],
+ Y[block + 2],
+ Y[block + 2 + 1],
+ Y[block + 34],
+ Y[block + 34 + 1],
+ (double) +0.980785280403230, (double) -0.195090322016128);
+ BUTTERFLY_XY (Y[block + 4], /* W8 */
+ Y[block + 4 + 1],
+ Y[block + 36],
+ Y[block + 36 + 1],
+ Y[block + 4],
+ Y[block + 4 + 1],
+ Y[block + 36],
+ Y[block + 36 + 1],
+ (double) +0.923879532511287, (double) -0.382683432365090);
+ BUTTERFLY_XY (Y[block + 6], /* W12 */
+ Y[block + 6 + 1],
+ Y[block + 38],
+ Y[block + 38 + 1],
+ Y[block + 6],
+ Y[block + 6 + 1],
+ Y[block + 38],
+ Y[block + 38 + 1],
+ (double) +0.831469612302545, (double) -0.555570233019602);
+ BUTTERFLY_yY (Y[block + 8], /* W16 */
+ Y[block + 8 + 1],
+ Y[block + 40],
+ Y[block + 40 + 1],
+ Y[block + 8],
+ Y[block + 8 + 1],
+ Y[block + 40],
+ Y[block + 40 + 1],
+ (double) +0.707106781186548, (double) -0.707106781186547);
+ BUTTERFLY_XY (Y[block + 10], /* W20 */
+ Y[block + 10 + 1],
+ Y[block + 42],
+ Y[block + 42 + 1],
+ Y[block + 10],
+ Y[block + 10 + 1],
+ Y[block + 42],
+ Y[block + 42 + 1],
+ (double) +0.555570233019602, (double) -0.831469612302545);
+ BUTTERFLY_XY (Y[block + 12], /* W24 */
+ Y[block + 12 + 1],
+ Y[block + 44],
+ Y[block + 44 + 1],
+ Y[block + 12],
+ Y[block + 12 + 1],
+ Y[block + 44],
+ Y[block + 44 + 1],
+ (double) +0.382683432365090, (double) -0.923879532511287);
+ BUTTERFLY_XY (Y[block + 14], /* W28 */
+ Y[block + 14 + 1],
+ Y[block + 46],
+ Y[block + 46 + 1],
+ Y[block + 14],
+ Y[block + 14 + 1],
+ Y[block + 46],
+ Y[block + 46 + 1],
+ (double) +0.195090322016128, (double) -0.980785280403230);
+ BUTTERFLY_0m (Y[block + 16], /* W32 */
+ Y[block + 16 + 1],
+ Y[block + 48],
+ Y[block + 48 + 1],
+ Y[block + 16],
+ Y[block + 16 + 1],
+ Y[block + 48],
+ Y[block + 48 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_XY (Y[block + 18], /* W36 */
+ Y[block + 18 + 1],
+ Y[block + 50],
+ Y[block + 50 + 1],
+ Y[block + 18],
+ Y[block + 18 + 1],
+ Y[block + 50],
+ Y[block + 50 + 1],
+ (double) -0.195090322016128, (double) -0.980785280403230);
+ BUTTERFLY_XY (Y[block + 20], /* W40 */
+ Y[block + 20 + 1],
+ Y[block + 52],
+ Y[block + 52 + 1],
+ Y[block + 20],
+ Y[block + 20 + 1],
+ Y[block + 52],
+ Y[block + 52 + 1],
+ (double) -0.382683432365090, (double) -0.923879532511287);
+ BUTTERFLY_XY (Y[block + 22], /* W44 */
+ Y[block + 22 + 1],
+ Y[block + 54],
+ Y[block + 54 + 1],
+ Y[block + 22],
+ Y[block + 22 + 1],
+ Y[block + 54],
+ Y[block + 54 + 1],
+ (double) -0.555570233019602, (double) -0.831469612302545);
+ BUTTERFLY_XX (Y[block + 24], /* W48 */
+ Y[block + 24 + 1],
+ Y[block + 56],
+ Y[block + 56 + 1],
+ Y[block + 24],
+ Y[block + 24 + 1],
+ Y[block + 56],
+ Y[block + 56 + 1],
+ (double) -0.707106781186547, (double) -0.707106781186548);
+ BUTTERFLY_XY (Y[block + 26], /* W52 */
+ Y[block + 26 + 1],
+ Y[block + 58],
+ Y[block + 58 + 1],
+ Y[block + 26],
+ Y[block + 26 + 1],
+ Y[block + 58],
+ Y[block + 58 + 1],
+ (double) -0.831469612302545, (double) -0.555570233019602);
+ BUTTERFLY_XY (Y[block + 28], /* W56 */
+ Y[block + 28 + 1],
+ Y[block + 60],
+ Y[block + 60 + 1],
+ Y[block + 28],
+ Y[block + 28 + 1],
+ Y[block + 60],
+ Y[block + 60 + 1],
+ (double) -0.923879532511287, (double) -0.382683432365090);
+ BUTTERFLY_XY (Y[block + 30], /* W60 */
+ Y[block + 30 + 1],
+ Y[block + 62],
+ Y[block + 62 + 1],
+ Y[block + 30],
+ Y[block + 30 + 1],
+ Y[block + 62],
+ Y[block + 62 + 1],
+ (double) -0.980785280403230, (double) -0.195090322016129);
+ }
+
+ /* perform 2 times fft64 */
+ for (block = 0; block < 256; block += 128) {
+ BUTTERFLY_10 (Y[block + 0], /* W0 */
+ Y[block + 0 + 1],
+ Y[block + 64],
+ Y[block + 64 + 1],
+ Y[block + 0],
+ Y[block + 0 + 1],
+ Y[block + 64],
+ Y[block + 64 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XY (Y[block + 2], /* W2 */
+ Y[block + 2 + 1],
+ Y[block + 66],
+ Y[block + 66 + 1],
+ Y[block + 2],
+ Y[block + 2 + 1],
+ Y[block + 66],
+ Y[block + 66 + 1],
+ (double) +0.995184726672197, (double) -0.098017140329561);
+ BUTTERFLY_XY (Y[block + 4], /* W4 */
+ Y[block + 4 + 1],
+ Y[block + 68],
+ Y[block + 68 + 1],
+ Y[block + 4],
+ Y[block + 4 + 1],
+ Y[block + 68],
+ Y[block + 68 + 1],
+ (double) +0.980785280403230, (double) -0.195090322016128);
+ BUTTERFLY_XY (Y[block + 6], /* W6 */
+ Y[block + 6 + 1],
+ Y[block + 70],
+ Y[block + 70 + 1],
+ Y[block + 6],
+ Y[block + 6 + 1],
+ Y[block + 70],
+ Y[block + 70 + 1],
+ (double) +0.956940335732209, (double) -0.290284677254462);
+ BUTTERFLY_XY (Y[block + 8], /* W8 */
+ Y[block + 8 + 1],
+ Y[block + 72],
+ Y[block + 72 + 1],
+ Y[block + 8],
+ Y[block + 8 + 1],
+ Y[block + 72],
+ Y[block + 72 + 1],
+ (double) +0.923879532511287, (double) -0.382683432365090);
+ BUTTERFLY_XY (Y[block + 10], /* W10 */
+ Y[block + 10 + 1],
+ Y[block + 74],
+ Y[block + 74 + 1],
+ Y[block + 10],
+ Y[block + 10 + 1],
+ Y[block + 74],
+ Y[block + 74 + 1],
+ (double) +0.881921264348355, (double) -0.471396736825998);
+ BUTTERFLY_XY (Y[block + 12], /* W12 */
+ Y[block + 12 + 1],
+ Y[block + 76],
+ Y[block + 76 + 1],
+ Y[block + 12],
+ Y[block + 12 + 1],
+ Y[block + 76],
+ Y[block + 76 + 1],
+ (double) +0.831469612302545, (double) -0.555570233019602);
+ BUTTERFLY_XY (Y[block + 14], /* W14 */
+ Y[block + 14 + 1],
+ Y[block + 78],
+ Y[block + 78 + 1],
+ Y[block + 14],
+ Y[block + 14 + 1],
+ Y[block + 78],
+ Y[block + 78 + 1],
+ (double) +0.773010453362737, (double) -0.634393284163645);
+ BUTTERFLY_yY (Y[block + 16], /* W16 */
+ Y[block + 16 + 1],
+ Y[block + 80],
+ Y[block + 80 + 1],
+ Y[block + 16],
+ Y[block + 16 + 1],
+ Y[block + 80],
+ Y[block + 80 + 1],
+ (double) +0.707106781186548, (double) -0.707106781186547);
+ BUTTERFLY_XY (Y[block + 18], /* W18 */
+ Y[block + 18 + 1],
+ Y[block + 82],
+ Y[block + 82 + 1],
+ Y[block + 18],
+ Y[block + 18 + 1],
+ Y[block + 82],
+ Y[block + 82 + 1],
+ (double) +0.634393284163645, (double) -0.773010453362737);
+ BUTTERFLY_XY (Y[block + 20], /* W20 */
+ Y[block + 20 + 1],
+ Y[block + 84],
+ Y[block + 84 + 1],
+ Y[block + 20],
+ Y[block + 20 + 1],
+ Y[block + 84],
+ Y[block + 84 + 1],
+ (double) +0.555570233019602, (double) -0.831469612302545);
+ BUTTERFLY_XY (Y[block + 22], /* W22 */
+ Y[block + 22 + 1],
+ Y[block + 86],
+ Y[block + 86 + 1],
+ Y[block + 22],
+ Y[block + 22 + 1],
+ Y[block + 86],
+ Y[block + 86 + 1],
+ (double) +0.471396736825998, (double) -0.881921264348355);
+ BUTTERFLY_XY (Y[block + 24], /* W24 */
+ Y[block + 24 + 1],
+ Y[block + 88],
+ Y[block + 88 + 1],
+ Y[block + 24],
+ Y[block + 24 + 1],
+ Y[block + 88],
+ Y[block + 88 + 1],
+ (double) +0.382683432365090, (double) -0.923879532511287);
+ BUTTERFLY_XY (Y[block + 26], /* W26 */
+ Y[block + 26 + 1],
+ Y[block + 90],
+ Y[block + 90 + 1],
+ Y[block + 26],
+ Y[block + 26 + 1],
+ Y[block + 90],
+ Y[block + 90 + 1],
+ (double) +0.290284677254462, (double) -0.956940335732209);
+ BUTTERFLY_XY (Y[block + 28], /* W28 */
+ Y[block + 28 + 1],
+ Y[block + 92],
+ Y[block + 92 + 1],
+ Y[block + 28],
+ Y[block + 28 + 1],
+ Y[block + 92],
+ Y[block + 92 + 1],
+ (double) +0.195090322016128, (double) -0.980785280403230);
+ BUTTERFLY_XY (Y[block + 30], /* W30 */
+ Y[block + 30 + 1],
+ Y[block + 94],
+ Y[block + 94 + 1],
+ Y[block + 30],
+ Y[block + 30 + 1],
+ Y[block + 94],
+ Y[block + 94 + 1],
+ (double) +0.098017140329561, (double) -0.995184726672197);
+ BUTTERFLY_0m (Y[block + 32], /* W32 */
+ Y[block + 32 + 1],
+ Y[block + 96],
+ Y[block + 96 + 1],
+ Y[block + 32],
+ Y[block + 32 + 1],
+ Y[block + 96],
+ Y[block + 96 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_XY (Y[block + 34], /* W34 */
+ Y[block + 34 + 1],
+ Y[block + 98],
+ Y[block + 98 + 1],
+ Y[block + 34],
+ Y[block + 34 + 1],
+ Y[block + 98],
+ Y[block + 98 + 1],
+ (double) -0.098017140329561, (double) -0.995184726672197);
+ BUTTERFLY_XY (Y[block + 36], /* W36 */
+ Y[block + 36 + 1],
+ Y[block + 100],
+ Y[block + 100 + 1],
+ Y[block + 36],
+ Y[block + 36 + 1],
+ Y[block + 100],
+ Y[block + 100 + 1],
+ (double) -0.195090322016128, (double) -0.980785280403230);
+ BUTTERFLY_XY (Y[block + 38], /* W38 */
+ Y[block + 38 + 1],
+ Y[block + 102],
+ Y[block + 102 + 1],
+ Y[block + 38],
+ Y[block + 38 + 1],
+ Y[block + 102],
+ Y[block + 102 + 1],
+ (double) -0.290284677254462, (double) -0.956940335732209);
+ BUTTERFLY_XY (Y[block + 40], /* W40 */
+ Y[block + 40 + 1],
+ Y[block + 104],
+ Y[block + 104 + 1],
+ Y[block + 40],
+ Y[block + 40 + 1],
+ Y[block + 104],
+ Y[block + 104 + 1],
+ (double) -0.382683432365090, (double) -0.923879532511287);
+ BUTTERFLY_XY (Y[block + 42], /* W42 */
+ Y[block + 42 + 1],
+ Y[block + 106],
+ Y[block + 106 + 1],
+ Y[block + 42],
+ Y[block + 42 + 1],
+ Y[block + 106],
+ Y[block + 106 + 1],
+ (double) -0.471396736825998, (double) -0.881921264348355);
+ BUTTERFLY_XY (Y[block + 44], /* W44 */
+ Y[block + 44 + 1],
+ Y[block + 108],
+ Y[block + 108 + 1],
+ Y[block + 44],
+ Y[block + 44 + 1],
+ Y[block + 108],
+ Y[block + 108 + 1],
+ (double) -0.555570233019602, (double) -0.831469612302545);
+ BUTTERFLY_XY (Y[block + 46], /* W46 */
+ Y[block + 46 + 1],
+ Y[block + 110],
+ Y[block + 110 + 1],
+ Y[block + 46],
+ Y[block + 46 + 1],
+ Y[block + 110],
+ Y[block + 110 + 1],
+ (double) -0.634393284163645, (double) -0.773010453362737);
+ BUTTERFLY_XX (Y[block + 48], /* W48 */
+ Y[block + 48 + 1],
+ Y[block + 112],
+ Y[block + 112 + 1],
+ Y[block + 48],
+ Y[block + 48 + 1],
+ Y[block + 112],
+ Y[block + 112 + 1],
+ (double) -0.707106781186547, (double) -0.707106781186548);
+ BUTTERFLY_XY (Y[block + 50], /* W50 */
+ Y[block + 50 + 1],
+ Y[block + 114],
+ Y[block + 114 + 1],
+ Y[block + 50],
+ Y[block + 50 + 1],
+ Y[block + 114],
+ Y[block + 114 + 1],
+ (double) -0.773010453362737, (double) -0.634393284163645);
+ BUTTERFLY_XY (Y[block + 52], /* W52 */
+ Y[block + 52 + 1],
+ Y[block + 116],
+ Y[block + 116 + 1],
+ Y[block + 52],
+ Y[block + 52 + 1],
+ Y[block + 116],
+ Y[block + 116 + 1],
+ (double) -0.831469612302545, (double) -0.555570233019602);
+ BUTTERFLY_XY (Y[block + 54], /* W54 */
+ Y[block + 54 + 1],
+ Y[block + 118],
+ Y[block + 118 + 1],
+ Y[block + 54],
+ Y[block + 54 + 1],
+ Y[block + 118],
+ Y[block + 118 + 1],
+ (double) -0.881921264348355, (double) -0.471396736825998);
+ BUTTERFLY_XY (Y[block + 56], /* W56 */
+ Y[block + 56 + 1],
+ Y[block + 120],
+ Y[block + 120 + 1],
+ Y[block + 56],
+ Y[block + 56 + 1],
+ Y[block + 120],
+ Y[block + 120 + 1],
+ (double) -0.923879532511287, (double) -0.382683432365090);
+ BUTTERFLY_XY (Y[block + 58], /* W58 */
+ Y[block + 58 + 1],
+ Y[block + 122],
+ Y[block + 122 + 1],
+ Y[block + 58],
+ Y[block + 58 + 1],
+ Y[block + 122],
+ Y[block + 122 + 1],
+ (double) -0.956940335732209, (double) -0.290284677254462);
+ BUTTERFLY_XY (Y[block + 60], /* W60 */
+ Y[block + 60 + 1],
+ Y[block + 124],
+ Y[block + 124 + 1],
+ Y[block + 60],
+ Y[block + 60 + 1],
+ Y[block + 124],
+ Y[block + 124 + 1],
+ (double) -0.980785280403230, (double) -0.195090322016129);
+ BUTTERFLY_XY (Y[block + 62], /* W62 */
+ Y[block + 62 + 1],
+ Y[block + 126],
+ Y[block + 126 + 1],
+ Y[block + 62],
+ Y[block + 62 + 1],
+ Y[block + 126],
+ Y[block + 126 + 1],
+ (double) -0.995184726672197, (double) -0.098017140329561);
+ }
+
+ /* perform 1 times fft128 */
+ BUTTERFLY_10 (Y[0], /* W0 */
+ Y[0 + 1],
+ Y[128],
+ Y[128 + 1],
+ Y[0],
+ Y[0 + 1],
+ Y[128],
+ Y[128 + 1],
+ (double) +1.000000000000000, (double) +0.000000000000000);
+ BUTTERFLY_XY (Y[2], /* W1 */
+ Y[2 + 1],
+ Y[130],
+ Y[130 + 1],
+ Y[2],
+ Y[2 + 1],
+ Y[130],
+ Y[130 + 1],
+ (double) +0.998795456205172, (double) -0.049067674327418);
+ BUTTERFLY_XY (Y[4], /* W2 */
+ Y[4 + 1],
+ Y[132],
+ Y[132 + 1],
+ Y[4],
+ Y[4 + 1],
+ Y[132],
+ Y[132 + 1],
+ (double) +0.995184726672197, (double) -0.098017140329561);
+ BUTTERFLY_XY (Y[6], /* W3 */
+ Y[6 + 1],
+ Y[134],
+ Y[134 + 1],
+ Y[6],
+ Y[6 + 1],
+ Y[134],
+ Y[134 + 1],
+ (double) +0.989176509964781, (double) -0.146730474455362);
+ BUTTERFLY_XY (Y[8], /* W4 */
+ Y[8 + 1],
+ Y[136],
+ Y[136 + 1],
+ Y[8],
+ Y[8 + 1],
+ Y[136],
+ Y[136 + 1],
+ (double) +0.980785280403230, (double) -0.195090322016128);
+ BUTTERFLY_XY (Y[10], /* W5 */
+ Y[10 + 1],
+ Y[138],
+ Y[138 + 1],
+ Y[10],
+ Y[10 + 1],
+ Y[138],
+ Y[138 + 1],
+ (double) +0.970031253194544, (double) -0.242980179903264);
+ BUTTERFLY_XY (Y[12], /* W6 */
+ Y[12 + 1],
+ Y[140],
+ Y[140 + 1],
+ Y[12],
+ Y[12 + 1],
+ Y[140],
+ Y[140 + 1],
+ (double) +0.956940335732209, (double) -0.290284677254462);
+ BUTTERFLY_XY (Y[14], /* W7 */
+ Y[14 + 1],
+ Y[142],
+ Y[142 + 1],
+ Y[14],
+ Y[14 + 1],
+ Y[142],
+ Y[142 + 1],
+ (double) +0.941544065183021, (double) -0.336889853392220);
+ BUTTERFLY_XY (Y[16], /* W8 */
+ Y[16 + 1],
+ Y[144],
+ Y[144 + 1],
+ Y[16],
+ Y[16 + 1],
+ Y[144],
+ Y[144 + 1],
+ (double) +0.923879532511287, (double) -0.382683432365090);
+ BUTTERFLY_XY (Y[18], /* W9 */
+ Y[18 + 1],
+ Y[146],
+ Y[146 + 1],
+ Y[18],
+ Y[18 + 1],
+ Y[146],
+ Y[146 + 1],
+ (double) +0.903989293123443, (double) -0.427555093430282);
+ BUTTERFLY_XY (Y[20], /* W10 */
+ Y[20 + 1],
+ Y[148],
+ Y[148 + 1],
+ Y[20],
+ Y[20 + 1],
+ Y[148],
+ Y[148 + 1],
+ (double) +0.881921264348355, (double) -0.471396736825998);
+ BUTTERFLY_XY (Y[22], /* W11 */
+ Y[22 + 1],
+ Y[150],
+ Y[150 + 1],
+ Y[22],
+ Y[22 + 1],
+ Y[150],
+ Y[150 + 1],
+ (double) +0.857728610000272, (double) -0.514102744193222);
+ BUTTERFLY_XY (Y[24], /* W12 */
+ Y[24 + 1],
+ Y[152],
+ Y[152 + 1],
+ Y[24],
+ Y[24 + 1],
+ Y[152],
+ Y[152 + 1],
+ (double) +0.831469612302545, (double) -0.555570233019602);
+ BUTTERFLY_XY (Y[26], /* W13 */
+ Y[26 + 1],
+ Y[154],
+ Y[154 + 1],
+ Y[26],
+ Y[26 + 1],
+ Y[154],
+ Y[154 + 1],
+ (double) +0.803207531480645, (double) -0.595699304492433);
+ BUTTERFLY_XY (Y[28], /* W14 */
+ Y[28 + 1],
+ Y[156],
+ Y[156 + 1],
+ Y[28],
+ Y[28 + 1],
+ Y[156],
+ Y[156 + 1],
+ (double) +0.773010453362737, (double) -0.634393284163645);
+ BUTTERFLY_XY (Y[30], /* W15 */
+ Y[30 + 1],
+ Y[158],
+ Y[158 + 1],
+ Y[30],
+ Y[30 + 1],
+ Y[158],
+ Y[158 + 1],
+ (double) +0.740951125354959, (double) -0.671558954847018);
+ BUTTERFLY_yY (Y[32], /* W16 */
+ Y[32 + 1],
+ Y[160],
+ Y[160 + 1],
+ Y[32],
+ Y[32 + 1],
+ Y[160],
+ Y[160 + 1],
+ (double) +0.707106781186548, (double) -0.707106781186547);
+ BUTTERFLY_XY (Y[34], /* W17 */
+ Y[34 + 1],
+ Y[162],
+ Y[162 + 1],
+ Y[34],
+ Y[34 + 1],
+ Y[162],
+ Y[162 + 1],
+ (double) +0.671558954847018, (double) -0.740951125354959);
+ BUTTERFLY_XY (Y[36], /* W18 */
+ Y[36 + 1],
+ Y[164],
+ Y[164 + 1],
+ Y[36],
+ Y[36 + 1],
+ Y[164],
+ Y[164 + 1],
+ (double) +0.634393284163645, (double) -0.773010453362737);
+ BUTTERFLY_XY (Y[38], /* W19 */
+ Y[38 + 1],
+ Y[166],
+ Y[166 + 1],
+ Y[38],
+ Y[38 + 1],
+ Y[166],
+ Y[166 + 1],
+ (double) +0.595699304492433, (double) -0.803207531480645);
+ BUTTERFLY_XY (Y[40], /* W20 */
+ Y[40 + 1],
+ Y[168],
+ Y[168 + 1],
+ Y[40],
+ Y[40 + 1],
+ Y[168],
+ Y[168 + 1],
+ (double) +0.555570233019602, (double) -0.831469612302545);
+ BUTTERFLY_XY (Y[42], /* W21 */
+ Y[42 + 1],
+ Y[170],
+ Y[170 + 1],
+ Y[42],
+ Y[42 + 1],
+ Y[170],
+ Y[170 + 1],
+ (double) +0.514102744193222, (double) -0.857728610000272);
+ BUTTERFLY_XY (Y[44], /* W22 */
+ Y[44 + 1],
+ Y[172],
+ Y[172 + 1],
+ Y[44],
+ Y[44 + 1],
+ Y[172],
+ Y[172 + 1],
+ (double) +0.471396736825998, (double) -0.881921264348355);
+ BUTTERFLY_XY (Y[46], /* W23 */
+ Y[46 + 1],
+ Y[174],
+ Y[174 + 1],
+ Y[46],
+ Y[46 + 1],
+ Y[174],
+ Y[174 + 1],
+ (double) +0.427555093430282, (double) -0.903989293123443);
+ BUTTERFLY_XY (Y[48], /* W24 */
+ Y[48 + 1],
+ Y[176],
+ Y[176 + 1],
+ Y[48],
+ Y[48 + 1],
+ Y[176],
+ Y[176 + 1],
+ (double) +0.382683432365090, (double) -0.923879532511287);
+ BUTTERFLY_XY (Y[50], /* W25 */
+ Y[50 + 1],
+ Y[178],
+ Y[178 + 1],
+ Y[50],
+ Y[50 + 1],
+ Y[178],
+ Y[178 + 1],
+ (double) +0.336889853392220, (double) -0.941544065183021);
+ BUTTERFLY_XY (Y[52], /* W26 */
+ Y[52 + 1],
+ Y[180],
+ Y[180 + 1],
+ Y[52],
+ Y[52 + 1],
+ Y[180],
+ Y[180 + 1],
+ (double) +0.290284677254462, (double) -0.956940335732209);
+ BUTTERFLY_XY (Y[54], /* W27 */
+ Y[54 + 1],
+ Y[182],
+ Y[182 + 1],
+ Y[54],
+ Y[54 + 1],
+ Y[182],
+ Y[182 + 1],
+ (double) +0.242980179903264, (double) -0.970031253194544);
+ BUTTERFLY_XY (Y[56], /* W28 */
+ Y[56 + 1],
+ Y[184],
+ Y[184 + 1],
+ Y[56],
+ Y[56 + 1],
+ Y[184],
+ Y[184 + 1],
+ (double) +0.195090322016128, (double) -0.980785280403230);
+ BUTTERFLY_XY (Y[58], /* W29 */
+ Y[58 + 1],
+ Y[186],
+ Y[186 + 1],
+ Y[58],
+ Y[58 + 1],
+ Y[186],
+ Y[186 + 1],
+ (double) +0.146730474455362, (double) -0.989176509964781);
+ BUTTERFLY_XY (Y[60], /* W30 */
+ Y[60 + 1],
+ Y[188],
+ Y[188 + 1],
+ Y[60],
+ Y[60 + 1],
+ Y[188],
+ Y[188 + 1],
+ (double) +0.098017140329561, (double) -0.995184726672197);
+ BUTTERFLY_XY (Y[62], /* W31 */
+ Y[62 + 1],
+ Y[190],
+ Y[190 + 1],
+ Y[62],
+ Y[62 + 1],
+ Y[190],
+ Y[190 + 1],
+ (double) +0.049067674327418, (double) -0.998795456205172);
+ BUTTERFLY_0m (Y[64], /* W32 */
+ Y[64 + 1],
+ Y[192],
+ Y[192 + 1],
+ Y[64],
+ Y[64 + 1],
+ Y[192],
+ Y[192 + 1],
+ (double) +0.000000000000000, (double) -1.000000000000000);
+ BUTTERFLY_XY (Y[66], /* W33 */
+ Y[66 + 1],
+ Y[194],
+ Y[194 + 1],
+ Y[66],
+ Y[66 + 1],
+ Y[194],
+ Y[194 + 1],
+ (double) -0.049067674327418, (double) -0.998795456205172);
+ BUTTERFLY_XY (Y[68], /* W34 */
+ Y[68 + 1],
+ Y[196],
+ Y[196 + 1],
+ Y[68],
+ Y[68 + 1],
+ Y[196],
+ Y[196 + 1],
+ (double) -0.098017140329561, (double) -0.995184726672197);
+ BUTTERFLY_XY (Y[70], /* W35 */
+ Y[70 + 1],
+ Y[198],
+ Y[198 + 1],
+ Y[70],
+ Y[70 + 1],
+ Y[198],
+ Y[198 + 1],
+ (double) -0.146730474455362, (double) -0.989176509964781);
+ BUTTERFLY_XY (Y[72], /* W36 */
+ Y[72 + 1],
+ Y[200],
+ Y[200 + 1],
+ Y[72],
+ Y[72 + 1],
+ Y[200],
+ Y[200 + 1],
+ (double) -0.195090322016128, (double) -0.980785280403230);
+ BUTTERFLY_XY (Y[74], /* W37 */
+ Y[74 + 1],
+ Y[202],
+ Y[202 + 1],
+ Y[74],
+ Y[74 + 1],
+ Y[202],
+ Y[202 + 1],
+ (double) -0.242980179903264, (double) -0.970031253194544);
+ BUTTERFLY_XY (Y[76], /* W38 */
+ Y[76 + 1],
+ Y[204],
+ Y[204 + 1],
+ Y[76],
+ Y[76 + 1],
+ Y[204],
+ Y[204 + 1],
+ (double) -0.290284677254462, (double) -0.956940335732209);
+ BUTTERFLY_XY (Y[78], /* W39 */
+ Y[78 + 1],
+ Y[206],
+ Y[206 + 1],
+ Y[78],
+ Y[78 + 1],
+ Y[206],
+ Y[206 + 1],
+ (double) -0.336889853392220, (double) -0.941544065183021);
+ BUTTERFLY_XY (Y[80], /* W40 */
+ Y[80 + 1],
+ Y[208],
+ Y[208 + 1],
+ Y[80],
+ Y[80 + 1],
+ Y[208],
+ Y[208 + 1],
+ (double) -0.382683432365090, (double) -0.923879532511287);
+ BUTTERFLY_XY (Y[82], /* W41 */
+ Y[82 + 1],
+ Y[210],
+ Y[210 + 1],
+ Y[82],
+ Y[82 + 1],
+ Y[210],
+ Y[210 + 1],
+ (double) -0.427555093430282, (double) -0.903989293123443);
+ BUTTERFLY_XY (Y[84], /* W42 */
+ Y[84 + 1],
+ Y[212],
+ Y[212 + 1],
+ Y[84],
+ Y[84 + 1],
+ Y[212],
+ Y[212 + 1],
+ (double) -0.471396736825998, (double) -0.881921264348355);
+ BUTTERFLY_XY (Y[86], /* W43 */
+ Y[86 + 1],
+ Y[214],
+ Y[214 + 1],
+ Y[86],
+ Y[86 + 1],
+ Y[214],
+ Y[214 + 1],
+ (double) -0.514102744193222, (double) -0.857728610000272);
+ BUTTERFLY_XY (Y[88], /* W44 */
+ Y[88 + 1],
+ Y[216],
+ Y[216 + 1],
+ Y[88],
+ Y[88 + 1],
+ Y[216],
+ Y[216 + 1],
+ (double) -0.555570233019602, (double) -0.831469612302545);
+ BUTTERFLY_XY (Y[90], /* W45 */
+ Y[90 + 1],
+ Y[218],
+ Y[218 + 1],
+ Y[90],
+ Y[90 + 1],
+ Y[218],
+ Y[218 + 1],
+ (double) -0.595699304492433, (double) -0.803207531480645);
+ BUTTERFLY_XY (Y[92], /* W46 */
+ Y[92 + 1],
+ Y[220],
+ Y[220 + 1],
+ Y[92],
+ Y[92 + 1],
+ Y[220],
+ Y[220 + 1],
+ (double) -0.634393284163645, (double) -0.773010453362737);
+ BUTTERFLY_XY (Y[94], /* W47 */
+ Y[94 + 1],
+ Y[222],
+ Y[222 + 1],
+ Y[94],
+ Y[94 + 1],
+ Y[222],
+ Y[222 + 1],
+ (double) -0.671558954847018, (double) -0.740951125354959);
+ BUTTERFLY_XX (Y[96], /* W48 */
+ Y[96 + 1],
+ Y[224],
+ Y[224 + 1],
+ Y[96],
+ Y[96 + 1],
+ Y[224],
+ Y[224 + 1],
+ (double) -0.707106781186547, (double) -0.707106781186548);
+ BUTTERFLY_XY (Y[98], /* W49 */
+ Y[98 + 1],
+ Y[226],
+ Y[226 + 1],
+ Y[98],
+ Y[98 + 1],
+ Y[226],
+ Y[226 + 1],
+ (double) -0.740951125354959, (double) -0.671558954847019);
+ BUTTERFLY_XY (Y[100], /* W50 */
+ Y[100 + 1],
+ Y[228],
+ Y[228 + 1],
+ Y[100],
+ Y[100 + 1],
+ Y[228],
+ Y[228 + 1],
+ (double) -0.773010453362737, (double) -0.634393284163645);
+ BUTTERFLY_XY (Y[102], /* W51 */
+ Y[102 + 1],
+ Y[230],
+ Y[230 + 1],
+ Y[102],
+ Y[102 + 1],
+ Y[230],
+ Y[230 + 1],
+ (double) -0.803207531480645, (double) -0.595699304492433);
+ BUTTERFLY_XY (Y[104], /* W52 */
+ Y[104 + 1],
+ Y[232],
+ Y[232 + 1],
+ Y[104],
+ Y[104 + 1],
+ Y[232],
+ Y[232 + 1],
+ (double) -0.831469612302545, (double) -0.555570233019602);
+ BUTTERFLY_XY (Y[106], /* W53 */
+ Y[106 + 1],
+ Y[234],
+ Y[234 + 1],
+ Y[106],
+ Y[106 + 1],
+ Y[234],
+ Y[234 + 1],
+ (double) -0.857728610000272, (double) -0.514102744193222);
+ BUTTERFLY_XY (Y[108], /* W54 */
+ Y[108 + 1],
+ Y[236],
+ Y[236 + 1],
+ Y[108],
+ Y[108 + 1],
+ Y[236],
+ Y[236 + 1],
+ (double) -0.881921264348355, (double) -0.471396736825998);
+ BUTTERFLY_XY (Y[110], /* W55 */
+ Y[110 + 1],
+ Y[238],
+ Y[238 + 1],
+ Y[110],
+ Y[110 + 1],
+ Y[238],
+ Y[238 + 1],
+ (double) -0.903989293123443, (double) -0.427555093430282);
+ BUTTERFLY_XY (Y[112], /* W56 */
+ Y[112 + 1],
+ Y[240],
+ Y[240 + 1],
+ Y[112],
+ Y[112 + 1],
+ Y[240],
+ Y[240 + 1],
+ (double) -0.923879532511287, (double) -0.382683432365090);
+ BUTTERFLY_XY (Y[114], /* W57 */
+ Y[114 + 1],
+ Y[242],
+ Y[242 + 1],
+ Y[114],
+ Y[114 + 1],
+ Y[242],
+ Y[242 + 1],
+ (double) -0.941544065183021, (double) -0.336889853392220);
+ BUTTERFLY_XY (Y[116], /* W58 */
+ Y[116 + 1],
+ Y[244],
+ Y[244 + 1],
+ Y[116],
+ Y[116 + 1],
+ Y[244],
+ Y[244 + 1],
+ (double) -0.956940335732209, (double) -0.290284677254462);
+ BUTTERFLY_XY (Y[118], /* W59 */
+ Y[118 + 1],
+ Y[246],
+ Y[246 + 1],
+ Y[118],
+ Y[118 + 1],
+ Y[246],
+ Y[246 + 1],
+ (double) -0.970031253194544, (double) -0.242980179903264);
+ BUTTERFLY_XY (Y[120], /* W60 */
+ Y[120 + 1],
+ Y[248],
+ Y[248 + 1],
+ Y[120],
+ Y[120 + 1],
+ Y[248],
+ Y[248 + 1],
+ (double) -0.980785280403230, (double) -0.195090322016129);
+ BUTTERFLY_XY (Y[122], /* W61 */
+ Y[122 + 1],
+ Y[250],
+ Y[250 + 1],
+ Y[122],
+ Y[122 + 1],
+ Y[250],
+ Y[250 + 1],
+ (double) -0.989176509964781, (double) -0.146730474455362);
+ BUTTERFLY_XY (Y[124], /* W62 */
+ Y[124 + 1],
+ Y[252],
+ Y[252 + 1],
+ Y[124],
+ Y[124 + 1],
+ Y[252],
+ Y[252 + 1],
+ (double) -0.995184726672197, (double) -0.098017140329561);
+ BUTTERFLY_XY (Y[126], /* W63 */
+ Y[126 + 1],
+ Y[254],
+ Y[254 + 1],
+ Y[126],
+ Y[126 + 1],
+ Y[254],
+ Y[254 + 1],
+ (double) -0.998795456205172, (double) -0.049067674327418);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 128 L S S S S S X)
+ **/
+static void
+gsl_power2_fft128synthesis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform fft2 and bitreverse input */
+ bitreverse_fft2synthesis (128, X, Y);
+
+ /* skipping 32 times fft4 */
+
+ /* skipping 16 times fft8 */
+
+ /* skipping 8 times fft16 */
+
+ /* skipping 4 times fft32 */
+
+ /* skipping 2 times fft64 */
+
+ /* perform 1 times fft128 */
+ gsl_power2_fft128synthesis_skip2 (X, Y);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 256 S S S S S S X T)
+ **/
+static void
+gsl_power2_fft256synthesis_skip2 (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* skipping 128 times fft2 */
+
+ /* skipping 64 times fft4 */
+
+ /* skipping 32 times fft8 */
+
+ /* skipping 16 times fft16 */
+
+ /* skipping 8 times fft32 */
+
+ /* skipping 4 times fft64 */
+
+ /* perform 2 times fft128 */
+ gsl_power2_fft128synthesis_skip2 (X, Y);
+ gsl_power2_fft128synthesis_skip2 (X + 256, Y + 256);
+
+ /* perform 1 times fft256 */
+ {
+ static const double Wconst256[] = {
+ +0.999698818696204, -0.024541228522912,
+ +0.998795456205172, -0.049067674327418,
+ +0.997290456678690, -0.073564563599667,
+ +0.995184726672197, -0.098017140329561,
+ +0.992479534598710, -0.122410675199216,
+ +0.989176509964781, -0.146730474455362,
+ +0.985277642388941, -0.170961888760301,
+ +0.980785280403230, -0.195090322016128,
+ +0.975702130038529, -0.219101240156870,
+ +0.970031253194544, -0.242980179903264,
+ +0.963776065795440, -0.266712757474898,
+ +0.956940335732209, -0.290284677254462,
+ +0.949528180593037, -0.313681740398892,
+ +0.941544065183021, -0.336889853392220,
+ +0.932992798834739, -0.359895036534988,
+ +0.923879532511287, -0.382683432365090,
+ +0.914209755703531, -0.405241314004990,
+ +0.903989293123443, -0.427555093430282,
+ +0.893224301195515, -0.449611329654607,
+ +0.881921264348355, -0.471396736825998,
+ +0.870086991108711, -0.492898192229784,
+ +0.857728610000272, -0.514102744193222,
+ +0.844853565249707, -0.534997619887097,
+ +0.831469612302545, -0.555570233019602,
+ +0.817584813151584, -0.575808191417845,
+ +0.803207531480645, -0.595699304492433,
+ +0.788346427626606, -0.615231590580627,
+ +0.773010453362737, -0.634393284163645,
+ +0.757208846506485, -0.653172842953777,
+ +0.740951125354959, -0.671558954847018,
+ +0.724247082951467, -0.689540544737067,
+ +0.707106781186548, -0.707106781186547,
+ +0.689540544737067, -0.724247082951467,
+ +0.671558954847018, -0.740951125354959,
+ +0.653172842953777, -0.757208846506484,
+ +0.634393284163645, -0.773010453362737,
+ +0.615231590580627, -0.788346427626606,
+ +0.595699304492433, -0.803207531480645,
+ +0.575808191417845, -0.817584813151584,
+ +0.555570233019602, -0.831469612302545,
+ +0.534997619887097, -0.844853565249707,
+ +0.514102744193222, -0.857728610000272,
+ +0.492898192229784, -0.870086991108711,
+ +0.471396736825998, -0.881921264348355,
+ +0.449611329654607, -0.893224301195515,
+ +0.427555093430282, -0.903989293123443,
+ +0.405241314004990, -0.914209755703531,
+ +0.382683432365090, -0.923879532511287,
+ +0.359895036534988, -0.932992798834739,
+ +0.336889853392220, -0.941544065183021,
+ +0.313681740398892, -0.949528180593037,
+ +0.290284677254462, -0.956940335732209,
+ +0.266712757474898, -0.963776065795440,
+ +0.242980179903264, -0.970031253194544,
+ +0.219101240156870, -0.975702130038529,
+ +0.195090322016128, -0.980785280403230,
+ +0.170961888760301, -0.985277642388941,
+ +0.146730474455362, -0.989176509964781,
+ +0.122410675199216, -0.992479534598710,
+ +0.098017140329561, -0.995184726672197,
+ +0.073564563599667, -0.997290456678690,
+ +0.049067674327418, -0.998795456205172,
+ +0.024541228522912, -0.999698818696204,
+ };
+ const double *W = Wconst256 - 2;
+ double *Z = Y + 128;
+ for (offset = 0; offset < 512; offset += 512) {
+ BUTTERFLY_10 (Y[offset], Y[offset + 1],
+ Y[offset + 256], Y[offset + 256 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 256], Y[offset + 256 + 1],
+ __1, __0);
+ BUTTERFLY_0m (Z[offset], Z[offset + 1],
+ Z[offset + 256], Z[offset + 256 + 1],
+ Z[offset], Z[offset + 1],
+ Z[offset + 256], Z[offset + 256 + 1],
+ __0, __1);
+ }
+ for (butterfly = 2; butterfly < 128; butterfly += 2) {
+ Wre = W[butterfly]; Wim = W[butterfly + 1];
+ for (block = 0; block < 512; block += 512) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 256], Y[offset + 256 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 256], Y[offset + 256 + 1],
+ Wre, Wim);
+ BUTTERFLY_yX (Z[offset], Z[offset + 1],
+ Z[offset + 256], Z[offset + 256 + 1],
+ Z[offset], Z[offset + 1],
+ Z[offset + 256], Z[offset + 256 + 1],
+ Wre, Wim);
+ }
+ }
+ }
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 256 L S S S S S S X)
+ **/
+static void
+gsl_power2_fft256synthesis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform fft2 and bitreverse input */
+ bitreverse_fft2synthesis (256, X, Y);
+
+ /* skipping 64 times fft4 */
+
+ /* skipping 32 times fft8 */
+
+ /* skipping 16 times fft16 */
+
+ /* skipping 8 times fft32 */
+
+ /* skipping 4 times fft64 */
+
+ /* skipping 2 times fft128 */
+
+ /* perform 1 times fft256 */
+ gsl_power2_fft256synthesis_skip2 (X, Y);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 512 S S S S S S X T T)
+ **/
+static void
+gsl_power2_fft512synthesis_skip2 (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* skipping 256 times fft2 */
+
+ /* skipping 128 times fft4 */
+
+ /* skipping 64 times fft8 */
+
+ /* skipping 32 times fft16 */
+
+ /* skipping 16 times fft32 */
+
+ /* skipping 8 times fft64 */
+
+ /* perform 4 times fft128 */
+ gsl_power2_fft128synthesis_skip2 (X, Y);
+ gsl_power2_fft128synthesis_skip2 (X + 256, Y + 256);
+ gsl_power2_fft128synthesis_skip2 (X + 512, Y + 512);
+ gsl_power2_fft128synthesis_skip2 (X + 768, Y + 768);
+
+ /* perform 2 times fft256 */
+ {
+ static const double Wconst256[] = {
+ +0.999698818696204, -0.024541228522912,
+ +0.998795456205172, -0.049067674327418,
+ +0.997290456678690, -0.073564563599667,
+ +0.995184726672197, -0.098017140329561,
+ +0.992479534598710, -0.122410675199216,
+ +0.989176509964781, -0.146730474455362,
+ +0.985277642388941, -0.170961888760301,
+ +0.980785280403230, -0.195090322016128,
+ +0.975702130038529, -0.219101240156870,
+ +0.970031253194544, -0.242980179903264,
+ +0.963776065795440, -0.266712757474898,
+ +0.956940335732209, -0.290284677254462,
+ +0.949528180593037, -0.313681740398892,
+ +0.941544065183021, -0.336889853392220,
+ +0.932992798834739, -0.359895036534988,
+ +0.923879532511287, -0.382683432365090,
+ +0.914209755703531, -0.405241314004990,
+ +0.903989293123443, -0.427555093430282,
+ +0.893224301195515, -0.449611329654607,
+ +0.881921264348355, -0.471396736825998,
+ +0.870086991108711, -0.492898192229784,
+ +0.857728610000272, -0.514102744193222,
+ +0.844853565249707, -0.534997619887097,
+ +0.831469612302545, -0.555570233019602,
+ +0.817584813151584, -0.575808191417845,
+ +0.803207531480645, -0.595699304492433,
+ +0.788346427626606, -0.615231590580627,
+ +0.773010453362737, -0.634393284163645,
+ +0.757208846506485, -0.653172842953777,
+ +0.740951125354959, -0.671558954847018,
+ +0.724247082951467, -0.689540544737067,
+ +0.707106781186548, -0.707106781186547,
+ +0.689540544737067, -0.724247082951467,
+ +0.671558954847018, -0.740951125354959,
+ +0.653172842953777, -0.757208846506484,
+ +0.634393284163645, -0.773010453362737,
+ +0.615231590580627, -0.788346427626606,
+ +0.595699304492433, -0.803207531480645,
+ +0.575808191417845, -0.817584813151584,
+ +0.555570233019602, -0.831469612302545,
+ +0.534997619887097, -0.844853565249707,
+ +0.514102744193222, -0.857728610000272,
+ +0.492898192229784, -0.870086991108711,
+ +0.471396736825998, -0.881921264348355,
+ +0.449611329654607, -0.893224301195515,
+ +0.427555093430282, -0.903989293123443,
+ +0.405241314004990, -0.914209755703531,
+ +0.382683432365090, -0.923879532511287,
+ +0.359895036534988, -0.932992798834739,
+ +0.336889853392220, -0.941544065183021,
+ +0.313681740398892, -0.949528180593037,
+ +0.290284677254462, -0.956940335732209,
+ +0.266712757474898, -0.963776065795440,
+ +0.242980179903264, -0.970031253194544,
+ +0.219101240156870, -0.975702130038529,
+ +0.195090322016128, -0.980785280403230,
+ +0.170961888760301, -0.985277642388941,
+ +0.146730474455362, -0.989176509964781,
+ +0.122410675199216, -0.992479534598710,
+ +0.098017140329561, -0.995184726672197,
+ +0.073564563599667, -0.997290456678690,
+ +0.049067674327418, -0.998795456205172,
+ +0.024541228522912, -0.999698818696204,
+ };
+ const double *W = Wconst256 - 2;
+ double *Z = Y + 128;
+ for (offset = 0; offset < 1024; offset += 512) {
+ BUTTERFLY_10 (Y[offset], Y[offset + 1],
+ Y[offset + 256], Y[offset + 256 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 256], Y[offset + 256 + 1],
+ __1, __0);
+ BUTTERFLY_0m (Z[offset], Z[offset + 1],
+ Z[offset + 256], Z[offset + 256 + 1],
+ Z[offset], Z[offset + 1],
+ Z[offset + 256], Z[offset + 256 + 1],
+ __0, __1);
+ }
+ for (butterfly = 2; butterfly < 128; butterfly += 2) {
+ Wre = W[butterfly]; Wim = W[butterfly + 1];
+ for (block = 0; block < 1024; block += 512) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 256], Y[offset + 256 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 256], Y[offset + 256 + 1],
+ Wre, Wim);
+ BUTTERFLY_yX (Z[offset], Z[offset + 1],
+ Z[offset + 256], Z[offset + 256 + 1],
+ Z[offset], Z[offset + 1],
+ Z[offset + 256], Z[offset + 256 + 1],
+ Wre, Wim);
+ }
+ }
+ }
+
+ /* perform 1 times fft512 */
+ {
+ static const double Wconst512[] = {
+ +0.999924701839145, -0.012271538285720,
+ +0.999698818696204, -0.024541228522912,
+ +0.999322384588350, -0.036807222941359,
+ +0.998795456205172, -0.049067674327418,
+ +0.998118112900149, -0.061320736302209,
+ +0.997290456678690, -0.073564563599667,
+ +0.996312612182778, -0.085797312344440,
+ +0.995184726672197, -0.098017140329561,
+ +0.993906970002356, -0.110222207293883,
+ +0.992479534598710, -0.122410675199216,
+ +0.990902635427780, -0.134580708507126,
+ +0.989176509964781, -0.146730474455362,
+ +0.987301418157858, -0.158858143333861,
+ +0.985277642388941, -0.170961888760301,
+ +0.983105487431216, -0.183039887955141,
+ +0.980785280403230, -0.195090322016128,
+ +0.978317370719628, -0.207111376192219,
+ +0.975702130038529, -0.219101240156870,
+ +0.972939952205560, -0.231058108280671,
+ +0.970031253194544, -0.242980179903264,
+ +0.966976471044852, -0.254865659604515,
+ +0.963776065795440, -0.266712757474898,
+ +0.960430519415566, -0.278519689385053,
+ +0.956940335732209, -0.290284677254462,
+ +0.953306040354194, -0.302005949319228,
+ +0.949528180593037, -0.313681740398892,
+ +0.945607325380521, -0.325310292162263,
+ +0.941544065183021, -0.336889853392220,
+ +0.937339011912575, -0.348418680249435,
+ +0.932992798834739, -0.359895036534988,
+ +0.928506080473216, -0.371317193951838,
+ +0.923879532511287, -0.382683432365090,
+ +0.919113851690058, -0.393992040061048,
+ +0.914209755703531, -0.405241314004990,
+ +0.909167983090522, -0.416429560097637,
+ +0.903989293123443, -0.427555093430282,
+ +0.898674465693954, -0.438616238538528,
+ +0.893224301195515, -0.449611329654607,
+ +0.887639620402854, -0.460538710958240,
+ +0.881921264348355, -0.471396736825998,
+ +0.876070094195407, -0.482183772079123,
+ +0.870086991108711, -0.492898192229784,
+ +0.863972856121587, -0.503538383725718,
+ +0.857728610000272, -0.514102744193222,
+ +0.851355193105265, -0.524589682678469,
+ +0.844853565249707, -0.534997619887097,
+ +0.838224705554838, -0.545324988422046,
+ +0.831469612302545, -0.555570233019602,
+ +0.824589302785025, -0.565731810783613,
+ +0.817584813151584, -0.575808191417845,
+ +0.810457198252595, -0.585797857456439,
+ +0.803207531480645, -0.595699304492433,
+ +0.795836904608884, -0.605511041404326,
+ +0.788346427626606, -0.615231590580627,
+ +0.780737228572094, -0.624859488142386,
+ +0.773010453362737, -0.634393284163645,
+ +0.765167265622459, -0.643831542889791,
+ +0.757208846506485, -0.653172842953777,
+ +0.749136394523459, -0.662415777590172,
+ +0.740951125354959, -0.671558954847018,
+ +0.732654271672413, -0.680600997795453,
+ +0.724247082951467, -0.689540544737067,
+ +0.715730825283819, -0.698376249408973,
+ +0.707106781186548, -0.707106781186547,
+ +0.698376249408973, -0.715730825283819,
+ +0.689540544737067, -0.724247082951467,
+ +0.680600997795453, -0.732654271672413,
+ +0.671558954847018, -0.740951125354959,
+ +0.662415777590172, -0.749136394523459,
+ +0.653172842953777, -0.757208846506484,
+ +0.643831542889791, -0.765167265622459,
+ +0.634393284163645, -0.773010453362737,
+ +0.624859488142386, -0.780737228572094,
+ +0.615231590580627, -0.788346427626606,
+ +0.605511041404326, -0.795836904608883,
+ +0.595699304492433, -0.803207531480645,
+ +0.585797857456439, -0.810457198252595,
+ +0.575808191417845, -0.817584813151584,
+ +0.565731810783613, -0.824589302785025,
+ +0.555570233019602, -0.831469612302545,
+ +0.545324988422046, -0.838224705554838,
+ +0.534997619887097, -0.844853565249707,
+ +0.524589682678469, -0.851355193105265,
+ +0.514102744193222, -0.857728610000272,
+ +0.503538383725718, -0.863972856121587,
+ +0.492898192229784, -0.870086991108711,
+ +0.482183772079123, -0.876070094195407,
+ +0.471396736825998, -0.881921264348355,
+ +0.460538710958240, -0.887639620402854,
+ +0.449611329654607, -0.893224301195515,
+ +0.438616238538528, -0.898674465693954,
+ +0.427555093430282, -0.903989293123443,
+ +0.416429560097637, -0.909167983090522,
+ +0.405241314004990, -0.914209755703531,
+ +0.393992040061048, -0.919113851690058,
+ +0.382683432365090, -0.923879532511287,
+ +0.371317193951838, -0.928506080473215,
+ +0.359895036534988, -0.932992798834739,
+ +0.348418680249435, -0.937339011912575,
+ +0.336889853392220, -0.941544065183021,
+ +0.325310292162263, -0.945607325380521,
+ +0.313681740398892, -0.949528180593037,
+ +0.302005949319228, -0.953306040354194,
+ +0.290284677254462, -0.956940335732209,
+ +0.278519689385053, -0.960430519415566,
+ +0.266712757474898, -0.963776065795440,
+ +0.254865659604515, -0.966976471044852,
+ +0.242980179903264, -0.970031253194544,
+ +0.231058108280671, -0.972939952205560,
+ +0.219101240156870, -0.975702130038529,
+ +0.207111376192219, -0.978317370719628,
+ +0.195090322016128, -0.980785280403230,
+ +0.183039887955141, -0.983105487431216,
+ +0.170961888760301, -0.985277642388941,
+ +0.158858143333861, -0.987301418157858,
+ +0.146730474455362, -0.989176509964781,
+ +0.134580708507126, -0.990902635427780,
+ +0.122410675199216, -0.992479534598710,
+ +0.110222207293883, -0.993906970002356,
+ +0.098017140329561, -0.995184726672197,
+ +0.085797312344440, -0.996312612182778,
+ +0.073564563599667, -0.997290456678690,
+ +0.061320736302209, -0.998118112900149,
+ +0.049067674327418, -0.998795456205172,
+ +0.036807222941359, -0.999322384588350,
+ +0.024541228522912, -0.999698818696204,
+ +0.012271538285720, -0.999924701839145,
+ };
+ const double *W = Wconst512 - 2;
+ double *Z = Y + 256;
+ for (offset = 0; offset < 1024; offset += 1024) {
+ BUTTERFLY_10 (Y[offset], Y[offset + 1],
+ Y[offset + 512], Y[offset + 512 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 512], Y[offset + 512 + 1],
+ __1, __0);
+ BUTTERFLY_0m (Z[offset], Z[offset + 1],
+ Z[offset + 512], Z[offset + 512 + 1],
+ Z[offset], Z[offset + 1],
+ Z[offset + 512], Z[offset + 512 + 1],
+ __0, __1);
+ }
+ for (butterfly = 2; butterfly < 256; butterfly += 2) {
+ Wre = W[butterfly]; Wim = W[butterfly + 1];
+ for (block = 0; block < 1024; block += 1024) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 512], Y[offset + 512 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 512], Y[offset + 512 + 1],
+ Wre, Wim);
+ BUTTERFLY_yX (Z[offset], Z[offset + 1],
+ Z[offset + 512], Z[offset + 512 + 1],
+ Z[offset], Z[offset + 1],
+ Z[offset + 512], Z[offset + 512 + 1],
+ Wre, Wim);
+ }
+ }
+ }
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 512 L S S S S S S S X)
+ **/
+static void
+gsl_power2_fft512synthesis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform fft2 and bitreverse input */
+ bitreverse_fft2synthesis (512, X, Y);
+
+ /* skipping 128 times fft4 */
+
+ /* skipping 64 times fft8 */
+
+ /* skipping 32 times fft16 */
+
+ /* skipping 16 times fft32 */
+
+ /* skipping 8 times fft64 */
+
+ /* skipping 4 times fft128 */
+
+ /* skipping 2 times fft256 */
+
+ /* perform 1 times fft512 */
+ gsl_power2_fft512synthesis_skip2 (X, Y);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 1024 S S S S S S S S X L)
+ **/
+static void
+gsl_power2_fft1024synthesis_skip2 (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* skipping 512 times fft2 */
+
+ /* skipping 256 times fft4 */
+
+ /* skipping 128 times fft8 */
+
+ /* skipping 64 times fft16 */
+
+ /* skipping 32 times fft32 */
+
+ /* skipping 16 times fft64 */
+
+ /* skipping 8 times fft128 */
+
+ /* skipping 4 times fft256 */
+
+ /* perform 2 times fft512 */
+ gsl_power2_fft512synthesis_skip2 (X, Y);
+ gsl_power2_fft512synthesis_skip2 (X + 1024, Y + 1024);
+
+ /* perform 1 times fft1024 */
+ for (offset = 0; offset < 2048; offset += 2048) {
+ BUTTERFLY_10 (Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ __1, __0);
+ }
+ Wre = +0.999981175282601; Wim = -0.006135884649154;
+ for (butterfly = 2; butterfly < 512; butterfly += 2) {
+ for (block = 0; block < 2048; block += 2048) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, -0.000018824717399, -0.006135884649154);
+ }
+ for (offset = 512; offset < 2048; offset += 2048) {
+ BUTTERFLY_0m (Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ __0, __1);
+ }
+ Wre = -0.006135884649154; Wim = -0.999981175282601;
+ for (butterfly = 514; butterfly < 1024; butterfly += 2) {
+ for (block = 0; block < 2048; block += 2048) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, -0.000018824717399, -0.006135884649154);
+ }
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 1024 L S S S S S S S S X)
+ **/
+static void
+gsl_power2_fft1024synthesis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform fft2 and bitreverse input */
+ bitreverse_fft2synthesis (1024, X, Y);
+
+ /* skipping 256 times fft4 */
+
+ /* skipping 128 times fft8 */
+
+ /* skipping 64 times fft16 */
+
+ /* skipping 32 times fft32 */
+
+ /* skipping 16 times fft64 */
+
+ /* skipping 8 times fft128 */
+
+ /* skipping 4 times fft256 */
+
+ /* skipping 2 times fft512 */
+
+ /* perform 1 times fft1024 */
+ gsl_power2_fft1024synthesis_skip2 (X, Y);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 2048 S S S S S S S S X L L)
+ **/
+static void
+gsl_power2_fft2048synthesis_skip2 (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* skipping 1024 times fft2 */
+
+ /* skipping 512 times fft4 */
+
+ /* skipping 256 times fft8 */
+
+ /* skipping 128 times fft16 */
+
+ /* skipping 64 times fft32 */
+
+ /* skipping 32 times fft64 */
+
+ /* skipping 16 times fft128 */
+
+ /* skipping 8 times fft256 */
+
+ /* perform 4 times fft512 */
+ gsl_power2_fft512synthesis_skip2 (X, Y);
+ gsl_power2_fft512synthesis_skip2 (X + 1024, Y + 1024);
+ gsl_power2_fft512synthesis_skip2 (X + 2048, Y + 2048);
+ gsl_power2_fft512synthesis_skip2 (X + 3072, Y + 3072);
+
+ /* perform 2 times fft1024 */
+ for (offset = 0; offset < 4096; offset += 2048) {
+ BUTTERFLY_10 (Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ __1, __0);
+ }
+ Wre = +0.999981175282601; Wim = -0.006135884649154;
+ for (butterfly = 2; butterfly < 512; butterfly += 2) {
+ for (block = 0; block < 4096; block += 2048) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, -0.000018824717399, -0.006135884649154);
+ }
+ for (offset = 512; offset < 4096; offset += 2048) {
+ BUTTERFLY_0m (Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ __0, __1);
+ }
+ Wre = -0.006135884649154; Wim = -0.999981175282601;
+ for (butterfly = 514; butterfly < 1024; butterfly += 2) {
+ for (block = 0; block < 4096; block += 2048) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 1024], Y[offset + 1024 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, -0.000018824717399, -0.006135884649154);
+ }
+
+ /* perform 1 times fft2048 */
+ for (offset = 0; offset < 4096; offset += 4096) {
+ BUTTERFLY_10 (Y[offset], Y[offset + 1],
+ Y[offset + 2048], Y[offset + 2048 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 2048], Y[offset + 2048 + 1],
+ __1, __0);
+ }
+ Wre = +0.999995293809576; Wim = -0.003067956762966;
+ for (butterfly = 2; butterfly < 1024; butterfly += 2) {
+ for (block = 0; block < 4096; block += 4096) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 2048], Y[offset + 2048 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 2048], Y[offset + 2048 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, -0.000004706190424, -0.003067956762966);
+ }
+ for (offset = 1024; offset < 4096; offset += 4096) {
+ BUTTERFLY_0m (Y[offset], Y[offset + 1],
+ Y[offset + 2048], Y[offset + 2048 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 2048], Y[offset + 2048 + 1],
+ __0, __1);
+ }
+ Wre = -0.003067956762966; Wim = -0.999995293809576;
+ for (butterfly = 1026; butterfly < 2048; butterfly += 2) {
+ for (block = 0; block < 4096; block += 4096) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 2048], Y[offset + 2048 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 2048], Y[offset + 2048 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, -0.000004706190424, -0.003067956762966);
+ }
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 2048 L S S S S S S S S S X)
+ **/
+static void
+gsl_power2_fft2048synthesis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform fft2 and bitreverse input */
+ bitreverse_fft2synthesis (2048, X, Y);
+
+ /* skipping 512 times fft4 */
+
+ /* skipping 256 times fft8 */
+
+ /* skipping 128 times fft16 */
+
+ /* skipping 64 times fft32 */
+
+ /* skipping 32 times fft64 */
+
+ /* skipping 16 times fft128 */
+
+ /* skipping 8 times fft256 */
+
+ /* skipping 4 times fft512 */
+
+ /* skipping 2 times fft1024 */
+
+ /* perform 1 times fft2048 */
+ gsl_power2_fft2048synthesis_skip2 (X, Y);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 4096 S S S S S S S S S S X L)
+ **/
+static void
+gsl_power2_fft4096synthesis_skip2 (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* skipping 2048 times fft2 */
+
+ /* skipping 1024 times fft4 */
+
+ /* skipping 512 times fft8 */
+
+ /* skipping 256 times fft16 */
+
+ /* skipping 128 times fft32 */
+
+ /* skipping 64 times fft64 */
+
+ /* skipping 32 times fft128 */
+
+ /* skipping 16 times fft256 */
+
+ /* skipping 8 times fft512 */
+
+ /* skipping 4 times fft1024 */
+
+ /* perform 2 times fft2048 */
+ gsl_power2_fft2048synthesis_skip2 (X, Y);
+ gsl_power2_fft2048synthesis_skip2 (X + 4096, Y + 4096);
+
+ /* perform 1 times fft4096 */
+ for (offset = 0; offset < 8192; offset += 8192) {
+ BUTTERFLY_10 (Y[offset], Y[offset + 1],
+ Y[offset + 4096], Y[offset + 4096 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 4096], Y[offset + 4096 + 1],
+ __1, __0);
+ }
+ Wre = +0.999998823451702; Wim = -0.001533980186285;
+ for (butterfly = 2; butterfly < 2048; butterfly += 2) {
+ for (block = 0; block < 8192; block += 8192) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 4096], Y[offset + 4096 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 4096], Y[offset + 4096 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, -0.000001176548298, -0.001533980186285);
+ }
+ for (offset = 2048; offset < 8192; offset += 8192) {
+ BUTTERFLY_0m (Y[offset], Y[offset + 1],
+ Y[offset + 4096], Y[offset + 4096 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 4096], Y[offset + 4096 + 1],
+ __0, __1);
+ }
+ Wre = -0.001533980186285; Wim = -0.999998823451702;
+ for (butterfly = 2050; butterfly < 4096; butterfly += 2) {
+ for (block = 0; block < 8192; block += 8192) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 4096], Y[offset + 4096 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 4096], Y[offset + 4096 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, -0.000001176548298, -0.001533980186285);
+ }
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 4096 L S S S S S S S S S S X)
+ **/
+static void
+gsl_power2_fft4096synthesis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform fft2 and bitreverse input */
+ bitreverse_fft2synthesis (4096, X, Y);
+
+ /* skipping 1024 times fft4 */
+
+ /* skipping 512 times fft8 */
+
+ /* skipping 256 times fft16 */
+
+ /* skipping 128 times fft32 */
+
+ /* skipping 64 times fft64 */
+
+ /* skipping 32 times fft128 */
+
+ /* skipping 16 times fft256 */
+
+ /* skipping 8 times fft512 */
+
+ /* skipping 4 times fft1024 */
+
+ /* skipping 2 times fft2048 */
+
+ /* perform 1 times fft4096 */
+ gsl_power2_fft4096synthesis_skip2 (X, Y);
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 8192 S S S S S S S S S S S X L)
+ **/
+static void
+gsl_power2_fft8192synthesis_skip2 (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* skipping 4096 times fft2 */
+
+ /* skipping 2048 times fft4 */
+
+ /* skipping 1024 times fft8 */
+
+ /* skipping 512 times fft16 */
+
+ /* skipping 256 times fft32 */
+
+ /* skipping 128 times fft64 */
+
+ /* skipping 64 times fft128 */
+
+ /* skipping 32 times fft256 */
+
+ /* skipping 16 times fft512 */
+
+ /* skipping 8 times fft1024 */
+
+ /* skipping 4 times fft2048 */
+
+ /* perform 2 times fft4096 */
+ gsl_power2_fft4096synthesis_skip2 (X, Y);
+ gsl_power2_fft4096synthesis_skip2 (X + 8192, Y + 8192);
+
+ /* perform 1 times fft8192 */
+ for (offset = 0; offset < 16384; offset += 16384) {
+ BUTTERFLY_10 (Y[offset], Y[offset + 1],
+ Y[offset + 8192], Y[offset + 8192 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 8192], Y[offset + 8192 + 1],
+ __1, __0);
+ }
+ Wre = +0.999999705862882; Wim = -0.000766990318743;
+ for (butterfly = 2; butterfly < 4096; butterfly += 2) {
+ for (block = 0; block < 16384; block += 16384) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 8192], Y[offset + 8192 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 8192], Y[offset + 8192 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, -0.000000294137118, -0.000766990318743);
+ }
+ for (offset = 4096; offset < 16384; offset += 16384) {
+ BUTTERFLY_0m (Y[offset], Y[offset + 1],
+ Y[offset + 8192], Y[offset + 8192 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 8192], Y[offset + 8192 + 1],
+ __0, __1);
+ }
+ Wre = -0.000766990318743; Wim = -0.999999705862882;
+ for (butterfly = 4098; butterfly < 8192; butterfly += 2) {
+ for (block = 0; block < 16384; block += 16384) {
+ offset = butterfly + block;
+ BUTTERFLY_XY (Y[offset], Y[offset + 1],
+ Y[offset + 8192], Y[offset + 8192 + 1],
+ Y[offset], Y[offset + 1],
+ Y[offset + 8192], Y[offset + 8192 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, -0.000000294137118, -0.000766990318743);
+ }
+}
+
+/**
+ ** Generated data ends here
+ **/
+/**
+ ** Generated data (by gsl-genfft 8192 L S S S S S S S S S S S X)
+ **/
+static void
+gsl_power2_fft8192synthesis (const double *X, double *Y)
+{
+ register unsigned int butterfly, block, offset;
+ register double Wre, Wim;
+
+ butterfly = block = offset = 0, Wre = Wim = 0.0; /* silence compiler */
+
+ /* perform fft2 and bitreverse input */
+ bitreverse_fft2synthesis (8192, X, Y);
+
+ /* skipping 2048 times fft4 */
+
+ /* skipping 1024 times fft8 */
+
+ /* skipping 512 times fft16 */
+
+ /* skipping 256 times fft32 */
+
+ /* skipping 128 times fft64 */
+
+ /* skipping 64 times fft128 */
+
+ /* skipping 32 times fft256 */
+
+ /* skipping 16 times fft512 */
+
+ /* skipping 8 times fft1024 */
+
+ /* skipping 4 times fft2048 */
+
+ /* skipping 2 times fft4096 */
+
+ /* perform 1 times fft8192 */
+ gsl_power2_fft8192synthesis_skip2 (X, Y);
+}
+
+/**
+ ** Generated data ends here
+ **/
+
+
+/* public FFT frontends and generic handling of huge fft sizes */
+
+
+static void
+gsl_power2_fftc_big (const unsigned int n_values,
+ const double *rivalues_in,
+ double *rivalues,
+ const int esign)
+{
+ const unsigned int n_values2 = n_values << 1;
+ double theta = esign < 0 ? -3.1415926535897932384626433832795029 : 3.1415926535897932384626433832795029;
+ unsigned int i, block_size = 8192 << 1;
+ double last_sin;
+
+ if (esign > 0)
+ {
+ if (rivalues_in)
+ bitreverse_fft2analysis (n_values, rivalues_in, rivalues);
+ for (i = 0; i < n_values; i += 8192)
+ gsl_power2_fft8192analysis_skip2 (rivalues + (i << 1), rivalues + (i << 1));
+ }
+ else
+ {
+ if (rivalues_in)
+ bitreverse_fft2synthesis (n_values, rivalues_in, rivalues);
+ for (i = 0; i < n_values; i += 8192)
+ gsl_power2_fft8192synthesis_skip2 (rivalues + (i << 1), rivalues + (i << 1));
+ }
+ theta *= (double) 1.0 / 8192.;
+ last_sin = sin (theta);
+
+ /* we're not combining the first and second halves coefficients
+ * in the below loop, since for fft sizes beyond 8192, it'd actually
+ * harm performance due to paging
+ */
+ do
+ {
+ double Dre, Dim, Wre, Wim;
+ unsigned int k, i, half_block = block_size >> 1;
+ unsigned int block_size2 = block_size << 1;
+
+ theta *= 0.5;
+ Dim = last_sin;
+ last_sin = sin (theta);
+ Dre = last_sin * last_sin * -2.;
+
+ /* loop over first coefficient in each block ==> w == {1,0} */
+ for (i = 0; i < n_values2; i += block_size2)
+ {
+ unsigned int v1 = i, v2 = i + block_size;
+
+ BUTTERFLY_10 (rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ __1, __0);
+ }
+ Wre = Dre + 1.0; /* update Wk */
+ Wim = Dim; /* update Wk */
+ /* loop for every Wk in the first half of each subblock */
+ for (k = 2; k < half_block; k += 2)
+ {
+ /* loop over kth coefficient in each block */
+ for (i = k; i < n_values2; i += block_size2)
+ {
+ unsigned int v1 = i, v2 = i + block_size;
+
+ BUTTERFLY_XY (rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, Dre, Dim); /* update Wk */
+ }
+ /* handle middle coefficient ==> w == {0,+-1} */
+ if (k < block_size)
+ {
+ /* loop over kth coefficient in each block */
+ if (esign > 0)
+ for (i = k; i < n_values2; i += block_size2)
+ {
+ unsigned int v1 = i, v2 = i + block_size;
+
+ BUTTERFLY_01 (rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ __0, __1);
+ }
+ else
+ for (i = k; i < n_values2; i += block_size2)
+ {
+ unsigned int v1 = i, v2 = i + block_size;
+
+ BUTTERFLY_0m (rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ __0, __1);
+ }
+ /* update Wk */
+ if (esign > 0)
+ {
+ Wre = -Dim;
+ Wim = Dre + 1.0;
+ }
+ else
+ {
+ Wre = Dim;
+ Wim = -Dre - 1.0;
+ }
+ k += 2;
+ }
+ /* loop for every Wk in the second half of each subblock */
+ for (; k < block_size; k += 2)
+ {
+ /* loop over kth coefficient in each block */
+ for (i = k; i < n_values2; i += block_size2)
+ {
+ unsigned int v1 = i, v2 = i + block_size;
+
+ BUTTERFLY_XY (rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, Dre, Dim); /* update Wk */
+ }
+ block_size = block_size2;
+ }
+ while (block_size <= n_values);
+}
+void
+gsl_power2_fftac (const unsigned int n_values,
+ const double *rivalues_in,
+ double *rivalues_out)
+{
+ g_return_if_fail ((n_values & (n_values - 1)) == 0 && n_values >= 1);
+
+ switch (n_values)
+ {
+ case 1: rivalues_out[0] = rivalues_in[0], rivalues_out[1] = rivalues_in[1]; break;
+ case 2: gsl_power2_fft2analysis (rivalues_in, rivalues_out); break;
+ case 4: gsl_power2_fft4analysis (rivalues_in, rivalues_out); break;
+ case 8: gsl_power2_fft8analysis (rivalues_in, rivalues_out); break;
+ case 16: gsl_power2_fft16analysis (rivalues_in, rivalues_out); break;
+ case 32: gsl_power2_fft32analysis (rivalues_in, rivalues_out); break;
+ case 64: gsl_power2_fft64analysis (rivalues_in, rivalues_out); break;
+ case 128: gsl_power2_fft128analysis (rivalues_in, rivalues_out); break;
+ case 256: gsl_power2_fft256analysis (rivalues_in, rivalues_out); break;
+ case 512: gsl_power2_fft512analysis (rivalues_in, rivalues_out); break;
+ case 1024: gsl_power2_fft1024analysis (rivalues_in, rivalues_out); break;
+ case 2048: gsl_power2_fft2048analysis (rivalues_in, rivalues_out); break;
+ case 4096: gsl_power2_fft4096analysis (rivalues_in, rivalues_out); break;
+ case 8192: gsl_power2_fft8192analysis (rivalues_in, rivalues_out); break;
+ default: gsl_power2_fftc_big (n_values, rivalues_in, rivalues_out, +1);
+ }
+}
+void
+gsl_power2_fftsc (const unsigned int n_values,
+ const double *rivalues_in,
+ double *rivalues_out)
+{
+ g_return_if_fail ((n_values & (n_values - 1)) == 0 && n_values >= 1);
+
+ switch (n_values)
+ {
+ case 1: rivalues_out[0] = rivalues_in[0], rivalues_out[1] = rivalues_in[1]; break;
+ case 2: gsl_power2_fft2synthesis (rivalues_in, rivalues_out); break;
+ case 4: gsl_power2_fft4synthesis (rivalues_in, rivalues_out); break;
+ case 8: gsl_power2_fft8synthesis (rivalues_in, rivalues_out); break;
+ case 16: gsl_power2_fft16synthesis (rivalues_in, rivalues_out); break;
+ case 32: gsl_power2_fft32synthesis (rivalues_in, rivalues_out); break;
+ case 64: gsl_power2_fft64synthesis (rivalues_in, rivalues_out); break;
+ case 128: gsl_power2_fft128synthesis (rivalues_in, rivalues_out); break;
+ case 256: gsl_power2_fft256synthesis (rivalues_in, rivalues_out); break;
+ case 512: gsl_power2_fft512synthesis (rivalues_in, rivalues_out); break;
+ case 1024: gsl_power2_fft1024synthesis (rivalues_in, rivalues_out); break;
+ case 2048: gsl_power2_fft2048synthesis (rivalues_in, rivalues_out); break;
+ case 4096: gsl_power2_fft4096synthesis (rivalues_in, rivalues_out); break;
+ case 8192: gsl_power2_fft8192synthesis (rivalues_in, rivalues_out); break;
+ default: gsl_power2_fftc_big (n_values, rivalues_in, rivalues_out, -1);
+ }
+ /* { unsigned int i; for (i = 0; i < n_values << 1; i++) rivalues_out[i] *= (double) n_values; } */
+}
+void
+gsl_power2_fftar (const unsigned int n_values,
+ const double *r_values_in,
+ double *rivalues_out)
+{
+ unsigned int n_cvalues = n_values >> 1;
+ double Dre, Dim, Wre, Wim, theta;
+ unsigned int i;
+
+ g_return_if_fail ((n_values & (n_values - 1)) == 0 && n_values >= 2);
+
+ gsl_power2_fftac (n_cvalues, r_values_in, rivalues_out);
+ theta = 3.1415926535897932384626433832795029;
+ theta /= (double) n_cvalues;
+
+ Dre = sin (0.5 * theta);
+ Dim = sin (theta);
+ Dre = Dre * Dre;
+ Wre = 0.5 - Dre;
+ Dre *= -2.;
+ Wim = Dim * 0.5;
+ for (i = 2; i < n_values >> 1; i += 2)
+ {
+ double F1re, F1im, F2re, F2im, H1re, H1im, H2re, H2im;
+ unsigned int r = n_values - i;
+ double FEre = rivalues_out[i] + rivalues_out[r];
+ double FEim = rivalues_out[i + 1] - rivalues_out[r + 1];
+ double FOre = rivalues_out[r] - rivalues_out[i];
+ double FOim = rivalues_out[r + 1] + rivalues_out[i + 1];
+
+ FEre *= 0.5;
+ FEim *= 0.5;
+ F2re = FOre * Wim;
+ F2im = FOim * Wim;
+ F1re = FOre * Wre;
+ F1im = FOim * Wre;
+
+ H1im = F2im + F1re;
+ H1re = F1im - F2re;
+ H2re = F2re - F1im;
+ H2im = H1im - FEim;
+ H1re += FEre;
+ H2re += FEre;
+ H1im += FEim;
+ rivalues_out[i] = H1re;
+ rivalues_out[i + 1] = H1im;
+ rivalues_out[r] = H2re;
+ rivalues_out[r + 1] = H2im;
+ WMULTIPLY (Wre, Wim, Dre, Dim);
+ }
+ Dre = rivalues_out[0];
+ rivalues_out[0] = Dre + rivalues_out[1];
+ rivalues_out[1] = Dre - rivalues_out[1];
+}
+void
+gsl_power2_fftsr (const unsigned int n_values,
+ const double *rivalues_in,
+ double *r_values_out)
+{
+ unsigned int n_cvalues = n_values >> 1;
+ double Dre, Dim, Wre, Wim, theta, scale;
+ unsigned int i, ri;
+
+ g_return_if_fail ((n_values & (n_values - 1)) == 0 && n_values >= 2);
+
+ theta = -3.1415926535897932384626433832795029;
+ theta /= (double) n_cvalues;
+
+ Dre = sin (0.5 * theta);
+ Dim = sin (theta);
+ Dre = Dre * Dre;
+ Wre = 0.5 - Dre;
+ Dre *= -2.;
+ Wim = Dim * 0.5;
+ for (i = 2, ri = 0; i < n_values >> 1; i += 2)
+ {
+ double F1re, F1im, F2re, F2im, H1re, H1im, H2re, H2im;
+ unsigned int g = n_values - i, j = n_values >> 2, rg = n_values - (ri << 1) - 2;
+ double FEre = rivalues_in[i] + rivalues_in[g];
+ double FEim = rivalues_in[i + 1] - rivalues_in[g + 1];
+ double FOre = rivalues_in[g] - rivalues_in[i];
+ double FOim = rivalues_in[g + 1] + rivalues_in[i + 1];
+
+ while (ri >= j)
+ {
+ ri -= j;
+ j >>= 1;
+ }
+ ri |= j;
+
+ FOre = -FOre;
+ FOim = -FOim;
+ FEre *= 0.5;
+ FEim *= 0.5;
+ F2re = FOre * Wim;
+ F2im = FOim * Wim;
+ F1re = FOre * Wre;
+ F1im = FOim * Wre;
+
+ H1im = F2im + F1re;
+ H1re = F1im - F2re;
+ H2re = F2re - F1im;
+ H2im = H1im - FEim;
+ H1re += FEre;
+ H2re += FEre;
+ H1im += FEim;
+
+ j = ri << 1;
+ r_values_out[j] = H1re;
+ r_values_out[j + 1] = H1im;
+ r_values_out[rg] = H2re;
+ r_values_out[rg + 1] = H2im;
+ WMULTIPLY (Wre, Wim, Dre, Dim);
+ }
+ Dre = rivalues_in[0];
+ r_values_out[0] = Dre + rivalues_in[1];
+ r_values_out[1] = Dre - rivalues_in[1];
+ r_values_out[0] *= 0.5;
+ r_values_out[1] *= 0.5;
+ if (n_values < 4)
+ return;
+ r_values_out[2] = rivalues_in[i];
+ r_values_out[2 + 1] = rivalues_in[i + 1];
+ scale = n_cvalues;
+ scale = 1.0 / scale;
+ for (i = 0; i < n_values; i += 4)
+ BUTTERFLY_10scale (r_values_out[i], r_values_out[i + 1],
+ r_values_out[i + 2], r_values_out[i + 3],
+ r_values_out[i], r_values_out[i + 1],
+ r_values_out[i + 2], r_values_out[i + 3],
+ scale);
+ switch (n_cvalues)
+ {
+ case 2: break;
+ case 4: gsl_power2_fft4synthesis_skip2 (NULL, r_values_out); break;
+ case 8: gsl_power2_fft8synthesis_skip2 (NULL, r_values_out); break;
+ case 16: gsl_power2_fft16synthesis_skip2 (NULL, r_values_out); break;
+ case 32: gsl_power2_fft32synthesis_skip2 (NULL, r_values_out); break;
+ case 64: gsl_power2_fft64synthesis_skip2 (NULL, r_values_out); break;
+ case 128: gsl_power2_fft128synthesis_skip2 (NULL, r_values_out); break;
+ case 256: gsl_power2_fft256synthesis_skip2 (NULL, r_values_out); break;
+ case 512: gsl_power2_fft512synthesis_skip2 (NULL, r_values_out); break;
+ case 1024: gsl_power2_fft1024synthesis_skip2 (NULL, r_values_out); break;
+ case 2048: gsl_power2_fft2048synthesis_skip2 (NULL, r_values_out); break;
+ case 4096: gsl_power2_fft4096synthesis_skip2 (NULL, r_values_out); break;
+ case 8192: gsl_power2_fft8192synthesis_skip2 (NULL, r_values_out); break;
+ default: gsl_power2_fftc_big (n_cvalues, NULL, r_values_out, -1);
+ }
+}
+void
+gsl_power2_fftar_simple (const unsigned int n_values,
+ const float *real_values,
+ float *complex_values)
+{
+ double *rv, *cv;
+ guint i;
+
+ g_return_if_fail ((n_values & (n_values - 1)) == 0 && n_values >= 2);
+
+ rv = g_new (double, n_values * 2);
+ cv = rv + n_values;
+ i = n_values;
+ while (i--)
+ rv[i] = real_values[i];
+ gsl_power2_fftar (n_values, rv, cv);
+ i = n_values;
+ while (i--)
+ complex_values[i] = cv[i];
+ complex_values[n_values] = complex_values[1];
+ complex_values[1] = 0.0;
+ complex_values[n_values + 1] = 0.0;
+ g_free (rv);
+}
+void
+gsl_power2_fftsr_simple (const unsigned int n_values,
+ const float *complex_values,
+ float *real_values)
+{
+ double *cv, *rv;
+ guint i;
+
+ g_return_if_fail ((n_values & (n_values - 1)) == 0 && n_values >= 2);
+
+ cv = g_new (double, n_values * 2);
+ rv = cv + n_values;
+ i = n_values;
+ while (i--)
+ cv[i] = complex_values[i];
+ cv[1] = complex_values[n_values];
+ gsl_power2_fftsr (n_values, cv, rv);
+ i = n_values;
+ while (i--)
+ real_values[i] = rv[i];
+ g_free (cv);
+}
diff --git a/flow/gsl/gslfft.h b/flow/gsl/gslfft.h
new file mode 100644
index 0000000..63e3892
--- /dev/null
+++ b/flow/gsl/gslfft.h
@@ -0,0 +1,126 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001 Tim Janik
+ *
+ * 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.
+ */
+#ifndef __GSL_FFT_H__
+#define __GSL_FFT_H__
+
+#include <gsl/gsldefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/**
+ * gsl_power2_fftac
+ * @n_values: Number of complex values
+ * @ri_values_in: Complex sample values [0..n_values*2-1]
+ * @ri_values_out: Complex frequency values [0..n_values*2-1]
+ * This function performs a decimation in time fourier transformation
+ * in forward direction, where the input values are equidistant sampled
+ * data, and the output values contain the frequency proportions of the
+ * input.
+ * The input and output arrays are complex values with real and imaginery
+ * portions interleaved, adressable in the range [0..2*n_values-1], where
+ * n_values must be a power of two.
+ * Frequencies are stored in-order, the K-th output corresponds to the
+ * frequency K/n_values. (If you want to interpret negative frequencies,
+ * note that the frequencies -K/n_values and (n_values-K)/n_values are
+ * equivalent).
+ * Note that the transformation is performed out of place, the input
+ * array is not modified, and may not overlap with the output array.
+ */
+void gsl_power2_fftac (const unsigned int n_values,
+ const double *ri_values_in,
+ double *ri_values_out);
+
+/**
+ * gsl_power2_fftsc
+ * @n_values: Number of complex values
+ * @ri_values_in: Complex frequency values [0..n_values*2-1]
+ * @ri_values_out: Complex sample values [0..n_values*2-1]
+ * This function performs a decimation in time fourier transformation
+ * in backwards direction with normalization. As such, this function
+ * represents the counterpart to gsl_power2_fftac(), that is, a value
+ * array which is transformed into the frequency domain with
+ * gsl_power2_fftac() can be reconstructed by issuing gsl_power2_fftsc()
+ * on the transform.
+ * Note that the transformation is performed out of place, the input
+ * array is not modified, and may not overlap with the output array.
+ */
+void gsl_power2_fftsc (const unsigned int n_values,
+ const double *ri_values_in,
+ double *ri_values_out);
+
+/**
+ * gsl_power2_fftar
+ * @n_values: Number of complex values
+ * @r_values_in: Real sample values [0..n_values-1]
+ * @ri_values_out: Complex frequency values [0..n_values-1]
+ * Real valued variant of gsl_power2_fftac(), the input array contains
+ * real valued equidistant sampled data [0..n_values-1], and the output
+ * array contains the positive frequency half of the complex valued
+ * fourier transform. Note, that the complex valued fourier transform H
+ * of a purely real valued set of data, satisfies H(-f) = Conj(H(f)),
+ * where Conj() denotes the complex conjugate, so that just the positive
+ * frequency half suffices to describe the entire frequency spectrum.
+ * Even so, the resulting n_values/2 complex frequencies are one value
+ * off in storage size, but the resulting frequencies H(0) and
+ * H(n_values/2) are both real valued, so the real portion of
+ * H(n_values/2) is stored in ri_values_out[1] (the imaginery part of
+ * H(0)), so that both r_values_in and ri_values_out can be of size
+ * n_values.
+ * Note that the transformation is performed out of place, the input
+ * array is not modified, and may not overlap with the output array.
+ */
+void gsl_power2_fftar (const unsigned int n_values,
+ const double *r_values_in,
+ double *ri_values_out);
+
+/**
+ * gsl_power2_fftsr
+ * @n_values: Number of complex values
+ * @ri_values_in: Complex frequency values [0..n_values-1]
+ * @r_values_out: Real sample values [0..n_values-1]
+ * Real valued variant of gsl_power2_fftsc(), counterpart to
+ * gsl_power2_fftar(), using the same frequency storage format.
+ * A real valued data set transformed into the frequency domain
+ * with gsl_power2_fftar() can be reconstructed using this function.
+ * Note that the transformation is performed out of place, the input
+ * array is not modified, and may not overlap with the output array.
+ */
+void gsl_power2_fftsr (const unsigned int n_values,
+ const double *ri_values_in,
+ double *r_values_out);
+
+
+/* --- convenience wrappers --- */
+void gsl_power2_fftar_simple (const unsigned int n_values,
+ const float *real_values,
+ float *complex_values);
+void gsl_power2_fftsr_simple (const unsigned int n_values,
+ const float *complex_values,
+ float *real_values);
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_FFT_H__ */ /* vim:set ts=8 sw=2 sts=2: */
diff --git a/flow/gsl/gslffttest.c b/flow/gsl/gslffttest.c
new file mode 100644
index 0000000..a568bc5
--- /dev/null
+++ b/flow/gsl/gslffttest.c
@@ -0,0 +1,435 @@
+/* GSL-GENFFT - Power2 FFT C Code Generator
+ * Copyright (C) 2001 Tim Janik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <gsl/gslcommon.h>
+#include <gsl/gslmath.h>
+#include <gsl/gslfft.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#define MAX_FFT_SIZE (65536 * 2)
+#define EPSILON (4.8e-6)
+
+
+/* --- prototypes --- */
+static void reference_power2_fftc (unsigned int n_values,
+ const double *rivalues_in,
+ double *rivalues_out,
+ int esign);
+static void fill_rand (guint n,
+ double *a);
+static double diff (guint m,
+ guint p,
+ double *a1,
+ double *a2,
+ const gchar *str);
+
+
+/* --- variables --- */
+static double ref_fft_in[MAX_FFT_SIZE] = { 0, };
+static double ref_fft_aout[MAX_FFT_SIZE] = { 0, };
+static double ref_fft_sout[MAX_FFT_SIZE] = { 0, };
+static double work_fft_in[MAX_FFT_SIZE] = { 0, };
+static double work_fft_aout[MAX_FFT_SIZE] = { 0, };
+static double work_fft_sout[MAX_FFT_SIZE] = { 0, };
+
+
+/* --- functions --- */
+int
+main (int argc,
+ char *argv[])
+{
+ struct timeval tv;
+ guint i;
+
+ /* initialize GSL */
+ if (!g_thread_supported ())
+ g_thread_init (NULL);
+ gsl_init (NULL, NULL);
+
+ /* initialize random numbers */
+ gettimeofday (&tv, NULL);
+ srand (tv.tv_sec ^ tv.tv_usec);
+
+ /* run tests */
+ for (i = 2; i <= MAX_FFT_SIZE >> 1; i <<= 1)
+ {
+ double d;
+
+ g_print ("Testing fft code for size %u\n", i);
+
+ /* setup reference and work fft records */
+ fill_rand (i << 1, ref_fft_in);
+ memset (ref_fft_aout, 0, MAX_FFT_SIZE * sizeof (ref_fft_aout[0]));
+ memset (ref_fft_sout, 0, MAX_FFT_SIZE * sizeof (ref_fft_sout[0]));
+ memcpy (work_fft_in, ref_fft_in, MAX_FFT_SIZE * sizeof (work_fft_in[0]));
+ memset (work_fft_aout, 0, MAX_FFT_SIZE * sizeof (work_fft_aout[0]));
+ memset (work_fft_sout, 0, MAX_FFT_SIZE * sizeof (work_fft_sout[0]));
+ reference_power2_fftc (i, ref_fft_in, ref_fft_aout, +1);
+ reference_power2_fftc (i, ref_fft_in, ref_fft_sout, -1);
+
+ /* perform fft test */
+ gsl_power2_fftac (i, work_fft_in, work_fft_aout);
+ gsl_power2_fftsc (i, work_fft_in, work_fft_sout);
+
+ /* check differences */
+ d = diff (MAX_FFT_SIZE, 0, ref_fft_in, work_fft_in, "Checking input record");
+ if (d)
+ g_error ("Reference record was modified");
+ d = diff (MAX_FFT_SIZE, 0, ref_fft_aout, work_fft_aout, "Reference analysis against GSL analysis");
+ if (fabs (d) > EPSILON)
+ g_error ("Error sum in analysis FFT exceeds epsilon: %g > %g", d, EPSILON);
+ d = diff (MAX_FFT_SIZE, 0, ref_fft_sout, work_fft_sout, "Reference synthesis against GSL synthesis");
+ if (fabs (d) > EPSILON)
+ g_error ("Error sum in analysis FFT exceeds epsilon: %g > %g", d, EPSILON);
+ }
+
+ return 0;
+}
+
+static void
+fill_rand (guint n,
+ double *a)
+{
+ while (n--)
+ a[n] = -1. + 2. * rand() / (RAND_MAX + 1.0);
+}
+
+static double
+diff (guint m,
+ guint p,
+ double *a1,
+ double *a2,
+ const gchar *str)
+{
+ double d = 0, max = 0, min = 1e+32;
+ guint n;
+
+ g_print ("%s\n", str);
+ for (n = 0; n < m; n++)
+ {
+ double a = ABS (a1[n] - a2[n]);
+ if (n < p)
+ g_print ("%3u:%.3f) % 19.9f - % 19.9f = % 19.9f (% 19.9f)\n",
+ n, ((float) n) / (float) m,
+ a1[n], a2[n],
+ a1[n] - a2[n],
+ a1[n] / a2[n]);
+ d += a;
+ max = MAX (max, a);
+ min = MIN (min, a);
+ }
+ g_print ("Diff sum: %.9f, ", d);
+ g_print ("min/av/max: %.9f %.9f %.9f, ", min, d / (double) m, max);
+ g_print ("noise: %u %u %u\n",
+ g_bit_storage (1. / min),
+ g_bit_storage (m / d),
+ g_bit_storage (1. / max));
+ return d;
+}
+
+
+/* --- fft implementation --- */
+#define BUTTERFLY_XY(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,Wre,Wim) { \
+ register double T1re, T1im, T2re, T2im; \
+ T1re = X2re * Wre; \
+ T1im = X2im * Wre; \
+ T2re = X2im * Wim; \
+ T2im = X2re * Wim; \
+ T1re -= T2re; \
+ T1im += T2im; \
+ T2re = X1re - T1re; \
+ T2im = X1im - T1im; \
+ Y1re = X1re + T1re; \
+ Y1im = X1im + T1im; \
+ Y2re = T2re; \
+ Y2im = T2im; \
+}
+#define BUTTERFLY_10(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,_1,_2) { \
+ register double T2re, T2im; \
+ T2re = X1re - X2re; \
+ T2im = X1im - X2im; \
+ Y1re = X1re + X2re; \
+ Y1im = X1im + X2im; \
+ Y2re = T2re; \
+ Y2im = T2im; \
+}
+#define BUTTERFLY_01(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,_1,_2) { \
+ register double T2re, T2im; \
+ T2re = X1re + X2im; \
+ T2im = X1im - X2re; \
+ Y1re = X1re - X2im; \
+ Y1im = X1im + X2re; \
+ Y2re = T2re; \
+ Y2im = T2im; \
+}
+#define BUTTERFLY_0m(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,_1,_2) { \
+ register double T2re, T2im; \
+ T2re = X1re - X2im; \
+ T2im = X1im + X2re; \
+ Y1re = X1re + X2im; \
+ Y1im = X1im - X2re; \
+ Y2re = T2re; \
+ Y2im = T2im; \
+}
+#define BUTTERFLY_10scale(X1re,X1im,X2re,X2im,Y1re,Y1im,Y2re,Y2im,S) { \
+ register double T2re, T2im; \
+ T2re = X1re - X2re; \
+ T2im = X1im - X2im; \
+ Y1re = X1re + X2re; \
+ Y1im = X1im + X2im; \
+ Y2re = T2re * S; \
+ Y2im = T2im * S; \
+ Y1re *= S; \
+ Y1im *= S; \
+}
+#define WMULTIPLY(Wre,Wim,Dre,Dim) { \
+ register double T1re, T1im, T2re, T2im; \
+ T1re = Wre * Dre; \
+ T1im = Wim * Dre; \
+ T2re = Wim * Dim; \
+ T2im = Wre * Dim; \
+ T1re -= T2re; \
+ T1im += T2im; \
+ Wre += T1re; \
+ Wim += T1im; \
+}
+
+static inline void
+reference_bitreverse_fft2analysis (const unsigned int n,
+ const double *X,
+ double *Y)
+{
+ const unsigned int n2 = n >> 1, n1 = n + n2, max = n >> 2;
+ unsigned int i, r;
+
+ BUTTERFLY_10 (X[0], X[1],
+ X[n], X[n + 1],
+ Y[0], Y[1],
+ Y[2], Y[3],
+ __1, __0);
+ if (n < 4)
+ return;
+ BUTTERFLY_10 (X[n2], X[n2 + 1],
+ X[n1], X[n1 + 1],
+ Y[4], Y[5],
+ Y[6], Y[7],
+ __1, __0);
+ if (n < 8)
+ return;
+ for (i = 1, r = 0; i < max; i++)
+ {
+ unsigned int k, j = n >> 1;
+
+ while (r >= j)
+ {
+ r -= j;
+ j >>= 1;
+ }
+ r |= j;
+
+ k = r >> 1;
+ j = i << 3;
+ BUTTERFLY_10 (X[k], X[k + 1],
+ X[k + n], X[k + n + 1],
+ Y[j], Y[j + 1],
+ Y[j + 2], Y[j + 3],
+ __1, __0);
+ k += n2;
+ j += 4;
+ BUTTERFLY_10 (X[k], X[k + 1],
+ X[k + n], X[k + n + 1],
+ Y[j], Y[j + 1],
+ Y[j + 2], Y[j + 3],
+ __1, __0);
+ }
+}
+
+static inline void
+reference_bitreverse_fft2synthesis (const unsigned int n,
+ const double *X,
+ double *Y)
+{
+ const unsigned int n2 = n >> 1, n1 = n + n2, max = n >> 2;
+ unsigned int i, r;
+ double scale = n;
+
+ scale = 1.0 / scale;
+ BUTTERFLY_10scale (X[0], X[1],
+ X[n], X[n + 1],
+ Y[0], Y[1],
+ Y[2], Y[3],
+ scale);
+ if (n < 4)
+ return;
+ BUTTERFLY_10scale (X[n2], X[n2 + 1],
+ X[n1], X[n1 + 1],
+ Y[4], Y[5],
+ Y[6], Y[7],
+ scale);
+ if (n < 8)
+ return;
+ for (i = 1, r = 0; i < max; i++)
+ {
+ unsigned int k, j = n >> 1;
+
+ while (r >= j)
+ {
+ r -= j;
+ j >>= 1;
+ }
+ r |= j;
+
+ k = r >> 1;
+ j = i << 3;
+ BUTTERFLY_10scale (X[k], X[k + 1],
+ X[k + n], X[k + n + 1],
+ Y[j], Y[j + 1],
+ Y[j + 2], Y[j + 3],
+ scale);
+ k += n2;
+ j += 4;
+ BUTTERFLY_10scale (X[k], X[k + 1],
+ X[k + n], X[k + n + 1],
+ Y[j], Y[j + 1],
+ Y[j + 2], Y[j + 3],
+ scale);
+ }
+}
+
+static void
+reference_power2_fftc (unsigned int n_values,
+ const double *rivalues_in,
+ double *rivalues,
+ int esign)
+{
+ const unsigned int n_values2 = n_values << 1;
+ double theta = esign < 0 ? -3.1415926535897932384626433832795029 : 3.1415926535897932384626433832795029;
+ unsigned int block_size = 2 << 1;
+ double last_sin;
+
+ if (esign > 0)
+ reference_bitreverse_fft2analysis (n_values, rivalues_in, rivalues);
+ else
+ reference_bitreverse_fft2synthesis (n_values, rivalues_in, rivalues);
+ theta *= (double) 1.0 / 2.;
+ last_sin = sin (theta);
+
+ if (n_values < 4)
+ return;
+
+ do
+ {
+ double Dre, Dim, Wre, Wim;
+ unsigned int k, i, half_block = block_size >> 1;
+ unsigned int block_size2 = block_size << 1;
+
+ theta *= 0.5;
+ Dim = last_sin;
+ last_sin = sin (theta);
+ Dre = last_sin * last_sin * -2.;
+
+ /* loop over first coefficient in each block ==> w == {1,0} */
+ for (i = 0; i < n_values2; i += block_size2)
+ {
+ unsigned int v1 = i, v2 = i + block_size;
+
+ BUTTERFLY_10 (rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ __1, __0);
+ }
+ Wre = Dre + 1.0; /* update Wk */
+ Wim = Dim; /* update Wk */
+ /* loop for every Wk in the first half of each subblock */
+ for (k = 2; k < half_block; k += 2)
+ {
+ /* loop over kth coefficient in each block */
+ for (i = k; i < n_values2; i += block_size2)
+ {
+ unsigned int v1 = i, v2 = i + block_size;
+
+ BUTTERFLY_XY (rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, Dre, Dim); /* update Wk */
+ }
+ /* handle middle coefficient ==> w == {0,+-1} */
+ if (k < block_size)
+ {
+ /* loop over kth coefficient in each block */
+ if (esign > 0)
+ for (i = k; i < n_values2; i += block_size2)
+ {
+ unsigned int v1 = i, v2 = i + block_size;
+
+ BUTTERFLY_01 (rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ __0, __1);
+ }
+ else
+ for (i = k; i < n_values2; i += block_size2)
+ {
+ unsigned int v1 = i, v2 = i + block_size;
+
+ BUTTERFLY_0m (rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ __0, __1);
+ }
+ /* update Wk */
+ if (esign > 0)
+ {
+ Wre = -Dim;
+ Wim = Dre + 1.0;
+ }
+ else
+ {
+ Wre = Dim;
+ Wim = -Dre - 1.0;
+ }
+ k += 2;
+ }
+ /* loop for every Wk in the second half of each subblock */
+ for (; k < block_size; k += 2)
+ {
+ /* loop over kth coefficient in each block */
+ for (i = k; i < n_values2; i += block_size2)
+ {
+ unsigned int v1 = i, v2 = i + block_size;
+
+ BUTTERFLY_XY (rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ rivalues[v1], rivalues[v1 + 1],
+ rivalues[v2], rivalues[v2 + 1],
+ Wre, Wim);
+ }
+ WMULTIPLY (Wre, Wim, Dre, Dim); /* update Wk */
+ }
+ block_size = block_size2;
+ }
+ while (block_size <= n_values);
+}
diff --git a/flow/gsl/gslfilehash.c b/flow/gsl/gslfilehash.c
new file mode 100644
index 0000000..ac4c066
--- /dev/null
+++ b/flow/gsl/gslfilehash.c
@@ -0,0 +1,464 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2002 Tim Janik
+ *
+ * This library 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 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include "gslfilehash.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+
+
+/* macros */
+#if (GLIB_SIZEOF_LONG > 4)
+#define HASH_LONG(l) (l + (l >> 32))
+#else
+#define HASH_LONG(l) (l)
+#endif
+
+
+/* --- variables --- */
+static GslMutex fdpool_mutex = { 0, };
+static GHashTable *hfile_ht = NULL;
+
+
+/* --- functions --- */
+static guint
+hfile_hash (gconstpointer key)
+{
+ const GslHFile *hfile = key;
+ guint h;
+
+ h = HASH_LONG (hfile->mtime);
+ h ^= g_str_hash (hfile->file_name);
+ h ^= HASH_LONG (hfile->n_bytes);
+
+ return h;
+}
+
+static gboolean
+hfile_equals (gconstpointer key1,
+ gconstpointer key2)
+{
+ const GslHFile *hfile1 = key1;
+ const GslHFile *hfile2 = key2;
+
+ return (hfile1->mtime == hfile2->mtime &&
+ hfile1->n_bytes == hfile2->n_bytes &&
+ strcmp (hfile1->file_name, hfile2->file_name) == 0);
+}
+
+void
+_gsl_init_fd_pool (void)
+{
+ g_assert (hfile_ht == NULL);
+
+ gsl_mutex_init (&fdpool_mutex);
+ hfile_ht = g_hash_table_new (hfile_hash, hfile_equals);
+}
+
+static gboolean
+stat_fd (gint fd,
+ GTime *mtime,
+ GslLong *n_bytes)
+{
+ struct stat statbuf = { 0, };
+
+ if (fstat (fd, &statbuf) < 0)
+ return FALSE; /* have errno */
+ if (mtime)
+ *mtime = statbuf.st_mtime;
+ if (n_bytes)
+ *n_bytes = statbuf.st_size;
+ return TRUE;
+}
+
+static gboolean
+stat_file (const gchar *file_name,
+ GTime *mtime,
+ GslLong *n_bytes)
+{
+ struct stat statbuf = { 0, };
+
+ if (stat (file_name, &statbuf) < 0)
+ return FALSE; /* have errno */
+ if (mtime)
+ *mtime = statbuf.st_mtime;
+ if (n_bytes)
+ *n_bytes = statbuf.st_size;
+ return TRUE;
+}
+
+/**
+ * gsl_hfile_open
+ * @file_name: name of the file to open
+ * @RETURNS: a new opened #GslHFile or NULL if an error occoured (errno set)
+ *
+ * Open a file for reading and return the associated GSL hashed file.
+ * The motivation for using a #GslHFile over normal unix file
+ * descriptors is to reduce the amount of opened unix file descriptors and
+ * to ensure thread safety upon reading offset relative byte blocks.
+ * Multiple open #GslHFiles with equal file names will share a
+ * single unix file descriptor as long as the file wasn't modified meanwhile.
+ * This function is MT-safe and may be called from any thread.
+ */
+GslHFile*
+gsl_hfile_open (const gchar *file_name)
+{
+ GslHFile key, *hfile;
+ gint ret_errno;
+
+ errno = EFAULT;
+ g_return_val_if_fail (file_name != NULL, NULL);
+
+ key.file_name = (gchar*) file_name;
+ if (!stat_file (file_name, &key.mtime, &key.n_bytes))
+ return NULL; /* errno from stat() */
+
+ GSL_SYNC_LOCK (&fdpool_mutex);
+ hfile = g_hash_table_lookup (hfile_ht, &key);
+ if (hfile)
+ {
+ GSL_SYNC_LOCK (&hfile->mutex);
+ hfile->ocount++;
+ GSL_SYNC_UNLOCK (&hfile->mutex);
+ ret_errno = 0;
+ }
+ else
+ {
+ gint fd;
+
+ fd = open (file_name, O_RDONLY | O_NOCTTY, 0);
+ if (fd >= 0)
+ {
+ hfile = gsl_new_struct0 (GslHFile, 1);
+ hfile->file_name = g_strdup (file_name);
+ hfile->mtime = key.mtime;
+ hfile->n_bytes = key.n_bytes;
+ hfile->cpos = 0;
+ hfile->fd = fd;
+ hfile->ocount = 1;
+ gsl_mutex_init (&hfile->mutex);
+ g_hash_table_insert (hfile_ht, hfile, hfile);
+ ret_errno = 0;
+ }
+ else
+ ret_errno = errno;
+ }
+ GSL_SYNC_UNLOCK (&fdpool_mutex);
+
+ errno = ret_errno;
+ return hfile;
+}
+
+/**
+ * gsl_hfile_close
+ * @hfile: valid #GslHFile
+ *
+ * Close and destroy a #GslHFile.
+ * This function is MT-safe and may be called from any thread.
+ */
+void
+gsl_hfile_close (GslHFile *hfile)
+{
+ gboolean destroy = FALSE;
+
+ g_return_if_fail (hfile != NULL);
+ g_return_if_fail (hfile->ocount > 0);
+
+ GSL_SYNC_LOCK (&fdpool_mutex);
+ GSL_SYNC_LOCK (&hfile->mutex);
+ if (hfile->ocount > 1)
+ hfile->ocount--;
+ else
+ {
+ if (!g_hash_table_remove (hfile_ht, hfile))
+ g_warning ("%s: failed to unlink hashed file (%p)",
+ G_STRLOC, hfile);
+ else
+ {
+ hfile->ocount = 0;
+ destroy = TRUE;
+ }
+ }
+ GSL_SYNC_UNLOCK (&hfile->mutex);
+ GSL_SYNC_UNLOCK (&fdpool_mutex);
+
+ if (destroy)
+ {
+ gsl_mutex_destroy (&hfile->mutex);
+ close (hfile->fd);
+ g_free (hfile->file_name);
+ gsl_delete_struct (GslHFile, hfile);
+ }
+ errno = 0;
+}
+
+/**
+ * gsl_hfile_pread
+ * @hfile: valid GslHFile
+ * @offset: offset in bytes within 0 and file end
+ * @n_bytes: number of bytes to read
+ * @bytes: buffer to store read bytes
+ * @error_p: pointer to GslErrorType location
+ * @RETURNS: amount of bytes read or -1 if an error occoured (errno set)
+ *
+ * Read a block of bytes from a GslHFile.
+ * This function is MT-safe and may be called from any thread.
+ */
+GslLong
+gsl_hfile_pread (GslHFile *hfile,
+ GslLong offset,
+ GslLong n_bytes,
+ gpointer bytes)
+{
+ GslLong ret_bytes = -1;
+ gint ret_errno;
+
+ errno = EFAULT;
+ g_return_val_if_fail (hfile != NULL, -1);
+ g_return_val_if_fail (hfile->ocount > 0, -1);
+ g_return_val_if_fail (offset >= 0, -1);
+ if (offset >= hfile->n_bytes || n_bytes < 1)
+ {
+ errno = 0;
+ return 0;
+ }
+ g_return_val_if_fail (bytes != NULL, -1);
+
+ GSL_SYNC_LOCK (&hfile->mutex);
+ if (hfile->ocount)
+ {
+ if (hfile->cpos != offset)
+ {
+ hfile->cpos = lseek (hfile->fd, offset, SEEK_SET);
+ if (hfile->cpos < 0 && errno != EINVAL)
+ {
+ ret_errno = errno;
+ GSL_SYNC_UNLOCK (&hfile->mutex);
+ errno = ret_errno;
+ return -1;
+ }
+ }
+ if (hfile->cpos == offset)
+ {
+ do
+ ret_bytes = read (hfile->fd, bytes, n_bytes);
+ while (ret_bytes < 0 && errno == EINTR);
+ if (ret_bytes < 0)
+ {
+ ret_errno = errno;
+ ret_bytes = -1;
+ }
+ else
+ {
+ ret_errno = 0;
+ hfile->cpos += ret_bytes;
+ }
+ }
+ else /* this should only happen if the file changed since open() */
+ {
+ hfile->cpos = -1;
+ if (offset + n_bytes > hfile->n_bytes)
+ n_bytes = hfile->n_bytes - offset;
+ memset (bytes, 0, n_bytes);
+ ret_bytes = n_bytes;
+ ret_errno = 0;
+ }
+ }
+ else
+ ret_errno = EFAULT;
+ GSL_SYNC_UNLOCK (&hfile->mutex);
+
+ errno = ret_errno;
+ return ret_bytes;
+}
+
+/**
+ * gsl_rfile_open
+ * @file_name: name of the file to open
+ * @RETURNS: a new opened #GslRFile or NULL if an error occoured (errno set)
+ *
+ * Open a file for reading and create a GSL read only file handle for it.
+ * The motivation for using a #GslRFile over normal unix files
+ * is to reduce the amount of opened unix file descriptors by using
+ * a #GslHFile for the actual IO.
+ */
+GslRFile*
+gsl_rfile_open (const gchar *file_name)
+{
+ GslHFile *hfile = gsl_hfile_open (file_name);
+ GslRFile *rfile;
+
+ if (!hfile)
+ rfile = NULL;
+ else
+ {
+ rfile = gsl_new_struct0 (GslRFile, 1);
+ rfile->hfile = hfile;
+ rfile->offset = 0;
+ }
+ return rfile;
+}
+
+/**
+ * gsl_rfile_name
+ * @rfile: valid #GslRFile
+ * @RETURNS: the file name used to open this file
+ *
+ * Retrive the file name used to open @rfile.
+ */
+gchar*
+gsl_rfile_name (GslRFile *rfile)
+{
+ errno = EFAULT;
+ g_return_val_if_fail (rfile != NULL, NULL);
+
+ errno = 0;
+ return rfile->hfile->file_name;
+}
+
+/**
+ * gsl_rfile_seek_set
+ * @rfile: valid #GslRFile
+ * @offset: new seek position within 0 and gsl_rfile_length()+1
+ * @RETURNS: resulting position within 0 and gsl_rfile_length()+1
+ *
+ * Set the current #GslRFile seek position.
+ */
+GslLong
+gsl_rfile_seek_set (GslRFile *rfile,
+ GslLong offset)
+{
+ GslLong l;
+
+ errno = EFAULT;
+ g_return_val_if_fail (rfile != NULL, 0);
+
+ l = rfile->hfile->n_bytes;
+ rfile->offset = CLAMP (offset, 0, l);
+
+ errno = 0;
+ return rfile->offset;
+}
+
+/**
+ * gsl_rfile_position
+ * @rfile: valid #GslRFile
+ * @RETURNS: current position within 0 and gsl_rfile_length()
+ *
+ * Retrive the current #GslRFile seek position.
+ */
+GslLong
+gsl_rfile_position (GslRFile *rfile)
+{
+ errno = EFAULT;
+ g_return_val_if_fail (rfile != NULL, 0);
+
+ errno = 0;
+ return rfile->offset;
+}
+
+/**
+ * gsl_rfile_length
+ * @rfile: valid #GslRFile
+ * @RETURNS: total length of the #GslRFile in bytes
+ *
+ * Retrive the file length of @rfile in bytes.
+ */
+GslLong
+gsl_rfile_length (GslRFile *rfile)
+{
+ GslLong l;
+
+ errno = EFAULT;
+ g_return_val_if_fail (rfile != NULL, 0);
+
+ l = rfile->hfile->n_bytes;
+
+ errno = 0;
+ return l;
+}
+
+/**
+ * gsl_rfile_pread
+ * @rfile: valid GslRFile
+ * @offset: offset in bytes within 0 and gsl_rfile_length()
+ * @n_bytes: number of bytes to read
+ * @bytes: buffer to store read bytes
+ * @error_p: pointer to GslErrorType location
+ * @RETURNS: amount of bytes read or -1 if an error occoured (errno set)
+ *
+ * Read a block of bytes from a GslRFile at a specified position.
+ */
+GslLong
+gsl_rfile_pread (GslRFile *rfile,
+ GslLong offset,
+ GslLong n_bytes,
+ gpointer bytes)
+{
+ errno = EFAULT;
+ g_return_val_if_fail (rfile != NULL, -1);
+
+ return gsl_hfile_pread (rfile->hfile, offset, n_bytes, bytes);
+}
+
+/**
+ * gsl_rfile_read
+ * @rfile: valid GslRFile
+ * @n_bytes: number of bytes to read
+ * @bytes: buffer to store read bytes
+ * @error_p: pointer to GslErrorType location
+ * @RETURNS: amount of bytes read or -1 if an error occoured (errno set)
+ *
+ * Read a block of bytes from a GslRFile from the current seek position
+ * and advance the seek position.
+ */
+GslLong
+gsl_rfile_read (GslRFile *rfile,
+ GslLong n_bytes,
+ gpointer bytes)
+{
+ GslLong l;
+
+ errno = EFAULT;
+ g_return_val_if_fail (rfile != NULL, -1);
+
+ l = gsl_hfile_pread (rfile->hfile, rfile->offset, n_bytes, bytes);
+ if (l > 0)
+ rfile->offset += l;
+ return l;
+}
+
+/**
+ * gsl_rfile_close
+ * @rfile: valid #GslRFile
+ *
+ * Close and destroy a #GslRFile.
+ */
+void
+gsl_rfile_close (GslRFile *rfile)
+{
+ errno = EFAULT;
+ g_return_if_fail (rfile != NULL);
+
+ gsl_hfile_close (rfile->hfile);
+ gsl_delete_struct (GslRFile, rfile);
+ errno = 0;
+}
diff --git a/flow/gsl/gslfilehash.h b/flow/gsl/gslfilehash.h
new file mode 100644
index 0000000..cc70bee
--- /dev/null
+++ b/flow/gsl/gslfilehash.h
@@ -0,0 +1,77 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2002 Tim Janik
+ *
+ * This library 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 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 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.
+ */
+#ifndef __GSL_FILE_HASH_H__
+#define __GSL_FILE_HASH_H__
+
+#include <gsl/gsldefs.h>
+#include <gsl/gslcommon.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+
+/* --- typedefs & structures --- */
+typedef struct {
+ gchar *file_name;
+ GTime mtime;
+ GslLong n_bytes;
+ /*< private >*/
+ GslLong cpos;
+ GslMutex mutex;
+ gint fd;
+ guint ocount;
+} GslHFile;
+typedef struct {
+ GslHFile *hfile;
+ GslLong offset;
+} GslRFile;
+
+
+/* --- GslHFile API --- */
+GslHFile* gsl_hfile_open (const gchar *file_name);
+GslLong gsl_hfile_pread (GslHFile *hfile,
+ GslLong offset,
+ GslLong n_bytes,
+ gpointer bytes);
+void gsl_hfile_close (GslHFile *hfile);
+
+
+/* --- GslRFile API --- */
+GslRFile* gsl_rfile_open (const gchar *file_name);
+gchar* gsl_rfile_name (GslRFile *rfile);
+GslLong gsl_rfile_pread (GslRFile *rfile,
+ GslLong offset,
+ GslLong n_bytes,
+ gpointer bytes);
+GslLong gsl_rfile_read (GslRFile *rfile,
+ GslLong n_bytes,
+ gpointer bytes);
+GslLong gsl_rfile_seek_set (GslRFile *rfile,
+ GslLong offset);
+GslLong gsl_rfile_position (GslRFile *rfile);
+GslLong gsl_rfile_length (GslRFile *rfile);
+void gsl_rfile_close (GslRFile *rfile);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_FILE_HASH_H__ */
diff --git a/flow/gsl/gslfilter.c b/flow/gsl/gslfilter.c
new file mode 100644
index 0000000..5bf8ff5
--- /dev/null
+++ b/flow/gsl/gslfilter.c
@@ -0,0 +1,1379 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001 Stefan Westerfeld and Tim Janik
+ *
+ * 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.
+ */
+#include "gslfilter.h"
+
+#include "gslfft.h"
+#include "gslsignal.h"
+#include <string.h>
+
+
+/* --- common utilities --- */
+static inline double
+cotan (double x)
+{
+ return - tan (x + GSL_PI * 0.5);
+}
+
+static double
+gsl_db_invert (double x)
+{
+ /* db = 20*log(x)/log(10); */
+ return exp (x * log (10) / 20.0);
+}
+
+static void
+band_filter_common (unsigned int iorder,
+ double p_freq, /* 0..pi */
+ double s_freq, /* 0..pi */
+ double epsilon,
+ GslComplex *roots,
+ GslComplex *poles,
+ double *a, /* [0..iorder] */
+ double *b,
+ gboolean band_pass,
+ gboolean t1_norm)
+{
+ unsigned int iorder2 = iorder >> 1;
+ GslComplex *poly = g_newa (GslComplex, iorder + 1);
+ GslComplex fpoly[2 + 1] = { { 0, }, { 0, }, { 1, 0 } };
+ double alpha, norm;
+ guint i;
+
+ epsilon = gsl_trans_zepsilon2ss (epsilon);
+ alpha = cos ((s_freq + p_freq) * 0.5) / cos ((s_freq - p_freq) * 0.5);
+
+ fpoly[0] = gsl_complex (1, 0);
+ fpoly[1] = gsl_complex (1, 0);
+ for (i = 0; i < iorder2; i++)
+ {
+ fpoly[0] = gsl_complex_mul (fpoly[0], gsl_complex_sub (gsl_complex (1, 0), gsl_complex_reciprocal (roots[i])));
+ fpoly[1] = gsl_complex_mul (fpoly[1], gsl_complex_sub (gsl_complex (1, 0), gsl_complex_reciprocal (poles[i])));
+ }
+ norm = gsl_complex_div (fpoly[1], fpoly[0]).re;
+
+ if ((iorder2 & 1) == 0) /* norm is fluctuation minimum */
+ norm *= sqrt (1.0 / (1.0 + epsilon * epsilon));
+
+ /* z nominator polynomial */
+ poly[0] = gsl_complex (norm, 0);
+ for (i = 0; i < iorder2; i++)
+ {
+ GslComplex t, alphac = gsl_complex (alpha, 0);
+
+ t = band_pass ? gsl_complex_inv (roots[i]) : roots[i];
+ fpoly[1] = gsl_complex_sub (gsl_complex_div (alphac, t), alphac);
+ fpoly[0] = gsl_complex_inv (gsl_complex_reciprocal (t));
+ gsl_cpoly_mul (poly, i * 2, poly, 2, fpoly);
+ }
+ for (i = 0; i <= iorder; i++)
+ a[i] = poly[i].re;
+
+ /* z denominator polynomial */
+ poly[0] = gsl_complex (1, 0);
+ for (i = 0; i < iorder2; i++)
+ {
+ GslComplex t, alphac = gsl_complex (alpha, 0);
+
+ t = band_pass ? gsl_complex_inv (poles[i]) : poles[i];
+ fpoly[1] = gsl_complex_sub (gsl_complex_div (alphac, t), alphac);
+ fpoly[0] = gsl_complex_inv (gsl_complex_reciprocal (t));
+ gsl_cpoly_mul (poly, i * 2, poly, 2, fpoly);
+ }
+ for (i = 0; i <= iorder; i++)
+ b[i] = poly[i].re;
+ gsl_poly_scale (iorder, a, 1.0 / b[0]);
+ gsl_poly_scale (iorder, b, 1.0 / b[0]);
+}
+
+static void
+filter_rp_to_z (unsigned int iorder,
+ GslComplex *roots, /* [0..iorder-1] */
+ GslComplex *poles,
+ double *a, /* [0..iorder] */
+ double *b)
+{
+ GslComplex *poly = g_newa (GslComplex, iorder + 1);
+ guint i;
+
+ /* z nominator polynomial */
+ poly[0] = gsl_complex (1, 0);
+ for (i = 0; i < iorder; i++)
+ gsl_cpoly_mul_reciprocal (i + 1, poly, roots[i]);
+ for (i = 0; i <= iorder; i++)
+ a[i] = poly[i].re;
+
+ /* z denominator polynomial */
+ poly[0] = gsl_complex (1, 0);
+ for (i = 0; i < iorder; i++)
+ gsl_cpoly_mul_reciprocal (i + 1, poly, poles[i]);
+ for (i = 0; i <= iorder; i++)
+ b[i] = poly[i].re;
+}
+
+static void
+filter_lp_invert (unsigned int iorder,
+ double *a, /* [0..iorder] */
+ double *b)
+{
+ guint i;
+
+ for (i = 1; i <= iorder; i +=2)
+ {
+ a[i] = -a[i];
+ b[i] = -b[i];
+ }
+}
+
+
+/* --- butterworth filter --- */
+void
+gsl_filter_butter_rp (unsigned int iorder,
+ double freq, /* 0..pi */
+ double epsilon,
+ GslComplex *roots, /* [0..iorder-1] */
+ GslComplex *poles)
+{
+ double pi = GSL_PI, order = iorder;
+ double beta_mul = pi / (2.0 * order);
+ /* double kappa = gsl_trans_freq2s (freq); */
+ double kappa;
+ GslComplex root;
+ unsigned int i;
+
+ epsilon = gsl_trans_zepsilon2ss (epsilon);
+ kappa = gsl_trans_freq2s (freq) * pow (epsilon, -1.0 / order);
+
+ /* construct poles for butterworth filter */
+ for (i = 1; i <= iorder; i++)
+ {
+ double t = (i << 1) + iorder - 1;
+ double beta = t * beta_mul;
+
+ root.re = kappa * cos (beta);
+ root.im = kappa * sin (beta);
+ poles[i - 1] = gsl_trans_s2z (root);
+ }
+
+ /* z nominator polynomial */
+ for (i = 0; i < iorder; i++)
+ roots[i] = gsl_complex (-1, 0);
+}
+
+
+/* --- tschebyscheff type 1 filter --- */
+static double
+tschebyscheff_eval (unsigned int degree,
+ double x)
+{
+ double td = x, td_m_1 = 1;
+ unsigned int d = 1;
+
+ /* eval polynomial for a certain x */
+ if (degree == 0)
+ return 1;
+
+ while (d < degree)
+ {
+ double td1 = 2 * x * td - td_m_1;
+
+ td_m_1 = td;
+ td = td1;
+ d++;
+ }
+ return td;
+}
+
+static double
+tschebyscheff_inverse (unsigned int degree,
+ double x)
+{
+ /* note, that thebyscheff_eval(degree,x)=cosh(degree*acosh(x)) */
+ return cosh (acosh (x) / degree);
+}
+
+void
+gsl_filter_tscheb1_rp (unsigned int iorder,
+ double freq, /* 1..pi */
+ double epsilon,
+ GslComplex *roots, /* [0..iorder-1] */
+ GslComplex *poles)
+{
+ double pi = GSL_PI, order = iorder;
+ double alpha;
+ double beta_mul = pi / (2.0 * order);
+ double kappa = gsl_trans_freq2s (freq);
+ GslComplex root;
+ unsigned int i;
+
+ epsilon = gsl_trans_zepsilon2ss (epsilon);
+ alpha = asinh (1.0 / epsilon) / order;
+
+ /* construct poles polynomial from tschebyscheff polynomial */
+ for (i = 1; i <= iorder; i++)
+ {
+ double t = (i << 1) + iorder - 1;
+ double beta = t * beta_mul;
+
+ root.re = kappa * sinh (alpha) * cos (beta);
+ root.im = kappa * cosh (alpha) * sin (beta);
+ poles[i - 1] = gsl_trans_s2z (root);
+ }
+
+ /* z nominator polynomial */
+ for (i = 0; i < iorder; i++)
+ roots[i] = gsl_complex (-1, 0);
+}
+
+
+/* --- tschebyscheff type 2 filter --- */
+void
+gsl_filter_tscheb2_rp (unsigned int iorder,
+ double c_freq, /* 1..pi */
+ double steepness,
+ double epsilon,
+ GslComplex *roots, /* [0..iorder-1] */
+ GslComplex *poles)
+{
+ double pi = GSL_PI, order = iorder;
+ double r_freq = c_freq * steepness;
+ double kappa_c = gsl_trans_freq2s (c_freq);
+ double kappa_r = gsl_trans_freq2s (r_freq);
+ double tepsilon;
+ double alpha;
+ double beta_mul = pi / (2.0 * order);
+ GslComplex root;
+ unsigned int i;
+
+#if 0
+ /* triggers an internal compiler error with gcc-2.95.4 (and certain
+ * combinations of optimization options)
+ */
+ g_return_if_fail (c_freq * steepness < GSL_PI);
+#endif
+ g_return_if_fail (steepness > 1.0);
+
+ epsilon = gsl_trans_zepsilon2ss (epsilon);
+ tepsilon = epsilon * tschebyscheff_eval (iorder, kappa_r / kappa_c);
+ alpha = asinh (tepsilon) / order;
+
+ /* construct poles polynomial from tschebyscheff polynomial */
+ for (i = 1; i <= iorder; i++)
+ {
+ double t = (i << 1) + iorder - 1;
+ double beta = t * beta_mul;
+
+ root.re = sinh (alpha) * cos (beta);
+ root.im = cosh (alpha) * sin (beta);
+ root = gsl_complex_div (gsl_complex (kappa_r, 0), root);
+ root = gsl_trans_s2z (root);
+ poles[i - 1] = root;
+ }
+
+ /* construct roots polynomial from tschebyscheff polynomial */
+ for (i = 1; i <= iorder; i++)
+ {
+ double t = (i << 1) - 1;
+ GslComplex root = gsl_complex (0, cos (t * beta_mul));
+
+ if (fabs (root.im) > 1e-14)
+ {
+ root = gsl_complex_div (gsl_complex (kappa_r, 0), root);
+ root = gsl_trans_s2z (root);
+ }
+ else
+ root = gsl_complex (-1, 0);
+ roots[i - 1] = root;
+ }
+}
+
+/**
+ * gsl_filter_tscheb2_steepness_db
+ * @iorder: filter order
+ * @c_freq: passband cutoff frequency (0..pi)
+ * @epsilon: fall off at passband frequency (0..1)
+ * @stopband_db: reduction in stopband in dB (>= 0)
+ * Calculates the steepness parameter for Tschebyscheff type 2 lowpass filter,
+ * based on the ripple residue in the stop band.
+ */
+double
+gsl_filter_tscheb2_steepness_db (unsigned int iorder,
+ double c_freq,
+ double epsilon,
+ double stopband_db)
+{
+ return gsl_filter_tscheb2_steepness (iorder, c_freq, epsilon, gsl_db_invert (-stopband_db));
+}
+
+/**
+ * gsl_filter_tscheb2_steepness
+ * @iorder: filter order
+ * @c_freq: passband cutoff frequency (0..pi)
+ * @epsilon: fall off at passband frequency (0..1)
+ * @residue: maximum of transfer function in stopband (0..1)
+ * Calculates the steepness parameter for Tschebyscheff type 2 lowpass filter,
+ * based on ripple residue in the stop band.
+ */
+double
+gsl_filter_tscheb2_steepness (unsigned int iorder,
+ double c_freq,
+ double epsilon,
+ double residue)
+{
+ double kappa_c, kappa_r, r_freq;
+
+ epsilon = gsl_trans_zepsilon2ss (epsilon);
+ kappa_c = gsl_trans_freq2s (c_freq);
+ kappa_r = tschebyscheff_inverse (iorder, sqrt (1.0 / (residue * residue) - 1.0) / epsilon) * kappa_c;
+ r_freq = gsl_trans_freq2z (kappa_r);
+
+ return r_freq / c_freq;
+}
+
+
+/* --- lowpass filters --- */
+/**
+ * gsl_filter_butter_lp
+ * @iorder: filter order
+ * @freq: cutoff frequency (0..pi)
+ * @epsilon: fall off at cutoff frequency (0..1)
+ * @a: root polynomial coefficients a[0..iorder]
+ * @b: pole polynomial coefficients b[0..iorder]
+ * Butterworth lowpass filter.
+ */
+void
+gsl_filter_butter_lp (unsigned int iorder,
+ double freq, /* 0..pi */
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b)
+{
+ GslComplex *roots = g_newa (GslComplex, iorder);
+ GslComplex *poles = g_newa (GslComplex, iorder);
+ double norm;
+
+ g_return_if_fail (freq > 0 && freq < GSL_PI);
+
+ gsl_filter_butter_rp (iorder, freq, epsilon, roots, poles);
+ filter_rp_to_z (iorder, roots, poles, a, b);
+
+ /* scale maximum to 1.0 */
+ norm = gsl_poly_eval (iorder, b, 1) / gsl_poly_eval (iorder, a, 1);
+ gsl_poly_scale (iorder, a, norm);
+}
+
+/**
+ * gsl_filter_tscheb1_lp
+ * @iorder: filter order
+ * @freq: cutoff frequency (0..pi)
+ * @epsilon: fall off at cutoff frequency (0..1)
+ * @a: root polynomial coefficients a[0..iorder]
+ * @b: pole polynomial coefficients b[0..iorder]
+ * Tschebyscheff type 1 lowpass filter.
+ */
+void
+gsl_filter_tscheb1_lp (unsigned int iorder,
+ double freq, /* 0..pi */
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b)
+{
+ GslComplex *roots = g_newa (GslComplex, iorder);
+ GslComplex *poles = g_newa (GslComplex, iorder);
+ double norm;
+
+ g_return_if_fail (freq > 0 && freq < GSL_PI);
+
+ gsl_filter_tscheb1_rp (iorder, freq, epsilon, roots, poles);
+ filter_rp_to_z (iorder, roots, poles, a, b);
+
+ /* scale maximum to 1.0 */
+ norm = gsl_poly_eval (iorder, b, 1) / gsl_poly_eval (iorder, a, 1);
+ if ((iorder & 1) == 0) /* norm is fluctuation minimum */
+ {
+ epsilon = gsl_trans_zepsilon2ss (epsilon);
+ norm *= sqrt (1.0 / (1.0 + epsilon * epsilon));
+ }
+ gsl_poly_scale (iorder, a, norm);
+}
+
+/**
+ * gsl_filter_tscheb2_lp
+ * @iorder: filter order
+ * @freq: passband cutoff frequency (0..pi)
+ * @steepness: frequency steepness (c_freq * steepness < pi)
+ * @epsilon: fall off at passband frequency (0..1)
+ * @a: root polynomial coefficients a[0..iorder]
+ * @b: pole polynomial coefficients b[0..iorder]
+ * Tschebyscheff type 2 lowpass filter.
+ * To gain a transition band between freq1 and freq2, pass arguements
+ * @freq=freq1 and @steepness=freq2/freq1. To specify the transition
+ * band width in fractions of octaves, pass @steepness=2^octave_fraction.
+ */
+void
+gsl_filter_tscheb2_lp (unsigned int iorder,
+ double freq, /* 0..pi */
+ double steepness,
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b)
+{
+ GslComplex *roots = g_newa (GslComplex, iorder);
+ GslComplex *poles = g_newa (GslComplex, iorder);
+ double norm;
+
+ g_return_if_fail (freq > 0 && freq < GSL_PI);
+ g_return_if_fail (freq * steepness < GSL_PI);
+ g_return_if_fail (steepness > 1.0);
+
+ gsl_filter_tscheb2_rp (iorder, freq, steepness, epsilon, roots, poles);
+ filter_rp_to_z (iorder, roots, poles, a, b);
+
+ /* scale maximum to 1.0 */
+ norm = gsl_poly_eval (iorder, b, 1) / gsl_poly_eval (iorder, a, 1); /* H(z=0):=1, e^(j*omega) for omega=0 => e^0==1 */
+ gsl_poly_scale (iorder, a, norm);
+}
+
+
+/* --- highpass filters --- */
+/**
+ * gsl_filter_butter_hp
+ * @iorder: filter order
+ * @freq: passband frequency (0..pi)
+ * @epsilon: fall off at passband frequency (0..1)
+ * @a: root polynomial coefficients a[0..iorder]
+ * @b: pole polynomial coefficients b[0..iorder]
+ * Butterworth highpass filter.
+ */
+void
+gsl_filter_butter_hp (unsigned int iorder,
+ double freq, /* 0..pi */
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b)
+{
+ g_return_if_fail (freq > 0 && freq < GSL_PI);
+
+ freq = GSL_PI - freq;
+ gsl_filter_butter_lp (iorder, freq, epsilon, a, b);
+ filter_lp_invert (iorder, a, b);
+}
+
+/**
+ * gsl_filter_tscheb1_hp
+ * @iorder: filter order
+ * @freq: passband frequency (0..pi)
+ * @epsilon: fall off at passband frequency (0..1)
+ * @a: root polynomial coefficients a[0..iorder]
+ * @b: pole polynomial coefficients b[0..iorder]
+ * Tschebyscheff type 1 highpass filter.
+ */
+void
+gsl_filter_tscheb1_hp (unsigned int iorder,
+ double freq, /* 0..pi */
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b)
+{
+ g_return_if_fail (freq > 0 && freq < GSL_PI);
+
+ freq = GSL_PI - freq;
+ gsl_filter_tscheb1_lp (iorder, freq, epsilon, a, b);
+ filter_lp_invert (iorder, a, b);
+}
+
+/**
+ * gsl_filter_tscheb2_hp
+ * @iorder: filter order
+ * @freq: stopband frequency (0..pi)
+ * @steepness: frequency steepness
+ * @epsilon: fall off at passband frequency (0..1)
+ * @a: root polynomial coefficients a[0..iorder]
+ * @b: pole polynomial coefficients b[0..iorder]
+ * Tschebyscheff type 2 highpass filter.
+ */
+void
+gsl_filter_tscheb2_hp (unsigned int iorder,
+ double freq,
+ double steepness,
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b)
+{
+ g_return_if_fail (freq > 0 && freq < GSL_PI);
+
+ freq = GSL_PI - freq;
+ gsl_filter_tscheb2_lp (iorder, freq, steepness, epsilon, a, b);
+ filter_lp_invert (iorder, a, b);
+}
+
+
+/* --- bandpass filters --- */
+/**
+ * gsl_filter_butter_bp
+ * @iorder: filter order (must be even)
+ * @freq1: stopband end frequency (0..pi)
+ * @freq2: passband end frequency (0..pi)
+ * @epsilon: fall off at passband frequency (0..1)
+ * @a: root polynomial coefficients a[0..iorder]
+ * @b: pole polynomial coefficients b[0..iorder]
+ * Butterworth bandpass filter.
+ */
+void
+gsl_filter_butter_bp (unsigned int iorder,
+ double freq1, /* 0..pi */
+ double freq2, /* 0..pi */
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b)
+{
+ unsigned int iorder2 = iorder >> 1;
+ GslComplex *roots = g_newa (GslComplex, iorder2);
+ GslComplex *poles = g_newa (GslComplex, iorder2);
+ double theta;
+
+ g_return_if_fail ((iorder & 0x01) == 0);
+ g_return_if_fail (freq1 > 0);
+ g_return_if_fail (freq1 < freq2);
+ g_return_if_fail (freq2 < GSL_PI);
+
+ theta = 2. * atan2 (1., cotan ((freq2 - freq1) * 0.5));
+
+ gsl_filter_butter_rp (iorder2, theta, epsilon, roots, poles);
+ band_filter_common (iorder, freq1, freq2, epsilon, roots, poles, a, b, TRUE, FALSE);
+}
+
+/**
+ * gsl_filter_tscheb1_bp
+ * @iorder: filter order (must be even)
+ * @freq1: stopband end frequency (0..pi)
+ * @freq2: passband end frequency (0..pi)
+ * @epsilon: fall off at passband frequency (0..1)
+ * @a: root polynomial coefficients a[0..iorder]
+ * @b: pole polynomial coefficients b[0..iorder]
+ * Tschebyscheff type 1 bandpass filter.
+ */
+void
+gsl_filter_tscheb1_bp (unsigned int iorder,
+ double freq1, /* 0..pi */
+ double freq2, /* 0..pi */
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b)
+{
+ unsigned int iorder2 = iorder >> 1;
+ GslComplex *roots = g_newa (GslComplex, iorder2);
+ GslComplex *poles = g_newa (GslComplex, iorder2);
+ double theta;
+
+ g_return_if_fail ((iorder & 0x01) == 0);
+ g_return_if_fail (freq1 > 0);
+ g_return_if_fail (freq1 < freq2);
+ g_return_if_fail (freq2 < GSL_PI);
+
+ theta = 2. * atan2 (1., cotan ((freq2 - freq1) * 0.5));
+
+ gsl_filter_tscheb1_rp (iorder2, theta, epsilon, roots, poles);
+ band_filter_common (iorder, freq1, freq2, epsilon, roots, poles, a, b, TRUE, TRUE);
+}
+
+/**
+ * gsl_filter_tscheb2_bp
+ * @iorder: filter order (must be even)
+ * @freq1: stopband end frequency (0..pi)
+ * @freq2: passband end frequency (0..pi)
+ * @steepness: frequency steepness factor
+ * @epsilon: fall off at passband frequency (0..1)
+ * @a: root polynomial coefficients a[0..iorder]
+ * @b: pole polynomial coefficients b[0..iorder]
+ * Tschebyscheff type 2 bandpass filter.
+ */
+void
+gsl_filter_tscheb2_bp (unsigned int iorder,
+ double freq1, /* 0..pi */
+ double freq2, /* 0..pi */
+ double steepness,
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b)
+{
+ unsigned int iorder2 = iorder >> 1;
+ GslComplex *roots = g_newa (GslComplex, iorder2);
+ GslComplex *poles = g_newa (GslComplex, iorder2);
+ double theta;
+
+ g_return_if_fail ((iorder & 0x01) == 0);
+ g_return_if_fail (freq1 > 0);
+ g_return_if_fail (freq1 < freq2);
+ g_return_if_fail (freq2 < GSL_PI);
+
+ theta = 2. * atan2 (1., cotan ((freq2 - freq1) * 0.5));
+
+ gsl_filter_tscheb2_rp (iorder2, theta, steepness, epsilon, roots, poles);
+ band_filter_common (iorder, freq1, freq2, epsilon, roots, poles, a, b, TRUE, FALSE);
+}
+
+
+/* --- bandstop filters --- */
+/**
+ * gsl_filter_butter_bs
+ * @iorder: filter order (must be even)
+ * @freq1: passband end frequency (0..pi)
+ * @freq2: stopband end frequency (0..pi)
+ * @epsilon: fall off at passband frequency (0..1)
+ * @a: root polynomial coefficients a[0..iorder]
+ * @b: pole polynomial coefficients b[0..iorder]
+ * Butterworth bandstop filter.
+ */
+void
+gsl_filter_butter_bs (unsigned int iorder,
+ double freq1, /* 0..pi */
+ double freq2, /* 0..pi */
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b)
+{
+ unsigned int iorder2 = iorder >> 1;
+ GslComplex *roots = g_newa (GslComplex, iorder2);
+ GslComplex *poles = g_newa (GslComplex, iorder2);
+ double theta;
+
+ g_return_if_fail ((iorder & 0x01) == 0);
+ g_return_if_fail (freq1 > 0);
+ g_return_if_fail (freq1 < freq2);
+ g_return_if_fail (freq2 < GSL_PI);
+
+ theta = 2. * atan2 (1., tan ((freq2 - freq1) * 0.5));
+
+ gsl_filter_butter_rp (iorder2, theta, epsilon, roots, poles);
+ band_filter_common (iorder, freq1, freq2, epsilon, roots, poles, a, b, FALSE, FALSE);
+}
+
+/**
+ * gsl_filter_tscheb1_bs
+ * @iorder: filter order (must be even)
+ * @freq1: passband end frequency (0..pi)
+ * @freq2: stopband end frequency (0..pi)
+ * @epsilon: fall off at passband frequency (0..1)
+ * @a: root polynomial coefficients a[0..iorder]
+ * @b: pole polynomial coefficients b[0..iorder]
+ * Tschebyscheff type 1 bandstop filter.
+ */
+void
+gsl_filter_tscheb1_bs (unsigned int iorder,
+ double freq1, /* 0..pi */
+ double freq2, /* 0..pi */
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b)
+{
+ unsigned int iorder2 = iorder >> 1;
+ GslComplex *roots = g_newa (GslComplex, iorder2);
+ GslComplex *poles = g_newa (GslComplex, iorder2);
+ double theta;
+
+ g_return_if_fail ((iorder & 0x01) == 0);
+ g_return_if_fail (freq1 > 0);
+ g_return_if_fail (freq1 < freq2);
+ g_return_if_fail (freq2 < GSL_PI);
+
+ theta = 2. * atan2 (1., tan ((freq2 - freq1) * 0.5));
+
+ gsl_filter_tscheb1_rp (iorder2, theta, epsilon, roots, poles);
+ band_filter_common (iorder, freq1, freq2, epsilon, roots, poles, a, b, FALSE, TRUE);
+}
+
+/**
+ * gsl_filter_tscheb2_bs
+ * @iorder: filter order (must be even)
+ * @freq1: passband end frequency (0..pi)
+ * @freq2: stopband end frequency (0..pi)
+ * @steepness: frequency steepness factor
+ * @epsilon: fall off at passband frequency (0..1)
+ * @a: root polynomial coefficients a[0..iorder]
+ * @b: pole polynomial coefficients b[0..iorder]
+ * Tschebyscheff type 2 bandstop filter.
+ */
+void
+gsl_filter_tscheb2_bs (unsigned int iorder,
+ double freq1, /* 0..pi */
+ double freq2, /* 0..pi */
+ double steepness,
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b)
+{
+ unsigned int iorder2 = iorder >> 1;
+ GslComplex *roots = g_newa (GslComplex, iorder2);
+ GslComplex *poles = g_newa (GslComplex, iorder2);
+ double theta;
+
+ g_return_if_fail ((iorder & 0x01) == 0);
+ g_return_if_fail (freq1 > 0);
+ g_return_if_fail (freq1 < freq2);
+ g_return_if_fail (freq2 < GSL_PI);
+
+ theta = 2. * atan2 (1., tan ((freq2 - freq1) * 0.5));
+
+ gsl_filter_tscheb2_rp (iorder2, theta, steepness, epsilon, roots, poles);
+ band_filter_common (iorder, freq1, freq2, epsilon, roots, poles, a, b, FALSE, FALSE);
+}
+
+
+/* --- tschebyscheff type 1 via generic root-finding --- */
+#if 0
+static void
+tschebyscheff_poly (unsigned int degree,
+ double *v)
+{
+ /* construct all polynomial koefficients */
+ if (degree == 0)
+ v[0] = 1;
+ else if (degree == 1)
+ {
+ v[1] = 1; v[0] = 0;
+ }
+ else
+ {
+ double *u = g_newa (double, 1 + degree);
+
+ u[degree] = 0; u[degree - 1] = 0;
+ tschebyscheff_poly (degree - 2, u);
+
+ v[0] = 0;
+ tschebyscheff_poly (degree - 1, v + 1);
+ gsl_poly_scale (degree - 1, v + 1, 2);
+
+ gsl_poly_sub (degree, v, u);
+ }
+}
+
+static void
+gsl_filter_tscheb1_test (unsigned int iorder,
+ double zomega,
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b)
+{
+ GslComplex *roots = g_newa (GslComplex, iorder * 2), *r;
+ GslComplex *zf = g_newa (GslComplex, 1 + iorder);
+ double *vk = g_newa (double, 1 + iorder), norm;
+ double *q = g_newa (double, 2 * (1 + iorder));
+ double O = gsl_trans_freq2s (zomega);
+ unsigned int i;
+
+ /* calc Vk() */
+ tschebyscheff_poly (iorder, vk);
+
+ /* calc q=1+e^2*Vk()^2 */
+ gsl_poly_mul (q, iorder >> 1, vk, iorder >> 1, vk);
+ iorder *= 2;
+ gsl_poly_scale (iorder, q, epsilon * epsilon);
+ q[0] += 1;
+
+ /* find roots, fix roots by 1/(jO) */
+ gsl_poly_complex_roots (iorder, q, roots);
+ for (i = 0; i < iorder; i++)
+ roots[i] = gsl_complex_mul (roots[i], gsl_complex (0, O));
+
+ /* choose roots from the left half-plane */
+ if (0)
+ g_print ("zhqr-root:\n%s\n", gsl_complex_list (iorder, roots, " "));
+ r = roots;
+ for (i = 0; i < iorder; i++)
+ if (roots[i].re < 0)
+ {
+ r->re = roots[i].re;
+ r->im = roots[i].im;
+ r++;
+ }
+ iorder /= 2;
+
+ /* assert roots found */
+ if (!(r - roots == iorder))
+ {
+ g_print ("ERROR: n_roots=%u != iorder=%u\n", r - roots, iorder);
+ abort ();
+ }
+
+ /* s => z */
+ for (i = 0; i < iorder; i++)
+ roots[i] = gsl_trans_s2z (roots[i]);
+
+ /* z denominator polynomial */
+ gsl_cpoly_from_roots (iorder, zf, roots);
+ for (i = 0; i <= iorder; i++)
+ b[i] = zf[i].re;
+
+ /* z nominator polynomial */
+ for (i = 0; i < iorder; i++)
+ {
+ roots[i].re = -1;
+ roots[i].im = 0;
+ }
+ gsl_cpoly_from_roots (iorder, zf, roots);
+ for (i = 0; i <= iorder; i++)
+ a[i] = zf[i].re;
+
+ /* scale for b[0]==1.0 */
+ gsl_poly_scale (iorder, b, 1.0 / b[0]);
+
+ /* scale maximum to 1.0 */
+ norm = gsl_poly_eval (iorder, a, 1) / gsl_poly_eval (iorder, b, 1);
+ if ((iorder & 0x01) == 0) /* norm is fluctuation minimum */
+ norm /= sqrt (1.0 / (1.0 + epsilon * epsilon));
+ gsl_poly_scale (iorder, a, 1.0 / norm);
+}
+#endif
+
+
+/* --- windowed fir approximation --- */
+/* returns a blackman window: x is supposed to be in the interval [0..1] */
+static inline double
+gsl_blackman_window (double x)
+{
+ if (x < 0)
+ return 0;
+ if (x > 1)
+ return 0;
+ return 0.42 - 0.5 * cos (GSL_PI * x * 2) + 0.08 * cos (4 * GSL_PI * x);
+}
+
+/**
+ * gsl_filter_fir_approx
+ *
+ * @iorder: order of the filter (must be oven, >= 2)
+ * @freq: the frequencies of the transfer function
+ * @value: the desired value of the transfer function
+ *
+ * Approximates a given transfer function with an iorder-coefficient FIR filter.
+ * It is recommended to provide enough frequency values, so that
+ * @n_points >= @iorder.
+ */
+void
+gsl_filter_fir_approx (unsigned int iorder,
+ double *a, /* [0..iorder] */
+ unsigned int n_points,
+ const double *freq,
+ const double *value)
+{
+ /* TODO:
+ *
+ * a) does fft_size matter for the quality of the approximation? i.e. do
+ * larger fft_sizes produce better filters?
+ * b) generalize windowing
+ */
+ unsigned int fft_size = 8;
+ unsigned int point = 0, i;
+ double lfreq = -2, lval = 1.0, rfreq = -1, rval = 1.0;
+ double *fft_in, *fft_out;
+ double ffact;
+
+ g_return_if_fail (iorder >= 2);
+ g_return_if_fail ((iorder & 1) == 0);
+
+ while (fft_size / 2 <= iorder)
+ fft_size *= 2;
+
+ fft_in = g_newa (double, fft_size*2);
+ fft_out = fft_in+fft_size;
+ ffact = 2.0 * GSL_PI / (double)fft_size;
+
+ for (i = 0; i <= fft_size / 2; i++)
+ {
+ double f = (double) i * ffact;
+ double pos, val;
+
+ while (f > rfreq && point != n_points)
+ {
+ lfreq = rfreq;
+ rfreq = freq[point];
+ lval = rval;
+ rval = value[point];
+ point++;
+ }
+
+ pos = (f - lfreq) / (rfreq - lfreq);
+ val = lval * (1.0 - pos) + rval * pos;
+
+ if (i != fft_size / 2)
+ {
+ fft_in[2 * i] = val;
+ fft_in[2 * i + 1] = 0.0;
+ }
+ else
+ fft_in[1] = val;
+ }
+
+ gsl_power2_fftsr (fft_size, fft_in, fft_out);
+
+ for (i = 0; i <= iorder / 2; i++)
+ {
+ double c = fft_out[i] * gsl_blackman_window (0.5 + (double) i / (iorder + 2.0));
+ a[iorder / 2 - i] = c;
+ a[iorder / 2 + i] = c;
+ }
+}
+
+
+/* --- filter evaluation --- */
+void
+gsl_iir_filter_setup (GslIIRFilter *f,
+ guint order,
+ const gdouble *a,
+ const gdouble *b,
+ gdouble *buffer) /* 4*(order+1) */
+{
+ guint i;
+
+ g_return_if_fail (f != NULL && a != NULL && b != NULL && buffer != NULL);
+ g_return_if_fail (order > 0);
+
+ f->order = order;
+ f->a = buffer;
+ f->b = f->a + order + 1;
+ f->w = f->b + order + 1;
+
+ memcpy (f->a, a, sizeof (a[0]) * (order + 1));
+ for (i = 0; i <= order; i++)
+ f->b[i] = -b[i];
+ memset (f->w, 0, sizeof (f->w[0]) * (order + 1) * 2);
+
+ g_return_if_fail (fabs (b[0] - 1.0) < 1e-14);
+}
+
+void
+gsl_iir_filter_change (GslIIRFilter *f,
+ guint order,
+ const gdouble *a,
+ const gdouble *b,
+ gdouble *buffer)
+{
+ guint i;
+
+ g_return_if_fail (f != NULL && a != NULL && b != NULL && buffer != NULL);
+ g_return_if_fail (order > 0);
+
+ /* there's no point in calling this function if f wasn't setup properly
+ * and it's only the As and Bs that changed
+ */
+ g_return_if_fail (f->a == buffer && f->b == f->a + f->order + 1 && f->w == f->b + f->order + 1);
+
+ /* if the order changed there's no chance preserving state */
+ if (f->order != order)
+ {
+ gsl_iir_filter_setup (f, order, a, b, buffer);
+ return;
+ }
+
+ memcpy (f->a, a, sizeof (a[0]) * (order + 1));
+ for (i = 0; i <= order; i++)
+ f->b[i] = -b[i];
+ /* leaving f->w to preserve state */
+
+ g_return_if_fail (fabs (b[0] - 1.0) < 1e-14);
+}
+
+static inline gdouble /* Y */
+filter_step_direct_canon_2 (GslIIRFilter *f,
+ gdouble X)
+{
+ register guint n = f->order;
+ gdouble *a = f->a, *b = f->b, *w = f->w;
+ gdouble x, y, v;
+
+ v = w[n];
+ x = b[n] * v;
+ y = a[n] * v;
+
+ while (--n)
+ {
+ gdouble t1, t2;
+
+ v = w[n];
+ t1 = v * b[n];
+ t2 = v * a[n];
+ w[n+1] = v;
+ x += t1;
+ y += t2;
+ }
+
+ x += X;
+ w[1] = x;
+ y += x * a[0];
+ /* w[0] unused */
+
+ return y;
+}
+
+static inline gdouble /* Y */
+filter_step_direct_canon_1 (GslIIRFilter *f,
+ gdouble X)
+{
+ register guint n = f->order;
+ gdouble *a = f->a, *b = f->b, *w = f->w;
+ gdouble y, v;
+
+ /* w[n] unused */
+ y = X * a[0] + w[0];
+ v = X * a[n] + y * b[n];
+
+ while (--n)
+ {
+ gdouble t = w[n];
+
+ w[n] = v;
+ t += X * a[n];
+ v = y * b[n];
+ v += t;
+ }
+ w[0] = v;
+
+ return y;
+}
+
+#define filter_step filter_step_direct_canon_1
+
+void
+gsl_iir_filter_eval (GslIIRFilter *f,
+ guint n_values,
+ const gfloat *x,
+ gfloat *y)
+{
+ const gfloat *bound;
+
+ g_return_if_fail (f != NULL && x != NULL && y != NULL);
+ g_return_if_fail (f->order > 0);
+
+ bound = x + n_values;
+ while (x < bound)
+ {
+ *y = filter_step (f, *x);
+ x++;
+ y++;
+ }
+}
+
+
+/* --- biquad filters --- */
+void
+gsl_biquad_config_init (GslBiquadConfig *c,
+ GslBiquadType type,
+ GslBiquadNormalize normalize)
+{
+ g_return_if_fail (c != NULL);
+
+ memset (c, 0, sizeof (*c));
+ c->type = type;
+ c->normalize = normalize;
+ gsl_biquad_config_setup (c, 0.5, 3, 1);
+ c->approx_values = TRUE; /* need _setup() */
+}
+
+void
+gsl_biquad_config_setup (GslBiquadConfig *c,
+ gfloat f_fn,
+ gfloat gain,
+ gfloat quality)
+{
+ g_return_if_fail (c != NULL);
+ g_return_if_fail (f_fn >= 0 && f_fn <= 1);
+
+ if (c->type == GSL_BIQUAD_RESONANT_HIGHPASS)
+ f_fn = 1.0 - f_fn;
+ c->f_fn = f_fn; /* nyquist relative (0=DC, 1=nyquist) */
+ c->gain = gain;
+ c->quality = quality; /* FIXME */
+ c->k = tan (c->f_fn * GSL_PI / 2.);
+ c->v = pow (10, c->gain / 20.); /* v=10^(gain[dB]/20) */
+ c->dirty = TRUE;
+ c->approx_values = FALSE;
+}
+
+void
+gsl_biquad_config_approx_freq (GslBiquadConfig *c,
+ gfloat f_fn)
+{
+ g_return_if_fail (f_fn >= 0 && f_fn <= 1);
+
+ if (c->type == GSL_BIQUAD_RESONANT_HIGHPASS)
+ f_fn = 1.0 - f_fn;
+ c->f_fn = f_fn; /* nyquist relative (0=DC, 1=nyquist) */
+ c->k = tan (c->f_fn * GSL_PI / 2.); /* FIXME */
+ c->dirty = TRUE;
+ c->approx_values = TRUE;
+}
+
+void
+gsl_biquad_config_approx_gain (GslBiquadConfig *c,
+ gfloat gain)
+{
+ c->gain = gain;
+ c->v = gsl_approx_exp2 (c->gain * GSL_LOG2POW20_10);
+ c->dirty = TRUE;
+ c->approx_values = TRUE;
+}
+
+static void
+biquad_lpreso (GslBiquadConfig *c,
+ GslBiquadFilter *f)
+{
+ gdouble kk, sqrt2_reso, denominator;
+ gdouble r2p_norm = 0; /* resonance gain to peak gain (pole: -sqrt2_reso+-j) */
+
+ kk = c->k * c->k;
+ sqrt2_reso = 1 / c->v;
+ denominator = 1 + (c->k + sqrt2_reso) * c->k;
+
+ switch (c->normalize)
+ {
+ case GSL_BIQUAD_NORMALIZE_PASSBAND:
+ r2p_norm = kk;
+ break;
+ case GSL_BIQUAD_NORMALIZE_RESONANCE_GAIN:
+ r2p_norm = kk * sqrt2_reso;
+ break;
+ case GSL_BIQUAD_NORMALIZE_PEAK_GAIN:
+ r2p_norm = (GSL_SQRT2 * sqrt2_reso - 1.0) / (sqrt2_reso * sqrt2_reso - 0.5);
+ r2p_norm = r2p_norm > 1 ? kk * sqrt2_reso : kk * r2p_norm * sqrt2_reso;
+ break;
+ }
+ f->xc0 = r2p_norm / denominator;
+ f->xc1 = 2 * f->xc0;
+ f->xc2 = f->xc0;
+ f->yc1 = 2 * (kk - 1) / denominator;
+ f->yc2 = (1 + (c->k - sqrt2_reso) * c->k) / denominator;
+}
+
+void
+gsl_biquad_filter_config (GslBiquadFilter *f,
+ GslBiquadConfig *c,
+ gboolean reset_state)
+{
+ g_return_if_fail (f != NULL);
+ g_return_if_fail (c != NULL);
+
+ if (c->dirty)
+ {
+ switch (c->type)
+ {
+ case GSL_BIQUAD_RESONANT_LOWPASS:
+ biquad_lpreso (c, f);
+ break;
+ case GSL_BIQUAD_RESONANT_HIGHPASS:
+ biquad_lpreso (c, f);
+ f->xc1 = -f->xc1;
+ f->yc1 = -f->yc1;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ c->dirty = FALSE;
+ }
+
+ if (reset_state)
+ f->xd1 = f->xd2 = f->yd1 = f->yd2 = 0;
+}
+
+void
+gsl_biquad_filter_eval (GslBiquadFilter *f,
+ guint n_values,
+ const gfloat *x,
+ gfloat *y)
+{
+ const gfloat *bound;
+ gdouble xc0, xc1, xc2, yc1, yc2, xd1, xd2, yd1, yd2;
+
+ g_return_if_fail (f != NULL && x != NULL && y != NULL);
+
+ xc0 = f->xc0;
+ xc1 = f->xc1;
+ xc2 = f->xc2;
+ yc1 = f->yc1;
+ yc2 = f->yc2;
+ xd1 = f->xd1;
+ xd2 = f->xd2;
+ yd1 = f->yd1;
+ yd2 = f->yd2;
+ bound = x + n_values;
+ while (x < bound)
+ {
+ gdouble k0, k1, k2;
+
+ k2 = xd2 * xc2;
+ k1 = xd1 * xc1;
+ xd2 = xd1;
+ xd1 = *x++;
+ k2 -= yd2 * yc2;
+ k1 -= yd1 * yc1;
+ yd2 = yd1;
+ k0 = xd1 * xc0;
+ yd1 = k2 + k1;
+ *y++ = yd1 += k0;
+ }
+ f->xd1 = xd1;
+ f->xd2 = xd2;
+ f->yd1 = yd1;
+ f->yd2 = yd2;
+}
+
+#if 0
+void
+gsl_biquad_lphp_reso (GslBiquadFilter *c,
+ gfloat f_fn, /* nyquist relative (0=DC, 1=nyquist) */
+ float gain,
+ gboolean design_highpass,
+ GslBiquadNormalize normalize)
+{
+ double k, kk, v;
+ double sqrt2_reso;
+ double denominator;
+ double r2p_norm = 0; /* resonance gain to peak gain (pole: -sqrt2_reso+-j) */
+
+ g_return_if_fail (c != NULL);
+ g_return_if_fail (f_fn >= 0 && f_fn <= 1);
+
+ if (design_highpass)
+ f_fn = 1.0 - f_fn;
+
+ v = pow (10, gain / 20.); /* v=10^(gain[dB]/20) */
+ k = tan (f_fn * GSL_PI / 2.);
+ kk = k * k;
+ sqrt2_reso = 1 / v;
+ denominator = 1 + (k + sqrt2_reso) * k;
+
+ if (0)
+ g_printerr ("BIQUAD-lp: R=%f\n", GSL_SQRT2 * sqrt2_reso);
+
+ switch (normalize)
+ {
+ case GSL_BIQUAD_NORMALIZE_PASSBAND:
+ r2p_norm = kk;
+ break;
+ case GSL_BIQUAD_NORMALIZE_RESONANCE_GAIN:
+ r2p_norm = kk * sqrt2_reso;
+ break;
+ case GSL_BIQUAD_NORMALIZE_PEAK_GAIN:
+ r2p_norm = (GSL_SQRT2 * sqrt2_reso - 1.0) / (sqrt2_reso * sqrt2_reso - 0.5);
+ g_print ("BIQUAD-lp: (peak-gain) r2p_norm = %f \n", r2p_norm);
+ r2p_norm = r2p_norm > 1 ? kk * sqrt2_reso : kk * r2p_norm * sqrt2_reso;
+ break;
+ }
+ c->xc0 = r2p_norm / denominator;
+ c->xc1 = 2 * c->xc0;
+ c->xc2 = c->xc0;
+ c->yc1 = 2 * (kk - 1) / denominator;
+ c->yc2 = (1 + (k - sqrt2_reso) * k) / denominator;
+
+ if (design_highpass)
+ {
+ c->xc1 = -c->xc1;
+ c->yc1 = -c->yc1;
+ }
+ /* normalization notes:
+ * pole: -sqrt2_reso+-j
+ * freq=0.5: reso->peak gain=8adjust:0.9799887, 9adjust:0.98415
+ * resonance gain = 1/(1-R)=sqrt2_reso
+ * sqrt2_reso*(1-R)=1
+ * 1-R=1/sqrt2_reso
+ * R= 1-1/sqrt2_reso
+ * peak gain = 2/(1-R^2)
+ * = 2 * (1 - (1 - 1 / sqrt2_reso) * (1 - 1 / sqrt2_reso))
+ * = 2 - 2 * (1 - 1 / sqrt2_reso)^2
+ */
+}
+#endif
+
+
+/* --- filter scanning -- */
+#define SINE_SCAN_SIZE 1024
+
+/**
+ * gsl_filter_sine_scan
+ *
+ * @order: order of the iir filter
+ * @a: root polynomial coefficients of the filter a[0..order]
+ * @b: pole polynomial coefficients of the filter b[0..order]
+ * @freq: frequency to test
+ * @n_values: number of samples
+ *
+ * This function sends a sine signal of the desired frequency through an IIR
+ * filter, to test the value of the transfer function at a given point. It uses
+ * gsl_iir_filter_eval to do so.
+ *
+ * Compared to a "mathematical approach" of finding the transfer function,
+ * this function makes it possible to see the effects of finite arithmetic
+ * during filter evaluation.
+ *
+ * The first half of the output signal is not considered, since a lot of IIR
+ * filters have a transient phase where also overshoot is possible.
+ *
+ * For n_values, you should specify a reasonable large value. It should be
+ * a lot larger than the filter order, and large enough to let the input
+ * signal become (close to) 1.0 multiple times.
+ */
+gdouble
+gsl_filter_sine_scan (guint order,
+ const gdouble *a,
+ const gdouble *b,
+ gdouble freq,
+ guint n_values)
+{
+ gfloat x[SINE_SCAN_SIZE], y[SINE_SCAN_SIZE];
+ gdouble pos = 0.0;
+ gdouble result = 0.0;
+ GslIIRFilter filter;
+ gdouble *filter_state;
+ guint scan_start = n_values / 2;
+
+ g_return_val_if_fail (order > 0, 0.0);
+ g_return_val_if_fail (a != NULL, 0.0);
+ g_return_val_if_fail (b != NULL, 0.0);
+ g_return_val_if_fail (freq > 0 && freq < GSL_PI, 0.0);
+ g_return_val_if_fail (n_values > 0, 0.0);
+
+ filter_state = g_newa (double, (order + 1) * 4);
+ gsl_iir_filter_setup (&filter, order, a, b, filter_state);
+
+ while (n_values)
+ {
+ guint todo = MIN (n_values, SINE_SCAN_SIZE);
+ guint i;
+
+ for (i = 0; i < todo; i++)
+ {
+ x[i] = sin (pos);
+ pos += freq;
+ }
+
+ gsl_iir_filter_eval (&filter, SINE_SCAN_SIZE, x, y);
+
+ for (i = 0; i < todo; i++)
+ if (n_values - i < scan_start)
+ result = MAX (y[i], result);
+
+ n_values -= todo;
+ }
+ return result;
+}
+
+
+
+
+
+/* vim:set ts=8 sts=2 sw=2: */
diff --git a/flow/gsl/gslfilter.h b/flow/gsl/gslfilter.h
new file mode 100644
index 0000000..3baa7e8
--- /dev/null
+++ b/flow/gsl/gslfilter.h
@@ -0,0 +1,281 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001 Stefan Westerfeld and Tim Janik
+ *
+ * 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.
+ */
+#ifndef __GSL_FILTER_H__
+#define __GSL_FILTER_H__
+
+#include <gsl/gslmath.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* --- transformations --- */
+static inline GslComplex gsl_trans_s2z (GslComplex s);
+static inline double gsl_trans_freq2s (double w);
+static inline double gsl_trans_zepsilon2ss (double epsilon);
+
+
+/* --- filter roots and poles --- */
+void gsl_filter_butter_rp (unsigned int iorder,
+ double freq, /* 0..pi */
+ double epsilon,
+ GslComplex *roots, /* [0..iorder-1] */
+ GslComplex *poles);
+void gsl_filter_tscheb1_rp (unsigned int iorder,
+ double freq, /* 0..pi */
+ double epsilon,
+ GslComplex *roots, /* [0..iorder-1] */
+ GslComplex *poles);
+void gsl_filter_tscheb2_rp (unsigned int iorder,
+ double c_freq, /* 0..pi */
+ double steepness,
+ double epsilon,
+ GslComplex *roots, /* [0..iorder-1] */
+ GslComplex *poles);
+
+
+/* --- tschebyscheff type II steepness --- */
+double gsl_filter_tscheb2_steepness_db (unsigned int iorder,
+ double c_freq,
+ double epsilon,
+ double stopband_db);
+double gsl_filter_tscheb2_steepness (unsigned int iorder,
+ double c_freq,
+ double epsilon,
+ double residue);
+
+
+/* --- lowpass filters --- */
+void gsl_filter_butter_lp (unsigned int iorder,
+ double freq, /* 0..pi */
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b);
+void gsl_filter_tscheb1_lp (unsigned int iorder,
+ double freq, /* 0..pi */
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b);
+void gsl_filter_tscheb2_lp (unsigned int iorder,
+ double c_freq, /* 0..pi */
+ double steepness,
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b);
+
+
+/* --- highpass filters --- */
+void gsl_filter_butter_hp (unsigned int iorder,
+ double freq, /* 0..pi */
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b);
+void gsl_filter_tscheb1_hp (unsigned int iorder,
+ double freq, /* 0..pi */
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b);
+void gsl_filter_tscheb2_hp (unsigned int iorder,
+ double c_freq, /* 0..pi */
+ double steepness,
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b);
+
+
+/* --- bandpass filters --- */
+void gsl_filter_butter_bp (unsigned int iorder,
+ double freq1, /* 0..pi */
+ double freq2, /* 0..pi */
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b);
+void gsl_filter_tscheb1_bp (unsigned int iorder,
+ double freq1, /* 0..pi */
+ double freq2, /* 0..pi */
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b);
+void gsl_filter_tscheb2_bp (unsigned int iorder,
+ double freq1, /* 0..pi */
+ double freq2, /* 0..pi */
+ double steepness,
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b);
+
+
+/* --- bandstop filters --- */
+void gsl_filter_butter_bs (unsigned int iorder,
+ double freq1, /* 0..pi */
+ double freq2, /* 0..pi */
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b);
+void gsl_filter_tscheb1_bs (unsigned int iorder,
+ double freq1, /* 0..pi */
+ double freq2, /* 0..pi */
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b);
+void gsl_filter_tscheb2_bs (unsigned int iorder,
+ double freq1, /* 0..pi */
+ double freq2, /* 0..pi */
+ double steepness,
+ double epsilon,
+ double *a, /* [0..iorder] */
+ double *b);
+
+
+/* --- FIR Filters --- */
+void gsl_filter_fir_approx (unsigned int iorder,
+ double *a, /* [0..iorder] */
+ unsigned int n_points,
+ const double *freq,
+ const double *value);
+
+
+/* --- IIR Filter Evaluation --- */
+typedef struct {
+ guint order;
+ gdouble *a; /* [0..order] */
+ gdouble *b; /* [0..order] */
+ gdouble *w; /* [0..2*order] */
+} GslIIRFilter;
+void gsl_iir_filter_setup (GslIIRFilter *f,
+ guint order,
+ const gdouble *a,
+ const gdouble *b,
+ gdouble *buffer); /* 4*(order+1) */
+void gsl_iir_filter_change (GslIIRFilter *f,
+ guint order,
+ const gdouble *a,
+ const gdouble *b,
+ gdouble *buffer); /* 4*(order+1) */
+void gsl_iir_filter_eval (GslIIRFilter *f,
+ guint n_values,
+ const gfloat *x,
+ gfloat *y);
+
+
+/* --- Biquad Filters --- */
+typedef enum /*< skip >*/
+{
+ GSL_BIQUAD_NORMALIZE_PASSBAND,
+ GSL_BIQUAD_NORMALIZE_RESONANCE_GAIN,
+ GSL_BIQUAD_NORMALIZE_PEAK_GAIN
+} GslBiquadNormalize;
+
+typedef enum /*< skip >*/
+{
+ GSL_BIQUAD_RESONANT_LOWPASS = 1,
+ GSL_BIQUAD_RESONANT_HIGHPASS,
+ GSL_BIQUAD_LOWSHELVE,
+ GSL_BIQUAD_HIGHSHELVE,
+ GSL_BIQUAD_PEAK
+} GslBiquadType;
+
+typedef struct {
+ GslBiquadType type;
+ GslBiquadNormalize normalize; /* high/low pass */
+ gfloat f_fn;
+ gfloat gain;
+ gfloat quality; /* peak/notch */
+ guint dirty : 1; /* post filter_config() changes? */
+ guint approx_values : 1; /* biquad_config_approx_*() called? */
+ /*< private >*/
+ gdouble k, v;
+} GslBiquadConfig;
+
+typedef struct {
+ gdouble xc0, xc1, xc2;
+ gdouble yc1, yc2; /* yc0==1 */
+ gdouble xd1, xd2, yd1, yd2; /* history */
+} GslBiquadFilter;
+
+void gsl_biquad_config_init (GslBiquadConfig *c,
+ GslBiquadType type,
+ GslBiquadNormalize normalize);
+void gsl_biquad_config_setup (GslBiquadConfig *c,
+ gfloat f_fn,
+ gfloat gain,
+ gfloat quality);
+void gsl_biquad_config_approx_freq (GslBiquadConfig *c,
+ gfloat f_fn);
+void gsl_biquad_config_approx_gain (GslBiquadConfig *c,
+ gfloat gain);
+void gsl_biquad_filter_config (GslBiquadFilter *f,
+ GslBiquadConfig *c,
+ gboolean reset_state);
+void gsl_biquad_filter_eval (GslBiquadFilter *f,
+ guint n_values,
+ const gfloat *x,
+ gfloat *y);
+
+
+/* --- filter scanning -- */
+gdouble gsl_filter_sine_scan (guint order,
+ const gdouble *a,
+ const gdouble *b,
+ gdouble freq,
+ guint n_values);
+
+
+/* --- implementations --- */
+static inline GslComplex
+gsl_trans_s2z (GslComplex s)
+{
+ /* 1 + (Td/2) * s
+ * z = ----------------
+ * 1 - (Td/2) * s
+ */
+ GslComplex one = { 1, 0 };
+ return gsl_complex_div (gsl_complex_add (one, s), gsl_complex_sub (one, s));
+ /* return gsl_complex_div (gsl_complex_sub (s, one), gsl_complex_add (s, one)); */
+}
+static inline double
+gsl_trans_freq2s (double w)
+{
+ return tan (w / 2.);
+}
+static inline double
+gsl_trans_zepsilon2ss (double zepsilon)
+{
+ double e2 = (1.0 - zepsilon) * (1.0 - zepsilon);
+ /* 1___ _________________
+ * | \ | 1.0
+ * |-----\<---- 1 - zepsilon zepsilon = \ | ----------------
+ * |_______\________________ \| 1 + sepsilon^2
+ */
+ return sqrt ((1.0 - e2) / e2);
+}
+static inline double
+gsl_trans_freq2z (double w)
+{
+ return atan (w) * 2.;
+}
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_FILTER_H__ */ /* vim:set ts=8 sw=2 sts=2: */
diff --git a/flow/gsl/gslglib.c b/flow/gsl/gslglib.c
new file mode 100644
index 0000000..f913df2
--- /dev/null
+++ b/flow/gsl/gslglib.c
@@ -0,0 +1,2400 @@
+#include "gsl/gslglib.h"
+#include "gsl/gsldefs.h"
+
+#include <locale.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#define GLIB_SIZEOF_INTMAX (GSL_SIZEOF_STD_INTMAX_T ? GSL_SIZEOF_STD_INTMAX_T : 8 /* educated guess */)
+
+gpointer g_malloc (gulong n_bytes) { void*p = malloc(n_bytes); GSL_ASSERT(p!=0); return p; }
+gpointer g_malloc0 (gulong n_bytes) { return memset(g_malloc(n_bytes),0,n_bytes); }
+gpointer g_realloc (gpointer mem,
+ gulong n_bytes) { void*p = realloc(mem,n_bytes); GSL_ASSERT(p!=0); return p; }
+void g_free (gpointer mem) { if (mem) free(mem); }
+void g_usleep (unsigned long usec) { usleep (usec); }
+char* g_strerror(int e) { return strerror (e); }
+
+
+gpointer g_memdup (gconstpointer mem, guint byte_size) { gpointer new_mem; if (mem) { new_mem = g_malloc (byte_size); memcpy (new_mem, mem, byte_size); } else new_mem = NULL; return new_mem; }
+gchar* g_strdup (const gchar *str) { gchar *new_str; if (str) { new_str = g_new (char, strlen (str) + 1); strcpy (new_str, str); } else new_str = NULL; return new_str; }
+gchar* g_strndup (const gchar *str, gsize n) { gchar *new_str; if (str) { new_str = g_new (gchar, n + 1); strncpy (new_str, str, n); new_str[n] = '\0'; } else new_str = NULL; return new_str; }
+gchar*g_strconcat (const gchar *string1, ...){ gsize l; va_list args; gchar *s; gchar *concat; gchar *ptr; g_return_val_if_fail (string1 != NULL, NULL); l = 1 + strlen (string1); va_start (args, string1); s = va_arg (args, gchar*); while (s) { l += strlen (s); s = va_arg (args, gchar*); } va_end (args); concat = g_new (gchar, l); ptr = concat; ptr = g_stpcpy (ptr, string1); va_start (args, string1); s = va_arg (args, gchar*); while (s) { ptr = g_stpcpy (ptr, s); s = va_arg (args, gchar*); } va_end (args); return concat; }
+
+gchar*
+g_strdup_printf (const gchar *format,
+ ...)
+{
+ gchar *buffer;
+ va_list args;
+
+ va_start (args, format);
+ buffer = g_strdup_vprintf (format, args);
+ va_end (args);
+
+ return buffer;
+}
+
+
+gchar*
+g_strdup_vprintf (const gchar *format,
+ va_list args1)
+{
+ gchar *buffer;
+#ifdef HAVE_VASPRINTF
+ if (vasprintf (&buffer, format, args1) < 0)
+ buffer = NULL;
+#else
+ va_list args2;
+
+ G_VA_COPY (args2, args1);
+
+ buffer = g_new (gchar, g_printf_string_upper_bound (format, args1));
+
+ vsprintf (buffer, format, args2);
+ va_end (args2);
+#endif
+ return buffer;
+}
+gchar *
+g_stpcpy (gchar *dest,
+ const gchar *src)
+{
+#ifdef GLIB_HAVE_STPCPY
+ g_return_val_if_fail (dest != NULL, NULL);
+ g_return_val_if_fail (src != NULL, NULL);
+ return stpcpy (dest, src);
+#else
+ register gchar *d = dest;
+ register const gchar *s = src;
+
+ g_return_val_if_fail (dest != NULL, NULL);
+ g_return_val_if_fail (src != NULL, NULL);
+ do
+ *d++ = *s;
+ while (*s++ != '\0');
+
+ return d - 1;
+#endif
+}
+
+gchar *
+g_strescape (const gchar *source,
+ const gchar *exceptions)
+{
+ const guchar *p;
+ gchar *dest;
+ gchar *q;
+ guchar excmap[256];
+
+ g_return_val_if_fail (source != NULL, NULL);
+
+ p = (guchar *) source;
+ /* Each source byte needs maximally four destination chars (\777) */
+ q = dest = g_malloc (strlen (source) * 4 + 1);
+
+ memset (excmap, 0, 256);
+ if (exceptions)
+ {
+ guchar *e = (guchar *) exceptions;
+
+ while (*e)
+ {
+ excmap[*e] = 1;
+ e++;
+ }
+ }
+
+ while (*p)
+ {
+ if (excmap[*p])
+ *q++ = *p;
+ else
+ {
+ switch (*p)
+ {
+ case '\b':
+ *q++ = '\\';
+ *q++ = 'b';
+ break;
+ case '\f':
+ *q++ = '\\';
+ *q++ = 'f';
+ break;
+ case '\n':
+ *q++ = '\\';
+ *q++ = 'n';
+ break;
+ case '\r':
+ *q++ = '\\';
+ *q++ = 'r';
+ break;
+ case '\t':
+ *q++ = '\\';
+ *q++ = 't';
+ break;
+ case '\\':
+ *q++ = '\\';
+ *q++ = '\\';
+ break;
+ case '"':
+ *q++ = '\\';
+ *q++ = '"';
+ break;
+ default:
+ if ((*p < ' ') || (*p >= 0177))
+ {
+ *q++ = '\\';
+ *q++ = '0' + (((*p) >> 6) & 07);
+ *q++ = '0' + (((*p) >> 3) & 07);
+ *q++ = '0' + ((*p) & 07);
+ }
+ else
+ *q++ = *p;
+ break;
+ }
+ }
+ p++;
+ }
+ *q = 0;
+ return dest;
+}
+
+
+
+
+guint g_direct_hash (gconstpointer v) { return GPOINTER_TO_UINT (v); }
+gboolean g_direct_equal (gconstpointer v1, gconstpointer v2) { return v1 == v2; }
+gboolean g_str_equal (gconstpointer v1, gconstpointer v2) { const gchar *string1 = v1; const gchar *string2 = v2; return strcmp (string1, string2) == 0; }
+guint g_str_hash (gconstpointer key) { const char *p = key; guint h = *p; if (h) for (p += 1; *p != '\0'; p++) h = (h << 5) - h + *p; return h; }
+
+
+void
+gsl_g_log (const gchar*msg,const char *format, va_list ap)
+{
+ if (msg) printf ("\n%s",msg);
+ vprintf(format, ap);
+ if (msg) printf ("\n");
+}
+
+void
+gsl_g_print_fd (int fd, const char *format, va_list ap)
+{
+ g_return_if_fail (fd == 1 || fd == 2);
+ if (fd == 1)
+ vprintf (format, ap);
+ else
+ vfprintf (stderr, format, ap);
+}
+
+gchar*
+gsl_g_convert (const gchar *str,
+ gsize len, /* gssize */
+ const gchar *to_codeset,
+ const gchar *from_codeset,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ void **error) /* GError */
+{
+ g_error ("g_convert not implemented");
+
+ /* not reached: */
+ return 0;
+}
+
+
+/* --- GScanner --- */
+
+#ifdef HAVE_SNPRINTF
+/* FIXME: might want to do the configure test in gsl instead of arts */
+#define g_snprintf snprintf
+#else
+#define g_snprintf gsl_g_snprintf
+static void
+gsl_g_snprintf (gchar *out_buffer,
+ size_t size,
+ const gchar *format,
+ ...)
+{
+ gchar *buffer;
+ va_list args;
+
+ /* print string into large enough buffer */
+ va_start (args, format);
+ buffer = g_strdup_printf (format, args);
+ va_end (args);
+
+ /* copy the first size bytes into out_buffer */
+ strncpy (out_buffer, buffer, size);
+ out_buffer[ size - 1 ] = '\0';
+ g_free (buffer);
+}
+#endif
+
+
+struct _GString
+{
+ gchar *str;
+ guint len;
+};
+
+static GString*
+g_string_new(const gchar* s)
+{
+ GString *gstr=g_new0(GString,1);
+ gstr->str= g_strdup(s);
+ gstr->len=strlen(s);
+ return gstr;
+}
+static GString*
+g_string_append_c(GString*gstr, int ch)
+{
+ gstr->str=g_renew(gchar,gstr->str,++gstr->len + 1);
+ gstr->str[gstr->len-1]=ch;
+ gstr->str[gstr->len]=0;
+ return gstr;
+}
+static void
+g_string_free(GString*gstr, int freeme)
+{
+ if(freeme)g_free(gstr->str);g_free(gstr);
+}
+
+
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * GScanner: Flexible lexical scanner for general purpose.
+ * Copyright (C) 1997, 1998 Tim Janik
+ *
+ * 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.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GLib Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+
+/* --- defines --- */
+#define to_lower(c) ( \
+ (guchar) ( \
+ ( (((guchar)(c))>='A' && ((guchar)(c))<='Z') * ('a'-'A') ) | \
+ ( (((guchar)(c))>=192 && ((guchar)(c))<=214) * (224-192) ) | \
+ ( (((guchar)(c))>=216 && ((guchar)(c))<=222) * (248-216) ) | \
+ ((guchar)(c)) \
+ ) \
+)
+#define READ_BUFFER_SIZE (4000)
+
+
+/* --- typedefs --- */
+typedef struct _GScannerKey GScannerKey;
+
+struct _GScannerKey
+{
+ guint scope_id;
+ gchar *symbol;
+ gpointer value;
+};
+
+
+
+/* --- variables --- */
+#define g_scanner_config_template _cplusplus_wont_have_a_problem_with_this_foog_scanner_config_template
+static GScannerConfig g_scanner_config_template =
+{
+ (
+ " \t\r\n"
+ ) /* cset_skip_characters */,
+ (
+ G_CSET_a_2_z
+ "_"
+ G_CSET_A_2_Z
+ ) /* cset_identifier_first */,
+ (
+ G_CSET_a_2_z
+ "_"
+ G_CSET_A_2_Z
+ G_CSET_DIGITS
+ G_CSET_LATINS
+ G_CSET_LATINC
+ ) /* cset_identifier_nth */,
+ ( "#\n" ) /* cpair_comment_single */,
+
+ FALSE /* case_sensitive */,
+
+ TRUE /* skip_comment_multi */,
+ TRUE /* skip_comment_single */,
+ TRUE /* scan_comment_multi */,
+ TRUE /* scan_identifier */,
+ FALSE /* scan_identifier_1char */,
+ FALSE /* scan_identifier_NULL */,
+ TRUE /* scan_symbols */,
+ FALSE /* scan_binary */,
+ TRUE /* scan_octal */,
+ TRUE /* scan_float */,
+ TRUE /* scan_hex */,
+ FALSE /* scan_hex_dollar */,
+ TRUE /* scan_string_sq */,
+ TRUE /* scan_string_dq */,
+ TRUE /* numbers_2_int */,
+ FALSE /* int_2_float */,
+ FALSE /* identifier_2_string */,
+ TRUE /* char_2_token */,
+ FALSE /* symbol_2_token */,
+ FALSE /* scope_0_fallback */,
+};
+
+
+/* --- prototypes --- */
+static inline
+GScannerKey* g_scanner_lookup_internal (GScanner *scanner,
+ guint scope_id,
+ const gchar *symbol);
+static gboolean g_scanner_key_equal (gconstpointer v1,
+ gconstpointer v2);
+static guint g_scanner_key_hash (gconstpointer v);
+static void g_scanner_get_token_ll (GScanner *scanner,
+ GTokenType *token_p,
+ GTokenValue *value_p,
+ guint *line_p,
+ guint *position_p);
+static void g_scanner_get_token_i (GScanner *scanner,
+ GTokenType *token_p,
+ GTokenValue *value_p,
+ guint *line_p,
+ guint *position_p);
+
+static guchar g_scanner_peek_next_char (GScanner *scanner);
+static guchar g_scanner_get_char (GScanner *scanner,
+ guint *line_p,
+ guint *position_p);
+static void g_scanner_msg_handler (GScanner *scanner,
+ gchar *message,
+ gint is_error);
+
+
+/* --- functions --- */
+static inline gint
+g_scanner_char_2_num (guchar c,
+ guchar base)
+{
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'A' && c <= 'Z')
+ c -= 'A' - 10;
+ else if (c >= 'a' && c <= 'z')
+ c -= 'a' - 10;
+ else
+ return -1;
+
+ if (c < base)
+ return c;
+
+ return -1;
+}
+
+GScanner*
+g_scanner_new (const GScannerConfig *config_templ)
+{
+ GScanner *scanner;
+
+ if (!config_templ)
+ config_templ = &g_scanner_config_template;
+
+ scanner = g_new0 (GScanner, 1);
+
+ scanner->user_data = NULL;
+ scanner->max_parse_errors = 0;
+ scanner->parse_errors = 0;
+ scanner->input_name = NULL;
+ /* g_datalist_init (&scanner->qdata); */
+
+ scanner->config = g_new0 (GScannerConfig, 1);
+
+ scanner->config->case_sensitive = config_templ->case_sensitive;
+ scanner->config->cset_skip_characters = config_templ->cset_skip_characters;
+ if (!scanner->config->cset_skip_characters)
+ scanner->config->cset_skip_characters = "";
+ scanner->config->cset_identifier_first = config_templ->cset_identifier_first;
+ scanner->config->cset_identifier_nth = config_templ->cset_identifier_nth;
+ scanner->config->cpair_comment_single = config_templ->cpair_comment_single;
+ scanner->config->skip_comment_multi = config_templ->skip_comment_multi;
+ scanner->config->skip_comment_single = config_templ->skip_comment_single;
+ scanner->config->scan_comment_multi = config_templ->scan_comment_multi;
+ scanner->config->scan_identifier = config_templ->scan_identifier;
+ scanner->config->scan_identifier_1char = config_templ->scan_identifier_1char;
+ scanner->config->scan_identifier_NULL = config_templ->scan_identifier_NULL;
+ scanner->config->scan_symbols = config_templ->scan_symbols;
+ scanner->config->scan_binary = config_templ->scan_binary;
+ scanner->config->scan_octal = config_templ->scan_octal;
+ scanner->config->scan_float = config_templ->scan_float;
+ scanner->config->scan_hex = config_templ->scan_hex;
+ scanner->config->scan_hex_dollar = config_templ->scan_hex_dollar;
+ scanner->config->scan_string_sq = config_templ->scan_string_sq;
+ scanner->config->scan_string_dq = config_templ->scan_string_dq;
+ scanner->config->numbers_2_int = config_templ->numbers_2_int;
+ scanner->config->int_2_float = config_templ->int_2_float;
+ scanner->config->identifier_2_string = config_templ->identifier_2_string;
+ scanner->config->char_2_token = config_templ->char_2_token;
+ scanner->config->symbol_2_token = config_templ->symbol_2_token;
+ scanner->config->scope_0_fallback = config_templ->scope_0_fallback;
+
+ scanner->token = G_TOKEN_NONE;
+ scanner->value.v_int = 0;
+ scanner->line = 1;
+ scanner->position = 0;
+
+ scanner->next_token = G_TOKEN_NONE;
+ scanner->next_value.v_int = 0;
+ scanner->next_line = 1;
+ scanner->next_position = 0;
+
+ scanner->symbol_table = g_hash_table_new (g_scanner_key_hash, g_scanner_key_equal);
+ scanner->input_fd = -1;
+ scanner->text = NULL;
+ scanner->text_end = NULL;
+ scanner->buffer = NULL;
+ scanner->scope_id = 0;
+
+ scanner->msg_handler = g_scanner_msg_handler;
+
+ return scanner;
+}
+
+static inline void
+g_scanner_free_value (GTokenType *token_p,
+ GTokenValue *value_p)
+{
+ switch (*token_p)
+ {
+ case G_TOKEN_STRING:
+ case G_TOKEN_IDENTIFIER:
+ case G_TOKEN_IDENTIFIER_NULL:
+ case G_TOKEN_COMMENT_SINGLE:
+ case G_TOKEN_COMMENT_MULTI:
+ g_free (value_p->v_string);
+ break;
+
+ default:
+ break;
+ }
+
+ *token_p = G_TOKEN_NONE;
+}
+
+static void
+g_scanner_destroy_symbol_table_entry (gpointer _key,
+ gpointer _value,
+ gpointer _data)
+{
+ GScannerKey *key = _key;
+
+ g_free (key->symbol);
+ g_free (key);
+}
+
+void
+g_scanner_destroy (GScanner *scanner)
+{
+ g_return_if_fail (scanner != NULL);
+
+ /* g_datalist_clear (&scanner->qdata); */
+ g_hash_table_foreach (scanner->symbol_table,
+ g_scanner_destroy_symbol_table_entry, NULL);
+ g_hash_table_destroy (scanner->symbol_table);
+ g_scanner_free_value (&scanner->token, &scanner->value);
+ g_scanner_free_value (&scanner->next_token, &scanner->next_value);
+ g_free (scanner->config);
+ g_free (scanner->buffer);
+ g_free (scanner);
+}
+
+static void
+g_scanner_msg_handler (GScanner *scanner,
+ gchar *message,
+ gint is_error)
+{
+ g_return_if_fail (scanner != NULL);
+
+ fprintf (stderr, "%s:%d: ", scanner->input_name, scanner->line);
+ if (is_error)
+ fprintf (stderr, "error: ");
+ fprintf (stderr, "%s\n", message);
+}
+
+void
+g_scanner_error (GScanner *scanner,
+ const gchar *format,
+ ...)
+{
+ g_return_if_fail (scanner != NULL);
+ g_return_if_fail (format != NULL);
+
+ scanner->parse_errors++;
+
+ if (scanner->msg_handler)
+ {
+ va_list args;
+ gchar *string;
+
+ va_start (args, format);
+ string = g_strdup_vprintf (format, args);
+ va_end (args);
+
+ scanner->msg_handler (scanner, string, TRUE);
+
+ g_free (string);
+ }
+}
+
+void
+g_scanner_warn (GScanner *scanner,
+ const gchar *format,
+ ...)
+{
+ g_return_if_fail (scanner != NULL);
+ g_return_if_fail (format != NULL);
+
+ if (scanner->msg_handler)
+ {
+ va_list args;
+ gchar *string;
+
+ va_start (args, format);
+ string = g_strdup_vprintf (format, args);
+ va_end (args);
+
+ scanner->msg_handler (scanner, string, FALSE);
+
+ g_free (string);
+ }
+}
+
+static gboolean
+g_scanner_key_equal (gconstpointer v1,
+ gconstpointer v2)
+{
+ const GScannerKey *key1 = v1;
+ const GScannerKey *key2 = v2;
+
+ return (key1->scope_id == key2->scope_id) && (strcmp (key1->symbol, key2->symbol) == 0);
+}
+
+static guint
+g_scanner_key_hash (gconstpointer v)
+{
+ const GScannerKey *key = v;
+ gchar *c;
+ guint h;
+
+ h = key->scope_id;
+ for (c = key->symbol; *c; c++)
+ h = (h << 5) - h + *c;
+
+ return h;
+}
+
+static inline GScannerKey*
+g_scanner_lookup_internal (GScanner *scanner,
+ guint scope_id,
+ const gchar *symbol)
+{
+ GScannerKey *key_p;
+ GScannerKey key;
+
+ key.scope_id = scope_id;
+
+ if (!scanner->config->case_sensitive)
+ {
+ gchar *d;
+ const gchar *c;
+
+ key.symbol = g_new (gchar, strlen (symbol) + 1);
+ for (d = key.symbol, c = symbol; *c; c++, d++)
+ *d = to_lower (*c);
+ *d = 0;
+ key_p = g_hash_table_lookup (scanner->symbol_table, &key);
+ g_free (key.symbol);
+ }
+ else
+ {
+ key.symbol = (gchar*) symbol;
+ key_p = g_hash_table_lookup (scanner->symbol_table, &key);
+ }
+
+ return key_p;
+}
+
+void
+g_scanner_scope_add_symbol (GScanner *scanner,
+ guint scope_id,
+ const gchar *symbol,
+ gpointer value)
+{
+ GScannerKey *key;
+
+ g_return_if_fail (scanner != NULL);
+ g_return_if_fail (symbol != NULL);
+
+ key = g_scanner_lookup_internal (scanner, scope_id, symbol);
+
+ if (!key)
+ {
+ key = g_new (GScannerKey, 1);
+ key->scope_id = scope_id;
+ key->symbol = g_strdup (symbol);
+ key->value = value;
+ if (!scanner->config->case_sensitive)
+ {
+ gchar *c;
+
+ c = key->symbol;
+ while (*c != 0)
+ {
+ *c = to_lower (*c);
+ c++;
+ }
+ }
+ g_hash_table_insert (scanner->symbol_table, key, key);
+ }
+ else
+ key->value = value;
+}
+
+void
+g_scanner_scope_remove_symbol (GScanner *scanner,
+ guint scope_id,
+ const gchar *symbol)
+{
+ GScannerKey *key;
+
+ g_return_if_fail (scanner != NULL);
+ g_return_if_fail (symbol != NULL);
+
+ key = g_scanner_lookup_internal (scanner, scope_id, symbol);
+
+ if (key)
+ {
+ g_hash_table_remove (scanner->symbol_table, key);
+ g_free (key->symbol);
+ g_free (key);
+ }
+}
+
+gpointer
+g_scanner_lookup_symbol (GScanner *scanner,
+ const gchar *symbol)
+{
+ GScannerKey *key;
+ guint scope_id;
+
+ g_return_val_if_fail (scanner != NULL, NULL);
+
+ if (!symbol)
+ return NULL;
+
+ scope_id = scanner->scope_id;
+ key = g_scanner_lookup_internal (scanner, scope_id, symbol);
+ if (!key && scope_id && scanner->config->scope_0_fallback)
+ key = g_scanner_lookup_internal (scanner, 0, symbol);
+
+ if (key)
+ return key->value;
+ else
+ return NULL;
+}
+
+gpointer
+g_scanner_scope_lookup_symbol (GScanner *scanner,
+ guint scope_id,
+ const gchar *symbol)
+{
+ GScannerKey *key;
+
+ g_return_val_if_fail (scanner != NULL, NULL);
+
+ if (!symbol)
+ return NULL;
+
+ key = g_scanner_lookup_internal (scanner, scope_id, symbol);
+
+ if (key)
+ return key->value;
+ else
+ return NULL;
+}
+
+guint
+g_scanner_set_scope (GScanner *scanner,
+ guint scope_id)
+{
+ guint old_scope_id;
+
+ g_return_val_if_fail (scanner != NULL, 0);
+
+ old_scope_id = scanner->scope_id;
+ scanner->scope_id = scope_id;
+
+ return old_scope_id;
+}
+
+static void
+g_scanner_foreach_internal (gpointer _key,
+ gpointer _value,
+ gpointer _user_data)
+{
+ GScannerKey *key;
+ gpointer *d;
+ GHFunc func;
+ gpointer user_data;
+ guint *scope_id;
+
+ d = _user_data;
+ func = (GHFunc) d[0];
+ user_data = d[1];
+ scope_id = d[2];
+ key = _value;
+
+ if (key->scope_id == *scope_id)
+ func (key->symbol, key->value, user_data);
+}
+
+void
+g_scanner_scope_foreach_symbol (GScanner *scanner,
+ guint scope_id,
+ GHFunc func,
+ gpointer user_data)
+{
+ gpointer d[3];
+
+ g_return_if_fail (scanner != NULL);
+
+ d[0] = (gpointer) func;
+ d[1] = user_data;
+ d[2] = &scope_id;
+
+ g_hash_table_foreach (scanner->symbol_table, g_scanner_foreach_internal, d);
+}
+
+GTokenType
+g_scanner_peek_next_token (GScanner *scanner)
+{
+ g_return_val_if_fail (scanner != NULL, G_TOKEN_EOF);
+
+ if (scanner->next_token == G_TOKEN_NONE)
+ {
+ scanner->next_line = scanner->line;
+ scanner->next_position = scanner->position;
+ g_scanner_get_token_i (scanner,
+ &scanner->next_token,
+ &scanner->next_value,
+ &scanner->next_line,
+ &scanner->next_position);
+ }
+
+ return scanner->next_token;
+}
+
+GTokenType
+g_scanner_get_next_token (GScanner *scanner)
+{
+ g_return_val_if_fail (scanner != NULL, G_TOKEN_EOF);
+
+ if (scanner->next_token != G_TOKEN_NONE)
+ {
+ g_scanner_free_value (&scanner->token, &scanner->value);
+
+ scanner->token = scanner->next_token;
+ scanner->value = scanner->next_value;
+ scanner->line = scanner->next_line;
+ scanner->position = scanner->next_position;
+ scanner->next_token = G_TOKEN_NONE;
+ }
+ else
+ g_scanner_get_token_i (scanner,
+ &scanner->token,
+ &scanner->value,
+ &scanner->line,
+ &scanner->position);
+
+ return scanner->token;
+}
+
+GTokenType
+g_scanner_cur_token (GScanner *scanner)
+{
+ g_return_val_if_fail (scanner != NULL, G_TOKEN_EOF);
+
+ return scanner->token;
+}
+
+GTokenValue
+g_scanner_cur_value (GScanner *scanner)
+{
+ GTokenValue v;
+
+ v.v_int = 0;
+
+ g_return_val_if_fail (scanner != NULL, v);
+
+ /* MSC isn't capable of handling return scanner->value; ? */
+
+ v = scanner->value;
+
+ return v;
+}
+
+guint
+g_scanner_cur_line (GScanner *scanner)
+{
+ g_return_val_if_fail (scanner != NULL, 0);
+
+ return scanner->line;
+}
+
+guint
+g_scanner_cur_position (GScanner *scanner)
+{
+ g_return_val_if_fail (scanner != NULL, 0);
+
+ return scanner->position;
+}
+
+gboolean
+g_scanner_eof (GScanner *scanner)
+{
+ g_return_val_if_fail (scanner != NULL, TRUE);
+
+ return scanner->token == G_TOKEN_EOF;
+}
+
+void
+g_scanner_input_file (GScanner *scanner,
+ gint input_fd)
+{
+ g_return_if_fail (scanner != NULL);
+ g_return_if_fail (input_fd >= 0);
+
+ if (scanner->input_fd >= 0)
+ g_scanner_sync_file_offset (scanner);
+
+ scanner->token = G_TOKEN_NONE;
+ scanner->value.v_int = 0;
+ scanner->line = 1;
+ scanner->position = 0;
+ scanner->next_token = G_TOKEN_NONE;
+
+ scanner->input_fd = input_fd;
+ scanner->text = NULL;
+ scanner->text_end = NULL;
+
+ if (!scanner->buffer)
+ scanner->buffer = g_new (gchar, READ_BUFFER_SIZE + 1);
+}
+
+void
+g_scanner_input_text (GScanner *scanner,
+ const gchar *text,
+ guint text_len)
+{
+ g_return_if_fail (scanner != NULL);
+ if (text_len)
+ g_return_if_fail (text != NULL);
+ else
+ text = NULL;
+
+ if (scanner->input_fd >= 0)
+ g_scanner_sync_file_offset (scanner);
+
+ scanner->token = G_TOKEN_NONE;
+ scanner->value.v_int = 0;
+ scanner->line = 1;
+ scanner->position = 0;
+ scanner->next_token = G_TOKEN_NONE;
+
+ scanner->input_fd = -1;
+ scanner->text = text;
+ scanner->text_end = text + text_len;
+
+ if (scanner->buffer)
+ {
+ g_free (scanner->buffer);
+ scanner->buffer = NULL;
+ }
+}
+
+static guchar
+g_scanner_peek_next_char (GScanner *scanner)
+{
+ if (scanner->text < scanner->text_end)
+ {
+ return *scanner->text;
+ }
+ else if (scanner->input_fd >= 0)
+ {
+ gint count;
+ gchar *buffer;
+
+ buffer = scanner->buffer;
+ do
+ {
+ count = read (scanner->input_fd, buffer, READ_BUFFER_SIZE);
+ }
+ while (count == -1 && (errno == EINTR || errno == EAGAIN));
+
+ if (count < 1)
+ {
+ scanner->input_fd = -1;
+
+ return 0;
+ }
+ else
+ {
+ scanner->text = buffer;
+ scanner->text_end = buffer + count;
+
+ return *buffer;
+ }
+ }
+ else
+ return 0;
+}
+
+void
+g_scanner_sync_file_offset (GScanner *scanner)
+{
+ g_return_if_fail (scanner != NULL);
+
+ /* for file input, rewind the filedescriptor to the current
+ * buffer position and blow the file read ahead buffer. useful for
+ * third party uses of our filedescriptor, which hooks onto the current
+ * scanning position.
+ */
+
+ if (scanner->input_fd >= 0 && scanner->text_end > scanner->text)
+ {
+ gint buffered;
+
+ buffered = scanner->text_end - scanner->text;
+ if (lseek (scanner->input_fd, - buffered, SEEK_CUR) >= 0)
+ {
+ /* we succeeded, blow our buffer's contents now */
+ scanner->text = NULL;
+ scanner->text_end = NULL;
+ }
+ else
+ errno = 0;
+ }
+}
+
+static guchar
+g_scanner_get_char (GScanner *scanner,
+ guint *line_p,
+ guint *position_p)
+{
+ guchar fchar;
+
+ if (scanner->text < scanner->text_end)
+ fchar = *(scanner->text++);
+ else if (scanner->input_fd >= 0)
+ {
+ gint count;
+ gchar *buffer;
+
+ buffer = scanner->buffer;
+ do
+ {
+ count = read (scanner->input_fd, buffer, READ_BUFFER_SIZE);
+ }
+ while (count == -1 && (errno == EINTR || errno == EAGAIN));
+
+ if (count < 1)
+ {
+ scanner->input_fd = -1;
+ fchar = 0;
+ }
+ else
+ {
+ scanner->text = buffer + 1;
+ scanner->text_end = buffer + count;
+ fchar = *buffer;
+ if (!fchar)
+ {
+ g_scanner_sync_file_offset (scanner);
+ scanner->text_end = scanner->text;
+ scanner->input_fd = -1;
+ }
+ }
+ }
+ else
+ fchar = 0;
+
+ if (fchar == '\n')
+ {
+ (*position_p) = 0;
+ (*line_p)++;
+ }
+ else if (fchar)
+ {
+ (*position_p)++;
+ }
+
+ return fchar;
+}
+
+void
+g_scanner_unexp_token (GScanner *scanner,
+ GTokenType expected_token,
+ const gchar *identifier_spec,
+ const gchar *symbol_spec,
+ const gchar *symbol_name,
+ const gchar *message,
+ gint is_error)
+{
+ gchar *token_string;
+ guint token_string_len;
+ gchar *expected_string;
+ guint expected_string_len;
+ const gchar *message_prefix;
+ gboolean print_unexp;
+ void (*msg_handler) (GScanner*, const gchar*, ...);
+
+ g_return_if_fail (scanner != NULL);
+
+ if (is_error)
+ msg_handler = g_scanner_error;
+ else
+ msg_handler = g_scanner_warn;
+
+ if (!identifier_spec)
+ identifier_spec = "identifier";
+ if (!symbol_spec)
+ symbol_spec = "symbol";
+
+ token_string_len = 56;
+ token_string = g_new (gchar, token_string_len + 1);
+ expected_string_len = 64;
+ expected_string = g_new (gchar, expected_string_len + 1);
+ print_unexp = TRUE;
+
+ switch (scanner->token)
+ {
+ case G_TOKEN_EOF:
+ g_snprintf (token_string, token_string_len, "end of file");
+ break;
+
+ default:
+ if (scanner->token >= 1 && scanner->token <= 255)
+ {
+ if ((scanner->token >= ' ' && scanner->token <= '~') ||
+ strchr (scanner->config->cset_identifier_first, scanner->token) ||
+ strchr (scanner->config->cset_identifier_nth, scanner->token))
+ g_snprintf (token_string, expected_string_len, "character `%c'", scanner->token);
+ else
+ g_snprintf (token_string, expected_string_len, "character `\\%o'", scanner->token);
+ break;
+ }
+ else if (!scanner->config->symbol_2_token)
+ {
+ g_snprintf (token_string, token_string_len, "(unknown) token <%d>", scanner->token);
+ break;
+ }
+ /* fall through */
+ case G_TOKEN_SYMBOL:
+ if (expected_token == G_TOKEN_SYMBOL ||
+ (scanner->config->symbol_2_token &&
+ expected_token > G_TOKEN_LAST))
+ print_unexp = FALSE;
+ if (symbol_name)
+ g_snprintf (token_string,
+ token_string_len,
+ "%s%s `%s'",
+ print_unexp ? "" : "invalid ",
+ symbol_spec,
+ symbol_name);
+ else
+ g_snprintf (token_string,
+ token_string_len,
+ "%s%s",
+ print_unexp ? "" : "invalid ",
+ symbol_spec);
+ break;
+
+ case G_TOKEN_ERROR:
+ print_unexp = FALSE;
+ expected_token = G_TOKEN_NONE;
+ switch (scanner->value.v_error)
+ {
+ case G_ERR_UNEXP_EOF:
+ g_snprintf (token_string, token_string_len, "scanner: unexpected end of file");
+ break;
+
+ case G_ERR_UNEXP_EOF_IN_STRING:
+ g_snprintf (token_string, token_string_len, "scanner: unterminated string constant");
+ break;
+
+ case G_ERR_UNEXP_EOF_IN_COMMENT:
+ g_snprintf (token_string, token_string_len, "scanner: unterminated comment");
+ break;
+
+ case G_ERR_NON_DIGIT_IN_CONST:
+ g_snprintf (token_string, token_string_len, "scanner: non digit in constant");
+ break;
+
+ case G_ERR_FLOAT_RADIX:
+ g_snprintf (token_string, token_string_len, "scanner: invalid radix for floating constant");
+ break;
+
+ case G_ERR_FLOAT_MALFORMED:
+ g_snprintf (token_string, token_string_len, "scanner: malformed floating constant");
+ break;
+
+ case G_ERR_DIGIT_RADIX:
+ g_snprintf (token_string, token_string_len, "scanner: digit is beyond radix");
+ break;
+
+ case G_ERR_UNKNOWN:
+ default:
+ g_snprintf (token_string, token_string_len, "scanner: unknown error");
+ break;
+ }
+ break;
+
+ case G_TOKEN_CHAR:
+ g_snprintf (token_string, token_string_len, "character `%c'", scanner->value.v_char);
+ break;
+
+ case G_TOKEN_IDENTIFIER:
+ case G_TOKEN_IDENTIFIER_NULL:
+ if (expected_token == G_TOKEN_IDENTIFIER ||
+ expected_token == G_TOKEN_IDENTIFIER_NULL)
+ print_unexp = FALSE;
+ g_snprintf (token_string,
+ token_string_len,
+ "%s%s `%s'",
+ print_unexp ? "" : "invalid ",
+ identifier_spec,
+ scanner->token == G_TOKEN_IDENTIFIER ? scanner->value.v_string : "null");
+ break;
+
+ case G_TOKEN_BINARY:
+ case G_TOKEN_OCTAL:
+ case G_TOKEN_INT:
+ case G_TOKEN_HEX:
+ g_snprintf (token_string, token_string_len, "number `%ld'", scanner->value.v_int);
+ break;
+
+ case G_TOKEN_FLOAT:
+ g_snprintf (token_string, token_string_len, "number `%.3f'", scanner->value.v_float);
+ break;
+
+ case G_TOKEN_STRING:
+ if (expected_token == G_TOKEN_STRING)
+ print_unexp = FALSE;
+ g_snprintf (token_string,
+ token_string_len,
+ "%s%sstring constant \"%s\"",
+ print_unexp ? "" : "invalid ",
+ scanner->value.v_string[0] == 0 ? "empty " : "",
+ scanner->value.v_string);
+ token_string[token_string_len - 2] = '"';
+ token_string[token_string_len - 1] = 0;
+ break;
+
+ case G_TOKEN_COMMENT_SINGLE:
+ case G_TOKEN_COMMENT_MULTI:
+ g_snprintf (token_string, token_string_len, "comment");
+ break;
+
+ case G_TOKEN_NONE:
+ /* somehow the user's parsing code is screwed, there isn't much
+ * we can do about it.
+ * Note, a common case to trigger this is
+ * g_scanner_peek_next_token(); g_scanner_unexp_token();
+ * without an intermediate g_scanner_get_next_token().
+ */
+ g_assert_not_reached ();
+ break;
+ }
+
+
+ switch (expected_token)
+ {
+ gboolean need_valid;
+
+ default:
+ if (expected_token >= 1 && expected_token <= 255)
+ {
+ if ((expected_token >= ' ' && expected_token <= '~') ||
+ strchr (scanner->config->cset_identifier_first, expected_token) ||
+ strchr (scanner->config->cset_identifier_nth, expected_token))
+ g_snprintf (expected_string, expected_string_len, "character `%c'", expected_token);
+ else
+ g_snprintf (expected_string, expected_string_len, "character `\\%o'", expected_token);
+ break;
+ }
+ else if (!scanner->config->symbol_2_token)
+ {
+ g_snprintf (expected_string, expected_string_len, "(unknown) token <%d>", expected_token);
+ break;
+ }
+ /* fall through */
+ case G_TOKEN_SYMBOL:
+ need_valid = (scanner->token == G_TOKEN_SYMBOL ||
+ (scanner->config->symbol_2_token &&
+ scanner->token > G_TOKEN_LAST));
+ g_snprintf (expected_string,
+ expected_string_len,
+ "%s%s",
+ need_valid ? "valid " : "",
+ symbol_spec);
+ /* FIXME: should we attempt to lookup the symbol_name for symbol_2_token? */
+ break;
+
+ case G_TOKEN_INT:
+ g_snprintf (expected_string, expected_string_len, "%snumber (integer)",
+ scanner->token == G_TOKEN_INT ? "valid " : "");
+ break;
+
+ case G_TOKEN_FLOAT:
+ g_snprintf (expected_string, expected_string_len, "%snumber (float)",
+ scanner->token == G_TOKEN_FLOAT ? "valid " : "");
+ break;
+
+ case G_TOKEN_STRING:
+ g_snprintf (expected_string,
+ expected_string_len,
+ "%sstring constant",
+ scanner->token == G_TOKEN_STRING ? "valid " : "");
+ break;
+
+ case G_TOKEN_IDENTIFIER:
+ case G_TOKEN_IDENTIFIER_NULL:
+ g_snprintf (expected_string,
+ expected_string_len,
+ "%s%s",
+ (scanner->token == G_TOKEN_IDENTIFIER_NULL ||
+ scanner->token == G_TOKEN_IDENTIFIER ? "valid " : ""),
+ identifier_spec);
+ break;
+
+ case G_TOKEN_EOF:
+ g_snprintf (expected_string, expected_string_len, "end of file");
+ break;
+
+ case G_TOKEN_NONE:
+ break;
+ }
+
+ if (message && message[0] != 0)
+ message_prefix = " - ";
+ else
+ {
+ message_prefix = "";
+ message = "";
+ }
+
+ if (expected_token != G_TOKEN_NONE)
+ {
+ if (print_unexp)
+ msg_handler (scanner,
+ "unexpected %s, expected %s%s%s",
+ token_string,
+ expected_string,
+ message_prefix,
+ message);
+ else
+ msg_handler (scanner,
+ "%s, expected %s%s%s",
+ token_string,
+ expected_string,
+ message_prefix,
+ message);
+ }
+ else
+ {
+ if (print_unexp)
+ msg_handler (scanner,
+ "unexpected %s%s%s",
+ token_string,
+ message_prefix,
+ message);
+ else
+ msg_handler (scanner,
+ "%s%s%s",
+ token_string,
+ message_prefix,
+ message);
+ }
+
+ g_free (token_string);
+ g_free (expected_string);
+}
+
+static void
+g_scanner_get_token_i (GScanner *scanner,
+ GTokenType *token_p,
+ GTokenValue *value_p,
+ guint *line_p,
+ guint *position_p)
+{
+ do
+ {
+ g_scanner_free_value (token_p, value_p);
+ g_scanner_get_token_ll (scanner, token_p, value_p, line_p, position_p);
+ }
+ while (((*token_p > 0 && *token_p < 256) &&
+ strchr (scanner->config->cset_skip_characters, *token_p)) ||
+ (*token_p == G_TOKEN_CHAR &&
+ strchr (scanner->config->cset_skip_characters, value_p->v_char)) ||
+ (*token_p == G_TOKEN_COMMENT_MULTI &&
+ scanner->config->skip_comment_multi) ||
+ (*token_p == G_TOKEN_COMMENT_SINGLE &&
+ scanner->config->skip_comment_single));
+
+ switch (*token_p)
+ {
+ case G_TOKEN_IDENTIFIER:
+ if (scanner->config->identifier_2_string)
+ *token_p = G_TOKEN_STRING;
+ break;
+
+ case G_TOKEN_SYMBOL:
+ if (scanner->config->symbol_2_token)
+ *token_p = (GTokenType) value_p->v_symbol;
+ break;
+
+ case G_TOKEN_BINARY:
+ case G_TOKEN_OCTAL:
+ case G_TOKEN_HEX:
+ if (scanner->config->numbers_2_int)
+ *token_p = G_TOKEN_INT;
+ break;
+
+ default:
+ break;
+ }
+
+ if (*token_p == G_TOKEN_INT &&
+ scanner->config->int_2_float)
+ {
+ *token_p = G_TOKEN_FLOAT;
+ value_p->v_float = value_p->v_int;
+ }
+
+ errno = 0;
+}
+
+static void
+g_scanner_get_token_ll (GScanner *scanner,
+ GTokenType *token_p,
+ GTokenValue *value_p,
+ guint *line_p,
+ guint *position_p)
+{
+ GScannerConfig *config;
+ GTokenType token;
+ gboolean in_comment_multi;
+ gboolean in_comment_single;
+ gboolean in_string_sq;
+ gboolean in_string_dq;
+ GString *gstring;
+ GTokenValue value;
+ guchar ch;
+
+ config = scanner->config;
+ (*value_p).v_int = 0;
+
+ if ((scanner->text >= scanner->text_end && scanner->input_fd < 0) ||
+ scanner->token == G_TOKEN_EOF)
+ {
+ *token_p = G_TOKEN_EOF;
+ return;
+ }
+
+ in_comment_multi = FALSE;
+ in_comment_single = FALSE;
+ in_string_sq = FALSE;
+ in_string_dq = FALSE;
+ gstring = NULL;
+
+ do /* while (ch != 0) */
+ {
+ gboolean dotted_float = FALSE;
+
+ ch = g_scanner_get_char (scanner, line_p, position_p);
+
+ value.v_int = 0;
+ token = G_TOKEN_NONE;
+
+ /* this is *evil*, but needed ;(
+ * we first check for identifier first character, because it
+ * might interfere with other key chars like slashes or numbers
+ */
+ if (config->scan_identifier &&
+ ch && strchr (config->cset_identifier_first, ch))
+ goto identifier_precedence;
+
+ switch (ch)
+ {
+ case 0:
+ token = G_TOKEN_EOF;
+ (*position_p)++;
+ /* ch = 0; */
+ break;
+
+ case '/':
+ if (!config->scan_comment_multi ||
+ g_scanner_peek_next_char (scanner) != '*')
+ goto default_case;
+ g_scanner_get_char (scanner, line_p, position_p);
+ token = G_TOKEN_COMMENT_MULTI;
+ in_comment_multi = TRUE;
+ gstring = g_string_new ("");
+ while ((ch = g_scanner_get_char (scanner, line_p, position_p)) != 0)
+ {
+ if (ch == '*' && g_scanner_peek_next_char (scanner) == '/')
+ {
+ g_scanner_get_char (scanner, line_p, position_p);
+ in_comment_multi = FALSE;
+ break;
+ }
+ else
+ g_string_append_c (gstring, ch);
+ }
+ ch = 0;
+ break;
+
+ case '\'':
+ if (!config->scan_string_sq)
+ goto default_case;
+ token = G_TOKEN_STRING;
+ in_string_sq = TRUE;
+ gstring = g_string_new ("");
+ while ((ch = g_scanner_get_char (scanner, line_p, position_p)) != 0)
+ {
+ if (ch == '\'')
+ {
+ in_string_sq = FALSE;
+ break;
+ }
+ else
+ gstring = g_string_append_c (gstring, ch);
+ }
+ ch = 0;
+ break;
+
+ case '"':
+ if (!config->scan_string_dq)
+ goto default_case;
+ token = G_TOKEN_STRING;
+ in_string_dq = TRUE;
+ gstring = g_string_new ("");
+ while ((ch = g_scanner_get_char (scanner, line_p, position_p)) != 0)
+ {
+ if (ch == '"')
+ {
+ in_string_dq = FALSE;
+ break;
+ }
+ else
+ {
+ if (ch == '\\')
+ {
+ ch = g_scanner_get_char (scanner, line_p, position_p);
+ switch (ch)
+ {
+ guint i;
+ guint fchar;
+
+ case 0:
+ break;
+
+ case '\\':
+ gstring = g_string_append_c (gstring, '\\');
+ break;
+
+ case 'n':
+ gstring = g_string_append_c (gstring, '\n');
+ break;
+
+ case 't':
+ gstring = g_string_append_c (gstring, '\t');
+ break;
+
+ case 'r':
+ gstring = g_string_append_c (gstring, '\r');
+ break;
+
+ case 'b':
+ gstring = g_string_append_c (gstring, '\b');
+ break;
+
+ case 'f':
+ gstring = g_string_append_c (gstring, '\f');
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ i = ch - '0';
+ fchar = g_scanner_peek_next_char (scanner);
+ if (fchar >= '0' && fchar <= '7')
+ {
+ ch = g_scanner_get_char (scanner, line_p, position_p);
+ i = i * 8 + ch - '0';
+ fchar = g_scanner_peek_next_char (scanner);
+ if (fchar >= '0' && fchar <= '7')
+ {
+ ch = g_scanner_get_char (scanner, line_p, position_p);
+ i = i * 8 + ch - '0';
+ }
+ }
+ gstring = g_string_append_c (gstring, i);
+ break;
+
+ default:
+ gstring = g_string_append_c (gstring, ch);
+ break;
+ }
+ }
+ else
+ gstring = g_string_append_c (gstring, ch);
+ }
+ }
+ ch = 0;
+ break;
+
+ case '.':
+ if (!config->scan_float)
+ goto default_case;
+ token = G_TOKEN_FLOAT;
+ dotted_float = TRUE;
+ ch = g_scanner_get_char (scanner, line_p, position_p);
+ goto number_parsing;
+
+ case '$':
+ if (!config->scan_hex_dollar)
+ goto default_case;
+ token = G_TOKEN_HEX;
+ ch = g_scanner_get_char (scanner, line_p, position_p);
+ goto number_parsing;
+
+ case '0':
+ if (config->scan_octal)
+ token = G_TOKEN_OCTAL;
+ else
+ token = G_TOKEN_INT;
+ ch = g_scanner_peek_next_char (scanner);
+ if (config->scan_hex && (ch == 'x' || ch == 'X'))
+ {
+ token = G_TOKEN_HEX;
+ g_scanner_get_char (scanner, line_p, position_p);
+ ch = g_scanner_get_char (scanner, line_p, position_p);
+ if (ch == 0)
+ {
+ token = G_TOKEN_ERROR;
+ value.v_error = G_ERR_UNEXP_EOF;
+ (*position_p)++;
+ break;
+ }
+ if (g_scanner_char_2_num (ch, 16) < 0)
+ {
+ token = G_TOKEN_ERROR;
+ value.v_error = G_ERR_DIGIT_RADIX;
+ ch = 0;
+ break;
+ }
+ }
+ else if (config->scan_binary && (ch == 'b' || ch == 'B'))
+ {
+ token = G_TOKEN_BINARY;
+ g_scanner_get_char (scanner, line_p, position_p);
+ ch = g_scanner_get_char (scanner, line_p, position_p);
+ if (ch == 0)
+ {
+ token = G_TOKEN_ERROR;
+ value.v_error = G_ERR_UNEXP_EOF;
+ (*position_p)++;
+ break;
+ }
+ if (g_scanner_char_2_num (ch, 10) < 0)
+ {
+ token = G_TOKEN_ERROR;
+ value.v_error = G_ERR_NON_DIGIT_IN_CONST;
+ ch = 0;
+ break;
+ }
+ }
+ else
+ ch = '0';
+ /* fall through */
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ number_parsing:
+ {
+ gboolean in_number = TRUE;
+ gchar *endptr;
+
+ if (token == G_TOKEN_NONE)
+ token = G_TOKEN_INT;
+
+ gstring = g_string_new (dotted_float ? "0." : "");
+ gstring = g_string_append_c (gstring, ch);
+
+ do /* while (in_number) */
+ {
+ gboolean is_E;
+
+ is_E = token == G_TOKEN_FLOAT && (ch == 'e' || ch == 'E');
+
+ ch = g_scanner_peek_next_char (scanner);
+
+ if (g_scanner_char_2_num (ch, 36) >= 0 ||
+ (config->scan_float && ch == '.') ||
+ (is_E && (ch == '+' || ch == '-')))
+ {
+ ch = g_scanner_get_char (scanner, line_p, position_p);
+
+ switch (ch)
+ {
+ case '.':
+ if (token != G_TOKEN_INT && token != G_TOKEN_OCTAL)
+ {
+ value.v_error = token == G_TOKEN_FLOAT ? G_ERR_FLOAT_MALFORMED : G_ERR_FLOAT_RADIX;
+ token = G_TOKEN_ERROR;
+ in_number = FALSE;
+ }
+ else
+ {
+ token = G_TOKEN_FLOAT;
+ gstring = g_string_append_c (gstring, ch);
+ }
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ gstring = g_string_append_c (gstring, ch);
+ break;
+
+ case '-':
+ case '+':
+ if (token != G_TOKEN_FLOAT)
+ {
+ token = G_TOKEN_ERROR;
+ value.v_error = G_ERR_NON_DIGIT_IN_CONST;
+ in_number = FALSE;
+ }
+ else
+ gstring = g_string_append_c (gstring, ch);
+ break;
+
+ case 'e':
+ case 'E':
+ if ((token != G_TOKEN_HEX && !config->scan_float) ||
+ (token != G_TOKEN_HEX &&
+ token != G_TOKEN_OCTAL &&
+ token != G_TOKEN_FLOAT &&
+ token != G_TOKEN_INT))
+ {
+ token = G_TOKEN_ERROR;
+ value.v_error = G_ERR_NON_DIGIT_IN_CONST;
+ in_number = FALSE;
+ }
+ else
+ {
+ if (token != G_TOKEN_HEX)
+ token = G_TOKEN_FLOAT;
+ gstring = g_string_append_c (gstring, ch);
+ }
+ break;
+
+ default:
+ if (token != G_TOKEN_HEX)
+ {
+ token = G_TOKEN_ERROR;
+ value.v_error = G_ERR_NON_DIGIT_IN_CONST;
+ in_number = FALSE;
+ }
+ else
+ gstring = g_string_append_c (gstring, ch);
+ break;
+ }
+ }
+ else
+ in_number = FALSE;
+ }
+ while (in_number);
+
+ endptr = NULL;
+ switch (token)
+ {
+ case G_TOKEN_BINARY:
+ value.v_binary = strtol (gstring->str, &endptr, 2);
+ break;
+
+ case G_TOKEN_OCTAL:
+ value.v_octal = strtol (gstring->str, &endptr, 8);
+ break;
+
+ case G_TOKEN_INT:
+ value.v_int = strtol (gstring->str, &endptr, 10);
+ break;
+
+ case G_TOKEN_FLOAT:
+ value.v_float = g_strtod (gstring->str, &endptr);
+ break;
+
+ case G_TOKEN_HEX:
+ value.v_hex = strtol (gstring->str, &endptr, 16);
+ break;
+
+ default:
+ break;
+ }
+ if (endptr && *endptr)
+ {
+ token = G_TOKEN_ERROR;
+ if (*endptr == 'e' || *endptr == 'E')
+ value.v_error = G_ERR_NON_DIGIT_IN_CONST;
+ else
+ value.v_error = G_ERR_DIGIT_RADIX;
+ }
+ g_string_free (gstring, TRUE);
+ gstring = NULL;
+ ch = 0;
+ } /* number_parsing:... */
+ break;
+
+ default:
+ default_case:
+ {
+ if (config->cpair_comment_single &&
+ ch == config->cpair_comment_single[0])
+ {
+ token = G_TOKEN_COMMENT_SINGLE;
+ in_comment_single = TRUE;
+ gstring = g_string_new ("");
+ ch = g_scanner_get_char (scanner, line_p, position_p);
+ while (ch != 0)
+ {
+ if (ch == config->cpair_comment_single[1])
+ {
+ in_comment_single = FALSE;
+ ch = 0;
+ break;
+ }
+
+ gstring = g_string_append_c (gstring, ch);
+ ch = g_scanner_get_char (scanner, line_p, position_p);
+ }
+ }
+ else if (config->scan_identifier && ch &&
+ strchr (config->cset_identifier_first, ch))
+ {
+ identifier_precedence:
+
+ if (config->cset_identifier_nth && ch &&
+ strchr (config->cset_identifier_nth,
+ g_scanner_peek_next_char (scanner)))
+ {
+ token = G_TOKEN_IDENTIFIER;
+ gstring = g_string_new ("");
+ gstring = g_string_append_c (gstring, ch);
+ do
+ {
+ ch = g_scanner_get_char (scanner, line_p, position_p);
+ gstring = g_string_append_c (gstring, ch);
+ ch = g_scanner_peek_next_char (scanner);
+ }
+ while (ch && strchr (config->cset_identifier_nth, ch));
+ ch = 0;
+ }
+ else if (config->scan_identifier_1char)
+ {
+ token = G_TOKEN_IDENTIFIER;
+ value.v_identifier = g_new0 (gchar, 2);
+ value.v_identifier[0] = ch;
+ ch = 0;
+ }
+ }
+ if (ch)
+ {
+ if (config->char_2_token)
+ token = ch;
+ else
+ {
+ token = G_TOKEN_CHAR;
+ value.v_char = ch;
+ }
+ ch = 0;
+ }
+ } /* default_case:... */
+ break;
+ }
+ g_assert (ch == 0 && token != G_TOKEN_NONE); /* paranoid */
+ }
+ while (ch != 0);
+
+ if (in_comment_multi || in_comment_single ||
+ in_string_sq || in_string_dq)
+ {
+ token = G_TOKEN_ERROR;
+ if (gstring)
+ {
+ g_string_free (gstring, TRUE);
+ gstring = NULL;
+ }
+ (*position_p)++;
+ if (in_comment_multi || in_comment_single)
+ value.v_error = G_ERR_UNEXP_EOF_IN_COMMENT;
+ else /* (in_string_sq || in_string_dq) */
+ value.v_error = G_ERR_UNEXP_EOF_IN_STRING;
+ }
+
+ if (gstring)
+ {
+ value.v_string = gstring->str;
+ g_string_free (gstring, FALSE);
+ gstring = NULL;
+ }
+
+ if (token == G_TOKEN_IDENTIFIER)
+ {
+ if (config->scan_symbols)
+ {
+ GScannerKey *key;
+ guint scope_id;
+
+ scope_id = scanner->scope_id;
+ key = g_scanner_lookup_internal (scanner, scope_id, value.v_identifier);
+ if (!key && scope_id && scanner->config->scope_0_fallback)
+ key = g_scanner_lookup_internal (scanner, 0, value.v_identifier);
+
+ if (key)
+ {
+ g_free (value.v_identifier);
+ token = G_TOKEN_SYMBOL;
+ value.v_symbol = key->value;
+ }
+ }
+
+ if (token == G_TOKEN_IDENTIFIER &&
+ config->scan_identifier_NULL &&
+ strlen (value.v_identifier) == 4)
+ {
+ const gchar *null_upper = "NULL";
+ const gchar *null_lower = "null";
+
+ if (scanner->config->case_sensitive)
+ {
+ if (value.v_identifier[0] == null_upper[0] &&
+ value.v_identifier[1] == null_upper[1] &&
+ value.v_identifier[2] == null_upper[2] &&
+ value.v_identifier[3] == null_upper[3])
+ token = G_TOKEN_IDENTIFIER_NULL;
+ }
+ else
+ {
+ if ((value.v_identifier[0] == null_upper[0] ||
+ value.v_identifier[0] == null_lower[0]) &&
+ (value.v_identifier[1] == null_upper[1] ||
+ value.v_identifier[1] == null_lower[1]) &&
+ (value.v_identifier[2] == null_upper[2] ||
+ value.v_identifier[2] == null_lower[2]) &&
+ (value.v_identifier[3] == null_upper[3] ||
+ value.v_identifier[3] == null_lower[3]))
+ token = G_TOKEN_IDENTIFIER_NULL;
+ }
+ }
+ }
+
+ *token_p = token;
+ *value_p = value;
+}
+
+
+
+
+gdouble
+g_strtod (const gchar *nptr,
+ gchar **endptr)
+{
+ gchar *fail_pos_1;
+ gchar *fail_pos_2;
+ gdouble val_1;
+ gdouble val_2 = 0;
+
+ g_return_val_if_fail (nptr != NULL, 0);
+
+ fail_pos_1 = NULL;
+ fail_pos_2 = NULL;
+
+ val_1 = strtod (nptr, &fail_pos_1);
+
+ if (fail_pos_1 && fail_pos_1[0] != 0)
+ {
+ gchar *old_locale;
+
+ old_locale = g_strdup (setlocale (LC_NUMERIC, NULL));
+ setlocale (LC_NUMERIC, "C");
+ val_2 = strtod (nptr, &fail_pos_2);
+ setlocale (LC_NUMERIC, old_locale);
+ g_free (old_locale);
+ }
+
+ if (!fail_pos_1 || fail_pos_1[0] == 0 || fail_pos_1 >= fail_pos_2)
+ {
+ if (endptr)
+ *endptr = fail_pos_1;
+ return val_1;
+ }
+ else
+ {
+ if (endptr)
+ *endptr = fail_pos_2;
+ return val_2;
+ }
+}
+
+
+#ifndef MB_LEN_MAX
+# define MB_LEN_MAX 8
+#endif
+
+typedef struct
+{
+ guint min_width;
+ guint precision;
+ gboolean alternate_format, zero_padding, adjust_left, locale_grouping;
+ gboolean add_space, add_sign, possible_sign, seen_precision;
+ gboolean mod_half, mod_long, mod_extra_long;
+} PrintfArgSpec;
+
+
+static gsize
+printf_string_upper_bound (const gchar *format,
+ gboolean may_warn,
+ va_list args)
+{
+ static gboolean honour_longs = sizeof(long) > 4 || sizeof(void*) > 4;
+ gsize len = 1;
+
+ if (!format)
+ return len;
+
+ while (*format)
+ {
+ register gchar c = *format++;
+
+ if (c != '%')
+ len += 1;
+ else /* (c == '%') */
+ {
+ PrintfArgSpec spec = { 0, };
+ gboolean seen_l = FALSE, conv_done = FALSE;
+ gsize conv_len = 0;
+ const gchar *spec_start = format;
+
+ do
+ {
+ c = *format++;
+ switch (c)
+ {
+ GDoubleIEEE754 u_double;
+ guint v_uint;
+ gint v_int;
+ const gchar *v_string;
+
+ /* beware of positional parameters
+ */
+ case '$':
+ if (may_warn)
+ g_warning (G_STRLOC ": unable to handle positional parameters (%%n$)");
+ len += 1024; /* try adding some safety padding */
+ break;
+
+ /* parse flags
+ */
+ case '#':
+ spec.alternate_format = TRUE;
+ break;
+ case '0':
+ spec.zero_padding = TRUE;
+ break;
+ case '-':
+ spec.adjust_left = TRUE;
+ break;
+ case ' ':
+ spec.add_space = TRUE;
+ break;
+ case '+':
+ spec.add_sign = TRUE;
+ break;
+ case '\'':
+ spec.locale_grouping = TRUE;
+ break;
+
+ /* parse output size specifications
+ */
+ case '.':
+ spec.seen_precision = TRUE;
+ break;
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ v_uint = c - '0';
+ c = *format;
+ while (c >= '0' && c <= '9')
+ {
+ format++;
+ v_uint = v_uint * 10 + c - '0';
+ c = *format;
+ }
+ if (spec.seen_precision)
+ spec.precision = MAX (spec.precision, v_uint);
+ else
+ spec.min_width = MAX (spec.min_width, v_uint);
+ break;
+ case '*':
+ v_int = va_arg (args, int);
+ if (spec.seen_precision)
+ {
+ /* forget about negative precision */
+ if (v_int >= 0)
+ spec.precision = MAX (spec.precision, v_int);
+ }
+ else
+ {
+ if (v_int < 0)
+ {
+ v_int = - v_int;
+ spec.adjust_left = TRUE;
+ }
+ spec.min_width = MAX (spec.min_width, v_int);
+ }
+ break;
+
+ /* parse type modifiers
+ */
+ case 'h':
+ spec.mod_half = TRUE;
+ break;
+ case 'l':
+ if (!seen_l)
+ {
+ spec.mod_long = TRUE;
+ seen_l = TRUE;
+ break;
+ }
+ /* else, fall through */
+ case 'L':
+ case 'q':
+ spec.mod_long = TRUE;
+ spec.mod_extra_long = TRUE;
+ break;
+ case 'z':
+ case 'Z':
+ if (sizeof(size_t))
+ {
+ spec.mod_long = TRUE;
+ spec.mod_extra_long = TRUE;
+ }
+ break;
+ case 't':
+ if (sizeof(ptrdiff_t) > 4)
+ {
+ spec.mod_long = TRUE;
+ spec.mod_extra_long = TRUE;
+ }
+ break;
+ case 'j':
+ if (GLIB_SIZEOF_INTMAX > 4)
+ {
+ spec.mod_long = TRUE;
+ spec.mod_extra_long = TRUE;
+ }
+ break;
+
+ /* parse output conversions
+ */
+ case '%':
+ conv_len += 1;
+ break;
+ case 'O':
+ case 'D':
+ case 'I':
+ case 'U':
+ /* some C libraries feature long variants for these as well? */
+ spec.mod_long = TRUE;
+ /* fall through */
+ case 'o':
+ conv_len += 2;
+ /* fall through */
+ case 'd':
+ case 'i':
+ conv_len += 1; /* sign */
+ /* fall through */
+ case 'u':
+ conv_len += 4;
+ /* fall through */
+ case 'x':
+ case 'X':
+ spec.possible_sign = TRUE;
+ conv_len += 10;
+ if (spec.mod_long && honour_longs)
+ conv_len *= 2;
+ if (spec.mod_extra_long)
+ conv_len *= 2;
+ if (spec.mod_extra_long)
+ {
+ (void) va_arg (args, gint64);
+ }
+ else if (spec.mod_long)
+ (void) va_arg (args, long);
+ else
+ (void) va_arg (args, int);
+ break;
+ case 'A':
+ case 'a':
+ /* 0x */
+ conv_len += 2;
+ /* fall through */
+ case 'g':
+ case 'G':
+ case 'e':
+ case 'E':
+ case 'f':
+ spec.possible_sign = TRUE;
+ /* n . dddddddddddddddddddddddd E +- eeee */
+ conv_len += 1 + 1 + MAX (24, spec.precision) + 1 + 1 + 4;
+ if (may_warn && spec.mod_extra_long)
+ g_warning (G_STRLOC ": unable to handle long double, collecting double only");
+#ifdef HAVE_LONG_DOUBLE
+#error need to implement special handling for long double
+#endif
+ u_double.v_double = va_arg (args, double);
+ /* %f can expand up to all significant digits before '.' (308) */
+ if (c == 'f' &&
+ u_double.mpn.biased_exponent > 0 && u_double.mpn.biased_exponent < 2047)
+ {
+ gint exp = u_double.mpn.biased_exponent;
+
+ exp -= G_IEEE754_DOUBLE_BIAS;
+ exp = exp * G_LOG_2_BASE_10 + 1;
+ conv_len += ABS (exp); /* exp can be <0 */
+ }
+ /* some printf() implementations require extra padding for rounding */
+ conv_len += 2;
+ /* we can't really handle locale specific grouping here */
+ if (spec.locale_grouping)
+ conv_len *= 2;
+ break;
+ case 'C':
+ spec.mod_long = TRUE;
+ /* fall through */
+ case 'c':
+ conv_len += spec.mod_long ? MB_LEN_MAX : 1;
+ (void) va_arg (args, int);
+ break;
+ case 'S':
+ spec.mod_long = TRUE;
+ /* fall through */
+ case 's':
+ v_string = va_arg (args, char*);
+ if (!v_string)
+ conv_len += 8; /* hold "(null)" */
+ else if (spec.seen_precision)
+ conv_len += spec.precision;
+ else
+ conv_len += strlen (v_string);
+ conv_done = TRUE;
+ if (spec.mod_long)
+ {
+ if (may_warn)
+ g_warning (G_STRLOC": unable to handle wide char strings");
+ len += 1024; /* try adding some safety padding */
+ }
+ break;
+ case 'P': /* do we actually need this? */
+ /* fall through */
+ case 'p':
+ spec.alternate_format = TRUE;
+ conv_len += 10;
+ if (honour_longs)
+ conv_len *= 2;
+ /* fall through */
+ case 'n':
+ conv_done = TRUE;
+ (void) va_arg (args, void*);
+ break;
+ case 'm':
+ /* there's not much we can do to be clever */
+ v_string = g_strerror (errno);
+ v_uint = v_string ? strlen (v_string) : 0;
+ conv_len += MAX (256, v_uint);
+ break;
+
+ /* handle invalid cases
+ */
+ case '\000':
+ /* no conversion specification, bad bad */
+ conv_len += format - spec_start;
+ break;
+ default:
+ if (may_warn)
+ g_warning (G_STRLOC": unable to handle `%c' while parsing format",
+ c);
+ break;
+ }
+ conv_done |= conv_len > 0;
+ }
+ while (!conv_done);
+ /* handle width specifications */
+ conv_len = MAX (conv_len, MAX (spec.precision, spec.min_width));
+ /* handle flags */
+ conv_len += spec.alternate_format ? 2 : 0;
+ conv_len += (spec.add_space || spec.add_sign || spec.possible_sign);
+ /* finally done */
+ len += conv_len;
+ } /* else (c == '%') */
+ } /* while (*format) */
+
+ return len;
+}
+
+
+
+gsize
+g_printf_string_upper_bound (const gchar *format,
+ va_list args)
+{
+ return printf_string_upper_bound (format, TRUE, args);
+}
+
+gchar*
+g_get_current_dir (void)
+{
+ gchar *buffer = NULL;
+ gchar *dir = NULL;
+ static gulong max_len = 0;
+
+ if (max_len == 0)
+ max_len = (G_PATH_LENGTH == -1) ? 2048 : G_PATH_LENGTH;
+
+ /* We don't use getcwd(3) on SUNOS, because, it does a popen("pwd")
+ * and, if that wasn't bad enough, hangs in doing so.
+ */
+#if (defined (sun) && !defined (__SVR4)) || !defined(HAVE_GETCWD)
+ buffer = g_new (gchar, max_len + 1);
+ *buffer = 0;
+ dir = getwd (buffer);
+#else /* !sun || !HAVE_GETCWD */
+ while (max_len < G_MAXULONG / 2)
+ {
+ buffer = g_new (gchar, max_len + 1);
+ *buffer = 0;
+ dir = getcwd (buffer, max_len);
+
+ if (dir || errno != ERANGE)
+ break;
+
+ g_free (buffer);
+ max_len *= 2;
+ }
+#endif /* !sun || !HAVE_GETCWD */
+
+ if (!dir || !*buffer)
+ {
+ /* hm, should we g_error() out here?
+ * this can happen if e.g. "./" has mode \0000
+ */
+ buffer[0] = G_DIR_SEPARATOR;
+ buffer[1] = 0;
+ }
+
+ dir = g_strdup (buffer);
+ g_free (buffer);
+
+ return dir;
+}
+
+gboolean
+g_path_is_absolute (const gchar *file_name)
+{
+ g_return_val_if_fail (file_name != NULL, FALSE);
+
+ if (file_name[0] == G_DIR_SEPARATOR
+#ifdef G_OS_WIN32
+ || file_name[0] == '/'
+#endif
+ )
+ return TRUE;
+
+#ifdef G_OS_WIN32
+ /* Recognize drive letter on native Windows */
+ if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':' && (file_name[2] == G_DIR_SEPARATOR || file_name[2] == '/'))
+ return TRUE;
+#endif /* G_OS_WIN32 */
+
+ return FALSE;
+}
+
+/* vim:set ts=8 sw=2 sts=2: */
diff --git a/flow/gsl/gslglib.h b/flow/gsl/gslglib.h
new file mode 100644
index 0000000..cd1f952
--- /dev/null
+++ b/flow/gsl/gslglib.h
@@ -0,0 +1,858 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001 Stefan Westerfeld and Tim Janik
+ *
+ * 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.
+ */
+#ifndef __GSL_GLIB_H__
+#define __GSL_GLIB_H__
+
+#ifndef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "GSL"
+#endif
+
+
+#include <limits.h>
+#include <float.h>
+#include <stddef.h>
+#include <stdarg.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/* for -ansi -pedantic */
+#ifdef __GNUC__
+#define asm __asm__
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define GSL_ASSERT(foo) do { if (!(foo)) g_error ("assertion failed `%s'", #foo); } while (0)
+
+/* --- GLib typedefs --- */
+typedef void* gpointer;
+typedef const void* gconstpointer;
+typedef char gchar;
+typedef unsigned char guchar;
+typedef signed short gshort;
+typedef unsigned short gushort;
+typedef signed int gint;
+typedef unsigned int guint;
+typedef signed long glong;
+typedef unsigned long gulong;
+typedef float gfloat;
+typedef double gdouble;
+typedef size_t gsize;
+typedef gchar gint8;
+typedef guchar guint8;
+typedef gshort gint16;
+typedef gushort guint16;
+typedef gint gint32;
+typedef guint guint32;
+typedef gint gboolean;
+typedef gint32 GTime;
+#ifdef __alpha
+typedef long int gint64;
+typedef unsigned long int guint64;
+#else
+typedef long long int gint64;
+typedef unsigned long long int guint64;
+#endif
+typedef struct _GString GString;
+typedef struct _GDebugKey GDebugKey;
+struct _GDebugKey
+{
+ const gchar *key;
+ guint value;
+};
+typedef struct _GTimeVal GTimeVal;
+struct _GTimeVal
+{
+ glong tv_sec;
+ glong tv_usec;
+};
+typedef gint (*GCompareFunc) (gconstpointer a,
+ gconstpointer b);
+
+
+/* --- standard macros --- */
+#ifndef ABS
+#define ABS(a) ((a) > 0 ? (a) : -(a))
+#endif
+#ifndef MAX
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+#ifndef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+#ifndef CLAMP
+#define CLAMP(v,l,h) ((v) < (l) ? (l) : (v) > (h) ? (h) : (v))
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
+#ifndef NULL
+#define NULL ((void*) 0)
+#endif
+
+
+/* --- glib macros --- */
+#define G_MINFLOAT FLT_MIN
+#define G_MAXFLOAT FLT_MAX
+#define G_MINDOUBLE DBL_MIN
+#define G_MAXDOUBLE DBL_MAX
+#define G_MINSHORT SHRT_MIN
+#define G_MAXSHORT SHRT_MAX
+#define G_MAXUSHORT USHRT_MAX
+#define G_MININT INT_MIN
+#define G_MININT64 ((gint64) 0x8000000000000000)
+#define G_MAXINT INT_MAX
+#define G_MAXINT64 ((gint64) 0x7fffffffffffffff)
+#define G_MAXUINT UINT_MAX
+#define G_MAXUINT64 ((guint64) 0xffffffffffffffff)
+#define G_MINLONG LONG_MIN
+#define G_MAXLONG LONG_MAX
+#define G_MAXULONG ULONG_MAX
+#define G_USEC_PER_SEC 1000000
+#define G_LITTLE_ENDIAN 1234
+#define G_BIG_ENDIAN 4321
+
+#define G_DIR_SEPARATOR '/'
+#ifdef MAXPATHLEN
+#define G_PATH_LENGTH MAXPATHLEN
+#elif defined (PATH_MAX)
+#define G_PATH_LENGTH PATH_MAX
+#elif defined (_PC_PATH_MAX)
+#define G_PATH_LENGTH sysconf(_PC_PATH_MAX)
+#else
+#define G_PATH_LENGTH 2048
+#endif
+
+#define G_N_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0]))
+#define G_STRINGIFY(macro_or_string) G_STRINGIFY_ARG (macro_or_string)
+#define G_STRINGIFY_ARG(contents) #contents
+#define G_STRLOC __FILE__ ":" G_STRINGIFY (__LINE__)
+#if !(defined (G_STMT_START) && defined (G_STMT_END))
+# if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus)
+# define G_STMT_START (void)(
+# define G_STMT_END )
+# else
+# if (defined (sun) || defined (__sun__))
+# define G_STMT_START if (1)
+# define G_STMT_END else (void)0
+# else
+# define G_STMT_START do
+# define G_STMT_END while (0)
+# endif
+# endif
+#endif
+#define G_STRUCT_OFFSET(struct_type, member) \
+ ((glong) ((guint8*) &((struct_type*) 0)->member))
+#define G_STRUCT_MEMBER_P(struct_p, struct_offset) \
+ ((gpointer) ((guint8*) (struct_p) + (glong) (struct_offset)))
+#define G_STRUCT_MEMBER(member_type, struct_p, struct_offset) \
+ (*(member_type*) G_STRUCT_MEMBER_P ((struct_p), (struct_offset)))
+#define GINT_TO_POINTER(i) ((gpointer) (int) (i))
+#define GUINT_TO_POINTER(i) ((gpointer) (guint) (i))
+#define GPOINTER_TO_INT(p) ((int) (p))
+#define GPOINTER_TO_UINT(p) ((guint) (p))
+#define GUINT16_SWAP_LE_BE(val) ((guint16) ( \
+ (((guint16) (val) & (guint16) 0x00ffU) << 8) | \
+ (((guint16) (val) & (guint16) 0xff00U) >> 8)))
+#define GUINT32_SWAP_LE_BE(val) ((guint32) ( \
+ (((guint32) (val) & (guint32) 0x000000ffU) << 24) | \
+ (((guint32) (val) & (guint32) 0x0000ff00U) << 8) | \
+ (((guint32) (val) & (guint32) 0x00ff0000U) >> 8) | \
+ (((guint32) (val) & (guint32) 0xff000000U) >> 24)))
+
+#ifdef WORDS_BIGENDIAN
+#define GUINT16_TO_LE(val) GUINT16_SWAP_LE_BE(val)
+#define GUINT32_TO_LE(val) GUINT32_SWAP_LE_BE(val)
+#define GUINT16_TO_BE(val) ((guint16) (val))
+#define GUINT32_TO_BE(val) ((guint32) (val))
+#else /* LITTLEENDIAN */
+#define GUINT16_TO_LE(val) ((guint16) (val))
+#define GUINT32_TO_LE(val) ((guint32) (val))
+#define GUINT16_TO_BE(val) GUINT16_SWAP_LE_BE(val)
+#define GUINT32_TO_BE(val) GUINT32_SWAP_LE_BE(val)
+#endif
+
+#define GUINT16_FROM_LE(val) (GUINT16_TO_LE (val))
+#define GUINT16_FROM_BE(val) (GUINT16_TO_BE (val))
+#define GUINT32_FROM_LE(val) (GUINT32_TO_LE (val))
+#define GUINT32_FROM_BE(val) (GUINT32_TO_BE (val))
+
+
+#define g_memmove memmove
+#define g_assert GSL_ASSERT
+#define g_assert_not_reached() g_assert(!G_STRLOC": should not be reached")
+#define g_return_if_fail(foo) do { if (!(foo)) g_message (G_STRLOC ": assertion failed `%s'", #foo); } while (0)
+#define g_return_val_if_fail(foo,v) do { if (!(foo)) { g_message (G_STRLOC ": assertion failed `%s'", #foo); return(v);}} while (0)
+
+/* from galloca.h */
+
+#ifdef __GNUC__
+/* GCC does the right thing */
+# undef alloca
+# define alloca(size) __builtin_alloca (size)
+#elif defined (GLIB_HAVE_ALLOCA_H)
+/* a native and working alloca.h is there */
+# include <alloca.h>
+#else /* !__GNUC__ && !GLIB_HAVE_ALLOCA_H */
+# ifdef _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+# else /* !_MSC_VER */
+# ifdef _AIX
+ #pragma alloca
+# else /* !_AIX */
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif /* !alloca */
+# endif /* !_AIX */
+# endif /* !_MSC_VER */
+#endif /* !__GNUC__ && !GLIB_HAVE_ALLOCA_H */
+
+#define g_alloca(size) alloca (size)
+#define g_newa(struct_type, n_structs) ((struct_type*) g_alloca (sizeof (struct_type) * (gsize) (n_structs)))
+
+/* needs inline configure check */
+#if defined (__xlc__)
+# if !defined (inline)
+# define inline _Inline
+# endif
+#elif defined (__GNUC__)
+#define inline __inline__
+#else
+#define inline /* no inline */
+#endif
+
+
+/* --- inline functions --- */
+void
+gsl_g_log (const gchar*msg,const char *format, va_list ap);
+void
+gsl_g_print_fd (int fd,const char *format, va_list ap);
+static inline void
+g_error (const gchar *format,
+ ...)
+{
+ va_list args;
+ va_start (args, format);
+ gsl_g_log ("**ERROR**", format, args);
+ va_end (args);
+}
+static inline void
+g_message (const gchar *format,
+ ...)
+{
+ va_list args;
+ va_start (args, format);
+ gsl_g_log ("**MESSAGE**", format, args);
+ va_end (args);
+}
+static inline void
+g_critical (const gchar *format,
+ ...)
+{
+ va_list args;
+ va_start (args, format);
+ gsl_g_log ("**CRITICAL**", format, args);
+ va_end (args);
+}
+static inline void
+g_warning (const gchar *format,
+ ...)
+{
+ va_list args;
+ va_start (args, format);
+ gsl_g_log ("**WARNING**", format, args);
+ va_end (args);
+}
+static inline void
+g_print (const gchar *format,
+ ...)
+{
+ va_list args;
+ va_start (args, format);
+ gsl_g_print_fd (1, format, args);
+ va_end (args);
+}
+static inline void
+g_printerr (const gchar *format,
+ ...)
+{
+ va_list args;
+ va_start (args, format);
+ gsl_g_print_fd (2, format, args);
+ va_end (args);
+}
+typedef struct _GTrashStack GTrashStack;
+struct _GTrashStack
+{
+ GTrashStack *next;
+};
+static inline guint
+g_bit_storage (gulong number)
+{
+ register guint n_bits = 0;
+
+ do
+ {
+ n_bits++;
+ number >>= 1;
+ }
+ while (number);
+ return n_bits;
+}
+static inline void
+g_trash_stack_push (GTrashStack **stack_p,
+ gpointer data_p)
+{
+ GTrashStack *data = (GTrashStack *) data_p;
+
+ data->next = *stack_p;
+ *stack_p = data;
+}
+static inline gpointer
+g_trash_stack_pop (GTrashStack **stack_p)
+{
+ GTrashStack *data;
+
+ data = *stack_p;
+ if (data)
+ {
+ *stack_p = data->next;
+ /* NULLify private pointer here, most platforms store NULL as
+ * subsequent 0 bytes
+ */
+ data->next = NULL;
+ }
+
+ return data;
+}
+static inline gpointer
+g_trash_stack_peek (GTrashStack **stack_p)
+{
+ GTrashStack *data;
+
+ data = *stack_p;
+
+ return data;
+}
+static inline guint
+g_trash_stack_height (GTrashStack **stack_p)
+{
+ GTrashStack *data;
+ guint i = 0;
+
+ for (data = *stack_p; data; data = data->next)
+ i++;
+
+ return i;
+}
+
+
+/* --- GCC features --- */
+#if __GNUC__ >= 2 && __GNUC_MINOR__ > 95
+#define G_GNUC_PRINTF( format_idx, arg_idx ) \
+ __attribute__((format (printf, format_idx, arg_idx)))
+#define G_GNUC_SCANF( format_idx, arg_idx ) \
+ __attribute__((format (scanf, format_idx, arg_idx)))
+#define G_GNUC_FORMAT( arg_idx ) \
+ __attribute__((format_arg (arg_idx)))
+#define G_GNUC_NORETURN \
+ __attribute__((noreturn))
+#define G_GNUC_CONST \
+ __attribute__((const))
+#define G_GNUC_UNUSED \
+ __attribute__((unused))
+#define G_GNUC_NO_INSTRUMENT \
+ __attribute__((no_instrument_function))
+#else /* !__GNUC__ */
+#define G_GNUC_PRINTF( format_idx, arg_idx )
+#define G_GNUC_SCANF( format_idx, arg_idx )
+#define G_GNUC_FORMAT( arg_idx )
+#define G_GNUC_NORETURN
+#define G_GNUC_CONST
+#define G_GNUC_UNUSED
+#define G_GNUC_NO_INSTRUMENT
+#endif /* !__GNUC__ */
+
+
+
+/* --- GPollFD (for poll(2)) --- */
+#define G_IO_IN (0x0001 /* There is data to read */)
+#define G_IO_PRI (0x0002 /* There is urgent data to read */)
+#define G_IO_OUT (0x0004 /* Writing now will not block */)
+#define G_IO_ERR (0x0008 /* Error condition */)
+#define G_IO_HUP (0x0010 /* Hung up */)
+#define G_IO_NVAL (0x0020 /* Invalid request: fd not open */)
+typedef struct
+{
+ gint fd;
+ gushort events;
+ gushort revents;
+} GPollFD;
+
+
+
+/* --- functions --- */
+#define g_malloc gsl_g_malloc
+#define g_malloc0 gsl_g_malloc0
+#define g_realloc gsl_g_realloc
+#define g_free gsl_g_free
+#define g_strdup gsl_g_strdup
+#define g_strndup gsl_g_strndup
+#define g_memdup gsl_g_memdup
+#define g_strdup_printf gsl_g_strdup_printf
+#define g_strdup_vprintf gsl_g_strdup_vprintf
+#define g_strndup gsl_g_strndup
+#define g_strconcat gsl_g_strconcat
+#define g_usleep gsl_g_usleep
+#define g_strerror gsl_g_strerror
+#define g_convert gsl_g_convert
+#define g_direct_hash gsl_g_direct_hash
+#define g_direct_equal gsl_g_direct_equal
+#define g_str_equal gsl_g_str_equal
+#define g_str_hash gsl_g_str_hash
+#define g_strtod gsl_g_strtod
+#define g_stpcpy gsl_g_stpcpy
+#define g_strescape gsl_g_strescape
+#define g_get_current_dir gsl_g_get_current_dir
+#define g_path_is_absolute gsl_g_path_is_absolute
+#define g_printf_string_upper_bound gsl_g_printf_string_upper_bound
+
+gpointer g_malloc (gulong n_bytes);
+gpointer g_malloc0 (gulong n_bytes);
+gpointer g_realloc (gpointer mem,
+ gulong n_bytes);
+void g_free (gpointer mem);
+gpointer g_memdup (gconstpointer mem,
+ guint byte_size);
+gchar* g_strdup (const gchar *str);
+gchar* g_strndup (const gchar *str,
+ gsize n);
+gchar* g_strdup_printf (const gchar *format,
+ ...) G_GNUC_PRINTF (1, 2);
+gchar* g_strdup_vprintf (const gchar *format,
+ va_list args);
+gchar* g_strndup (const gchar *str,
+ gsize n);
+gchar* g_strconcat (const gchar *string1,
+ ...); /* NULL terminated */
+gchar* g_convert (const gchar *str,
+ gsize len, /* gssize */
+ const gchar *to_codeset,
+ const gchar *from_codeset,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ void **error); /* GError */
+void g_usleep(unsigned long usec);
+char* g_strerror(int e);
+guint g_direct_hash (gconstpointer v);
+gboolean g_direct_equal (gconstpointer v1, gconstpointer v2);
+gboolean g_str_equal (gconstpointer v1, gconstpointer v2);
+guint g_str_hash (gconstpointer key);
+gdouble g_strtod (const gchar *nptr, gchar **endptr);
+gsize g_printf_string_upper_bound (const gchar *format, va_list args);
+gchar * g_stpcpy (gchar *dest, const gchar *src);
+gchar * g_strescape (const gchar *source, const gchar *exceptions);
+gchar * g_get_current_dir (void);
+gboolean g_path_is_absolute (const gchar *file_name);
+
+
+
+/* --- function defines --- */
+#define g_new(struct_type, n_structs) \
+ ((struct_type *) g_malloc (((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
+#define g_new0(struct_type, n_structs) \
+ ((struct_type *) g_malloc0 (((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
+#define g_renew(struct_type, mem, n_structs) \
+ ((struct_type *) g_realloc ((mem), ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
+#define g_try_malloc malloc
+#define g_try_realloc realloc
+
+
+
+/* --- configure stuff!!! --- */
+#ifdef WORDS_BIGENDIAN
+#define G_BYTE_ORDER G_BIG_ENDIAN
+#else
+#define G_BYTE_ORDER G_LITTLE_ENDIAN
+#endif
+
+/* #define GLIB_HAVE_STPCPY 1 */
+/* Define G_VA_COPY() to do the right thing for copying va_list variables.
+ * glibconfig.h may have already defined G_VA_COPY as va_copy or __va_copy.
+ */
+#if !defined (G_VA_COPY)
+# if defined (__GNUC__) && ( defined (__PPC__) || defined (__s390__) ) && (defined (_CALL_SYSV) || defined (_WIN32) || defined (__s390__) )
+# define G_VA_COPY(ap1, ap2) (*(ap1) = *(ap2))
+# elif defined (G_VA_COPY_AS_ARRAY)
+# define G_VA_COPY(ap1, ap2) g_memmove ((ap1), (ap2), sizeof (va_list))
+# else /* va_list is a pointer */
+# define G_VA_COPY(ap1, ap2) ((ap1) = (ap2))
+# endif /* va_list is a pointer */
+#endif /* !G_VA_COPY */
+
+
+
+
+/* subtract from biased_exponent to form base2 exponent (normal numbers) */
+typedef union _GDoubleIEEE754 GDoubleIEEE754;
+typedef union _GFloatIEEE754 GFloatIEEE754;
+#define G_IEEE754_FLOAT_BIAS (127)
+#define G_IEEE754_DOUBLE_BIAS (1023)
+/* multiply with base2 exponent to get base10 exponent (nomal numbers) */
+#define G_LOG_2_BASE_10 (0.30102999566398119521)
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+union _GFloatIEEE754
+{
+ gfloat v_float;
+ struct {
+ guint mantissa : 23;
+ guint biased_exponent : 8;
+ guint sign : 1;
+ } mpn;
+};
+union _GDoubleIEEE754
+{
+ gdouble v_double;
+ struct {
+ guint mantissa_low : 32;
+ guint mantissa_high : 20;
+ guint biased_exponent : 11;
+ guint sign : 1;
+ } mpn;
+};
+#elif G_BYTE_ORDER == G_BIG_ENDIAN
+union _GFloatIEEE754
+{
+ gfloat v_float;
+ struct {
+ guint sign : 1;
+ guint biased_exponent : 8;
+ guint mantissa : 23;
+ } mpn;
+};
+union _GDoubleIEEE754
+{
+ gdouble v_double;
+ struct {
+ guint sign : 1;
+ guint biased_exponent : 11;
+ guint mantissa_high : 20;
+ guint mantissa_low : 32;
+ } mpn;
+};
+#else /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */
+#error unknown ENDIAN type
+#endif /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */
+
+
+
+/* --- GHashTable --- */
+typedef struct _GHashTable GHashTable;
+typedef gboolean (*GHRFunc) (gpointer key,
+ gpointer value,
+ gpointer user_data);
+typedef void (*GHFunc) (gpointer key,
+ gpointer value,
+ gpointer user_data);
+typedef guint (*GHashFunc) (gconstpointer key);
+typedef gboolean (*GEqualFunc) (gconstpointer a,
+ gconstpointer b);
+typedef void (*GDestroyNotify) (gpointer data);
+#define g_hash_table_new gsl_g_hash_table_new
+#define g_hash_table_new_full gsl_g_hash_table_new_full
+#define g_hash_table_destroy gsl_g_hash_table_destroy
+#define g_hash_table_insert gsl_g_hash_table_insert
+#define g_hash_table_replace gsl_g_hash_table_replace
+#define g_hash_table_remove gsl_g_hash_table_remove
+#define g_hash_table_steal gsl_g_hash_table_steal
+#define g_hash_table_lookup gsl_g_hash_table_lookup
+#define g_hash_table_lookup_extended gsl_g_hash_table_lookup_extended
+#define g_hash_table_foreach gsl_g_hash_table_foreach
+#define g_hash_table_foreach_remove gsl_g_hash_table_foreach_remove
+#define g_hash_table_foreach_steal gsl_g_hash_table_foreach_steal
+#define g_hash_table_size gsl_g_hash_table_size
+GHashTable* g_hash_table_new (GHashFunc hash_func,
+ GEqualFunc key_equal_func);
+GHashTable* g_hash_table_new_full (GHashFunc hash_func,
+ GEqualFunc key_equal_func,
+ GDestroyNotify key_destroy_func,
+ GDestroyNotify value_destroy_func);
+void g_hash_table_destroy (GHashTable *hash_table);
+void g_hash_table_insert (GHashTable *hash_table,
+ gpointer key,
+ gpointer value);
+void g_hash_table_replace (GHashTable *hash_table,
+ gpointer key,
+ gpointer value);
+gboolean g_hash_table_remove (GHashTable *hash_table,
+ gconstpointer key);
+gboolean g_hash_table_steal (GHashTable *hash_table,
+ gconstpointer key);
+gpointer g_hash_table_lookup (GHashTable *hash_table,
+ gconstpointer key);
+gboolean g_hash_table_lookup_extended (GHashTable *hash_table,
+ gconstpointer lookup_key,
+ gpointer *orig_key,
+ gpointer *value);
+void g_hash_table_foreach (GHashTable *hash_table,
+ GHFunc func,
+ gpointer user_data);
+guint g_hash_table_foreach_remove (GHashTable *hash_table,
+ GHRFunc func,
+ gpointer user_data);
+guint g_hash_table_foreach_steal (GHashTable *hash_table,
+ GHRFunc func,
+ gpointer user_data);
+guint g_hash_table_size (GHashTable *hash_table);
+
+
+/* --- GScanner --- */
+typedef struct _GScanner GScanner;
+typedef struct _GScannerConfig GScannerConfig;
+typedef union _GTokenValue GTokenValue;
+typedef void (*GScannerMsgFunc) (GScanner *scanner,
+ gchar *message,
+ gint error);
+#define G_CSET_A_2_Z "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+#define G_CSET_a_2_z "abcdefghijklmnopqrstuvwxyz"
+#define G_CSET_DIGITS "0123456789"
+#define G_CSET_LATINC "\300\301\302\303\304\305\306"\
+ "\307\310\311\312\313\314\315\316\317\320"\
+ "\321\322\323\324\325\326"\
+ "\330\331\332\333\334\335\336"
+#define G_CSET_LATINS "\337\340\341\342\343\344\345\346"\
+ "\347\350\351\352\353\354\355\356\357\360"\
+ "\361\362\363\364\365\366"\
+ "\370\371\372\373\374\375\376\377"
+typedef enum
+{
+ G_ERR_UNKNOWN,
+ G_ERR_UNEXP_EOF,
+ G_ERR_UNEXP_EOF_IN_STRING,
+ G_ERR_UNEXP_EOF_IN_COMMENT,
+ G_ERR_NON_DIGIT_IN_CONST,
+ G_ERR_DIGIT_RADIX,
+ G_ERR_FLOAT_RADIX,
+ G_ERR_FLOAT_MALFORMED
+} GErrorType;
+typedef enum
+{
+ G_TOKEN_EOF = 0,
+
+ G_TOKEN_LEFT_PAREN = '(',
+ G_TOKEN_RIGHT_PAREN = ')',
+ G_TOKEN_LEFT_CURLY = '{',
+ G_TOKEN_RIGHT_CURLY = '}',
+ G_TOKEN_LEFT_BRACE = '[',
+ G_TOKEN_RIGHT_BRACE = ']',
+ G_TOKEN_EQUAL_SIGN = '=',
+ G_TOKEN_COMMA = ',',
+
+ G_TOKEN_NONE = 256,
+
+ G_TOKEN_ERROR,
+
+ G_TOKEN_CHAR,
+ G_TOKEN_BINARY,
+ G_TOKEN_OCTAL,
+ G_TOKEN_INT,
+ G_TOKEN_HEX,
+ G_TOKEN_FLOAT,
+ G_TOKEN_STRING,
+
+ G_TOKEN_SYMBOL,
+ G_TOKEN_IDENTIFIER,
+ G_TOKEN_IDENTIFIER_NULL,
+
+ G_TOKEN_COMMENT_SINGLE,
+ G_TOKEN_COMMENT_MULTI,
+ G_TOKEN_LAST
+} GTokenType;
+union _GTokenValue
+{
+ gpointer v_symbol;
+ gchar *v_identifier;
+ gulong v_binary;
+ gulong v_octal;
+ gulong v_int;
+ gdouble v_float;
+ gulong v_hex;
+ gchar *v_string;
+ gchar *v_comment;
+ guchar v_char;
+ guint v_error;
+};
+struct _GScannerConfig
+{
+ const gchar *cset_skip_characters; /* default: " \t\n" */
+ const gchar *cset_identifier_first;
+ const gchar *cset_identifier_nth;
+ const gchar *cpair_comment_single; /* default: "#\n" */
+ guint case_sensitive : 1;
+ guint skip_comment_multi : 1; /* C like comment */
+ guint skip_comment_single : 1; /* single line comment */
+ guint scan_comment_multi : 1; /* scan multi line comments? */
+ guint scan_identifier : 1;
+ guint scan_identifier_1char : 1;
+ guint scan_identifier_NULL : 1;
+ guint scan_symbols : 1;
+ guint scan_binary : 1;
+ guint scan_octal : 1;
+ guint scan_float : 1;
+ guint scan_hex : 1; /* `0x0ff0' */
+ guint scan_hex_dollar : 1; /* `$0ff0' */
+ guint scan_string_sq : 1; /* string: 'anything' */
+ guint scan_string_dq : 1; /* string: "\\-escapes!\n" */
+ guint numbers_2_int : 1; /* bin, octal, hex => int */
+ guint int_2_float : 1; /* int => G_TOKEN_FLOAT? */
+ guint identifier_2_string : 1;
+ guint char_2_token : 1; /* return G_TOKEN_CHAR? */
+ guint symbol_2_token : 1;
+ guint scope_0_fallback : 1; /* try scope 0 on lookups? */
+};
+struct _GScanner
+{
+ gpointer user_data;
+ guint max_parse_errors;
+ guint parse_errors;
+ const gchar *input_name;
+ /* GData *qdata; */
+ GScannerConfig *config;
+ GTokenType token;
+ GTokenValue value;
+ guint line;
+ guint position;
+ GTokenType next_token;
+ GTokenValue next_value;
+ guint next_line;
+ guint next_position;
+ GHashTable *symbol_table;
+ gint input_fd;
+ const gchar *text;
+ const gchar *text_end;
+ gchar *buffer;
+ guint scope_id;
+ GScannerMsgFunc msg_handler;
+};
+#define g_scanner_new gsl_g_scanner_new
+#define g_scanner_destroy gsl_g_scanner_destroy
+#define g_scanner_input_file gsl_g_scanner_input_file
+#define g_scanner_sync_file_offset gsl_g_scanner_sync_file_offset
+#define g_scanner_input_text gsl_g_scanner_input_text
+#define g_scanner_get_next_token gsl_g_scanner_get_next_token
+#define g_scanner_peek_next_token gsl_g_scanner_peek_next_token
+#define g_scanner_cur_token gsl_g_scanner_cur_token
+#define g_scanner_cur_value gsl_g_scanner_cur_value
+#define g_scanner_cur_line gsl_g_scanner_cur_line
+#define g_scanner_cur_position gsl_g_scanner_cur_position
+#define g_scanner_eof gsl_g_scanner_eof
+#define g_scanner_set_scope gsl_g_scanner_set_scope
+#define g_scanner_scope_add_symbol gsl_g_scanner_scope_add_symbol
+#define g_scanner_scope_remove_symbol gsl_g_scanner_scope_remove_symbol
+#define g_scanner_scope_lookup_symbol gsl_g_scanner_scope_lookup_symbol
+#define g_scanner_scope_foreach_symbol gsl_g_scanner_scope_foreach_symbol
+#define g_scanner_lookup_symbol gsl_g_scanner_lookup_symbol
+#define g_scanner_unexp_token gsl_g_scanner_unexp_token
+#define g_scanner_error gsl_g_scanner_error
+#define g_scanner_warn gsl_g_scanner_warn
+GScanner* g_scanner_new (const GScannerConfig *config_templ);
+void g_scanner_destroy (GScanner *scanner);
+void g_scanner_input_file (GScanner *scanner,
+ gint input_fd);
+void g_scanner_sync_file_offset (GScanner *scanner);
+void g_scanner_input_text (GScanner *scanner,
+ const gchar *text,
+ guint text_len);
+GTokenType g_scanner_get_next_token (GScanner *scanner);
+GTokenType g_scanner_peek_next_token (GScanner *scanner);
+GTokenType g_scanner_cur_token (GScanner *scanner);
+GTokenValue g_scanner_cur_value (GScanner *scanner);
+guint g_scanner_cur_line (GScanner *scanner);
+guint g_scanner_cur_position (GScanner *scanner);
+gboolean g_scanner_eof (GScanner *scanner);
+guint g_scanner_set_scope (GScanner *scanner,
+ guint scope_id);
+void g_scanner_scope_add_symbol (GScanner *scanner,
+ guint scope_id,
+ const gchar *symbol,
+ gpointer value);
+void g_scanner_scope_remove_symbol (GScanner *scanner,
+ guint scope_id,
+ const gchar *symbol);
+gpointer g_scanner_scope_lookup_symbol (GScanner *scanner,
+ guint scope_id,
+ const gchar *symbol);
+void g_scanner_scope_foreach_symbol (GScanner *scanner,
+ guint scope_id,
+ GHFunc func,
+ gpointer user_data);
+gpointer g_scanner_lookup_symbol (GScanner *scanner,
+ const gchar *symbol);
+void g_scanner_unexp_token (GScanner *scanner,
+ GTokenType expected_token,
+ const gchar *identifier_spec,
+ const gchar *symbol_spec,
+ const gchar *symbol_name,
+ const gchar *message,
+ gint is_error);
+void g_scanner_error (GScanner *scanner,
+ const gchar *format,
+ ...) G_GNUC_PRINTF (2,3);
+void g_scanner_warn (GScanner *scanner,
+ const gchar *format,
+ ...) G_GNUC_PRINTF (2,3);
+#define g_scanner_add_symbol( scanner, symbol, value ) G_STMT_START { \
+ g_scanner_scope_add_symbol ((scanner), 0, (symbol), (value)); \
+} G_STMT_END
+#define g_scanner_remove_symbol( scanner, symbol ) G_STMT_START { \
+ g_scanner_scope_remove_symbol ((scanner), 0, (symbol)); \
+} G_STMT_END
+#define g_scanner_foreach_symbol( scanner, func, data ) G_STMT_START { \
+ g_scanner_scope_foreach_symbol ((scanner), 0, (func), (data)); \
+} G_STMT_END
+
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#include <gsl/gslconfig.h>
+#if GSL_USE_ARTS_THREADS
+#include <gsl/gslartsthreads.h>
+#endif
+
+/* if inline is defined in C++ mode, it can cause a lot of grief with C++ */
+/* header files so we need to undefine it here again */
+
+#if defined(__cplusplus) && defined(inline)
+#undef inline
+#endif
+
+#endif /* __GSL_GLIB_H__ */ /* vim: set ts=8 sw=2 sts=2: */
+
diff --git a/flow/gsl/gslglibhash.cc b/flow/gsl/gslglibhash.cc
new file mode 100644
index 0000000..a8c82b0
--- /dev/null
+++ b/flow/gsl/gslglibhash.cc
@@ -0,0 +1,151 @@
+/* GSL Glib Hashtable implementation
+ * Copyright (C) 2001 Stefan Westerfeld
+ *
+ * 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.
+ */
+#include "gslglib.h"
+#include <list>
+#include <map>
+
+using std::list;
+using std::pair;
+using std::map;
+
+/*
+ * this uses a map of list to emulate somewhat hashtable like behaviour - note
+ * that insert and remove are O(log N) due to the use of a map, instead of
+ * ~ O(1) which they would be for a "real" hashtable
+ */
+struct _GHashTable
+{
+ GHashFunc hashFunc;
+ GEqualFunc equalFunc;
+ map<guint /*hashvalue for key*/, list< pair<gpointer,gpointer> > /*(key,value) pairs*/> nodes;
+
+ /*Con*/ _GHashTable (GHashFunc hf, GEqualFunc ef) :
+ hashFunc(hf), equalFunc(ef) { }
+};
+
+
+GHashTable* g_hash_table_new (GHashFunc hash_func,
+ GEqualFunc key_equal_func)
+{
+ return new GHashTable (hash_func?hash_func:g_direct_hash, key_equal_func?key_equal_func:g_direct_equal);
+}
+void g_hash_table_destroy (GHashTable *hash_table)
+{
+ g_return_if_fail (hash_table != NULL);
+
+ delete hash_table;
+}
+void g_hash_table_insert (GHashTable *hash_table,
+ gpointer key,
+ gpointer value)
+{
+ g_return_if_fail (hash_table != NULL);
+ guint hashvalue = hash_table->hashFunc (key);
+
+ list< pair<gpointer,gpointer> >& bucket = hash_table->nodes[hashvalue];
+ list< pair<gpointer,gpointer> >::iterator i;
+
+ for (i = bucket.begin(); i != bucket.end(); i++)
+ {
+ if (hash_table->equalFunc(i->first, key))
+ {
+ if (value || TRUE)
+ {
+ i->second = value; /* overwrite old hash value */
+ return;
+ }
+ else
+ {
+ bucket.erase(i); /* remove value */
+
+ if (bucket.empty()) /* remove bucket if this was the only value */
+ hash_table->nodes.erase (hashvalue);
+ return;
+ }
+ }
+ }
+
+ if (value)
+ hash_table->nodes[hashvalue].push_back(std::make_pair (key, value));
+}
+
+gpointer g_hash_table_lookup (GHashTable *hash_table,
+ gconstpointer key)
+{
+ g_return_val_if_fail (hash_table != NULL, NULL);
+
+ guint hashvalue = hash_table->hashFunc (key);
+
+ list< pair<gpointer,gpointer> >& bucket = hash_table->nodes[hashvalue];
+ list< pair<gpointer,gpointer> >::iterator i;
+
+ for (i = bucket.begin(); i != bucket.end(); i++)
+ {
+ if (hash_table->equalFunc(i->first, key))
+ return i->second;
+ }
+
+ return 0;
+}
+gboolean g_hash_table_remove (GHashTable *hash_table,
+ gconstpointer key)
+{
+ g_return_val_if_fail (hash_table != NULL, FALSE);
+
+ guint hashvalue = hash_table->hashFunc (key);
+
+ list< pair<gpointer,gpointer> >& bucket = hash_table->nodes[hashvalue];
+ list< pair<gpointer,gpointer> >::iterator i;
+
+ for (i = bucket.begin(); i != bucket.end(); i++)
+ {
+ if (hash_table->equalFunc(i->first, key))
+ {
+ bucket.erase (i);
+
+ if (bucket.empty()) /* remove bucket if this was the only value */
+ hash_table->nodes.erase (hashvalue);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void g_hash_table_foreach (GHashTable *hash_table,
+ GHFunc func,
+ gpointer user_data)
+{
+ map<guint, list< pair<gpointer,gpointer> > >::iterator bi;
+
+ g_return_if_fail (hash_table != NULL);
+
+ /* for all buckets */
+ for (bi = hash_table->nodes.begin (); bi != hash_table->nodes.end (); bi++)
+ {
+ list< pair<gpointer,gpointer> >& bucket = bi->second;
+ list< pair<gpointer,gpointer> >::iterator i;
+
+ /* for each element in the current bucket */
+ for (i = bucket.begin(); i != bucket.end(); i++)
+ func ((void*) i->first, (void*) i->second, user_data);
+ }
+}
+
+/* vim:set ts=8 sw=2 sts=2: */
diff --git a/flow/gsl/gslglibhashtest.cc b/flow/gsl/gslglibhashtest.cc
new file mode 100644
index 0000000..da50c10
--- /dev/null
+++ b/flow/gsl/gslglibhashtest.cc
@@ -0,0 +1,123 @@
+/* GSL Glib Hashtable test
+ * Copyright (C) 2001 Stefan Westerfeld
+ *
+ * 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.
+ */
+#include "gsldefs.h"
+#include <string.h>
+
+/* cause hashvalue collisions for the test */
+guint g_str_narrow_hash (gconstpointer key) {
+ return g_str_hash (key) & 15;
+}
+
+struct Test {
+ char *key;
+ char *value;
+ int count;
+} test[50];
+
+void print_func (gpointer key, gpointer value, gpointer user_data) {
+#if 0 /* <- enable to get printing of some entries */
+ g_print ("%s: %s = %s\n", user_data, key, value);
+#endif
+}
+
+void fail_func (gpointer key, gpointer value, gpointer user_data) {
+ g_error ("*this* should not have happened");
+}
+
+
+void count_func (gpointer key, gpointer value, gpointer user_data) {
+ g_assert (value != NULL && key != NULL);
+ for(int i=0;i<50;i++)
+ {
+ if(strcmp((char *)key, test[i].key) == 0)
+ {
+ g_assert(strcmp((char *)value, test[i].value) == 0);
+ test[i].count++;
+ }
+ }
+}
+
+
+int main()
+{
+ GHashTable *t = g_hash_table_new (g_str_narrow_hash, g_str_equal);
+
+ for(int i=0;i<50;i++)
+ {
+ test[i].key = g_strdup_printf ("key-%d",i);
+ test[i].value = g_strdup_printf ("value-%d",i);
+ test[i].count = 0;
+
+ g_hash_table_insert (t, test[i].key, test[i].value);
+ }
+
+ g_assert (strcmp ((char *)g_hash_table_lookup (t, "key-24"), "value-24") == 0);
+ g_hash_table_foreach(t, print_func, g_strdup("all-keys-50"));
+ g_hash_table_foreach(t, count_func, 0);
+
+ for(int i=0;i<50;i++)
+ {
+ /* each key should have been found once in the hash table now */
+ g_assert(test[i].count == 1);
+ }
+
+ for(int i=0;i<25;i++)
+ {
+ test[i].key = g_strdup_printf ("key-%d",i);
+ test[i].value = g_strdup_printf ("another-value-%d",i);
+
+ g_hash_table_insert (t, test[i].key, test[i].value);
+ }
+
+ g_assert (strcmp ((char *)g_hash_table_lookup (t, "key-24"), "another-value-24") == 0);
+ g_hash_table_foreach(t, print_func, g_strdup("all-keys-new-25-old-25"));
+ g_hash_table_foreach(t, count_func, 0);
+
+ for(int i=0;i<50;i++)
+ {
+ /* each key should have been found once (with the new value) */
+ g_assert(test[i].count == 2);
+ }
+
+ for(int i=0;i<50;i+=2)
+ {
+ /* remove even valued keys */
+ g_hash_table_remove (t, test[i].key);
+ }
+
+ g_assert (g_hash_table_lookup (t, "key-24") == 0);
+ g_hash_table_foreach(t, print_func, g_strdup("only-odd-keys-25"));
+ g_hash_table_foreach(t, count_func, 0);
+
+ for(int i=0;i<50;i++)
+ {
+ /* only odd keys should be there */
+ g_assert((test[i].count == 3 && (i & 1))
+ || (test[i].count == 2 && !(i & 1)));
+ }
+
+ for(int i=1;i<50;i+=2)
+ {
+ /* remove odd valued keys */
+ g_hash_table_remove (t, g_strdup(test[i].key));
+ }
+
+ g_hash_table_foreach(t, fail_func, 0);
+ return 0;
+}
diff --git a/flow/gsl/gslieee754.h b/flow/gsl/gslieee754.h
new file mode 100644
index 0000000..48ea0ee
--- /dev/null
+++ b/flow/gsl/gslieee754.h
@@ -0,0 +1,246 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 1999, 2001 Tim Janik
+ *
+ * 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.
+ */
+#ifndef __GSL_IEEE754_H__
+#define __GSL_IEEE754_H__
+
+#include <gsl/gsldefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* IEEE 754 single precision floating point layout:
+ * 31 30 23 22 0
+ * +--------+---------------+---------------+
+ * | s 1bit | e[30:23] 8bit | f[22:0] 23bit |
+ * +--------+---------------+---------------+
+ * B0------------------->B1------->B2-->B3-->
+ *
+ * IEEE 754 double precision floating point layout:
+ * 63 62 52 51 32 31 0
+ * +--------+----------------+----------------+ +---------------+
+ * | s 1bit | e[62:52] 11bit | f[51:32] 20bit | | f[31:0] 32bit |
+ * +--------+----------------+----------------+ +---------------+
+ * B0--------------->B1---------->B2--->B3----> B4->B5->B6->B7->
+ */
+
+/* floating point type related constants */
+#define GSL_FLOAT_BIAS (127)
+#define GSL_FLOAT_MAX_NORMAL (3.40282347e+38) /* 7f7fffff */
+#define GSL_FLOAT_MIN_NORMAL (1.17549435e-38) /* 00800000 */
+#define GSL_FLOAT_MAX_SUBNORMAL (1.17549421e-38) /* 007fffff */
+#define GSL_FLOAT_MIN_SUBNORMAL (1.40129846e-45) /* 00000001 */
+#define GSL_DOUBLE_BIAS (1023)
+#define GSL_DOUBLE_MAX_NORMAL (1.7976931348623157e+308) /* 7fefffff ffffffff */
+#define GSL_DOUBLE_MIN_NORMAL (2.2250738585072014e-308) /* 00100000 00000000 */
+#define GSL_DOUBLE_MAX_SUBNORMAL (2.2250738585072009e-308) /* 000fffff ffffffff */
+#define GSL_DOUBLE_MIN_SUBNORMAL (4.9406564584124654e-324) /* 00000000 00000001 */
+#define GSL_DOUBLE_INF (_gsl_dinf_union.d)
+#define GSL_DOUBLE_NAN (_gsl_dnan_union.d)
+#define GSL_FLOAT_INF (_gsl_finf_union.f)
+#define GSL_FLOAT_NAN (_gsl_fnan_union.f)
+
+/* multiply with base2 exponent to get base10 exponent (for nomal numbers) */
+#define GSL_LOG_2_BASE_10 (0.30102999566398119521)
+
+/* the following macros work only on variables
+ * and evaluate arguments multiple times
+ */
+
+/* single precision value checks */
+#define GSL_FLOAT_IS_ZERO(f) ((f) == 0.0) /* compiler knows this one */
+#define GSL_FLOAT_IS_NORMAL(f) (GSL_FLOAT_PARTS (f).mpn.biased_exponent > 0 && \
+ GSL_FLOAT_PARTS (f).mpn.biased_exponent < 255)
+#define GSL_FLOAT_IS_SUBNORMAL(f) (GSL_FLOAT_PARTS (f).mpn.biased_exponent == 0 && \
+ GSL_FLOAT_PARTS (f).mpn.mantissa != 0)
+#define GSL_FLOAT_IS_NANINF(f) (GSL_FLOAT_PARTS (f).mpn.biased_exponent == 255)
+#define GSL_FLOAT_IS_NAN(f) (GSL_FLOAT_IS_NANINF (f) && GSL_FLOAT_PARTS (f).mpn.mantissa != 0)
+#define GSL_FLOAT_IS_INF(f) (GSL_FLOAT_IS_NANINF (f) && GSL_FLOAT_PARTS (f).mpn.mantissa == 0)
+#define GSL_FLOAT_IS_INF_POSITIVE(f) (GSL_FLOAT_IS_INF (f) && GSL_FLOAT_PARTS (f).mpn.sign == 0)
+#define GSL_FLOAT_IS_INF_NEGATIVE(f) (GSL_FLOAT_IS_INF (f) && GSL_FLOAT_PARTS (f).mpn.sign == 1)
+#define GSL_FLOAT_SIGN(f) (GSL_FLOAT_PARTS (f).mpn.sign)
+
+/* double precision value checks */
+#define GSL_DOUBLE_IS_ZERO(d) ((d) == 0.0) /* compiler knows this one */
+#define GSL_DOUBLE_IS_NORMAL(d) (GSL_DOUBLE_PARTS (d).mpn.biased_exponent > 0 && \
+ GSL_DOUBLE_PARTS (d).mpn.biased_exponent < 2047)
+#define GSL_DOUBLE_IS_SUBNORMAL(d) (GSL_DOUBLE_PARTS (d).mpn.biased_exponent == 0 && \
+ (GSL_DOUBLE_PARTS (d).mpn.mantissa_low != 0 || \
+ GSL_DOUBLE_PARTS (d).mpn.mantissa_high != 0))
+#define GSL_DOUBLE_IS_NANINF(d) (GSL_DOUBLE_PARTS (d).mpn.biased_exponent == 2047)
+#define GSL_DOUBLE_IS_NAN(d) (GSL_DOUBLE_IS_NANINF (d) && \
+ (GSL_DOUBLE_PARTS (d).mpn.mantissa_low != 0 || \
+ GSL_DOUBLE_PARTS (d).mpn.mantissa_high != 0))
+#define GSL_DOUBLE_IS_INF(d) (GSL_DOUBLE_IS_NANINF (d) && \
+ GSL_DOUBLE_PARTS (d).mpn.mantissa_low == 0 && \
+ GSL_DOUBLE_PARTS (d).mpn.mantissa_high == 0)
+#define GSL_DOUBLE_IS_INF_POSITIVE(d) (GSL_DOUBLE_IS_INF (d) && GSL_DOUBLE_PARTS (d).mpn.sign == 0)
+#define GSL_DOUBLE_IS_INF_NEGATIVE(d) (GSL_DOUBLE_IS_INF (d) && GSL_DOUBLE_PARTS (d).mpn.sign == 1)
+#define GSL_DOUBLE_SIGN(d) (GSL_DOUBLE_PARTS (d).mpn.sign)
+
+/* get structured parts of floating point numbers */
+#define GSL_FLOAT_PARTS(f) (*((GslFloatIEEE754*) &(f)))
+#define GSL_DOUBLE_PARTS(d) (*((GslDoubleIEEE754*) &(d)))
+
+/* --- rounding --- */
+typedef unsigned short int GslFpuState;
+#if defined (__i386__) && defined (__GNUC__)
+/* setting/restoring rounding mode shouldn't actually
+ * be necessary as round-to-nearest is the hardware
+ * default (can be checked with gsl_fpu_okround()).
+ */
+static inline void gsl_fpu_setround (GslFpuState *cw);
+static inline int gsl_fpu_okround (void);
+static inline void gsl_fpu_restore (GslFpuState cv);
+static inline int gsl_ftoi /* nearest */ (register float f) G_GNUC_CONST;
+static inline int gsl_dtoi /* nearest */ (register double f) G_GNUC_CONST;
+/* fallbacks for the !386 case are below */
+#endif
+
+
+/* --- implementation bits --- */
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+typedef union
+{
+ float v_float;
+ struct {
+ unsigned int mantissa : 23;
+ unsigned int biased_exponent : 8;
+ unsigned int sign : 1;
+ } mpn;
+} GslFloatIEEE754;
+typedef union
+{
+ double v_double;
+ struct {
+ unsigned int mantissa_low : 32;
+ unsigned int mantissa_high : 20;
+ unsigned int biased_exponent : 11;
+ unsigned int sign : 1;
+ } mpn;
+} GslDoubleIEEE754;
+#define _GSL_DOUBLE_INF_BYTES { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f }
+#define _GSL_DOUBLE_NAN_BYTES { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f }
+#define _GSL_FLOAT_INF_BYTES { 0x00, 0x00, 0x80, 0x7f }
+#define _GSL_FLOAT_NAN_BYTES { 0x00, 0x00, 0xc0, 0x7f }
+#elif G_BYTE_ORDER == G_BIG_ENDIAN
+typedef union
+{
+ float v_float;
+ struct {
+ unsigned int sign : 1;
+ unsigned int biased_exponent : 8;
+ unsigned int mantissa : 23;
+ } mpn;
+} GslFloatIEEE754;
+typedef union
+{
+ double v_double;
+ struct {
+ unsigned int sign : 1;
+ unsigned int biased_exponent : 11;
+ unsigned int mantissa_high : 20;
+ unsigned int mantissa_low : 32;
+ } mpn;
+} GslDoubleIEEE754;
+#define _GSL_DOUBLE_INF_BYTES { 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define _GSL_DOUBLE_NAN_BYTES { 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+#define _GSL_FLOAT_INF_BYTES { 0x7f, 0x80, 0x00, 0x00 }
+#define _GSL_FLOAT_NAN_BYTES { 0x7f, 0xc0, 0x00, 0x00 }
+#else /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */
+#error unknown ENDIAN type
+#endif /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */
+
+static const union { unsigned char c[8]; double d; } _gsl_dnan_union = { _GSL_DOUBLE_NAN_BYTES };
+static const union { unsigned char c[8]; double d; } _gsl_dinf_union = { _GSL_DOUBLE_INF_BYTES };
+static const union { unsigned char c[4]; float f; } _gsl_fnan_union = { _GSL_FLOAT_NAN_BYTES };
+static const union { unsigned char c[4]; float f; } _gsl_finf_union = { _GSL_FLOAT_INF_BYTES };
+
+#if defined (__i386__) && defined (__GNUC__)
+static inline void
+gsl_fpu_setround (GslFpuState *cw)
+{
+ GslFpuState cv;
+
+ __asm__ ("fnstcw %0"
+ : "=m" (*&cv));
+ *cw = cv;
+ cv &= ~0x0c00;
+ __asm__ ("fldcw %0"
+ :
+ : "m" (*&cv));
+}
+static inline int
+gsl_fpu_okround (void)
+{
+ GslFpuState cv;
+
+ __asm__ ("fnstcw %0"
+ : "=m" (*&cv));
+ return !(cv & 0x0c00);
+}
+static inline void
+gsl_fpu_restore (GslFpuState cv)
+{
+ __asm__ ("fldcw %0"
+ :
+ : "m" (*&cv));
+}
+static inline int G_GNUC_CONST
+gsl_ftoi (register float f)
+{
+ int r;
+
+ __asm__ ("fistl %0"
+ : "=m" (r)
+ : "t" (f));
+ return r;
+}
+static inline int G_GNUC_CONST
+gsl_dtoi (register double f)
+{
+ int r;
+
+ __asm__ ("fistl %0"
+ : "=m" (r)
+ : "t" (f));
+ return r;
+}
+#else /* !386 */
+# define gsl_fpu_setround(p) ((void) (p));
+# define gsl_fpu_okround() (1)
+# define gsl_fpu_restore(x) /* nop */
+static inline int G_GNUC_CONST
+gsl_ftoi (register float v)
+{
+ return v < -0.0 ? v - 0.5 : v + 0.5;
+}
+static inline int G_GNUC_CONST
+gsl_dtoi (register double v)
+{
+ return v < -0.0 ? v - 0.5 : v + 0.5;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_IEEE754_H__ */ /* vim: set ts=8 sw=2 sts=2: */
diff --git a/flow/gsl/gslincluder.c b/flow/gsl/gslincluder.c
new file mode 100644
index 0000000..4ed4e85
--- /dev/null
+++ b/flow/gsl/gslincluder.c
@@ -0,0 +1,13420 @@
+/* GSL - Generic Sound Layer
+ *
+ * This file 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.
+ */
+
+#if 0
+/* script, used to create this file's contents:
+ */
+{
+ my $first_case = 0;
+ my $last_case = 1024;
+ my $i;
+
+ print "#define GSL_INCLUDER_MAKE_FUNC(name,case) GSL_INCLUDER_CONCAT3 (name, __, case)\n";
+ print "#define GSL_INCLUDER_CONCAT3(x,y,z) x ## y ## z\n";
+ print "#define GSL_INCLUDER_FUNC GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, GSL_INCLUDER_CASE)\n";
+ print "#ifndef GSL_INCLUDER_REJECT\n";
+ print "#define GSL_INCLUDER_REJECT(icase) 0\n";
+ print "#endif\n";
+ print "\n";
+ print "/* check range: $first_case .. $last_case */\n";
+ print "#if (GSL_INCLUDER_FIRST_CASE < $first_case)\n";
+ print "#error GSL_INCLUDER_FIRST_CASE < $first_case is not supported\n";
+ print "#endif\n";
+ print "#if (GSL_INCLUDER_LAST_CASE > $last_case)\n";
+ print "#error GSL_INCLUDER_LAST_CASE > $last_case is not supported\n";
+ print "#endif\n";
+ print "\n";
+ for ($i = $first_case; $i <= $last_case; $i++)
+ {
+ print "/* $i */\n";
+ print "#if (($i >= GSL_INCLUDER_FIRST_CASE) && ($i <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT ($i)))\n";
+ print "#define GSL_INCLUDER_CASE $i\n";
+ print "#include GSL_INCLUDER_FILE\n";
+ print "#undef GSL_INCLUDER_CASE\n";
+ print "#endif\n";
+ }
+ print "\n";
+ print "GSL_INCLUDER_TABLE = {\n";
+ for ($i = $first_case; $i <= $last_case; $i++)
+ {
+ print "#if (($i >= GSL_INCLUDER_FIRST_CASE) && ($i <= GSL_INCLUDER_LAST_CASE))\n";
+ print "#if (GSL_INCLUDER_REJECT ($i))\n";
+ print " NULL,\n";
+ print "#else\n";
+ print " GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, $i),\n";
+ print "#endif\n";
+ print "#endif\n";
+ }
+ print "};\n";
+ print "\n";
+ print "#undef GSL_INCLUDER_REJECT\n";
+ print "#undef GSL_INCLUDER_FUNC\n";
+ print "#undef GSL_INCLUDER_CONCAT3\n";
+ print "#undef GSL_INCLUDER_MAKE_FUNC\n";
+ print "#undef GSL_INCLUDER_FIRST_CASE\n";
+ print "#undef GSL_INCLUDER_LAST_CASE\n";
+ print "#undef GSL_INCLUDER_NAME\n";
+ print "#undef GSL_INCLUDER_TABLE\n";
+ print "#undef GSL_INCLUDER_FILE\n";
+}
+#endif
+
+
+#define GSL_INCLUDER_MAKE_FUNC(name,case) GSL_INCLUDER_CONCAT3 (name, __, case)
+#define GSL_INCLUDER_CONCAT3(x,y,z) x ## y ## z
+#define GSL_INCLUDER_FUNC GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, GSL_INCLUDER_CASE)
+#ifndef GSL_INCLUDER_REJECT
+#define GSL_INCLUDER_REJECT(icase) 0
+#endif
+
+/* check range: 0 .. 1024 */
+#if (GSL_INCLUDER_FIRST_CASE < 0)
+#error GSL_INCLUDER_FIRST_CASE < 0 is not supported
+#endif
+#if (GSL_INCLUDER_LAST_CASE > 1024)
+#error GSL_INCLUDER_LAST_CASE > 1024 is not supported
+#endif
+
+/* 0 */
+#if ((0 >= GSL_INCLUDER_FIRST_CASE) && (0 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (0)))
+#define GSL_INCLUDER_CASE 0
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1 */
+#if ((1 >= GSL_INCLUDER_FIRST_CASE) && (1 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1)))
+#define GSL_INCLUDER_CASE 1
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 2 */
+#if ((2 >= GSL_INCLUDER_FIRST_CASE) && (2 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (2)))
+#define GSL_INCLUDER_CASE 2
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 3 */
+#if ((3 >= GSL_INCLUDER_FIRST_CASE) && (3 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (3)))
+#define GSL_INCLUDER_CASE 3
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 4 */
+#if ((4 >= GSL_INCLUDER_FIRST_CASE) && (4 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (4)))
+#define GSL_INCLUDER_CASE 4
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 5 */
+#if ((5 >= GSL_INCLUDER_FIRST_CASE) && (5 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (5)))
+#define GSL_INCLUDER_CASE 5
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 6 */
+#if ((6 >= GSL_INCLUDER_FIRST_CASE) && (6 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (6)))
+#define GSL_INCLUDER_CASE 6
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 7 */
+#if ((7 >= GSL_INCLUDER_FIRST_CASE) && (7 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (7)))
+#define GSL_INCLUDER_CASE 7
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 8 */
+#if ((8 >= GSL_INCLUDER_FIRST_CASE) && (8 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (8)))
+#define GSL_INCLUDER_CASE 8
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 9 */
+#if ((9 >= GSL_INCLUDER_FIRST_CASE) && (9 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (9)))
+#define GSL_INCLUDER_CASE 9
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 10 */
+#if ((10 >= GSL_INCLUDER_FIRST_CASE) && (10 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (10)))
+#define GSL_INCLUDER_CASE 10
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 11 */
+#if ((11 >= GSL_INCLUDER_FIRST_CASE) && (11 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (11)))
+#define GSL_INCLUDER_CASE 11
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 12 */
+#if ((12 >= GSL_INCLUDER_FIRST_CASE) && (12 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (12)))
+#define GSL_INCLUDER_CASE 12
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 13 */
+#if ((13 >= GSL_INCLUDER_FIRST_CASE) && (13 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (13)))
+#define GSL_INCLUDER_CASE 13
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 14 */
+#if ((14 >= GSL_INCLUDER_FIRST_CASE) && (14 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (14)))
+#define GSL_INCLUDER_CASE 14
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 15 */
+#if ((15 >= GSL_INCLUDER_FIRST_CASE) && (15 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (15)))
+#define GSL_INCLUDER_CASE 15
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 16 */
+#if ((16 >= GSL_INCLUDER_FIRST_CASE) && (16 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (16)))
+#define GSL_INCLUDER_CASE 16
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 17 */
+#if ((17 >= GSL_INCLUDER_FIRST_CASE) && (17 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (17)))
+#define GSL_INCLUDER_CASE 17
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 18 */
+#if ((18 >= GSL_INCLUDER_FIRST_CASE) && (18 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (18)))
+#define GSL_INCLUDER_CASE 18
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 19 */
+#if ((19 >= GSL_INCLUDER_FIRST_CASE) && (19 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (19)))
+#define GSL_INCLUDER_CASE 19
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 20 */
+#if ((20 >= GSL_INCLUDER_FIRST_CASE) && (20 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (20)))
+#define GSL_INCLUDER_CASE 20
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 21 */
+#if ((21 >= GSL_INCLUDER_FIRST_CASE) && (21 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (21)))
+#define GSL_INCLUDER_CASE 21
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 22 */
+#if ((22 >= GSL_INCLUDER_FIRST_CASE) && (22 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (22)))
+#define GSL_INCLUDER_CASE 22
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 23 */
+#if ((23 >= GSL_INCLUDER_FIRST_CASE) && (23 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (23)))
+#define GSL_INCLUDER_CASE 23
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 24 */
+#if ((24 >= GSL_INCLUDER_FIRST_CASE) && (24 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (24)))
+#define GSL_INCLUDER_CASE 24
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 25 */
+#if ((25 >= GSL_INCLUDER_FIRST_CASE) && (25 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (25)))
+#define GSL_INCLUDER_CASE 25
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 26 */
+#if ((26 >= GSL_INCLUDER_FIRST_CASE) && (26 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (26)))
+#define GSL_INCLUDER_CASE 26
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 27 */
+#if ((27 >= GSL_INCLUDER_FIRST_CASE) && (27 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (27)))
+#define GSL_INCLUDER_CASE 27
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 28 */
+#if ((28 >= GSL_INCLUDER_FIRST_CASE) && (28 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (28)))
+#define GSL_INCLUDER_CASE 28
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 29 */
+#if ((29 >= GSL_INCLUDER_FIRST_CASE) && (29 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (29)))
+#define GSL_INCLUDER_CASE 29
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 30 */
+#if ((30 >= GSL_INCLUDER_FIRST_CASE) && (30 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (30)))
+#define GSL_INCLUDER_CASE 30
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 31 */
+#if ((31 >= GSL_INCLUDER_FIRST_CASE) && (31 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (31)))
+#define GSL_INCLUDER_CASE 31
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 32 */
+#if ((32 >= GSL_INCLUDER_FIRST_CASE) && (32 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (32)))
+#define GSL_INCLUDER_CASE 32
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 33 */
+#if ((33 >= GSL_INCLUDER_FIRST_CASE) && (33 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (33)))
+#define GSL_INCLUDER_CASE 33
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 34 */
+#if ((34 >= GSL_INCLUDER_FIRST_CASE) && (34 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (34)))
+#define GSL_INCLUDER_CASE 34
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 35 */
+#if ((35 >= GSL_INCLUDER_FIRST_CASE) && (35 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (35)))
+#define GSL_INCLUDER_CASE 35
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 36 */
+#if ((36 >= GSL_INCLUDER_FIRST_CASE) && (36 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (36)))
+#define GSL_INCLUDER_CASE 36
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 37 */
+#if ((37 >= GSL_INCLUDER_FIRST_CASE) && (37 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (37)))
+#define GSL_INCLUDER_CASE 37
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 38 */
+#if ((38 >= GSL_INCLUDER_FIRST_CASE) && (38 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (38)))
+#define GSL_INCLUDER_CASE 38
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 39 */
+#if ((39 >= GSL_INCLUDER_FIRST_CASE) && (39 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (39)))
+#define GSL_INCLUDER_CASE 39
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 40 */
+#if ((40 >= GSL_INCLUDER_FIRST_CASE) && (40 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (40)))
+#define GSL_INCLUDER_CASE 40
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 41 */
+#if ((41 >= GSL_INCLUDER_FIRST_CASE) && (41 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (41)))
+#define GSL_INCLUDER_CASE 41
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 42 */
+#if ((42 >= GSL_INCLUDER_FIRST_CASE) && (42 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (42)))
+#define GSL_INCLUDER_CASE 42
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 43 */
+#if ((43 >= GSL_INCLUDER_FIRST_CASE) && (43 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (43)))
+#define GSL_INCLUDER_CASE 43
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 44 */
+#if ((44 >= GSL_INCLUDER_FIRST_CASE) && (44 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (44)))
+#define GSL_INCLUDER_CASE 44
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 45 */
+#if ((45 >= GSL_INCLUDER_FIRST_CASE) && (45 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (45)))
+#define GSL_INCLUDER_CASE 45
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 46 */
+#if ((46 >= GSL_INCLUDER_FIRST_CASE) && (46 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (46)))
+#define GSL_INCLUDER_CASE 46
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 47 */
+#if ((47 >= GSL_INCLUDER_FIRST_CASE) && (47 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (47)))
+#define GSL_INCLUDER_CASE 47
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 48 */
+#if ((48 >= GSL_INCLUDER_FIRST_CASE) && (48 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (48)))
+#define GSL_INCLUDER_CASE 48
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 49 */
+#if ((49 >= GSL_INCLUDER_FIRST_CASE) && (49 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (49)))
+#define GSL_INCLUDER_CASE 49
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 50 */
+#if ((50 >= GSL_INCLUDER_FIRST_CASE) && (50 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (50)))
+#define GSL_INCLUDER_CASE 50
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 51 */
+#if ((51 >= GSL_INCLUDER_FIRST_CASE) && (51 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (51)))
+#define GSL_INCLUDER_CASE 51
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 52 */
+#if ((52 >= GSL_INCLUDER_FIRST_CASE) && (52 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (52)))
+#define GSL_INCLUDER_CASE 52
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 53 */
+#if ((53 >= GSL_INCLUDER_FIRST_CASE) && (53 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (53)))
+#define GSL_INCLUDER_CASE 53
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 54 */
+#if ((54 >= GSL_INCLUDER_FIRST_CASE) && (54 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (54)))
+#define GSL_INCLUDER_CASE 54
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 55 */
+#if ((55 >= GSL_INCLUDER_FIRST_CASE) && (55 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (55)))
+#define GSL_INCLUDER_CASE 55
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 56 */
+#if ((56 >= GSL_INCLUDER_FIRST_CASE) && (56 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (56)))
+#define GSL_INCLUDER_CASE 56
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 57 */
+#if ((57 >= GSL_INCLUDER_FIRST_CASE) && (57 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (57)))
+#define GSL_INCLUDER_CASE 57
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 58 */
+#if ((58 >= GSL_INCLUDER_FIRST_CASE) && (58 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (58)))
+#define GSL_INCLUDER_CASE 58
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 59 */
+#if ((59 >= GSL_INCLUDER_FIRST_CASE) && (59 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (59)))
+#define GSL_INCLUDER_CASE 59
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 60 */
+#if ((60 >= GSL_INCLUDER_FIRST_CASE) && (60 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (60)))
+#define GSL_INCLUDER_CASE 60
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 61 */
+#if ((61 >= GSL_INCLUDER_FIRST_CASE) && (61 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (61)))
+#define GSL_INCLUDER_CASE 61
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 62 */
+#if ((62 >= GSL_INCLUDER_FIRST_CASE) && (62 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (62)))
+#define GSL_INCLUDER_CASE 62
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 63 */
+#if ((63 >= GSL_INCLUDER_FIRST_CASE) && (63 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (63)))
+#define GSL_INCLUDER_CASE 63
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 64 */
+#if ((64 >= GSL_INCLUDER_FIRST_CASE) && (64 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (64)))
+#define GSL_INCLUDER_CASE 64
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 65 */
+#if ((65 >= GSL_INCLUDER_FIRST_CASE) && (65 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (65)))
+#define GSL_INCLUDER_CASE 65
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 66 */
+#if ((66 >= GSL_INCLUDER_FIRST_CASE) && (66 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (66)))
+#define GSL_INCLUDER_CASE 66
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 67 */
+#if ((67 >= GSL_INCLUDER_FIRST_CASE) && (67 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (67)))
+#define GSL_INCLUDER_CASE 67
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 68 */
+#if ((68 >= GSL_INCLUDER_FIRST_CASE) && (68 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (68)))
+#define GSL_INCLUDER_CASE 68
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 69 */
+#if ((69 >= GSL_INCLUDER_FIRST_CASE) && (69 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (69)))
+#define GSL_INCLUDER_CASE 69
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 70 */
+#if ((70 >= GSL_INCLUDER_FIRST_CASE) && (70 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (70)))
+#define GSL_INCLUDER_CASE 70
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 71 */
+#if ((71 >= GSL_INCLUDER_FIRST_CASE) && (71 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (71)))
+#define GSL_INCLUDER_CASE 71
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 72 */
+#if ((72 >= GSL_INCLUDER_FIRST_CASE) && (72 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (72)))
+#define GSL_INCLUDER_CASE 72
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 73 */
+#if ((73 >= GSL_INCLUDER_FIRST_CASE) && (73 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (73)))
+#define GSL_INCLUDER_CASE 73
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 74 */
+#if ((74 >= GSL_INCLUDER_FIRST_CASE) && (74 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (74)))
+#define GSL_INCLUDER_CASE 74
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 75 */
+#if ((75 >= GSL_INCLUDER_FIRST_CASE) && (75 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (75)))
+#define GSL_INCLUDER_CASE 75
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 76 */
+#if ((76 >= GSL_INCLUDER_FIRST_CASE) && (76 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (76)))
+#define GSL_INCLUDER_CASE 76
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 77 */
+#if ((77 >= GSL_INCLUDER_FIRST_CASE) && (77 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (77)))
+#define GSL_INCLUDER_CASE 77
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 78 */
+#if ((78 >= GSL_INCLUDER_FIRST_CASE) && (78 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (78)))
+#define GSL_INCLUDER_CASE 78
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 79 */
+#if ((79 >= GSL_INCLUDER_FIRST_CASE) && (79 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (79)))
+#define GSL_INCLUDER_CASE 79
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 80 */
+#if ((80 >= GSL_INCLUDER_FIRST_CASE) && (80 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (80)))
+#define GSL_INCLUDER_CASE 80
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 81 */
+#if ((81 >= GSL_INCLUDER_FIRST_CASE) && (81 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (81)))
+#define GSL_INCLUDER_CASE 81
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 82 */
+#if ((82 >= GSL_INCLUDER_FIRST_CASE) && (82 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (82)))
+#define GSL_INCLUDER_CASE 82
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 83 */
+#if ((83 >= GSL_INCLUDER_FIRST_CASE) && (83 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (83)))
+#define GSL_INCLUDER_CASE 83
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 84 */
+#if ((84 >= GSL_INCLUDER_FIRST_CASE) && (84 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (84)))
+#define GSL_INCLUDER_CASE 84
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 85 */
+#if ((85 >= GSL_INCLUDER_FIRST_CASE) && (85 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (85)))
+#define GSL_INCLUDER_CASE 85
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 86 */
+#if ((86 >= GSL_INCLUDER_FIRST_CASE) && (86 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (86)))
+#define GSL_INCLUDER_CASE 86
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 87 */
+#if ((87 >= GSL_INCLUDER_FIRST_CASE) && (87 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (87)))
+#define GSL_INCLUDER_CASE 87
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 88 */
+#if ((88 >= GSL_INCLUDER_FIRST_CASE) && (88 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (88)))
+#define GSL_INCLUDER_CASE 88
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 89 */
+#if ((89 >= GSL_INCLUDER_FIRST_CASE) && (89 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (89)))
+#define GSL_INCLUDER_CASE 89
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 90 */
+#if ((90 >= GSL_INCLUDER_FIRST_CASE) && (90 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (90)))
+#define GSL_INCLUDER_CASE 90
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 91 */
+#if ((91 >= GSL_INCLUDER_FIRST_CASE) && (91 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (91)))
+#define GSL_INCLUDER_CASE 91
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 92 */
+#if ((92 >= GSL_INCLUDER_FIRST_CASE) && (92 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (92)))
+#define GSL_INCLUDER_CASE 92
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 93 */
+#if ((93 >= GSL_INCLUDER_FIRST_CASE) && (93 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (93)))
+#define GSL_INCLUDER_CASE 93
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 94 */
+#if ((94 >= GSL_INCLUDER_FIRST_CASE) && (94 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (94)))
+#define GSL_INCLUDER_CASE 94
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 95 */
+#if ((95 >= GSL_INCLUDER_FIRST_CASE) && (95 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (95)))
+#define GSL_INCLUDER_CASE 95
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 96 */
+#if ((96 >= GSL_INCLUDER_FIRST_CASE) && (96 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (96)))
+#define GSL_INCLUDER_CASE 96
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 97 */
+#if ((97 >= GSL_INCLUDER_FIRST_CASE) && (97 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (97)))
+#define GSL_INCLUDER_CASE 97
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 98 */
+#if ((98 >= GSL_INCLUDER_FIRST_CASE) && (98 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (98)))
+#define GSL_INCLUDER_CASE 98
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 99 */
+#if ((99 >= GSL_INCLUDER_FIRST_CASE) && (99 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (99)))
+#define GSL_INCLUDER_CASE 99
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 100 */
+#if ((100 >= GSL_INCLUDER_FIRST_CASE) && (100 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (100)))
+#define GSL_INCLUDER_CASE 100
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 101 */
+#if ((101 >= GSL_INCLUDER_FIRST_CASE) && (101 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (101)))
+#define GSL_INCLUDER_CASE 101
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 102 */
+#if ((102 >= GSL_INCLUDER_FIRST_CASE) && (102 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (102)))
+#define GSL_INCLUDER_CASE 102
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 103 */
+#if ((103 >= GSL_INCLUDER_FIRST_CASE) && (103 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (103)))
+#define GSL_INCLUDER_CASE 103
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 104 */
+#if ((104 >= GSL_INCLUDER_FIRST_CASE) && (104 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (104)))
+#define GSL_INCLUDER_CASE 104
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 105 */
+#if ((105 >= GSL_INCLUDER_FIRST_CASE) && (105 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (105)))
+#define GSL_INCLUDER_CASE 105
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 106 */
+#if ((106 >= GSL_INCLUDER_FIRST_CASE) && (106 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (106)))
+#define GSL_INCLUDER_CASE 106
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 107 */
+#if ((107 >= GSL_INCLUDER_FIRST_CASE) && (107 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (107)))
+#define GSL_INCLUDER_CASE 107
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 108 */
+#if ((108 >= GSL_INCLUDER_FIRST_CASE) && (108 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (108)))
+#define GSL_INCLUDER_CASE 108
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 109 */
+#if ((109 >= GSL_INCLUDER_FIRST_CASE) && (109 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (109)))
+#define GSL_INCLUDER_CASE 109
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 110 */
+#if ((110 >= GSL_INCLUDER_FIRST_CASE) && (110 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (110)))
+#define GSL_INCLUDER_CASE 110
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 111 */
+#if ((111 >= GSL_INCLUDER_FIRST_CASE) && (111 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (111)))
+#define GSL_INCLUDER_CASE 111
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 112 */
+#if ((112 >= GSL_INCLUDER_FIRST_CASE) && (112 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (112)))
+#define GSL_INCLUDER_CASE 112
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 113 */
+#if ((113 >= GSL_INCLUDER_FIRST_CASE) && (113 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (113)))
+#define GSL_INCLUDER_CASE 113
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 114 */
+#if ((114 >= GSL_INCLUDER_FIRST_CASE) && (114 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (114)))
+#define GSL_INCLUDER_CASE 114
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 115 */
+#if ((115 >= GSL_INCLUDER_FIRST_CASE) && (115 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (115)))
+#define GSL_INCLUDER_CASE 115
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 116 */
+#if ((116 >= GSL_INCLUDER_FIRST_CASE) && (116 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (116)))
+#define GSL_INCLUDER_CASE 116
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 117 */
+#if ((117 >= GSL_INCLUDER_FIRST_CASE) && (117 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (117)))
+#define GSL_INCLUDER_CASE 117
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 118 */
+#if ((118 >= GSL_INCLUDER_FIRST_CASE) && (118 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (118)))
+#define GSL_INCLUDER_CASE 118
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 119 */
+#if ((119 >= GSL_INCLUDER_FIRST_CASE) && (119 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (119)))
+#define GSL_INCLUDER_CASE 119
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 120 */
+#if ((120 >= GSL_INCLUDER_FIRST_CASE) && (120 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (120)))
+#define GSL_INCLUDER_CASE 120
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 121 */
+#if ((121 >= GSL_INCLUDER_FIRST_CASE) && (121 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (121)))
+#define GSL_INCLUDER_CASE 121
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 122 */
+#if ((122 >= GSL_INCLUDER_FIRST_CASE) && (122 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (122)))
+#define GSL_INCLUDER_CASE 122
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 123 */
+#if ((123 >= GSL_INCLUDER_FIRST_CASE) && (123 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (123)))
+#define GSL_INCLUDER_CASE 123
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 124 */
+#if ((124 >= GSL_INCLUDER_FIRST_CASE) && (124 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (124)))
+#define GSL_INCLUDER_CASE 124
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 125 */
+#if ((125 >= GSL_INCLUDER_FIRST_CASE) && (125 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (125)))
+#define GSL_INCLUDER_CASE 125
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 126 */
+#if ((126 >= GSL_INCLUDER_FIRST_CASE) && (126 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (126)))
+#define GSL_INCLUDER_CASE 126
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 127 */
+#if ((127 >= GSL_INCLUDER_FIRST_CASE) && (127 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (127)))
+#define GSL_INCLUDER_CASE 127
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 128 */
+#if ((128 >= GSL_INCLUDER_FIRST_CASE) && (128 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (128)))
+#define GSL_INCLUDER_CASE 128
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 129 */
+#if ((129 >= GSL_INCLUDER_FIRST_CASE) && (129 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (129)))
+#define GSL_INCLUDER_CASE 129
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 130 */
+#if ((130 >= GSL_INCLUDER_FIRST_CASE) && (130 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (130)))
+#define GSL_INCLUDER_CASE 130
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 131 */
+#if ((131 >= GSL_INCLUDER_FIRST_CASE) && (131 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (131)))
+#define GSL_INCLUDER_CASE 131
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 132 */
+#if ((132 >= GSL_INCLUDER_FIRST_CASE) && (132 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (132)))
+#define GSL_INCLUDER_CASE 132
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 133 */
+#if ((133 >= GSL_INCLUDER_FIRST_CASE) && (133 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (133)))
+#define GSL_INCLUDER_CASE 133
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 134 */
+#if ((134 >= GSL_INCLUDER_FIRST_CASE) && (134 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (134)))
+#define GSL_INCLUDER_CASE 134
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 135 */
+#if ((135 >= GSL_INCLUDER_FIRST_CASE) && (135 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (135)))
+#define GSL_INCLUDER_CASE 135
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 136 */
+#if ((136 >= GSL_INCLUDER_FIRST_CASE) && (136 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (136)))
+#define GSL_INCLUDER_CASE 136
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 137 */
+#if ((137 >= GSL_INCLUDER_FIRST_CASE) && (137 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (137)))
+#define GSL_INCLUDER_CASE 137
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 138 */
+#if ((138 >= GSL_INCLUDER_FIRST_CASE) && (138 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (138)))
+#define GSL_INCLUDER_CASE 138
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 139 */
+#if ((139 >= GSL_INCLUDER_FIRST_CASE) && (139 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (139)))
+#define GSL_INCLUDER_CASE 139
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 140 */
+#if ((140 >= GSL_INCLUDER_FIRST_CASE) && (140 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (140)))
+#define GSL_INCLUDER_CASE 140
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 141 */
+#if ((141 >= GSL_INCLUDER_FIRST_CASE) && (141 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (141)))
+#define GSL_INCLUDER_CASE 141
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 142 */
+#if ((142 >= GSL_INCLUDER_FIRST_CASE) && (142 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (142)))
+#define GSL_INCLUDER_CASE 142
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 143 */
+#if ((143 >= GSL_INCLUDER_FIRST_CASE) && (143 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (143)))
+#define GSL_INCLUDER_CASE 143
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 144 */
+#if ((144 >= GSL_INCLUDER_FIRST_CASE) && (144 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (144)))
+#define GSL_INCLUDER_CASE 144
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 145 */
+#if ((145 >= GSL_INCLUDER_FIRST_CASE) && (145 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (145)))
+#define GSL_INCLUDER_CASE 145
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 146 */
+#if ((146 >= GSL_INCLUDER_FIRST_CASE) && (146 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (146)))
+#define GSL_INCLUDER_CASE 146
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 147 */
+#if ((147 >= GSL_INCLUDER_FIRST_CASE) && (147 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (147)))
+#define GSL_INCLUDER_CASE 147
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 148 */
+#if ((148 >= GSL_INCLUDER_FIRST_CASE) && (148 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (148)))
+#define GSL_INCLUDER_CASE 148
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 149 */
+#if ((149 >= GSL_INCLUDER_FIRST_CASE) && (149 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (149)))
+#define GSL_INCLUDER_CASE 149
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 150 */
+#if ((150 >= GSL_INCLUDER_FIRST_CASE) && (150 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (150)))
+#define GSL_INCLUDER_CASE 150
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 151 */
+#if ((151 >= GSL_INCLUDER_FIRST_CASE) && (151 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (151)))
+#define GSL_INCLUDER_CASE 151
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 152 */
+#if ((152 >= GSL_INCLUDER_FIRST_CASE) && (152 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (152)))
+#define GSL_INCLUDER_CASE 152
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 153 */
+#if ((153 >= GSL_INCLUDER_FIRST_CASE) && (153 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (153)))
+#define GSL_INCLUDER_CASE 153
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 154 */
+#if ((154 >= GSL_INCLUDER_FIRST_CASE) && (154 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (154)))
+#define GSL_INCLUDER_CASE 154
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 155 */
+#if ((155 >= GSL_INCLUDER_FIRST_CASE) && (155 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (155)))
+#define GSL_INCLUDER_CASE 155
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 156 */
+#if ((156 >= GSL_INCLUDER_FIRST_CASE) && (156 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (156)))
+#define GSL_INCLUDER_CASE 156
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 157 */
+#if ((157 >= GSL_INCLUDER_FIRST_CASE) && (157 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (157)))
+#define GSL_INCLUDER_CASE 157
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 158 */
+#if ((158 >= GSL_INCLUDER_FIRST_CASE) && (158 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (158)))
+#define GSL_INCLUDER_CASE 158
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 159 */
+#if ((159 >= GSL_INCLUDER_FIRST_CASE) && (159 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (159)))
+#define GSL_INCLUDER_CASE 159
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 160 */
+#if ((160 >= GSL_INCLUDER_FIRST_CASE) && (160 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (160)))
+#define GSL_INCLUDER_CASE 160
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 161 */
+#if ((161 >= GSL_INCLUDER_FIRST_CASE) && (161 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (161)))
+#define GSL_INCLUDER_CASE 161
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 162 */
+#if ((162 >= GSL_INCLUDER_FIRST_CASE) && (162 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (162)))
+#define GSL_INCLUDER_CASE 162
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 163 */
+#if ((163 >= GSL_INCLUDER_FIRST_CASE) && (163 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (163)))
+#define GSL_INCLUDER_CASE 163
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 164 */
+#if ((164 >= GSL_INCLUDER_FIRST_CASE) && (164 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (164)))
+#define GSL_INCLUDER_CASE 164
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 165 */
+#if ((165 >= GSL_INCLUDER_FIRST_CASE) && (165 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (165)))
+#define GSL_INCLUDER_CASE 165
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 166 */
+#if ((166 >= GSL_INCLUDER_FIRST_CASE) && (166 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (166)))
+#define GSL_INCLUDER_CASE 166
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 167 */
+#if ((167 >= GSL_INCLUDER_FIRST_CASE) && (167 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (167)))
+#define GSL_INCLUDER_CASE 167
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 168 */
+#if ((168 >= GSL_INCLUDER_FIRST_CASE) && (168 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (168)))
+#define GSL_INCLUDER_CASE 168
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 169 */
+#if ((169 >= GSL_INCLUDER_FIRST_CASE) && (169 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (169)))
+#define GSL_INCLUDER_CASE 169
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 170 */
+#if ((170 >= GSL_INCLUDER_FIRST_CASE) && (170 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (170)))
+#define GSL_INCLUDER_CASE 170
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 171 */
+#if ((171 >= GSL_INCLUDER_FIRST_CASE) && (171 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (171)))
+#define GSL_INCLUDER_CASE 171
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 172 */
+#if ((172 >= GSL_INCLUDER_FIRST_CASE) && (172 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (172)))
+#define GSL_INCLUDER_CASE 172
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 173 */
+#if ((173 >= GSL_INCLUDER_FIRST_CASE) && (173 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (173)))
+#define GSL_INCLUDER_CASE 173
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 174 */
+#if ((174 >= GSL_INCLUDER_FIRST_CASE) && (174 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (174)))
+#define GSL_INCLUDER_CASE 174
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 175 */
+#if ((175 >= GSL_INCLUDER_FIRST_CASE) && (175 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (175)))
+#define GSL_INCLUDER_CASE 175
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 176 */
+#if ((176 >= GSL_INCLUDER_FIRST_CASE) && (176 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (176)))
+#define GSL_INCLUDER_CASE 176
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 177 */
+#if ((177 >= GSL_INCLUDER_FIRST_CASE) && (177 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (177)))
+#define GSL_INCLUDER_CASE 177
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 178 */
+#if ((178 >= GSL_INCLUDER_FIRST_CASE) && (178 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (178)))
+#define GSL_INCLUDER_CASE 178
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 179 */
+#if ((179 >= GSL_INCLUDER_FIRST_CASE) && (179 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (179)))
+#define GSL_INCLUDER_CASE 179
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 180 */
+#if ((180 >= GSL_INCLUDER_FIRST_CASE) && (180 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (180)))
+#define GSL_INCLUDER_CASE 180
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 181 */
+#if ((181 >= GSL_INCLUDER_FIRST_CASE) && (181 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (181)))
+#define GSL_INCLUDER_CASE 181
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 182 */
+#if ((182 >= GSL_INCLUDER_FIRST_CASE) && (182 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (182)))
+#define GSL_INCLUDER_CASE 182
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 183 */
+#if ((183 >= GSL_INCLUDER_FIRST_CASE) && (183 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (183)))
+#define GSL_INCLUDER_CASE 183
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 184 */
+#if ((184 >= GSL_INCLUDER_FIRST_CASE) && (184 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (184)))
+#define GSL_INCLUDER_CASE 184
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 185 */
+#if ((185 >= GSL_INCLUDER_FIRST_CASE) && (185 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (185)))
+#define GSL_INCLUDER_CASE 185
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 186 */
+#if ((186 >= GSL_INCLUDER_FIRST_CASE) && (186 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (186)))
+#define GSL_INCLUDER_CASE 186
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 187 */
+#if ((187 >= GSL_INCLUDER_FIRST_CASE) && (187 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (187)))
+#define GSL_INCLUDER_CASE 187
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 188 */
+#if ((188 >= GSL_INCLUDER_FIRST_CASE) && (188 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (188)))
+#define GSL_INCLUDER_CASE 188
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 189 */
+#if ((189 >= GSL_INCLUDER_FIRST_CASE) && (189 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (189)))
+#define GSL_INCLUDER_CASE 189
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 190 */
+#if ((190 >= GSL_INCLUDER_FIRST_CASE) && (190 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (190)))
+#define GSL_INCLUDER_CASE 190
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 191 */
+#if ((191 >= GSL_INCLUDER_FIRST_CASE) && (191 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (191)))
+#define GSL_INCLUDER_CASE 191
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 192 */
+#if ((192 >= GSL_INCLUDER_FIRST_CASE) && (192 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (192)))
+#define GSL_INCLUDER_CASE 192
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 193 */
+#if ((193 >= GSL_INCLUDER_FIRST_CASE) && (193 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (193)))
+#define GSL_INCLUDER_CASE 193
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 194 */
+#if ((194 >= GSL_INCLUDER_FIRST_CASE) && (194 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (194)))
+#define GSL_INCLUDER_CASE 194
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 195 */
+#if ((195 >= GSL_INCLUDER_FIRST_CASE) && (195 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (195)))
+#define GSL_INCLUDER_CASE 195
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 196 */
+#if ((196 >= GSL_INCLUDER_FIRST_CASE) && (196 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (196)))
+#define GSL_INCLUDER_CASE 196
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 197 */
+#if ((197 >= GSL_INCLUDER_FIRST_CASE) && (197 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (197)))
+#define GSL_INCLUDER_CASE 197
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 198 */
+#if ((198 >= GSL_INCLUDER_FIRST_CASE) && (198 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (198)))
+#define GSL_INCLUDER_CASE 198
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 199 */
+#if ((199 >= GSL_INCLUDER_FIRST_CASE) && (199 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (199)))
+#define GSL_INCLUDER_CASE 199
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 200 */
+#if ((200 >= GSL_INCLUDER_FIRST_CASE) && (200 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (200)))
+#define GSL_INCLUDER_CASE 200
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 201 */
+#if ((201 >= GSL_INCLUDER_FIRST_CASE) && (201 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (201)))
+#define GSL_INCLUDER_CASE 201
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 202 */
+#if ((202 >= GSL_INCLUDER_FIRST_CASE) && (202 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (202)))
+#define GSL_INCLUDER_CASE 202
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 203 */
+#if ((203 >= GSL_INCLUDER_FIRST_CASE) && (203 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (203)))
+#define GSL_INCLUDER_CASE 203
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 204 */
+#if ((204 >= GSL_INCLUDER_FIRST_CASE) && (204 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (204)))
+#define GSL_INCLUDER_CASE 204
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 205 */
+#if ((205 >= GSL_INCLUDER_FIRST_CASE) && (205 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (205)))
+#define GSL_INCLUDER_CASE 205
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 206 */
+#if ((206 >= GSL_INCLUDER_FIRST_CASE) && (206 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (206)))
+#define GSL_INCLUDER_CASE 206
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 207 */
+#if ((207 >= GSL_INCLUDER_FIRST_CASE) && (207 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (207)))
+#define GSL_INCLUDER_CASE 207
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 208 */
+#if ((208 >= GSL_INCLUDER_FIRST_CASE) && (208 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (208)))
+#define GSL_INCLUDER_CASE 208
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 209 */
+#if ((209 >= GSL_INCLUDER_FIRST_CASE) && (209 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (209)))
+#define GSL_INCLUDER_CASE 209
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 210 */
+#if ((210 >= GSL_INCLUDER_FIRST_CASE) && (210 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (210)))
+#define GSL_INCLUDER_CASE 210
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 211 */
+#if ((211 >= GSL_INCLUDER_FIRST_CASE) && (211 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (211)))
+#define GSL_INCLUDER_CASE 211
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 212 */
+#if ((212 >= GSL_INCLUDER_FIRST_CASE) && (212 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (212)))
+#define GSL_INCLUDER_CASE 212
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 213 */
+#if ((213 >= GSL_INCLUDER_FIRST_CASE) && (213 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (213)))
+#define GSL_INCLUDER_CASE 213
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 214 */
+#if ((214 >= GSL_INCLUDER_FIRST_CASE) && (214 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (214)))
+#define GSL_INCLUDER_CASE 214
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 215 */
+#if ((215 >= GSL_INCLUDER_FIRST_CASE) && (215 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (215)))
+#define GSL_INCLUDER_CASE 215
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 216 */
+#if ((216 >= GSL_INCLUDER_FIRST_CASE) && (216 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (216)))
+#define GSL_INCLUDER_CASE 216
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 217 */
+#if ((217 >= GSL_INCLUDER_FIRST_CASE) && (217 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (217)))
+#define GSL_INCLUDER_CASE 217
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 218 */
+#if ((218 >= GSL_INCLUDER_FIRST_CASE) && (218 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (218)))
+#define GSL_INCLUDER_CASE 218
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 219 */
+#if ((219 >= GSL_INCLUDER_FIRST_CASE) && (219 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (219)))
+#define GSL_INCLUDER_CASE 219
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 220 */
+#if ((220 >= GSL_INCLUDER_FIRST_CASE) && (220 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (220)))
+#define GSL_INCLUDER_CASE 220
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 221 */
+#if ((221 >= GSL_INCLUDER_FIRST_CASE) && (221 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (221)))
+#define GSL_INCLUDER_CASE 221
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 222 */
+#if ((222 >= GSL_INCLUDER_FIRST_CASE) && (222 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (222)))
+#define GSL_INCLUDER_CASE 222
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 223 */
+#if ((223 >= GSL_INCLUDER_FIRST_CASE) && (223 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (223)))
+#define GSL_INCLUDER_CASE 223
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 224 */
+#if ((224 >= GSL_INCLUDER_FIRST_CASE) && (224 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (224)))
+#define GSL_INCLUDER_CASE 224
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 225 */
+#if ((225 >= GSL_INCLUDER_FIRST_CASE) && (225 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (225)))
+#define GSL_INCLUDER_CASE 225
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 226 */
+#if ((226 >= GSL_INCLUDER_FIRST_CASE) && (226 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (226)))
+#define GSL_INCLUDER_CASE 226
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 227 */
+#if ((227 >= GSL_INCLUDER_FIRST_CASE) && (227 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (227)))
+#define GSL_INCLUDER_CASE 227
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 228 */
+#if ((228 >= GSL_INCLUDER_FIRST_CASE) && (228 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (228)))
+#define GSL_INCLUDER_CASE 228
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 229 */
+#if ((229 >= GSL_INCLUDER_FIRST_CASE) && (229 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (229)))
+#define GSL_INCLUDER_CASE 229
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 230 */
+#if ((230 >= GSL_INCLUDER_FIRST_CASE) && (230 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (230)))
+#define GSL_INCLUDER_CASE 230
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 231 */
+#if ((231 >= GSL_INCLUDER_FIRST_CASE) && (231 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (231)))
+#define GSL_INCLUDER_CASE 231
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 232 */
+#if ((232 >= GSL_INCLUDER_FIRST_CASE) && (232 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (232)))
+#define GSL_INCLUDER_CASE 232
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 233 */
+#if ((233 >= GSL_INCLUDER_FIRST_CASE) && (233 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (233)))
+#define GSL_INCLUDER_CASE 233
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 234 */
+#if ((234 >= GSL_INCLUDER_FIRST_CASE) && (234 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (234)))
+#define GSL_INCLUDER_CASE 234
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 235 */
+#if ((235 >= GSL_INCLUDER_FIRST_CASE) && (235 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (235)))
+#define GSL_INCLUDER_CASE 235
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 236 */
+#if ((236 >= GSL_INCLUDER_FIRST_CASE) && (236 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (236)))
+#define GSL_INCLUDER_CASE 236
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 237 */
+#if ((237 >= GSL_INCLUDER_FIRST_CASE) && (237 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (237)))
+#define GSL_INCLUDER_CASE 237
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 238 */
+#if ((238 >= GSL_INCLUDER_FIRST_CASE) && (238 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (238)))
+#define GSL_INCLUDER_CASE 238
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 239 */
+#if ((239 >= GSL_INCLUDER_FIRST_CASE) && (239 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (239)))
+#define GSL_INCLUDER_CASE 239
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 240 */
+#if ((240 >= GSL_INCLUDER_FIRST_CASE) && (240 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (240)))
+#define GSL_INCLUDER_CASE 240
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 241 */
+#if ((241 >= GSL_INCLUDER_FIRST_CASE) && (241 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (241)))
+#define GSL_INCLUDER_CASE 241
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 242 */
+#if ((242 >= GSL_INCLUDER_FIRST_CASE) && (242 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (242)))
+#define GSL_INCLUDER_CASE 242
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 243 */
+#if ((243 >= GSL_INCLUDER_FIRST_CASE) && (243 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (243)))
+#define GSL_INCLUDER_CASE 243
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 244 */
+#if ((244 >= GSL_INCLUDER_FIRST_CASE) && (244 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (244)))
+#define GSL_INCLUDER_CASE 244
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 245 */
+#if ((245 >= GSL_INCLUDER_FIRST_CASE) && (245 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (245)))
+#define GSL_INCLUDER_CASE 245
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 246 */
+#if ((246 >= GSL_INCLUDER_FIRST_CASE) && (246 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (246)))
+#define GSL_INCLUDER_CASE 246
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 247 */
+#if ((247 >= GSL_INCLUDER_FIRST_CASE) && (247 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (247)))
+#define GSL_INCLUDER_CASE 247
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 248 */
+#if ((248 >= GSL_INCLUDER_FIRST_CASE) && (248 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (248)))
+#define GSL_INCLUDER_CASE 248
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 249 */
+#if ((249 >= GSL_INCLUDER_FIRST_CASE) && (249 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (249)))
+#define GSL_INCLUDER_CASE 249
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 250 */
+#if ((250 >= GSL_INCLUDER_FIRST_CASE) && (250 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (250)))
+#define GSL_INCLUDER_CASE 250
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 251 */
+#if ((251 >= GSL_INCLUDER_FIRST_CASE) && (251 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (251)))
+#define GSL_INCLUDER_CASE 251
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 252 */
+#if ((252 >= GSL_INCLUDER_FIRST_CASE) && (252 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (252)))
+#define GSL_INCLUDER_CASE 252
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 253 */
+#if ((253 >= GSL_INCLUDER_FIRST_CASE) && (253 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (253)))
+#define GSL_INCLUDER_CASE 253
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 254 */
+#if ((254 >= GSL_INCLUDER_FIRST_CASE) && (254 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (254)))
+#define GSL_INCLUDER_CASE 254
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 255 */
+#if ((255 >= GSL_INCLUDER_FIRST_CASE) && (255 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (255)))
+#define GSL_INCLUDER_CASE 255
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 256 */
+#if ((256 >= GSL_INCLUDER_FIRST_CASE) && (256 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (256)))
+#define GSL_INCLUDER_CASE 256
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 257 */
+#if ((257 >= GSL_INCLUDER_FIRST_CASE) && (257 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (257)))
+#define GSL_INCLUDER_CASE 257
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 258 */
+#if ((258 >= GSL_INCLUDER_FIRST_CASE) && (258 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (258)))
+#define GSL_INCLUDER_CASE 258
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 259 */
+#if ((259 >= GSL_INCLUDER_FIRST_CASE) && (259 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (259)))
+#define GSL_INCLUDER_CASE 259
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 260 */
+#if ((260 >= GSL_INCLUDER_FIRST_CASE) && (260 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (260)))
+#define GSL_INCLUDER_CASE 260
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 261 */
+#if ((261 >= GSL_INCLUDER_FIRST_CASE) && (261 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (261)))
+#define GSL_INCLUDER_CASE 261
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 262 */
+#if ((262 >= GSL_INCLUDER_FIRST_CASE) && (262 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (262)))
+#define GSL_INCLUDER_CASE 262
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 263 */
+#if ((263 >= GSL_INCLUDER_FIRST_CASE) && (263 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (263)))
+#define GSL_INCLUDER_CASE 263
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 264 */
+#if ((264 >= GSL_INCLUDER_FIRST_CASE) && (264 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (264)))
+#define GSL_INCLUDER_CASE 264
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 265 */
+#if ((265 >= GSL_INCLUDER_FIRST_CASE) && (265 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (265)))
+#define GSL_INCLUDER_CASE 265
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 266 */
+#if ((266 >= GSL_INCLUDER_FIRST_CASE) && (266 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (266)))
+#define GSL_INCLUDER_CASE 266
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 267 */
+#if ((267 >= GSL_INCLUDER_FIRST_CASE) && (267 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (267)))
+#define GSL_INCLUDER_CASE 267
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 268 */
+#if ((268 >= GSL_INCLUDER_FIRST_CASE) && (268 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (268)))
+#define GSL_INCLUDER_CASE 268
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 269 */
+#if ((269 >= GSL_INCLUDER_FIRST_CASE) && (269 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (269)))
+#define GSL_INCLUDER_CASE 269
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 270 */
+#if ((270 >= GSL_INCLUDER_FIRST_CASE) && (270 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (270)))
+#define GSL_INCLUDER_CASE 270
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 271 */
+#if ((271 >= GSL_INCLUDER_FIRST_CASE) && (271 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (271)))
+#define GSL_INCLUDER_CASE 271
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 272 */
+#if ((272 >= GSL_INCLUDER_FIRST_CASE) && (272 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (272)))
+#define GSL_INCLUDER_CASE 272
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 273 */
+#if ((273 >= GSL_INCLUDER_FIRST_CASE) && (273 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (273)))
+#define GSL_INCLUDER_CASE 273
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 274 */
+#if ((274 >= GSL_INCLUDER_FIRST_CASE) && (274 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (274)))
+#define GSL_INCLUDER_CASE 274
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 275 */
+#if ((275 >= GSL_INCLUDER_FIRST_CASE) && (275 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (275)))
+#define GSL_INCLUDER_CASE 275
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 276 */
+#if ((276 >= GSL_INCLUDER_FIRST_CASE) && (276 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (276)))
+#define GSL_INCLUDER_CASE 276
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 277 */
+#if ((277 >= GSL_INCLUDER_FIRST_CASE) && (277 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (277)))
+#define GSL_INCLUDER_CASE 277
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 278 */
+#if ((278 >= GSL_INCLUDER_FIRST_CASE) && (278 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (278)))
+#define GSL_INCLUDER_CASE 278
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 279 */
+#if ((279 >= GSL_INCLUDER_FIRST_CASE) && (279 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (279)))
+#define GSL_INCLUDER_CASE 279
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 280 */
+#if ((280 >= GSL_INCLUDER_FIRST_CASE) && (280 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (280)))
+#define GSL_INCLUDER_CASE 280
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 281 */
+#if ((281 >= GSL_INCLUDER_FIRST_CASE) && (281 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (281)))
+#define GSL_INCLUDER_CASE 281
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 282 */
+#if ((282 >= GSL_INCLUDER_FIRST_CASE) && (282 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (282)))
+#define GSL_INCLUDER_CASE 282
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 283 */
+#if ((283 >= GSL_INCLUDER_FIRST_CASE) && (283 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (283)))
+#define GSL_INCLUDER_CASE 283
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 284 */
+#if ((284 >= GSL_INCLUDER_FIRST_CASE) && (284 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (284)))
+#define GSL_INCLUDER_CASE 284
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 285 */
+#if ((285 >= GSL_INCLUDER_FIRST_CASE) && (285 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (285)))
+#define GSL_INCLUDER_CASE 285
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 286 */
+#if ((286 >= GSL_INCLUDER_FIRST_CASE) && (286 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (286)))
+#define GSL_INCLUDER_CASE 286
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 287 */
+#if ((287 >= GSL_INCLUDER_FIRST_CASE) && (287 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (287)))
+#define GSL_INCLUDER_CASE 287
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 288 */
+#if ((288 >= GSL_INCLUDER_FIRST_CASE) && (288 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (288)))
+#define GSL_INCLUDER_CASE 288
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 289 */
+#if ((289 >= GSL_INCLUDER_FIRST_CASE) && (289 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (289)))
+#define GSL_INCLUDER_CASE 289
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 290 */
+#if ((290 >= GSL_INCLUDER_FIRST_CASE) && (290 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (290)))
+#define GSL_INCLUDER_CASE 290
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 291 */
+#if ((291 >= GSL_INCLUDER_FIRST_CASE) && (291 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (291)))
+#define GSL_INCLUDER_CASE 291
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 292 */
+#if ((292 >= GSL_INCLUDER_FIRST_CASE) && (292 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (292)))
+#define GSL_INCLUDER_CASE 292
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 293 */
+#if ((293 >= GSL_INCLUDER_FIRST_CASE) && (293 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (293)))
+#define GSL_INCLUDER_CASE 293
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 294 */
+#if ((294 >= GSL_INCLUDER_FIRST_CASE) && (294 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (294)))
+#define GSL_INCLUDER_CASE 294
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 295 */
+#if ((295 >= GSL_INCLUDER_FIRST_CASE) && (295 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (295)))
+#define GSL_INCLUDER_CASE 295
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 296 */
+#if ((296 >= GSL_INCLUDER_FIRST_CASE) && (296 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (296)))
+#define GSL_INCLUDER_CASE 296
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 297 */
+#if ((297 >= GSL_INCLUDER_FIRST_CASE) && (297 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (297)))
+#define GSL_INCLUDER_CASE 297
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 298 */
+#if ((298 >= GSL_INCLUDER_FIRST_CASE) && (298 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (298)))
+#define GSL_INCLUDER_CASE 298
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 299 */
+#if ((299 >= GSL_INCLUDER_FIRST_CASE) && (299 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (299)))
+#define GSL_INCLUDER_CASE 299
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 300 */
+#if ((300 >= GSL_INCLUDER_FIRST_CASE) && (300 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (300)))
+#define GSL_INCLUDER_CASE 300
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 301 */
+#if ((301 >= GSL_INCLUDER_FIRST_CASE) && (301 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (301)))
+#define GSL_INCLUDER_CASE 301
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 302 */
+#if ((302 >= GSL_INCLUDER_FIRST_CASE) && (302 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (302)))
+#define GSL_INCLUDER_CASE 302
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 303 */
+#if ((303 >= GSL_INCLUDER_FIRST_CASE) && (303 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (303)))
+#define GSL_INCLUDER_CASE 303
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 304 */
+#if ((304 >= GSL_INCLUDER_FIRST_CASE) && (304 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (304)))
+#define GSL_INCLUDER_CASE 304
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 305 */
+#if ((305 >= GSL_INCLUDER_FIRST_CASE) && (305 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (305)))
+#define GSL_INCLUDER_CASE 305
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 306 */
+#if ((306 >= GSL_INCLUDER_FIRST_CASE) && (306 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (306)))
+#define GSL_INCLUDER_CASE 306
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 307 */
+#if ((307 >= GSL_INCLUDER_FIRST_CASE) && (307 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (307)))
+#define GSL_INCLUDER_CASE 307
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 308 */
+#if ((308 >= GSL_INCLUDER_FIRST_CASE) && (308 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (308)))
+#define GSL_INCLUDER_CASE 308
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 309 */
+#if ((309 >= GSL_INCLUDER_FIRST_CASE) && (309 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (309)))
+#define GSL_INCLUDER_CASE 309
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 310 */
+#if ((310 >= GSL_INCLUDER_FIRST_CASE) && (310 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (310)))
+#define GSL_INCLUDER_CASE 310
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 311 */
+#if ((311 >= GSL_INCLUDER_FIRST_CASE) && (311 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (311)))
+#define GSL_INCLUDER_CASE 311
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 312 */
+#if ((312 >= GSL_INCLUDER_FIRST_CASE) && (312 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (312)))
+#define GSL_INCLUDER_CASE 312
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 313 */
+#if ((313 >= GSL_INCLUDER_FIRST_CASE) && (313 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (313)))
+#define GSL_INCLUDER_CASE 313
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 314 */
+#if ((314 >= GSL_INCLUDER_FIRST_CASE) && (314 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (314)))
+#define GSL_INCLUDER_CASE 314
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 315 */
+#if ((315 >= GSL_INCLUDER_FIRST_CASE) && (315 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (315)))
+#define GSL_INCLUDER_CASE 315
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 316 */
+#if ((316 >= GSL_INCLUDER_FIRST_CASE) && (316 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (316)))
+#define GSL_INCLUDER_CASE 316
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 317 */
+#if ((317 >= GSL_INCLUDER_FIRST_CASE) && (317 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (317)))
+#define GSL_INCLUDER_CASE 317
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 318 */
+#if ((318 >= GSL_INCLUDER_FIRST_CASE) && (318 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (318)))
+#define GSL_INCLUDER_CASE 318
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 319 */
+#if ((319 >= GSL_INCLUDER_FIRST_CASE) && (319 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (319)))
+#define GSL_INCLUDER_CASE 319
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 320 */
+#if ((320 >= GSL_INCLUDER_FIRST_CASE) && (320 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (320)))
+#define GSL_INCLUDER_CASE 320
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 321 */
+#if ((321 >= GSL_INCLUDER_FIRST_CASE) && (321 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (321)))
+#define GSL_INCLUDER_CASE 321
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 322 */
+#if ((322 >= GSL_INCLUDER_FIRST_CASE) && (322 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (322)))
+#define GSL_INCLUDER_CASE 322
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 323 */
+#if ((323 >= GSL_INCLUDER_FIRST_CASE) && (323 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (323)))
+#define GSL_INCLUDER_CASE 323
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 324 */
+#if ((324 >= GSL_INCLUDER_FIRST_CASE) && (324 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (324)))
+#define GSL_INCLUDER_CASE 324
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 325 */
+#if ((325 >= GSL_INCLUDER_FIRST_CASE) && (325 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (325)))
+#define GSL_INCLUDER_CASE 325
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 326 */
+#if ((326 >= GSL_INCLUDER_FIRST_CASE) && (326 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (326)))
+#define GSL_INCLUDER_CASE 326
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 327 */
+#if ((327 >= GSL_INCLUDER_FIRST_CASE) && (327 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (327)))
+#define GSL_INCLUDER_CASE 327
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 328 */
+#if ((328 >= GSL_INCLUDER_FIRST_CASE) && (328 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (328)))
+#define GSL_INCLUDER_CASE 328
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 329 */
+#if ((329 >= GSL_INCLUDER_FIRST_CASE) && (329 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (329)))
+#define GSL_INCLUDER_CASE 329
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 330 */
+#if ((330 >= GSL_INCLUDER_FIRST_CASE) && (330 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (330)))
+#define GSL_INCLUDER_CASE 330
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 331 */
+#if ((331 >= GSL_INCLUDER_FIRST_CASE) && (331 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (331)))
+#define GSL_INCLUDER_CASE 331
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 332 */
+#if ((332 >= GSL_INCLUDER_FIRST_CASE) && (332 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (332)))
+#define GSL_INCLUDER_CASE 332
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 333 */
+#if ((333 >= GSL_INCLUDER_FIRST_CASE) && (333 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (333)))
+#define GSL_INCLUDER_CASE 333
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 334 */
+#if ((334 >= GSL_INCLUDER_FIRST_CASE) && (334 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (334)))
+#define GSL_INCLUDER_CASE 334
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 335 */
+#if ((335 >= GSL_INCLUDER_FIRST_CASE) && (335 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (335)))
+#define GSL_INCLUDER_CASE 335
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 336 */
+#if ((336 >= GSL_INCLUDER_FIRST_CASE) && (336 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (336)))
+#define GSL_INCLUDER_CASE 336
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 337 */
+#if ((337 >= GSL_INCLUDER_FIRST_CASE) && (337 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (337)))
+#define GSL_INCLUDER_CASE 337
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 338 */
+#if ((338 >= GSL_INCLUDER_FIRST_CASE) && (338 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (338)))
+#define GSL_INCLUDER_CASE 338
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 339 */
+#if ((339 >= GSL_INCLUDER_FIRST_CASE) && (339 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (339)))
+#define GSL_INCLUDER_CASE 339
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 340 */
+#if ((340 >= GSL_INCLUDER_FIRST_CASE) && (340 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (340)))
+#define GSL_INCLUDER_CASE 340
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 341 */
+#if ((341 >= GSL_INCLUDER_FIRST_CASE) && (341 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (341)))
+#define GSL_INCLUDER_CASE 341
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 342 */
+#if ((342 >= GSL_INCLUDER_FIRST_CASE) && (342 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (342)))
+#define GSL_INCLUDER_CASE 342
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 343 */
+#if ((343 >= GSL_INCLUDER_FIRST_CASE) && (343 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (343)))
+#define GSL_INCLUDER_CASE 343
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 344 */
+#if ((344 >= GSL_INCLUDER_FIRST_CASE) && (344 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (344)))
+#define GSL_INCLUDER_CASE 344
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 345 */
+#if ((345 >= GSL_INCLUDER_FIRST_CASE) && (345 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (345)))
+#define GSL_INCLUDER_CASE 345
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 346 */
+#if ((346 >= GSL_INCLUDER_FIRST_CASE) && (346 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (346)))
+#define GSL_INCLUDER_CASE 346
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 347 */
+#if ((347 >= GSL_INCLUDER_FIRST_CASE) && (347 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (347)))
+#define GSL_INCLUDER_CASE 347
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 348 */
+#if ((348 >= GSL_INCLUDER_FIRST_CASE) && (348 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (348)))
+#define GSL_INCLUDER_CASE 348
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 349 */
+#if ((349 >= GSL_INCLUDER_FIRST_CASE) && (349 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (349)))
+#define GSL_INCLUDER_CASE 349
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 350 */
+#if ((350 >= GSL_INCLUDER_FIRST_CASE) && (350 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (350)))
+#define GSL_INCLUDER_CASE 350
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 351 */
+#if ((351 >= GSL_INCLUDER_FIRST_CASE) && (351 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (351)))
+#define GSL_INCLUDER_CASE 351
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 352 */
+#if ((352 >= GSL_INCLUDER_FIRST_CASE) && (352 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (352)))
+#define GSL_INCLUDER_CASE 352
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 353 */
+#if ((353 >= GSL_INCLUDER_FIRST_CASE) && (353 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (353)))
+#define GSL_INCLUDER_CASE 353
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 354 */
+#if ((354 >= GSL_INCLUDER_FIRST_CASE) && (354 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (354)))
+#define GSL_INCLUDER_CASE 354
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 355 */
+#if ((355 >= GSL_INCLUDER_FIRST_CASE) && (355 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (355)))
+#define GSL_INCLUDER_CASE 355
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 356 */
+#if ((356 >= GSL_INCLUDER_FIRST_CASE) && (356 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (356)))
+#define GSL_INCLUDER_CASE 356
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 357 */
+#if ((357 >= GSL_INCLUDER_FIRST_CASE) && (357 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (357)))
+#define GSL_INCLUDER_CASE 357
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 358 */
+#if ((358 >= GSL_INCLUDER_FIRST_CASE) && (358 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (358)))
+#define GSL_INCLUDER_CASE 358
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 359 */
+#if ((359 >= GSL_INCLUDER_FIRST_CASE) && (359 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (359)))
+#define GSL_INCLUDER_CASE 359
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 360 */
+#if ((360 >= GSL_INCLUDER_FIRST_CASE) && (360 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (360)))
+#define GSL_INCLUDER_CASE 360
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 361 */
+#if ((361 >= GSL_INCLUDER_FIRST_CASE) && (361 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (361)))
+#define GSL_INCLUDER_CASE 361
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 362 */
+#if ((362 >= GSL_INCLUDER_FIRST_CASE) && (362 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (362)))
+#define GSL_INCLUDER_CASE 362
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 363 */
+#if ((363 >= GSL_INCLUDER_FIRST_CASE) && (363 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (363)))
+#define GSL_INCLUDER_CASE 363
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 364 */
+#if ((364 >= GSL_INCLUDER_FIRST_CASE) && (364 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (364)))
+#define GSL_INCLUDER_CASE 364
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 365 */
+#if ((365 >= GSL_INCLUDER_FIRST_CASE) && (365 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (365)))
+#define GSL_INCLUDER_CASE 365
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 366 */
+#if ((366 >= GSL_INCLUDER_FIRST_CASE) && (366 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (366)))
+#define GSL_INCLUDER_CASE 366
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 367 */
+#if ((367 >= GSL_INCLUDER_FIRST_CASE) && (367 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (367)))
+#define GSL_INCLUDER_CASE 367
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 368 */
+#if ((368 >= GSL_INCLUDER_FIRST_CASE) && (368 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (368)))
+#define GSL_INCLUDER_CASE 368
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 369 */
+#if ((369 >= GSL_INCLUDER_FIRST_CASE) && (369 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (369)))
+#define GSL_INCLUDER_CASE 369
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 370 */
+#if ((370 >= GSL_INCLUDER_FIRST_CASE) && (370 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (370)))
+#define GSL_INCLUDER_CASE 370
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 371 */
+#if ((371 >= GSL_INCLUDER_FIRST_CASE) && (371 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (371)))
+#define GSL_INCLUDER_CASE 371
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 372 */
+#if ((372 >= GSL_INCLUDER_FIRST_CASE) && (372 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (372)))
+#define GSL_INCLUDER_CASE 372
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 373 */
+#if ((373 >= GSL_INCLUDER_FIRST_CASE) && (373 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (373)))
+#define GSL_INCLUDER_CASE 373
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 374 */
+#if ((374 >= GSL_INCLUDER_FIRST_CASE) && (374 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (374)))
+#define GSL_INCLUDER_CASE 374
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 375 */
+#if ((375 >= GSL_INCLUDER_FIRST_CASE) && (375 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (375)))
+#define GSL_INCLUDER_CASE 375
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 376 */
+#if ((376 >= GSL_INCLUDER_FIRST_CASE) && (376 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (376)))
+#define GSL_INCLUDER_CASE 376
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 377 */
+#if ((377 >= GSL_INCLUDER_FIRST_CASE) && (377 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (377)))
+#define GSL_INCLUDER_CASE 377
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 378 */
+#if ((378 >= GSL_INCLUDER_FIRST_CASE) && (378 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (378)))
+#define GSL_INCLUDER_CASE 378
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 379 */
+#if ((379 >= GSL_INCLUDER_FIRST_CASE) && (379 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (379)))
+#define GSL_INCLUDER_CASE 379
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 380 */
+#if ((380 >= GSL_INCLUDER_FIRST_CASE) && (380 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (380)))
+#define GSL_INCLUDER_CASE 380
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 381 */
+#if ((381 >= GSL_INCLUDER_FIRST_CASE) && (381 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (381)))
+#define GSL_INCLUDER_CASE 381
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 382 */
+#if ((382 >= GSL_INCLUDER_FIRST_CASE) && (382 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (382)))
+#define GSL_INCLUDER_CASE 382
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 383 */
+#if ((383 >= GSL_INCLUDER_FIRST_CASE) && (383 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (383)))
+#define GSL_INCLUDER_CASE 383
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 384 */
+#if ((384 >= GSL_INCLUDER_FIRST_CASE) && (384 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (384)))
+#define GSL_INCLUDER_CASE 384
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 385 */
+#if ((385 >= GSL_INCLUDER_FIRST_CASE) && (385 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (385)))
+#define GSL_INCLUDER_CASE 385
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 386 */
+#if ((386 >= GSL_INCLUDER_FIRST_CASE) && (386 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (386)))
+#define GSL_INCLUDER_CASE 386
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 387 */
+#if ((387 >= GSL_INCLUDER_FIRST_CASE) && (387 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (387)))
+#define GSL_INCLUDER_CASE 387
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 388 */
+#if ((388 >= GSL_INCLUDER_FIRST_CASE) && (388 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (388)))
+#define GSL_INCLUDER_CASE 388
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 389 */
+#if ((389 >= GSL_INCLUDER_FIRST_CASE) && (389 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (389)))
+#define GSL_INCLUDER_CASE 389
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 390 */
+#if ((390 >= GSL_INCLUDER_FIRST_CASE) && (390 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (390)))
+#define GSL_INCLUDER_CASE 390
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 391 */
+#if ((391 >= GSL_INCLUDER_FIRST_CASE) && (391 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (391)))
+#define GSL_INCLUDER_CASE 391
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 392 */
+#if ((392 >= GSL_INCLUDER_FIRST_CASE) && (392 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (392)))
+#define GSL_INCLUDER_CASE 392
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 393 */
+#if ((393 >= GSL_INCLUDER_FIRST_CASE) && (393 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (393)))
+#define GSL_INCLUDER_CASE 393
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 394 */
+#if ((394 >= GSL_INCLUDER_FIRST_CASE) && (394 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (394)))
+#define GSL_INCLUDER_CASE 394
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 395 */
+#if ((395 >= GSL_INCLUDER_FIRST_CASE) && (395 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (395)))
+#define GSL_INCLUDER_CASE 395
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 396 */
+#if ((396 >= GSL_INCLUDER_FIRST_CASE) && (396 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (396)))
+#define GSL_INCLUDER_CASE 396
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 397 */
+#if ((397 >= GSL_INCLUDER_FIRST_CASE) && (397 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (397)))
+#define GSL_INCLUDER_CASE 397
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 398 */
+#if ((398 >= GSL_INCLUDER_FIRST_CASE) && (398 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (398)))
+#define GSL_INCLUDER_CASE 398
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 399 */
+#if ((399 >= GSL_INCLUDER_FIRST_CASE) && (399 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (399)))
+#define GSL_INCLUDER_CASE 399
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 400 */
+#if ((400 >= GSL_INCLUDER_FIRST_CASE) && (400 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (400)))
+#define GSL_INCLUDER_CASE 400
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 401 */
+#if ((401 >= GSL_INCLUDER_FIRST_CASE) && (401 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (401)))
+#define GSL_INCLUDER_CASE 401
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 402 */
+#if ((402 >= GSL_INCLUDER_FIRST_CASE) && (402 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (402)))
+#define GSL_INCLUDER_CASE 402
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 403 */
+#if ((403 >= GSL_INCLUDER_FIRST_CASE) && (403 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (403)))
+#define GSL_INCLUDER_CASE 403
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 404 */
+#if ((404 >= GSL_INCLUDER_FIRST_CASE) && (404 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (404)))
+#define GSL_INCLUDER_CASE 404
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 405 */
+#if ((405 >= GSL_INCLUDER_FIRST_CASE) && (405 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (405)))
+#define GSL_INCLUDER_CASE 405
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 406 */
+#if ((406 >= GSL_INCLUDER_FIRST_CASE) && (406 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (406)))
+#define GSL_INCLUDER_CASE 406
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 407 */
+#if ((407 >= GSL_INCLUDER_FIRST_CASE) && (407 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (407)))
+#define GSL_INCLUDER_CASE 407
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 408 */
+#if ((408 >= GSL_INCLUDER_FIRST_CASE) && (408 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (408)))
+#define GSL_INCLUDER_CASE 408
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 409 */
+#if ((409 >= GSL_INCLUDER_FIRST_CASE) && (409 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (409)))
+#define GSL_INCLUDER_CASE 409
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 410 */
+#if ((410 >= GSL_INCLUDER_FIRST_CASE) && (410 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (410)))
+#define GSL_INCLUDER_CASE 410
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 411 */
+#if ((411 >= GSL_INCLUDER_FIRST_CASE) && (411 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (411)))
+#define GSL_INCLUDER_CASE 411
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 412 */
+#if ((412 >= GSL_INCLUDER_FIRST_CASE) && (412 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (412)))
+#define GSL_INCLUDER_CASE 412
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 413 */
+#if ((413 >= GSL_INCLUDER_FIRST_CASE) && (413 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (413)))
+#define GSL_INCLUDER_CASE 413
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 414 */
+#if ((414 >= GSL_INCLUDER_FIRST_CASE) && (414 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (414)))
+#define GSL_INCLUDER_CASE 414
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 415 */
+#if ((415 >= GSL_INCLUDER_FIRST_CASE) && (415 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (415)))
+#define GSL_INCLUDER_CASE 415
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 416 */
+#if ((416 >= GSL_INCLUDER_FIRST_CASE) && (416 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (416)))
+#define GSL_INCLUDER_CASE 416
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 417 */
+#if ((417 >= GSL_INCLUDER_FIRST_CASE) && (417 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (417)))
+#define GSL_INCLUDER_CASE 417
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 418 */
+#if ((418 >= GSL_INCLUDER_FIRST_CASE) && (418 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (418)))
+#define GSL_INCLUDER_CASE 418
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 419 */
+#if ((419 >= GSL_INCLUDER_FIRST_CASE) && (419 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (419)))
+#define GSL_INCLUDER_CASE 419
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 420 */
+#if ((420 >= GSL_INCLUDER_FIRST_CASE) && (420 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (420)))
+#define GSL_INCLUDER_CASE 420
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 421 */
+#if ((421 >= GSL_INCLUDER_FIRST_CASE) && (421 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (421)))
+#define GSL_INCLUDER_CASE 421
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 422 */
+#if ((422 >= GSL_INCLUDER_FIRST_CASE) && (422 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (422)))
+#define GSL_INCLUDER_CASE 422
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 423 */
+#if ((423 >= GSL_INCLUDER_FIRST_CASE) && (423 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (423)))
+#define GSL_INCLUDER_CASE 423
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 424 */
+#if ((424 >= GSL_INCLUDER_FIRST_CASE) && (424 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (424)))
+#define GSL_INCLUDER_CASE 424
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 425 */
+#if ((425 >= GSL_INCLUDER_FIRST_CASE) && (425 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (425)))
+#define GSL_INCLUDER_CASE 425
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 426 */
+#if ((426 >= GSL_INCLUDER_FIRST_CASE) && (426 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (426)))
+#define GSL_INCLUDER_CASE 426
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 427 */
+#if ((427 >= GSL_INCLUDER_FIRST_CASE) && (427 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (427)))
+#define GSL_INCLUDER_CASE 427
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 428 */
+#if ((428 >= GSL_INCLUDER_FIRST_CASE) && (428 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (428)))
+#define GSL_INCLUDER_CASE 428
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 429 */
+#if ((429 >= GSL_INCLUDER_FIRST_CASE) && (429 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (429)))
+#define GSL_INCLUDER_CASE 429
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 430 */
+#if ((430 >= GSL_INCLUDER_FIRST_CASE) && (430 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (430)))
+#define GSL_INCLUDER_CASE 430
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 431 */
+#if ((431 >= GSL_INCLUDER_FIRST_CASE) && (431 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (431)))
+#define GSL_INCLUDER_CASE 431
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 432 */
+#if ((432 >= GSL_INCLUDER_FIRST_CASE) && (432 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (432)))
+#define GSL_INCLUDER_CASE 432
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 433 */
+#if ((433 >= GSL_INCLUDER_FIRST_CASE) && (433 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (433)))
+#define GSL_INCLUDER_CASE 433
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 434 */
+#if ((434 >= GSL_INCLUDER_FIRST_CASE) && (434 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (434)))
+#define GSL_INCLUDER_CASE 434
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 435 */
+#if ((435 >= GSL_INCLUDER_FIRST_CASE) && (435 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (435)))
+#define GSL_INCLUDER_CASE 435
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 436 */
+#if ((436 >= GSL_INCLUDER_FIRST_CASE) && (436 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (436)))
+#define GSL_INCLUDER_CASE 436
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 437 */
+#if ((437 >= GSL_INCLUDER_FIRST_CASE) && (437 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (437)))
+#define GSL_INCLUDER_CASE 437
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 438 */
+#if ((438 >= GSL_INCLUDER_FIRST_CASE) && (438 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (438)))
+#define GSL_INCLUDER_CASE 438
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 439 */
+#if ((439 >= GSL_INCLUDER_FIRST_CASE) && (439 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (439)))
+#define GSL_INCLUDER_CASE 439
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 440 */
+#if ((440 >= GSL_INCLUDER_FIRST_CASE) && (440 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (440)))
+#define GSL_INCLUDER_CASE 440
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 441 */
+#if ((441 >= GSL_INCLUDER_FIRST_CASE) && (441 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (441)))
+#define GSL_INCLUDER_CASE 441
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 442 */
+#if ((442 >= GSL_INCLUDER_FIRST_CASE) && (442 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (442)))
+#define GSL_INCLUDER_CASE 442
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 443 */
+#if ((443 >= GSL_INCLUDER_FIRST_CASE) && (443 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (443)))
+#define GSL_INCLUDER_CASE 443
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 444 */
+#if ((444 >= GSL_INCLUDER_FIRST_CASE) && (444 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (444)))
+#define GSL_INCLUDER_CASE 444
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 445 */
+#if ((445 >= GSL_INCLUDER_FIRST_CASE) && (445 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (445)))
+#define GSL_INCLUDER_CASE 445
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 446 */
+#if ((446 >= GSL_INCLUDER_FIRST_CASE) && (446 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (446)))
+#define GSL_INCLUDER_CASE 446
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 447 */
+#if ((447 >= GSL_INCLUDER_FIRST_CASE) && (447 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (447)))
+#define GSL_INCLUDER_CASE 447
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 448 */
+#if ((448 >= GSL_INCLUDER_FIRST_CASE) && (448 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (448)))
+#define GSL_INCLUDER_CASE 448
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 449 */
+#if ((449 >= GSL_INCLUDER_FIRST_CASE) && (449 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (449)))
+#define GSL_INCLUDER_CASE 449
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 450 */
+#if ((450 >= GSL_INCLUDER_FIRST_CASE) && (450 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (450)))
+#define GSL_INCLUDER_CASE 450
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 451 */
+#if ((451 >= GSL_INCLUDER_FIRST_CASE) && (451 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (451)))
+#define GSL_INCLUDER_CASE 451
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 452 */
+#if ((452 >= GSL_INCLUDER_FIRST_CASE) && (452 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (452)))
+#define GSL_INCLUDER_CASE 452
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 453 */
+#if ((453 >= GSL_INCLUDER_FIRST_CASE) && (453 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (453)))
+#define GSL_INCLUDER_CASE 453
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 454 */
+#if ((454 >= GSL_INCLUDER_FIRST_CASE) && (454 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (454)))
+#define GSL_INCLUDER_CASE 454
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 455 */
+#if ((455 >= GSL_INCLUDER_FIRST_CASE) && (455 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (455)))
+#define GSL_INCLUDER_CASE 455
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 456 */
+#if ((456 >= GSL_INCLUDER_FIRST_CASE) && (456 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (456)))
+#define GSL_INCLUDER_CASE 456
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 457 */
+#if ((457 >= GSL_INCLUDER_FIRST_CASE) && (457 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (457)))
+#define GSL_INCLUDER_CASE 457
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 458 */
+#if ((458 >= GSL_INCLUDER_FIRST_CASE) && (458 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (458)))
+#define GSL_INCLUDER_CASE 458
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 459 */
+#if ((459 >= GSL_INCLUDER_FIRST_CASE) && (459 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (459)))
+#define GSL_INCLUDER_CASE 459
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 460 */
+#if ((460 >= GSL_INCLUDER_FIRST_CASE) && (460 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (460)))
+#define GSL_INCLUDER_CASE 460
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 461 */
+#if ((461 >= GSL_INCLUDER_FIRST_CASE) && (461 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (461)))
+#define GSL_INCLUDER_CASE 461
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 462 */
+#if ((462 >= GSL_INCLUDER_FIRST_CASE) && (462 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (462)))
+#define GSL_INCLUDER_CASE 462
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 463 */
+#if ((463 >= GSL_INCLUDER_FIRST_CASE) && (463 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (463)))
+#define GSL_INCLUDER_CASE 463
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 464 */
+#if ((464 >= GSL_INCLUDER_FIRST_CASE) && (464 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (464)))
+#define GSL_INCLUDER_CASE 464
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 465 */
+#if ((465 >= GSL_INCLUDER_FIRST_CASE) && (465 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (465)))
+#define GSL_INCLUDER_CASE 465
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 466 */
+#if ((466 >= GSL_INCLUDER_FIRST_CASE) && (466 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (466)))
+#define GSL_INCLUDER_CASE 466
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 467 */
+#if ((467 >= GSL_INCLUDER_FIRST_CASE) && (467 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (467)))
+#define GSL_INCLUDER_CASE 467
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 468 */
+#if ((468 >= GSL_INCLUDER_FIRST_CASE) && (468 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (468)))
+#define GSL_INCLUDER_CASE 468
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 469 */
+#if ((469 >= GSL_INCLUDER_FIRST_CASE) && (469 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (469)))
+#define GSL_INCLUDER_CASE 469
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 470 */
+#if ((470 >= GSL_INCLUDER_FIRST_CASE) && (470 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (470)))
+#define GSL_INCLUDER_CASE 470
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 471 */
+#if ((471 >= GSL_INCLUDER_FIRST_CASE) && (471 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (471)))
+#define GSL_INCLUDER_CASE 471
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 472 */
+#if ((472 >= GSL_INCLUDER_FIRST_CASE) && (472 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (472)))
+#define GSL_INCLUDER_CASE 472
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 473 */
+#if ((473 >= GSL_INCLUDER_FIRST_CASE) && (473 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (473)))
+#define GSL_INCLUDER_CASE 473
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 474 */
+#if ((474 >= GSL_INCLUDER_FIRST_CASE) && (474 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (474)))
+#define GSL_INCLUDER_CASE 474
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 475 */
+#if ((475 >= GSL_INCLUDER_FIRST_CASE) && (475 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (475)))
+#define GSL_INCLUDER_CASE 475
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 476 */
+#if ((476 >= GSL_INCLUDER_FIRST_CASE) && (476 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (476)))
+#define GSL_INCLUDER_CASE 476
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 477 */
+#if ((477 >= GSL_INCLUDER_FIRST_CASE) && (477 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (477)))
+#define GSL_INCLUDER_CASE 477
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 478 */
+#if ((478 >= GSL_INCLUDER_FIRST_CASE) && (478 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (478)))
+#define GSL_INCLUDER_CASE 478
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 479 */
+#if ((479 >= GSL_INCLUDER_FIRST_CASE) && (479 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (479)))
+#define GSL_INCLUDER_CASE 479
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 480 */
+#if ((480 >= GSL_INCLUDER_FIRST_CASE) && (480 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (480)))
+#define GSL_INCLUDER_CASE 480
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 481 */
+#if ((481 >= GSL_INCLUDER_FIRST_CASE) && (481 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (481)))
+#define GSL_INCLUDER_CASE 481
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 482 */
+#if ((482 >= GSL_INCLUDER_FIRST_CASE) && (482 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (482)))
+#define GSL_INCLUDER_CASE 482
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 483 */
+#if ((483 >= GSL_INCLUDER_FIRST_CASE) && (483 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (483)))
+#define GSL_INCLUDER_CASE 483
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 484 */
+#if ((484 >= GSL_INCLUDER_FIRST_CASE) && (484 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (484)))
+#define GSL_INCLUDER_CASE 484
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 485 */
+#if ((485 >= GSL_INCLUDER_FIRST_CASE) && (485 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (485)))
+#define GSL_INCLUDER_CASE 485
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 486 */
+#if ((486 >= GSL_INCLUDER_FIRST_CASE) && (486 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (486)))
+#define GSL_INCLUDER_CASE 486
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 487 */
+#if ((487 >= GSL_INCLUDER_FIRST_CASE) && (487 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (487)))
+#define GSL_INCLUDER_CASE 487
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 488 */
+#if ((488 >= GSL_INCLUDER_FIRST_CASE) && (488 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (488)))
+#define GSL_INCLUDER_CASE 488
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 489 */
+#if ((489 >= GSL_INCLUDER_FIRST_CASE) && (489 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (489)))
+#define GSL_INCLUDER_CASE 489
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 490 */
+#if ((490 >= GSL_INCLUDER_FIRST_CASE) && (490 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (490)))
+#define GSL_INCLUDER_CASE 490
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 491 */
+#if ((491 >= GSL_INCLUDER_FIRST_CASE) && (491 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (491)))
+#define GSL_INCLUDER_CASE 491
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 492 */
+#if ((492 >= GSL_INCLUDER_FIRST_CASE) && (492 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (492)))
+#define GSL_INCLUDER_CASE 492
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 493 */
+#if ((493 >= GSL_INCLUDER_FIRST_CASE) && (493 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (493)))
+#define GSL_INCLUDER_CASE 493
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 494 */
+#if ((494 >= GSL_INCLUDER_FIRST_CASE) && (494 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (494)))
+#define GSL_INCLUDER_CASE 494
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 495 */
+#if ((495 >= GSL_INCLUDER_FIRST_CASE) && (495 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (495)))
+#define GSL_INCLUDER_CASE 495
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 496 */
+#if ((496 >= GSL_INCLUDER_FIRST_CASE) && (496 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (496)))
+#define GSL_INCLUDER_CASE 496
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 497 */
+#if ((497 >= GSL_INCLUDER_FIRST_CASE) && (497 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (497)))
+#define GSL_INCLUDER_CASE 497
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 498 */
+#if ((498 >= GSL_INCLUDER_FIRST_CASE) && (498 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (498)))
+#define GSL_INCLUDER_CASE 498
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 499 */
+#if ((499 >= GSL_INCLUDER_FIRST_CASE) && (499 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (499)))
+#define GSL_INCLUDER_CASE 499
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 500 */
+#if ((500 >= GSL_INCLUDER_FIRST_CASE) && (500 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (500)))
+#define GSL_INCLUDER_CASE 500
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 501 */
+#if ((501 >= GSL_INCLUDER_FIRST_CASE) && (501 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (501)))
+#define GSL_INCLUDER_CASE 501
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 502 */
+#if ((502 >= GSL_INCLUDER_FIRST_CASE) && (502 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (502)))
+#define GSL_INCLUDER_CASE 502
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 503 */
+#if ((503 >= GSL_INCLUDER_FIRST_CASE) && (503 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (503)))
+#define GSL_INCLUDER_CASE 503
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 504 */
+#if ((504 >= GSL_INCLUDER_FIRST_CASE) && (504 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (504)))
+#define GSL_INCLUDER_CASE 504
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 505 */
+#if ((505 >= GSL_INCLUDER_FIRST_CASE) && (505 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (505)))
+#define GSL_INCLUDER_CASE 505
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 506 */
+#if ((506 >= GSL_INCLUDER_FIRST_CASE) && (506 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (506)))
+#define GSL_INCLUDER_CASE 506
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 507 */
+#if ((507 >= GSL_INCLUDER_FIRST_CASE) && (507 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (507)))
+#define GSL_INCLUDER_CASE 507
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 508 */
+#if ((508 >= GSL_INCLUDER_FIRST_CASE) && (508 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (508)))
+#define GSL_INCLUDER_CASE 508
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 509 */
+#if ((509 >= GSL_INCLUDER_FIRST_CASE) && (509 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (509)))
+#define GSL_INCLUDER_CASE 509
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 510 */
+#if ((510 >= GSL_INCLUDER_FIRST_CASE) && (510 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (510)))
+#define GSL_INCLUDER_CASE 510
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 511 */
+#if ((511 >= GSL_INCLUDER_FIRST_CASE) && (511 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (511)))
+#define GSL_INCLUDER_CASE 511
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 512 */
+#if ((512 >= GSL_INCLUDER_FIRST_CASE) && (512 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (512)))
+#define GSL_INCLUDER_CASE 512
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 513 */
+#if ((513 >= GSL_INCLUDER_FIRST_CASE) && (513 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (513)))
+#define GSL_INCLUDER_CASE 513
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 514 */
+#if ((514 >= GSL_INCLUDER_FIRST_CASE) && (514 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (514)))
+#define GSL_INCLUDER_CASE 514
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 515 */
+#if ((515 >= GSL_INCLUDER_FIRST_CASE) && (515 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (515)))
+#define GSL_INCLUDER_CASE 515
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 516 */
+#if ((516 >= GSL_INCLUDER_FIRST_CASE) && (516 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (516)))
+#define GSL_INCLUDER_CASE 516
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 517 */
+#if ((517 >= GSL_INCLUDER_FIRST_CASE) && (517 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (517)))
+#define GSL_INCLUDER_CASE 517
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 518 */
+#if ((518 >= GSL_INCLUDER_FIRST_CASE) && (518 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (518)))
+#define GSL_INCLUDER_CASE 518
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 519 */
+#if ((519 >= GSL_INCLUDER_FIRST_CASE) && (519 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (519)))
+#define GSL_INCLUDER_CASE 519
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 520 */
+#if ((520 >= GSL_INCLUDER_FIRST_CASE) && (520 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (520)))
+#define GSL_INCLUDER_CASE 520
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 521 */
+#if ((521 >= GSL_INCLUDER_FIRST_CASE) && (521 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (521)))
+#define GSL_INCLUDER_CASE 521
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 522 */
+#if ((522 >= GSL_INCLUDER_FIRST_CASE) && (522 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (522)))
+#define GSL_INCLUDER_CASE 522
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 523 */
+#if ((523 >= GSL_INCLUDER_FIRST_CASE) && (523 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (523)))
+#define GSL_INCLUDER_CASE 523
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 524 */
+#if ((524 >= GSL_INCLUDER_FIRST_CASE) && (524 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (524)))
+#define GSL_INCLUDER_CASE 524
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 525 */
+#if ((525 >= GSL_INCLUDER_FIRST_CASE) && (525 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (525)))
+#define GSL_INCLUDER_CASE 525
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 526 */
+#if ((526 >= GSL_INCLUDER_FIRST_CASE) && (526 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (526)))
+#define GSL_INCLUDER_CASE 526
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 527 */
+#if ((527 >= GSL_INCLUDER_FIRST_CASE) && (527 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (527)))
+#define GSL_INCLUDER_CASE 527
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 528 */
+#if ((528 >= GSL_INCLUDER_FIRST_CASE) && (528 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (528)))
+#define GSL_INCLUDER_CASE 528
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 529 */
+#if ((529 >= GSL_INCLUDER_FIRST_CASE) && (529 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (529)))
+#define GSL_INCLUDER_CASE 529
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 530 */
+#if ((530 >= GSL_INCLUDER_FIRST_CASE) && (530 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (530)))
+#define GSL_INCLUDER_CASE 530
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 531 */
+#if ((531 >= GSL_INCLUDER_FIRST_CASE) && (531 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (531)))
+#define GSL_INCLUDER_CASE 531
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 532 */
+#if ((532 >= GSL_INCLUDER_FIRST_CASE) && (532 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (532)))
+#define GSL_INCLUDER_CASE 532
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 533 */
+#if ((533 >= GSL_INCLUDER_FIRST_CASE) && (533 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (533)))
+#define GSL_INCLUDER_CASE 533
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 534 */
+#if ((534 >= GSL_INCLUDER_FIRST_CASE) && (534 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (534)))
+#define GSL_INCLUDER_CASE 534
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 535 */
+#if ((535 >= GSL_INCLUDER_FIRST_CASE) && (535 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (535)))
+#define GSL_INCLUDER_CASE 535
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 536 */
+#if ((536 >= GSL_INCLUDER_FIRST_CASE) && (536 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (536)))
+#define GSL_INCLUDER_CASE 536
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 537 */
+#if ((537 >= GSL_INCLUDER_FIRST_CASE) && (537 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (537)))
+#define GSL_INCLUDER_CASE 537
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 538 */
+#if ((538 >= GSL_INCLUDER_FIRST_CASE) && (538 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (538)))
+#define GSL_INCLUDER_CASE 538
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 539 */
+#if ((539 >= GSL_INCLUDER_FIRST_CASE) && (539 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (539)))
+#define GSL_INCLUDER_CASE 539
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 540 */
+#if ((540 >= GSL_INCLUDER_FIRST_CASE) && (540 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (540)))
+#define GSL_INCLUDER_CASE 540
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 541 */
+#if ((541 >= GSL_INCLUDER_FIRST_CASE) && (541 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (541)))
+#define GSL_INCLUDER_CASE 541
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 542 */
+#if ((542 >= GSL_INCLUDER_FIRST_CASE) && (542 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (542)))
+#define GSL_INCLUDER_CASE 542
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 543 */
+#if ((543 >= GSL_INCLUDER_FIRST_CASE) && (543 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (543)))
+#define GSL_INCLUDER_CASE 543
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 544 */
+#if ((544 >= GSL_INCLUDER_FIRST_CASE) && (544 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (544)))
+#define GSL_INCLUDER_CASE 544
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 545 */
+#if ((545 >= GSL_INCLUDER_FIRST_CASE) && (545 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (545)))
+#define GSL_INCLUDER_CASE 545
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 546 */
+#if ((546 >= GSL_INCLUDER_FIRST_CASE) && (546 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (546)))
+#define GSL_INCLUDER_CASE 546
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 547 */
+#if ((547 >= GSL_INCLUDER_FIRST_CASE) && (547 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (547)))
+#define GSL_INCLUDER_CASE 547
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 548 */
+#if ((548 >= GSL_INCLUDER_FIRST_CASE) && (548 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (548)))
+#define GSL_INCLUDER_CASE 548
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 549 */
+#if ((549 >= GSL_INCLUDER_FIRST_CASE) && (549 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (549)))
+#define GSL_INCLUDER_CASE 549
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 550 */
+#if ((550 >= GSL_INCLUDER_FIRST_CASE) && (550 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (550)))
+#define GSL_INCLUDER_CASE 550
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 551 */
+#if ((551 >= GSL_INCLUDER_FIRST_CASE) && (551 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (551)))
+#define GSL_INCLUDER_CASE 551
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 552 */
+#if ((552 >= GSL_INCLUDER_FIRST_CASE) && (552 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (552)))
+#define GSL_INCLUDER_CASE 552
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 553 */
+#if ((553 >= GSL_INCLUDER_FIRST_CASE) && (553 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (553)))
+#define GSL_INCLUDER_CASE 553
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 554 */
+#if ((554 >= GSL_INCLUDER_FIRST_CASE) && (554 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (554)))
+#define GSL_INCLUDER_CASE 554
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 555 */
+#if ((555 >= GSL_INCLUDER_FIRST_CASE) && (555 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (555)))
+#define GSL_INCLUDER_CASE 555
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 556 */
+#if ((556 >= GSL_INCLUDER_FIRST_CASE) && (556 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (556)))
+#define GSL_INCLUDER_CASE 556
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 557 */
+#if ((557 >= GSL_INCLUDER_FIRST_CASE) && (557 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (557)))
+#define GSL_INCLUDER_CASE 557
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 558 */
+#if ((558 >= GSL_INCLUDER_FIRST_CASE) && (558 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (558)))
+#define GSL_INCLUDER_CASE 558
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 559 */
+#if ((559 >= GSL_INCLUDER_FIRST_CASE) && (559 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (559)))
+#define GSL_INCLUDER_CASE 559
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 560 */
+#if ((560 >= GSL_INCLUDER_FIRST_CASE) && (560 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (560)))
+#define GSL_INCLUDER_CASE 560
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 561 */
+#if ((561 >= GSL_INCLUDER_FIRST_CASE) && (561 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (561)))
+#define GSL_INCLUDER_CASE 561
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 562 */
+#if ((562 >= GSL_INCLUDER_FIRST_CASE) && (562 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (562)))
+#define GSL_INCLUDER_CASE 562
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 563 */
+#if ((563 >= GSL_INCLUDER_FIRST_CASE) && (563 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (563)))
+#define GSL_INCLUDER_CASE 563
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 564 */
+#if ((564 >= GSL_INCLUDER_FIRST_CASE) && (564 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (564)))
+#define GSL_INCLUDER_CASE 564
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 565 */
+#if ((565 >= GSL_INCLUDER_FIRST_CASE) && (565 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (565)))
+#define GSL_INCLUDER_CASE 565
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 566 */
+#if ((566 >= GSL_INCLUDER_FIRST_CASE) && (566 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (566)))
+#define GSL_INCLUDER_CASE 566
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 567 */
+#if ((567 >= GSL_INCLUDER_FIRST_CASE) && (567 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (567)))
+#define GSL_INCLUDER_CASE 567
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 568 */
+#if ((568 >= GSL_INCLUDER_FIRST_CASE) && (568 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (568)))
+#define GSL_INCLUDER_CASE 568
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 569 */
+#if ((569 >= GSL_INCLUDER_FIRST_CASE) && (569 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (569)))
+#define GSL_INCLUDER_CASE 569
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 570 */
+#if ((570 >= GSL_INCLUDER_FIRST_CASE) && (570 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (570)))
+#define GSL_INCLUDER_CASE 570
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 571 */
+#if ((571 >= GSL_INCLUDER_FIRST_CASE) && (571 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (571)))
+#define GSL_INCLUDER_CASE 571
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 572 */
+#if ((572 >= GSL_INCLUDER_FIRST_CASE) && (572 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (572)))
+#define GSL_INCLUDER_CASE 572
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 573 */
+#if ((573 >= GSL_INCLUDER_FIRST_CASE) && (573 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (573)))
+#define GSL_INCLUDER_CASE 573
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 574 */
+#if ((574 >= GSL_INCLUDER_FIRST_CASE) && (574 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (574)))
+#define GSL_INCLUDER_CASE 574
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 575 */
+#if ((575 >= GSL_INCLUDER_FIRST_CASE) && (575 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (575)))
+#define GSL_INCLUDER_CASE 575
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 576 */
+#if ((576 >= GSL_INCLUDER_FIRST_CASE) && (576 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (576)))
+#define GSL_INCLUDER_CASE 576
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 577 */
+#if ((577 >= GSL_INCLUDER_FIRST_CASE) && (577 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (577)))
+#define GSL_INCLUDER_CASE 577
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 578 */
+#if ((578 >= GSL_INCLUDER_FIRST_CASE) && (578 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (578)))
+#define GSL_INCLUDER_CASE 578
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 579 */
+#if ((579 >= GSL_INCLUDER_FIRST_CASE) && (579 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (579)))
+#define GSL_INCLUDER_CASE 579
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 580 */
+#if ((580 >= GSL_INCLUDER_FIRST_CASE) && (580 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (580)))
+#define GSL_INCLUDER_CASE 580
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 581 */
+#if ((581 >= GSL_INCLUDER_FIRST_CASE) && (581 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (581)))
+#define GSL_INCLUDER_CASE 581
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 582 */
+#if ((582 >= GSL_INCLUDER_FIRST_CASE) && (582 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (582)))
+#define GSL_INCLUDER_CASE 582
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 583 */
+#if ((583 >= GSL_INCLUDER_FIRST_CASE) && (583 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (583)))
+#define GSL_INCLUDER_CASE 583
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 584 */
+#if ((584 >= GSL_INCLUDER_FIRST_CASE) && (584 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (584)))
+#define GSL_INCLUDER_CASE 584
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 585 */
+#if ((585 >= GSL_INCLUDER_FIRST_CASE) && (585 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (585)))
+#define GSL_INCLUDER_CASE 585
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 586 */
+#if ((586 >= GSL_INCLUDER_FIRST_CASE) && (586 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (586)))
+#define GSL_INCLUDER_CASE 586
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 587 */
+#if ((587 >= GSL_INCLUDER_FIRST_CASE) && (587 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (587)))
+#define GSL_INCLUDER_CASE 587
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 588 */
+#if ((588 >= GSL_INCLUDER_FIRST_CASE) && (588 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (588)))
+#define GSL_INCLUDER_CASE 588
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 589 */
+#if ((589 >= GSL_INCLUDER_FIRST_CASE) && (589 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (589)))
+#define GSL_INCLUDER_CASE 589
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 590 */
+#if ((590 >= GSL_INCLUDER_FIRST_CASE) && (590 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (590)))
+#define GSL_INCLUDER_CASE 590
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 591 */
+#if ((591 >= GSL_INCLUDER_FIRST_CASE) && (591 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (591)))
+#define GSL_INCLUDER_CASE 591
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 592 */
+#if ((592 >= GSL_INCLUDER_FIRST_CASE) && (592 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (592)))
+#define GSL_INCLUDER_CASE 592
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 593 */
+#if ((593 >= GSL_INCLUDER_FIRST_CASE) && (593 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (593)))
+#define GSL_INCLUDER_CASE 593
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 594 */
+#if ((594 >= GSL_INCLUDER_FIRST_CASE) && (594 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (594)))
+#define GSL_INCLUDER_CASE 594
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 595 */
+#if ((595 >= GSL_INCLUDER_FIRST_CASE) && (595 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (595)))
+#define GSL_INCLUDER_CASE 595
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 596 */
+#if ((596 >= GSL_INCLUDER_FIRST_CASE) && (596 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (596)))
+#define GSL_INCLUDER_CASE 596
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 597 */
+#if ((597 >= GSL_INCLUDER_FIRST_CASE) && (597 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (597)))
+#define GSL_INCLUDER_CASE 597
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 598 */
+#if ((598 >= GSL_INCLUDER_FIRST_CASE) && (598 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (598)))
+#define GSL_INCLUDER_CASE 598
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 599 */
+#if ((599 >= GSL_INCLUDER_FIRST_CASE) && (599 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (599)))
+#define GSL_INCLUDER_CASE 599
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 600 */
+#if ((600 >= GSL_INCLUDER_FIRST_CASE) && (600 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (600)))
+#define GSL_INCLUDER_CASE 600
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 601 */
+#if ((601 >= GSL_INCLUDER_FIRST_CASE) && (601 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (601)))
+#define GSL_INCLUDER_CASE 601
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 602 */
+#if ((602 >= GSL_INCLUDER_FIRST_CASE) && (602 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (602)))
+#define GSL_INCLUDER_CASE 602
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 603 */
+#if ((603 >= GSL_INCLUDER_FIRST_CASE) && (603 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (603)))
+#define GSL_INCLUDER_CASE 603
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 604 */
+#if ((604 >= GSL_INCLUDER_FIRST_CASE) && (604 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (604)))
+#define GSL_INCLUDER_CASE 604
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 605 */
+#if ((605 >= GSL_INCLUDER_FIRST_CASE) && (605 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (605)))
+#define GSL_INCLUDER_CASE 605
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 606 */
+#if ((606 >= GSL_INCLUDER_FIRST_CASE) && (606 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (606)))
+#define GSL_INCLUDER_CASE 606
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 607 */
+#if ((607 >= GSL_INCLUDER_FIRST_CASE) && (607 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (607)))
+#define GSL_INCLUDER_CASE 607
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 608 */
+#if ((608 >= GSL_INCLUDER_FIRST_CASE) && (608 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (608)))
+#define GSL_INCLUDER_CASE 608
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 609 */
+#if ((609 >= GSL_INCLUDER_FIRST_CASE) && (609 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (609)))
+#define GSL_INCLUDER_CASE 609
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 610 */
+#if ((610 >= GSL_INCLUDER_FIRST_CASE) && (610 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (610)))
+#define GSL_INCLUDER_CASE 610
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 611 */
+#if ((611 >= GSL_INCLUDER_FIRST_CASE) && (611 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (611)))
+#define GSL_INCLUDER_CASE 611
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 612 */
+#if ((612 >= GSL_INCLUDER_FIRST_CASE) && (612 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (612)))
+#define GSL_INCLUDER_CASE 612
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 613 */
+#if ((613 >= GSL_INCLUDER_FIRST_CASE) && (613 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (613)))
+#define GSL_INCLUDER_CASE 613
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 614 */
+#if ((614 >= GSL_INCLUDER_FIRST_CASE) && (614 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (614)))
+#define GSL_INCLUDER_CASE 614
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 615 */
+#if ((615 >= GSL_INCLUDER_FIRST_CASE) && (615 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (615)))
+#define GSL_INCLUDER_CASE 615
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 616 */
+#if ((616 >= GSL_INCLUDER_FIRST_CASE) && (616 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (616)))
+#define GSL_INCLUDER_CASE 616
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 617 */
+#if ((617 >= GSL_INCLUDER_FIRST_CASE) && (617 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (617)))
+#define GSL_INCLUDER_CASE 617
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 618 */
+#if ((618 >= GSL_INCLUDER_FIRST_CASE) && (618 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (618)))
+#define GSL_INCLUDER_CASE 618
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 619 */
+#if ((619 >= GSL_INCLUDER_FIRST_CASE) && (619 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (619)))
+#define GSL_INCLUDER_CASE 619
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 620 */
+#if ((620 >= GSL_INCLUDER_FIRST_CASE) && (620 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (620)))
+#define GSL_INCLUDER_CASE 620
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 621 */
+#if ((621 >= GSL_INCLUDER_FIRST_CASE) && (621 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (621)))
+#define GSL_INCLUDER_CASE 621
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 622 */
+#if ((622 >= GSL_INCLUDER_FIRST_CASE) && (622 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (622)))
+#define GSL_INCLUDER_CASE 622
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 623 */
+#if ((623 >= GSL_INCLUDER_FIRST_CASE) && (623 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (623)))
+#define GSL_INCLUDER_CASE 623
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 624 */
+#if ((624 >= GSL_INCLUDER_FIRST_CASE) && (624 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (624)))
+#define GSL_INCLUDER_CASE 624
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 625 */
+#if ((625 >= GSL_INCLUDER_FIRST_CASE) && (625 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (625)))
+#define GSL_INCLUDER_CASE 625
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 626 */
+#if ((626 >= GSL_INCLUDER_FIRST_CASE) && (626 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (626)))
+#define GSL_INCLUDER_CASE 626
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 627 */
+#if ((627 >= GSL_INCLUDER_FIRST_CASE) && (627 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (627)))
+#define GSL_INCLUDER_CASE 627
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 628 */
+#if ((628 >= GSL_INCLUDER_FIRST_CASE) && (628 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (628)))
+#define GSL_INCLUDER_CASE 628
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 629 */
+#if ((629 >= GSL_INCLUDER_FIRST_CASE) && (629 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (629)))
+#define GSL_INCLUDER_CASE 629
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 630 */
+#if ((630 >= GSL_INCLUDER_FIRST_CASE) && (630 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (630)))
+#define GSL_INCLUDER_CASE 630
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 631 */
+#if ((631 >= GSL_INCLUDER_FIRST_CASE) && (631 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (631)))
+#define GSL_INCLUDER_CASE 631
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 632 */
+#if ((632 >= GSL_INCLUDER_FIRST_CASE) && (632 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (632)))
+#define GSL_INCLUDER_CASE 632
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 633 */
+#if ((633 >= GSL_INCLUDER_FIRST_CASE) && (633 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (633)))
+#define GSL_INCLUDER_CASE 633
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 634 */
+#if ((634 >= GSL_INCLUDER_FIRST_CASE) && (634 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (634)))
+#define GSL_INCLUDER_CASE 634
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 635 */
+#if ((635 >= GSL_INCLUDER_FIRST_CASE) && (635 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (635)))
+#define GSL_INCLUDER_CASE 635
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 636 */
+#if ((636 >= GSL_INCLUDER_FIRST_CASE) && (636 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (636)))
+#define GSL_INCLUDER_CASE 636
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 637 */
+#if ((637 >= GSL_INCLUDER_FIRST_CASE) && (637 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (637)))
+#define GSL_INCLUDER_CASE 637
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 638 */
+#if ((638 >= GSL_INCLUDER_FIRST_CASE) && (638 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (638)))
+#define GSL_INCLUDER_CASE 638
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 639 */
+#if ((639 >= GSL_INCLUDER_FIRST_CASE) && (639 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (639)))
+#define GSL_INCLUDER_CASE 639
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 640 */
+#if ((640 >= GSL_INCLUDER_FIRST_CASE) && (640 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (640)))
+#define GSL_INCLUDER_CASE 640
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 641 */
+#if ((641 >= GSL_INCLUDER_FIRST_CASE) && (641 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (641)))
+#define GSL_INCLUDER_CASE 641
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 642 */
+#if ((642 >= GSL_INCLUDER_FIRST_CASE) && (642 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (642)))
+#define GSL_INCLUDER_CASE 642
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 643 */
+#if ((643 >= GSL_INCLUDER_FIRST_CASE) && (643 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (643)))
+#define GSL_INCLUDER_CASE 643
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 644 */
+#if ((644 >= GSL_INCLUDER_FIRST_CASE) && (644 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (644)))
+#define GSL_INCLUDER_CASE 644
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 645 */
+#if ((645 >= GSL_INCLUDER_FIRST_CASE) && (645 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (645)))
+#define GSL_INCLUDER_CASE 645
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 646 */
+#if ((646 >= GSL_INCLUDER_FIRST_CASE) && (646 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (646)))
+#define GSL_INCLUDER_CASE 646
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 647 */
+#if ((647 >= GSL_INCLUDER_FIRST_CASE) && (647 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (647)))
+#define GSL_INCLUDER_CASE 647
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 648 */
+#if ((648 >= GSL_INCLUDER_FIRST_CASE) && (648 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (648)))
+#define GSL_INCLUDER_CASE 648
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 649 */
+#if ((649 >= GSL_INCLUDER_FIRST_CASE) && (649 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (649)))
+#define GSL_INCLUDER_CASE 649
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 650 */
+#if ((650 >= GSL_INCLUDER_FIRST_CASE) && (650 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (650)))
+#define GSL_INCLUDER_CASE 650
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 651 */
+#if ((651 >= GSL_INCLUDER_FIRST_CASE) && (651 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (651)))
+#define GSL_INCLUDER_CASE 651
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 652 */
+#if ((652 >= GSL_INCLUDER_FIRST_CASE) && (652 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (652)))
+#define GSL_INCLUDER_CASE 652
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 653 */
+#if ((653 >= GSL_INCLUDER_FIRST_CASE) && (653 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (653)))
+#define GSL_INCLUDER_CASE 653
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 654 */
+#if ((654 >= GSL_INCLUDER_FIRST_CASE) && (654 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (654)))
+#define GSL_INCLUDER_CASE 654
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 655 */
+#if ((655 >= GSL_INCLUDER_FIRST_CASE) && (655 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (655)))
+#define GSL_INCLUDER_CASE 655
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 656 */
+#if ((656 >= GSL_INCLUDER_FIRST_CASE) && (656 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (656)))
+#define GSL_INCLUDER_CASE 656
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 657 */
+#if ((657 >= GSL_INCLUDER_FIRST_CASE) && (657 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (657)))
+#define GSL_INCLUDER_CASE 657
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 658 */
+#if ((658 >= GSL_INCLUDER_FIRST_CASE) && (658 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (658)))
+#define GSL_INCLUDER_CASE 658
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 659 */
+#if ((659 >= GSL_INCLUDER_FIRST_CASE) && (659 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (659)))
+#define GSL_INCLUDER_CASE 659
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 660 */
+#if ((660 >= GSL_INCLUDER_FIRST_CASE) && (660 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (660)))
+#define GSL_INCLUDER_CASE 660
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 661 */
+#if ((661 >= GSL_INCLUDER_FIRST_CASE) && (661 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (661)))
+#define GSL_INCLUDER_CASE 661
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 662 */
+#if ((662 >= GSL_INCLUDER_FIRST_CASE) && (662 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (662)))
+#define GSL_INCLUDER_CASE 662
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 663 */
+#if ((663 >= GSL_INCLUDER_FIRST_CASE) && (663 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (663)))
+#define GSL_INCLUDER_CASE 663
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 664 */
+#if ((664 >= GSL_INCLUDER_FIRST_CASE) && (664 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (664)))
+#define GSL_INCLUDER_CASE 664
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 665 */
+#if ((665 >= GSL_INCLUDER_FIRST_CASE) && (665 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (665)))
+#define GSL_INCLUDER_CASE 665
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 666 */
+#if ((666 >= GSL_INCLUDER_FIRST_CASE) && (666 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (666)))
+#define GSL_INCLUDER_CASE 666
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 667 */
+#if ((667 >= GSL_INCLUDER_FIRST_CASE) && (667 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (667)))
+#define GSL_INCLUDER_CASE 667
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 668 */
+#if ((668 >= GSL_INCLUDER_FIRST_CASE) && (668 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (668)))
+#define GSL_INCLUDER_CASE 668
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 669 */
+#if ((669 >= GSL_INCLUDER_FIRST_CASE) && (669 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (669)))
+#define GSL_INCLUDER_CASE 669
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 670 */
+#if ((670 >= GSL_INCLUDER_FIRST_CASE) && (670 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (670)))
+#define GSL_INCLUDER_CASE 670
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 671 */
+#if ((671 >= GSL_INCLUDER_FIRST_CASE) && (671 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (671)))
+#define GSL_INCLUDER_CASE 671
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 672 */
+#if ((672 >= GSL_INCLUDER_FIRST_CASE) && (672 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (672)))
+#define GSL_INCLUDER_CASE 672
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 673 */
+#if ((673 >= GSL_INCLUDER_FIRST_CASE) && (673 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (673)))
+#define GSL_INCLUDER_CASE 673
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 674 */
+#if ((674 >= GSL_INCLUDER_FIRST_CASE) && (674 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (674)))
+#define GSL_INCLUDER_CASE 674
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 675 */
+#if ((675 >= GSL_INCLUDER_FIRST_CASE) && (675 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (675)))
+#define GSL_INCLUDER_CASE 675
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 676 */
+#if ((676 >= GSL_INCLUDER_FIRST_CASE) && (676 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (676)))
+#define GSL_INCLUDER_CASE 676
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 677 */
+#if ((677 >= GSL_INCLUDER_FIRST_CASE) && (677 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (677)))
+#define GSL_INCLUDER_CASE 677
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 678 */
+#if ((678 >= GSL_INCLUDER_FIRST_CASE) && (678 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (678)))
+#define GSL_INCLUDER_CASE 678
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 679 */
+#if ((679 >= GSL_INCLUDER_FIRST_CASE) && (679 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (679)))
+#define GSL_INCLUDER_CASE 679
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 680 */
+#if ((680 >= GSL_INCLUDER_FIRST_CASE) && (680 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (680)))
+#define GSL_INCLUDER_CASE 680
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 681 */
+#if ((681 >= GSL_INCLUDER_FIRST_CASE) && (681 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (681)))
+#define GSL_INCLUDER_CASE 681
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 682 */
+#if ((682 >= GSL_INCLUDER_FIRST_CASE) && (682 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (682)))
+#define GSL_INCLUDER_CASE 682
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 683 */
+#if ((683 >= GSL_INCLUDER_FIRST_CASE) && (683 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (683)))
+#define GSL_INCLUDER_CASE 683
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 684 */
+#if ((684 >= GSL_INCLUDER_FIRST_CASE) && (684 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (684)))
+#define GSL_INCLUDER_CASE 684
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 685 */
+#if ((685 >= GSL_INCLUDER_FIRST_CASE) && (685 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (685)))
+#define GSL_INCLUDER_CASE 685
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 686 */
+#if ((686 >= GSL_INCLUDER_FIRST_CASE) && (686 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (686)))
+#define GSL_INCLUDER_CASE 686
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 687 */
+#if ((687 >= GSL_INCLUDER_FIRST_CASE) && (687 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (687)))
+#define GSL_INCLUDER_CASE 687
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 688 */
+#if ((688 >= GSL_INCLUDER_FIRST_CASE) && (688 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (688)))
+#define GSL_INCLUDER_CASE 688
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 689 */
+#if ((689 >= GSL_INCLUDER_FIRST_CASE) && (689 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (689)))
+#define GSL_INCLUDER_CASE 689
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 690 */
+#if ((690 >= GSL_INCLUDER_FIRST_CASE) && (690 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (690)))
+#define GSL_INCLUDER_CASE 690
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 691 */
+#if ((691 >= GSL_INCLUDER_FIRST_CASE) && (691 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (691)))
+#define GSL_INCLUDER_CASE 691
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 692 */
+#if ((692 >= GSL_INCLUDER_FIRST_CASE) && (692 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (692)))
+#define GSL_INCLUDER_CASE 692
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 693 */
+#if ((693 >= GSL_INCLUDER_FIRST_CASE) && (693 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (693)))
+#define GSL_INCLUDER_CASE 693
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 694 */
+#if ((694 >= GSL_INCLUDER_FIRST_CASE) && (694 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (694)))
+#define GSL_INCLUDER_CASE 694
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 695 */
+#if ((695 >= GSL_INCLUDER_FIRST_CASE) && (695 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (695)))
+#define GSL_INCLUDER_CASE 695
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 696 */
+#if ((696 >= GSL_INCLUDER_FIRST_CASE) && (696 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (696)))
+#define GSL_INCLUDER_CASE 696
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 697 */
+#if ((697 >= GSL_INCLUDER_FIRST_CASE) && (697 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (697)))
+#define GSL_INCLUDER_CASE 697
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 698 */
+#if ((698 >= GSL_INCLUDER_FIRST_CASE) && (698 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (698)))
+#define GSL_INCLUDER_CASE 698
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 699 */
+#if ((699 >= GSL_INCLUDER_FIRST_CASE) && (699 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (699)))
+#define GSL_INCLUDER_CASE 699
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 700 */
+#if ((700 >= GSL_INCLUDER_FIRST_CASE) && (700 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (700)))
+#define GSL_INCLUDER_CASE 700
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 701 */
+#if ((701 >= GSL_INCLUDER_FIRST_CASE) && (701 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (701)))
+#define GSL_INCLUDER_CASE 701
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 702 */
+#if ((702 >= GSL_INCLUDER_FIRST_CASE) && (702 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (702)))
+#define GSL_INCLUDER_CASE 702
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 703 */
+#if ((703 >= GSL_INCLUDER_FIRST_CASE) && (703 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (703)))
+#define GSL_INCLUDER_CASE 703
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 704 */
+#if ((704 >= GSL_INCLUDER_FIRST_CASE) && (704 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (704)))
+#define GSL_INCLUDER_CASE 704
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 705 */
+#if ((705 >= GSL_INCLUDER_FIRST_CASE) && (705 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (705)))
+#define GSL_INCLUDER_CASE 705
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 706 */
+#if ((706 >= GSL_INCLUDER_FIRST_CASE) && (706 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (706)))
+#define GSL_INCLUDER_CASE 706
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 707 */
+#if ((707 >= GSL_INCLUDER_FIRST_CASE) && (707 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (707)))
+#define GSL_INCLUDER_CASE 707
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 708 */
+#if ((708 >= GSL_INCLUDER_FIRST_CASE) && (708 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (708)))
+#define GSL_INCLUDER_CASE 708
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 709 */
+#if ((709 >= GSL_INCLUDER_FIRST_CASE) && (709 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (709)))
+#define GSL_INCLUDER_CASE 709
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 710 */
+#if ((710 >= GSL_INCLUDER_FIRST_CASE) && (710 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (710)))
+#define GSL_INCLUDER_CASE 710
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 711 */
+#if ((711 >= GSL_INCLUDER_FIRST_CASE) && (711 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (711)))
+#define GSL_INCLUDER_CASE 711
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 712 */
+#if ((712 >= GSL_INCLUDER_FIRST_CASE) && (712 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (712)))
+#define GSL_INCLUDER_CASE 712
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 713 */
+#if ((713 >= GSL_INCLUDER_FIRST_CASE) && (713 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (713)))
+#define GSL_INCLUDER_CASE 713
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 714 */
+#if ((714 >= GSL_INCLUDER_FIRST_CASE) && (714 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (714)))
+#define GSL_INCLUDER_CASE 714
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 715 */
+#if ((715 >= GSL_INCLUDER_FIRST_CASE) && (715 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (715)))
+#define GSL_INCLUDER_CASE 715
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 716 */
+#if ((716 >= GSL_INCLUDER_FIRST_CASE) && (716 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (716)))
+#define GSL_INCLUDER_CASE 716
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 717 */
+#if ((717 >= GSL_INCLUDER_FIRST_CASE) && (717 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (717)))
+#define GSL_INCLUDER_CASE 717
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 718 */
+#if ((718 >= GSL_INCLUDER_FIRST_CASE) && (718 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (718)))
+#define GSL_INCLUDER_CASE 718
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 719 */
+#if ((719 >= GSL_INCLUDER_FIRST_CASE) && (719 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (719)))
+#define GSL_INCLUDER_CASE 719
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 720 */
+#if ((720 >= GSL_INCLUDER_FIRST_CASE) && (720 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (720)))
+#define GSL_INCLUDER_CASE 720
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 721 */
+#if ((721 >= GSL_INCLUDER_FIRST_CASE) && (721 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (721)))
+#define GSL_INCLUDER_CASE 721
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 722 */
+#if ((722 >= GSL_INCLUDER_FIRST_CASE) && (722 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (722)))
+#define GSL_INCLUDER_CASE 722
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 723 */
+#if ((723 >= GSL_INCLUDER_FIRST_CASE) && (723 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (723)))
+#define GSL_INCLUDER_CASE 723
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 724 */
+#if ((724 >= GSL_INCLUDER_FIRST_CASE) && (724 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (724)))
+#define GSL_INCLUDER_CASE 724
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 725 */
+#if ((725 >= GSL_INCLUDER_FIRST_CASE) && (725 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (725)))
+#define GSL_INCLUDER_CASE 725
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 726 */
+#if ((726 >= GSL_INCLUDER_FIRST_CASE) && (726 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (726)))
+#define GSL_INCLUDER_CASE 726
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 727 */
+#if ((727 >= GSL_INCLUDER_FIRST_CASE) && (727 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (727)))
+#define GSL_INCLUDER_CASE 727
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 728 */
+#if ((728 >= GSL_INCLUDER_FIRST_CASE) && (728 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (728)))
+#define GSL_INCLUDER_CASE 728
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 729 */
+#if ((729 >= GSL_INCLUDER_FIRST_CASE) && (729 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (729)))
+#define GSL_INCLUDER_CASE 729
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 730 */
+#if ((730 >= GSL_INCLUDER_FIRST_CASE) && (730 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (730)))
+#define GSL_INCLUDER_CASE 730
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 731 */
+#if ((731 >= GSL_INCLUDER_FIRST_CASE) && (731 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (731)))
+#define GSL_INCLUDER_CASE 731
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 732 */
+#if ((732 >= GSL_INCLUDER_FIRST_CASE) && (732 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (732)))
+#define GSL_INCLUDER_CASE 732
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 733 */
+#if ((733 >= GSL_INCLUDER_FIRST_CASE) && (733 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (733)))
+#define GSL_INCLUDER_CASE 733
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 734 */
+#if ((734 >= GSL_INCLUDER_FIRST_CASE) && (734 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (734)))
+#define GSL_INCLUDER_CASE 734
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 735 */
+#if ((735 >= GSL_INCLUDER_FIRST_CASE) && (735 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (735)))
+#define GSL_INCLUDER_CASE 735
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 736 */
+#if ((736 >= GSL_INCLUDER_FIRST_CASE) && (736 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (736)))
+#define GSL_INCLUDER_CASE 736
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 737 */
+#if ((737 >= GSL_INCLUDER_FIRST_CASE) && (737 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (737)))
+#define GSL_INCLUDER_CASE 737
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 738 */
+#if ((738 >= GSL_INCLUDER_FIRST_CASE) && (738 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (738)))
+#define GSL_INCLUDER_CASE 738
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 739 */
+#if ((739 >= GSL_INCLUDER_FIRST_CASE) && (739 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (739)))
+#define GSL_INCLUDER_CASE 739
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 740 */
+#if ((740 >= GSL_INCLUDER_FIRST_CASE) && (740 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (740)))
+#define GSL_INCLUDER_CASE 740
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 741 */
+#if ((741 >= GSL_INCLUDER_FIRST_CASE) && (741 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (741)))
+#define GSL_INCLUDER_CASE 741
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 742 */
+#if ((742 >= GSL_INCLUDER_FIRST_CASE) && (742 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (742)))
+#define GSL_INCLUDER_CASE 742
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 743 */
+#if ((743 >= GSL_INCLUDER_FIRST_CASE) && (743 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (743)))
+#define GSL_INCLUDER_CASE 743
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 744 */
+#if ((744 >= GSL_INCLUDER_FIRST_CASE) && (744 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (744)))
+#define GSL_INCLUDER_CASE 744
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 745 */
+#if ((745 >= GSL_INCLUDER_FIRST_CASE) && (745 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (745)))
+#define GSL_INCLUDER_CASE 745
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 746 */
+#if ((746 >= GSL_INCLUDER_FIRST_CASE) && (746 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (746)))
+#define GSL_INCLUDER_CASE 746
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 747 */
+#if ((747 >= GSL_INCLUDER_FIRST_CASE) && (747 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (747)))
+#define GSL_INCLUDER_CASE 747
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 748 */
+#if ((748 >= GSL_INCLUDER_FIRST_CASE) && (748 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (748)))
+#define GSL_INCLUDER_CASE 748
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 749 */
+#if ((749 >= GSL_INCLUDER_FIRST_CASE) && (749 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (749)))
+#define GSL_INCLUDER_CASE 749
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 750 */
+#if ((750 >= GSL_INCLUDER_FIRST_CASE) && (750 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (750)))
+#define GSL_INCLUDER_CASE 750
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 751 */
+#if ((751 >= GSL_INCLUDER_FIRST_CASE) && (751 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (751)))
+#define GSL_INCLUDER_CASE 751
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 752 */
+#if ((752 >= GSL_INCLUDER_FIRST_CASE) && (752 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (752)))
+#define GSL_INCLUDER_CASE 752
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 753 */
+#if ((753 >= GSL_INCLUDER_FIRST_CASE) && (753 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (753)))
+#define GSL_INCLUDER_CASE 753
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 754 */
+#if ((754 >= GSL_INCLUDER_FIRST_CASE) && (754 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (754)))
+#define GSL_INCLUDER_CASE 754
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 755 */
+#if ((755 >= GSL_INCLUDER_FIRST_CASE) && (755 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (755)))
+#define GSL_INCLUDER_CASE 755
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 756 */
+#if ((756 >= GSL_INCLUDER_FIRST_CASE) && (756 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (756)))
+#define GSL_INCLUDER_CASE 756
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 757 */
+#if ((757 >= GSL_INCLUDER_FIRST_CASE) && (757 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (757)))
+#define GSL_INCLUDER_CASE 757
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 758 */
+#if ((758 >= GSL_INCLUDER_FIRST_CASE) && (758 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (758)))
+#define GSL_INCLUDER_CASE 758
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 759 */
+#if ((759 >= GSL_INCLUDER_FIRST_CASE) && (759 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (759)))
+#define GSL_INCLUDER_CASE 759
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 760 */
+#if ((760 >= GSL_INCLUDER_FIRST_CASE) && (760 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (760)))
+#define GSL_INCLUDER_CASE 760
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 761 */
+#if ((761 >= GSL_INCLUDER_FIRST_CASE) && (761 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (761)))
+#define GSL_INCLUDER_CASE 761
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 762 */
+#if ((762 >= GSL_INCLUDER_FIRST_CASE) && (762 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (762)))
+#define GSL_INCLUDER_CASE 762
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 763 */
+#if ((763 >= GSL_INCLUDER_FIRST_CASE) && (763 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (763)))
+#define GSL_INCLUDER_CASE 763
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 764 */
+#if ((764 >= GSL_INCLUDER_FIRST_CASE) && (764 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (764)))
+#define GSL_INCLUDER_CASE 764
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 765 */
+#if ((765 >= GSL_INCLUDER_FIRST_CASE) && (765 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (765)))
+#define GSL_INCLUDER_CASE 765
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 766 */
+#if ((766 >= GSL_INCLUDER_FIRST_CASE) && (766 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (766)))
+#define GSL_INCLUDER_CASE 766
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 767 */
+#if ((767 >= GSL_INCLUDER_FIRST_CASE) && (767 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (767)))
+#define GSL_INCLUDER_CASE 767
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 768 */
+#if ((768 >= GSL_INCLUDER_FIRST_CASE) && (768 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (768)))
+#define GSL_INCLUDER_CASE 768
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 769 */
+#if ((769 >= GSL_INCLUDER_FIRST_CASE) && (769 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (769)))
+#define GSL_INCLUDER_CASE 769
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 770 */
+#if ((770 >= GSL_INCLUDER_FIRST_CASE) && (770 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (770)))
+#define GSL_INCLUDER_CASE 770
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 771 */
+#if ((771 >= GSL_INCLUDER_FIRST_CASE) && (771 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (771)))
+#define GSL_INCLUDER_CASE 771
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 772 */
+#if ((772 >= GSL_INCLUDER_FIRST_CASE) && (772 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (772)))
+#define GSL_INCLUDER_CASE 772
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 773 */
+#if ((773 >= GSL_INCLUDER_FIRST_CASE) && (773 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (773)))
+#define GSL_INCLUDER_CASE 773
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 774 */
+#if ((774 >= GSL_INCLUDER_FIRST_CASE) && (774 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (774)))
+#define GSL_INCLUDER_CASE 774
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 775 */
+#if ((775 >= GSL_INCLUDER_FIRST_CASE) && (775 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (775)))
+#define GSL_INCLUDER_CASE 775
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 776 */
+#if ((776 >= GSL_INCLUDER_FIRST_CASE) && (776 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (776)))
+#define GSL_INCLUDER_CASE 776
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 777 */
+#if ((777 >= GSL_INCLUDER_FIRST_CASE) && (777 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (777)))
+#define GSL_INCLUDER_CASE 777
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 778 */
+#if ((778 >= GSL_INCLUDER_FIRST_CASE) && (778 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (778)))
+#define GSL_INCLUDER_CASE 778
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 779 */
+#if ((779 >= GSL_INCLUDER_FIRST_CASE) && (779 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (779)))
+#define GSL_INCLUDER_CASE 779
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 780 */
+#if ((780 >= GSL_INCLUDER_FIRST_CASE) && (780 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (780)))
+#define GSL_INCLUDER_CASE 780
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 781 */
+#if ((781 >= GSL_INCLUDER_FIRST_CASE) && (781 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (781)))
+#define GSL_INCLUDER_CASE 781
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 782 */
+#if ((782 >= GSL_INCLUDER_FIRST_CASE) && (782 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (782)))
+#define GSL_INCLUDER_CASE 782
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 783 */
+#if ((783 >= GSL_INCLUDER_FIRST_CASE) && (783 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (783)))
+#define GSL_INCLUDER_CASE 783
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 784 */
+#if ((784 >= GSL_INCLUDER_FIRST_CASE) && (784 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (784)))
+#define GSL_INCLUDER_CASE 784
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 785 */
+#if ((785 >= GSL_INCLUDER_FIRST_CASE) && (785 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (785)))
+#define GSL_INCLUDER_CASE 785
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 786 */
+#if ((786 >= GSL_INCLUDER_FIRST_CASE) && (786 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (786)))
+#define GSL_INCLUDER_CASE 786
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 787 */
+#if ((787 >= GSL_INCLUDER_FIRST_CASE) && (787 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (787)))
+#define GSL_INCLUDER_CASE 787
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 788 */
+#if ((788 >= GSL_INCLUDER_FIRST_CASE) && (788 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (788)))
+#define GSL_INCLUDER_CASE 788
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 789 */
+#if ((789 >= GSL_INCLUDER_FIRST_CASE) && (789 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (789)))
+#define GSL_INCLUDER_CASE 789
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 790 */
+#if ((790 >= GSL_INCLUDER_FIRST_CASE) && (790 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (790)))
+#define GSL_INCLUDER_CASE 790
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 791 */
+#if ((791 >= GSL_INCLUDER_FIRST_CASE) && (791 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (791)))
+#define GSL_INCLUDER_CASE 791
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 792 */
+#if ((792 >= GSL_INCLUDER_FIRST_CASE) && (792 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (792)))
+#define GSL_INCLUDER_CASE 792
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 793 */
+#if ((793 >= GSL_INCLUDER_FIRST_CASE) && (793 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (793)))
+#define GSL_INCLUDER_CASE 793
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 794 */
+#if ((794 >= GSL_INCLUDER_FIRST_CASE) && (794 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (794)))
+#define GSL_INCLUDER_CASE 794
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 795 */
+#if ((795 >= GSL_INCLUDER_FIRST_CASE) && (795 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (795)))
+#define GSL_INCLUDER_CASE 795
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 796 */
+#if ((796 >= GSL_INCLUDER_FIRST_CASE) && (796 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (796)))
+#define GSL_INCLUDER_CASE 796
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 797 */
+#if ((797 >= GSL_INCLUDER_FIRST_CASE) && (797 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (797)))
+#define GSL_INCLUDER_CASE 797
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 798 */
+#if ((798 >= GSL_INCLUDER_FIRST_CASE) && (798 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (798)))
+#define GSL_INCLUDER_CASE 798
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 799 */
+#if ((799 >= GSL_INCLUDER_FIRST_CASE) && (799 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (799)))
+#define GSL_INCLUDER_CASE 799
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 800 */
+#if ((800 >= GSL_INCLUDER_FIRST_CASE) && (800 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (800)))
+#define GSL_INCLUDER_CASE 800
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 801 */
+#if ((801 >= GSL_INCLUDER_FIRST_CASE) && (801 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (801)))
+#define GSL_INCLUDER_CASE 801
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 802 */
+#if ((802 >= GSL_INCLUDER_FIRST_CASE) && (802 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (802)))
+#define GSL_INCLUDER_CASE 802
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 803 */
+#if ((803 >= GSL_INCLUDER_FIRST_CASE) && (803 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (803)))
+#define GSL_INCLUDER_CASE 803
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 804 */
+#if ((804 >= GSL_INCLUDER_FIRST_CASE) && (804 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (804)))
+#define GSL_INCLUDER_CASE 804
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 805 */
+#if ((805 >= GSL_INCLUDER_FIRST_CASE) && (805 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (805)))
+#define GSL_INCLUDER_CASE 805
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 806 */
+#if ((806 >= GSL_INCLUDER_FIRST_CASE) && (806 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (806)))
+#define GSL_INCLUDER_CASE 806
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 807 */
+#if ((807 >= GSL_INCLUDER_FIRST_CASE) && (807 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (807)))
+#define GSL_INCLUDER_CASE 807
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 808 */
+#if ((808 >= GSL_INCLUDER_FIRST_CASE) && (808 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (808)))
+#define GSL_INCLUDER_CASE 808
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 809 */
+#if ((809 >= GSL_INCLUDER_FIRST_CASE) && (809 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (809)))
+#define GSL_INCLUDER_CASE 809
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 810 */
+#if ((810 >= GSL_INCLUDER_FIRST_CASE) && (810 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (810)))
+#define GSL_INCLUDER_CASE 810
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 811 */
+#if ((811 >= GSL_INCLUDER_FIRST_CASE) && (811 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (811)))
+#define GSL_INCLUDER_CASE 811
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 812 */
+#if ((812 >= GSL_INCLUDER_FIRST_CASE) && (812 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (812)))
+#define GSL_INCLUDER_CASE 812
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 813 */
+#if ((813 >= GSL_INCLUDER_FIRST_CASE) && (813 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (813)))
+#define GSL_INCLUDER_CASE 813
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 814 */
+#if ((814 >= GSL_INCLUDER_FIRST_CASE) && (814 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (814)))
+#define GSL_INCLUDER_CASE 814
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 815 */
+#if ((815 >= GSL_INCLUDER_FIRST_CASE) && (815 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (815)))
+#define GSL_INCLUDER_CASE 815
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 816 */
+#if ((816 >= GSL_INCLUDER_FIRST_CASE) && (816 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (816)))
+#define GSL_INCLUDER_CASE 816
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 817 */
+#if ((817 >= GSL_INCLUDER_FIRST_CASE) && (817 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (817)))
+#define GSL_INCLUDER_CASE 817
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 818 */
+#if ((818 >= GSL_INCLUDER_FIRST_CASE) && (818 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (818)))
+#define GSL_INCLUDER_CASE 818
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 819 */
+#if ((819 >= GSL_INCLUDER_FIRST_CASE) && (819 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (819)))
+#define GSL_INCLUDER_CASE 819
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 820 */
+#if ((820 >= GSL_INCLUDER_FIRST_CASE) && (820 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (820)))
+#define GSL_INCLUDER_CASE 820
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 821 */
+#if ((821 >= GSL_INCLUDER_FIRST_CASE) && (821 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (821)))
+#define GSL_INCLUDER_CASE 821
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 822 */
+#if ((822 >= GSL_INCLUDER_FIRST_CASE) && (822 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (822)))
+#define GSL_INCLUDER_CASE 822
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 823 */
+#if ((823 >= GSL_INCLUDER_FIRST_CASE) && (823 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (823)))
+#define GSL_INCLUDER_CASE 823
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 824 */
+#if ((824 >= GSL_INCLUDER_FIRST_CASE) && (824 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (824)))
+#define GSL_INCLUDER_CASE 824
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 825 */
+#if ((825 >= GSL_INCLUDER_FIRST_CASE) && (825 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (825)))
+#define GSL_INCLUDER_CASE 825
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 826 */
+#if ((826 >= GSL_INCLUDER_FIRST_CASE) && (826 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (826)))
+#define GSL_INCLUDER_CASE 826
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 827 */
+#if ((827 >= GSL_INCLUDER_FIRST_CASE) && (827 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (827)))
+#define GSL_INCLUDER_CASE 827
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 828 */
+#if ((828 >= GSL_INCLUDER_FIRST_CASE) && (828 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (828)))
+#define GSL_INCLUDER_CASE 828
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 829 */
+#if ((829 >= GSL_INCLUDER_FIRST_CASE) && (829 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (829)))
+#define GSL_INCLUDER_CASE 829
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 830 */
+#if ((830 >= GSL_INCLUDER_FIRST_CASE) && (830 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (830)))
+#define GSL_INCLUDER_CASE 830
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 831 */
+#if ((831 >= GSL_INCLUDER_FIRST_CASE) && (831 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (831)))
+#define GSL_INCLUDER_CASE 831
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 832 */
+#if ((832 >= GSL_INCLUDER_FIRST_CASE) && (832 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (832)))
+#define GSL_INCLUDER_CASE 832
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 833 */
+#if ((833 >= GSL_INCLUDER_FIRST_CASE) && (833 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (833)))
+#define GSL_INCLUDER_CASE 833
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 834 */
+#if ((834 >= GSL_INCLUDER_FIRST_CASE) && (834 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (834)))
+#define GSL_INCLUDER_CASE 834
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 835 */
+#if ((835 >= GSL_INCLUDER_FIRST_CASE) && (835 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (835)))
+#define GSL_INCLUDER_CASE 835
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 836 */
+#if ((836 >= GSL_INCLUDER_FIRST_CASE) && (836 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (836)))
+#define GSL_INCLUDER_CASE 836
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 837 */
+#if ((837 >= GSL_INCLUDER_FIRST_CASE) && (837 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (837)))
+#define GSL_INCLUDER_CASE 837
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 838 */
+#if ((838 >= GSL_INCLUDER_FIRST_CASE) && (838 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (838)))
+#define GSL_INCLUDER_CASE 838
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 839 */
+#if ((839 >= GSL_INCLUDER_FIRST_CASE) && (839 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (839)))
+#define GSL_INCLUDER_CASE 839
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 840 */
+#if ((840 >= GSL_INCLUDER_FIRST_CASE) && (840 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (840)))
+#define GSL_INCLUDER_CASE 840
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 841 */
+#if ((841 >= GSL_INCLUDER_FIRST_CASE) && (841 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (841)))
+#define GSL_INCLUDER_CASE 841
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 842 */
+#if ((842 >= GSL_INCLUDER_FIRST_CASE) && (842 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (842)))
+#define GSL_INCLUDER_CASE 842
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 843 */
+#if ((843 >= GSL_INCLUDER_FIRST_CASE) && (843 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (843)))
+#define GSL_INCLUDER_CASE 843
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 844 */
+#if ((844 >= GSL_INCLUDER_FIRST_CASE) && (844 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (844)))
+#define GSL_INCLUDER_CASE 844
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 845 */
+#if ((845 >= GSL_INCLUDER_FIRST_CASE) && (845 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (845)))
+#define GSL_INCLUDER_CASE 845
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 846 */
+#if ((846 >= GSL_INCLUDER_FIRST_CASE) && (846 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (846)))
+#define GSL_INCLUDER_CASE 846
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 847 */
+#if ((847 >= GSL_INCLUDER_FIRST_CASE) && (847 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (847)))
+#define GSL_INCLUDER_CASE 847
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 848 */
+#if ((848 >= GSL_INCLUDER_FIRST_CASE) && (848 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (848)))
+#define GSL_INCLUDER_CASE 848
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 849 */
+#if ((849 >= GSL_INCLUDER_FIRST_CASE) && (849 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (849)))
+#define GSL_INCLUDER_CASE 849
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 850 */
+#if ((850 >= GSL_INCLUDER_FIRST_CASE) && (850 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (850)))
+#define GSL_INCLUDER_CASE 850
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 851 */
+#if ((851 >= GSL_INCLUDER_FIRST_CASE) && (851 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (851)))
+#define GSL_INCLUDER_CASE 851
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 852 */
+#if ((852 >= GSL_INCLUDER_FIRST_CASE) && (852 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (852)))
+#define GSL_INCLUDER_CASE 852
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 853 */
+#if ((853 >= GSL_INCLUDER_FIRST_CASE) && (853 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (853)))
+#define GSL_INCLUDER_CASE 853
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 854 */
+#if ((854 >= GSL_INCLUDER_FIRST_CASE) && (854 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (854)))
+#define GSL_INCLUDER_CASE 854
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 855 */
+#if ((855 >= GSL_INCLUDER_FIRST_CASE) && (855 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (855)))
+#define GSL_INCLUDER_CASE 855
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 856 */
+#if ((856 >= GSL_INCLUDER_FIRST_CASE) && (856 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (856)))
+#define GSL_INCLUDER_CASE 856
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 857 */
+#if ((857 >= GSL_INCLUDER_FIRST_CASE) && (857 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (857)))
+#define GSL_INCLUDER_CASE 857
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 858 */
+#if ((858 >= GSL_INCLUDER_FIRST_CASE) && (858 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (858)))
+#define GSL_INCLUDER_CASE 858
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 859 */
+#if ((859 >= GSL_INCLUDER_FIRST_CASE) && (859 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (859)))
+#define GSL_INCLUDER_CASE 859
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 860 */
+#if ((860 >= GSL_INCLUDER_FIRST_CASE) && (860 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (860)))
+#define GSL_INCLUDER_CASE 860
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 861 */
+#if ((861 >= GSL_INCLUDER_FIRST_CASE) && (861 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (861)))
+#define GSL_INCLUDER_CASE 861
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 862 */
+#if ((862 >= GSL_INCLUDER_FIRST_CASE) && (862 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (862)))
+#define GSL_INCLUDER_CASE 862
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 863 */
+#if ((863 >= GSL_INCLUDER_FIRST_CASE) && (863 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (863)))
+#define GSL_INCLUDER_CASE 863
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 864 */
+#if ((864 >= GSL_INCLUDER_FIRST_CASE) && (864 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (864)))
+#define GSL_INCLUDER_CASE 864
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 865 */
+#if ((865 >= GSL_INCLUDER_FIRST_CASE) && (865 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (865)))
+#define GSL_INCLUDER_CASE 865
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 866 */
+#if ((866 >= GSL_INCLUDER_FIRST_CASE) && (866 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (866)))
+#define GSL_INCLUDER_CASE 866
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 867 */
+#if ((867 >= GSL_INCLUDER_FIRST_CASE) && (867 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (867)))
+#define GSL_INCLUDER_CASE 867
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 868 */
+#if ((868 >= GSL_INCLUDER_FIRST_CASE) && (868 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (868)))
+#define GSL_INCLUDER_CASE 868
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 869 */
+#if ((869 >= GSL_INCLUDER_FIRST_CASE) && (869 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (869)))
+#define GSL_INCLUDER_CASE 869
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 870 */
+#if ((870 >= GSL_INCLUDER_FIRST_CASE) && (870 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (870)))
+#define GSL_INCLUDER_CASE 870
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 871 */
+#if ((871 >= GSL_INCLUDER_FIRST_CASE) && (871 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (871)))
+#define GSL_INCLUDER_CASE 871
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 872 */
+#if ((872 >= GSL_INCLUDER_FIRST_CASE) && (872 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (872)))
+#define GSL_INCLUDER_CASE 872
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 873 */
+#if ((873 >= GSL_INCLUDER_FIRST_CASE) && (873 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (873)))
+#define GSL_INCLUDER_CASE 873
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 874 */
+#if ((874 >= GSL_INCLUDER_FIRST_CASE) && (874 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (874)))
+#define GSL_INCLUDER_CASE 874
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 875 */
+#if ((875 >= GSL_INCLUDER_FIRST_CASE) && (875 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (875)))
+#define GSL_INCLUDER_CASE 875
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 876 */
+#if ((876 >= GSL_INCLUDER_FIRST_CASE) && (876 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (876)))
+#define GSL_INCLUDER_CASE 876
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 877 */
+#if ((877 >= GSL_INCLUDER_FIRST_CASE) && (877 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (877)))
+#define GSL_INCLUDER_CASE 877
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 878 */
+#if ((878 >= GSL_INCLUDER_FIRST_CASE) && (878 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (878)))
+#define GSL_INCLUDER_CASE 878
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 879 */
+#if ((879 >= GSL_INCLUDER_FIRST_CASE) && (879 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (879)))
+#define GSL_INCLUDER_CASE 879
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 880 */
+#if ((880 >= GSL_INCLUDER_FIRST_CASE) && (880 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (880)))
+#define GSL_INCLUDER_CASE 880
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 881 */
+#if ((881 >= GSL_INCLUDER_FIRST_CASE) && (881 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (881)))
+#define GSL_INCLUDER_CASE 881
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 882 */
+#if ((882 >= GSL_INCLUDER_FIRST_CASE) && (882 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (882)))
+#define GSL_INCLUDER_CASE 882
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 883 */
+#if ((883 >= GSL_INCLUDER_FIRST_CASE) && (883 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (883)))
+#define GSL_INCLUDER_CASE 883
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 884 */
+#if ((884 >= GSL_INCLUDER_FIRST_CASE) && (884 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (884)))
+#define GSL_INCLUDER_CASE 884
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 885 */
+#if ((885 >= GSL_INCLUDER_FIRST_CASE) && (885 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (885)))
+#define GSL_INCLUDER_CASE 885
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 886 */
+#if ((886 >= GSL_INCLUDER_FIRST_CASE) && (886 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (886)))
+#define GSL_INCLUDER_CASE 886
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 887 */
+#if ((887 >= GSL_INCLUDER_FIRST_CASE) && (887 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (887)))
+#define GSL_INCLUDER_CASE 887
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 888 */
+#if ((888 >= GSL_INCLUDER_FIRST_CASE) && (888 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (888)))
+#define GSL_INCLUDER_CASE 888
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 889 */
+#if ((889 >= GSL_INCLUDER_FIRST_CASE) && (889 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (889)))
+#define GSL_INCLUDER_CASE 889
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 890 */
+#if ((890 >= GSL_INCLUDER_FIRST_CASE) && (890 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (890)))
+#define GSL_INCLUDER_CASE 890
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 891 */
+#if ((891 >= GSL_INCLUDER_FIRST_CASE) && (891 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (891)))
+#define GSL_INCLUDER_CASE 891
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 892 */
+#if ((892 >= GSL_INCLUDER_FIRST_CASE) && (892 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (892)))
+#define GSL_INCLUDER_CASE 892
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 893 */
+#if ((893 >= GSL_INCLUDER_FIRST_CASE) && (893 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (893)))
+#define GSL_INCLUDER_CASE 893
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 894 */
+#if ((894 >= GSL_INCLUDER_FIRST_CASE) && (894 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (894)))
+#define GSL_INCLUDER_CASE 894
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 895 */
+#if ((895 >= GSL_INCLUDER_FIRST_CASE) && (895 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (895)))
+#define GSL_INCLUDER_CASE 895
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 896 */
+#if ((896 >= GSL_INCLUDER_FIRST_CASE) && (896 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (896)))
+#define GSL_INCLUDER_CASE 896
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 897 */
+#if ((897 >= GSL_INCLUDER_FIRST_CASE) && (897 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (897)))
+#define GSL_INCLUDER_CASE 897
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 898 */
+#if ((898 >= GSL_INCLUDER_FIRST_CASE) && (898 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (898)))
+#define GSL_INCLUDER_CASE 898
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 899 */
+#if ((899 >= GSL_INCLUDER_FIRST_CASE) && (899 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (899)))
+#define GSL_INCLUDER_CASE 899
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 900 */
+#if ((900 >= GSL_INCLUDER_FIRST_CASE) && (900 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (900)))
+#define GSL_INCLUDER_CASE 900
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 901 */
+#if ((901 >= GSL_INCLUDER_FIRST_CASE) && (901 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (901)))
+#define GSL_INCLUDER_CASE 901
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 902 */
+#if ((902 >= GSL_INCLUDER_FIRST_CASE) && (902 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (902)))
+#define GSL_INCLUDER_CASE 902
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 903 */
+#if ((903 >= GSL_INCLUDER_FIRST_CASE) && (903 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (903)))
+#define GSL_INCLUDER_CASE 903
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 904 */
+#if ((904 >= GSL_INCLUDER_FIRST_CASE) && (904 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (904)))
+#define GSL_INCLUDER_CASE 904
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 905 */
+#if ((905 >= GSL_INCLUDER_FIRST_CASE) && (905 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (905)))
+#define GSL_INCLUDER_CASE 905
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 906 */
+#if ((906 >= GSL_INCLUDER_FIRST_CASE) && (906 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (906)))
+#define GSL_INCLUDER_CASE 906
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 907 */
+#if ((907 >= GSL_INCLUDER_FIRST_CASE) && (907 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (907)))
+#define GSL_INCLUDER_CASE 907
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 908 */
+#if ((908 >= GSL_INCLUDER_FIRST_CASE) && (908 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (908)))
+#define GSL_INCLUDER_CASE 908
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 909 */
+#if ((909 >= GSL_INCLUDER_FIRST_CASE) && (909 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (909)))
+#define GSL_INCLUDER_CASE 909
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 910 */
+#if ((910 >= GSL_INCLUDER_FIRST_CASE) && (910 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (910)))
+#define GSL_INCLUDER_CASE 910
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 911 */
+#if ((911 >= GSL_INCLUDER_FIRST_CASE) && (911 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (911)))
+#define GSL_INCLUDER_CASE 911
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 912 */
+#if ((912 >= GSL_INCLUDER_FIRST_CASE) && (912 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (912)))
+#define GSL_INCLUDER_CASE 912
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 913 */
+#if ((913 >= GSL_INCLUDER_FIRST_CASE) && (913 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (913)))
+#define GSL_INCLUDER_CASE 913
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 914 */
+#if ((914 >= GSL_INCLUDER_FIRST_CASE) && (914 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (914)))
+#define GSL_INCLUDER_CASE 914
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 915 */
+#if ((915 >= GSL_INCLUDER_FIRST_CASE) && (915 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (915)))
+#define GSL_INCLUDER_CASE 915
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 916 */
+#if ((916 >= GSL_INCLUDER_FIRST_CASE) && (916 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (916)))
+#define GSL_INCLUDER_CASE 916
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 917 */
+#if ((917 >= GSL_INCLUDER_FIRST_CASE) && (917 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (917)))
+#define GSL_INCLUDER_CASE 917
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 918 */
+#if ((918 >= GSL_INCLUDER_FIRST_CASE) && (918 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (918)))
+#define GSL_INCLUDER_CASE 918
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 919 */
+#if ((919 >= GSL_INCLUDER_FIRST_CASE) && (919 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (919)))
+#define GSL_INCLUDER_CASE 919
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 920 */
+#if ((920 >= GSL_INCLUDER_FIRST_CASE) && (920 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (920)))
+#define GSL_INCLUDER_CASE 920
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 921 */
+#if ((921 >= GSL_INCLUDER_FIRST_CASE) && (921 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (921)))
+#define GSL_INCLUDER_CASE 921
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 922 */
+#if ((922 >= GSL_INCLUDER_FIRST_CASE) && (922 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (922)))
+#define GSL_INCLUDER_CASE 922
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 923 */
+#if ((923 >= GSL_INCLUDER_FIRST_CASE) && (923 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (923)))
+#define GSL_INCLUDER_CASE 923
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 924 */
+#if ((924 >= GSL_INCLUDER_FIRST_CASE) && (924 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (924)))
+#define GSL_INCLUDER_CASE 924
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 925 */
+#if ((925 >= GSL_INCLUDER_FIRST_CASE) && (925 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (925)))
+#define GSL_INCLUDER_CASE 925
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 926 */
+#if ((926 >= GSL_INCLUDER_FIRST_CASE) && (926 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (926)))
+#define GSL_INCLUDER_CASE 926
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 927 */
+#if ((927 >= GSL_INCLUDER_FIRST_CASE) && (927 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (927)))
+#define GSL_INCLUDER_CASE 927
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 928 */
+#if ((928 >= GSL_INCLUDER_FIRST_CASE) && (928 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (928)))
+#define GSL_INCLUDER_CASE 928
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 929 */
+#if ((929 >= GSL_INCLUDER_FIRST_CASE) && (929 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (929)))
+#define GSL_INCLUDER_CASE 929
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 930 */
+#if ((930 >= GSL_INCLUDER_FIRST_CASE) && (930 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (930)))
+#define GSL_INCLUDER_CASE 930
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 931 */
+#if ((931 >= GSL_INCLUDER_FIRST_CASE) && (931 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (931)))
+#define GSL_INCLUDER_CASE 931
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 932 */
+#if ((932 >= GSL_INCLUDER_FIRST_CASE) && (932 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (932)))
+#define GSL_INCLUDER_CASE 932
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 933 */
+#if ((933 >= GSL_INCLUDER_FIRST_CASE) && (933 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (933)))
+#define GSL_INCLUDER_CASE 933
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 934 */
+#if ((934 >= GSL_INCLUDER_FIRST_CASE) && (934 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (934)))
+#define GSL_INCLUDER_CASE 934
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 935 */
+#if ((935 >= GSL_INCLUDER_FIRST_CASE) && (935 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (935)))
+#define GSL_INCLUDER_CASE 935
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 936 */
+#if ((936 >= GSL_INCLUDER_FIRST_CASE) && (936 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (936)))
+#define GSL_INCLUDER_CASE 936
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 937 */
+#if ((937 >= GSL_INCLUDER_FIRST_CASE) && (937 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (937)))
+#define GSL_INCLUDER_CASE 937
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 938 */
+#if ((938 >= GSL_INCLUDER_FIRST_CASE) && (938 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (938)))
+#define GSL_INCLUDER_CASE 938
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 939 */
+#if ((939 >= GSL_INCLUDER_FIRST_CASE) && (939 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (939)))
+#define GSL_INCLUDER_CASE 939
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 940 */
+#if ((940 >= GSL_INCLUDER_FIRST_CASE) && (940 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (940)))
+#define GSL_INCLUDER_CASE 940
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 941 */
+#if ((941 >= GSL_INCLUDER_FIRST_CASE) && (941 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (941)))
+#define GSL_INCLUDER_CASE 941
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 942 */
+#if ((942 >= GSL_INCLUDER_FIRST_CASE) && (942 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (942)))
+#define GSL_INCLUDER_CASE 942
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 943 */
+#if ((943 >= GSL_INCLUDER_FIRST_CASE) && (943 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (943)))
+#define GSL_INCLUDER_CASE 943
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 944 */
+#if ((944 >= GSL_INCLUDER_FIRST_CASE) && (944 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (944)))
+#define GSL_INCLUDER_CASE 944
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 945 */
+#if ((945 >= GSL_INCLUDER_FIRST_CASE) && (945 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (945)))
+#define GSL_INCLUDER_CASE 945
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 946 */
+#if ((946 >= GSL_INCLUDER_FIRST_CASE) && (946 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (946)))
+#define GSL_INCLUDER_CASE 946
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 947 */
+#if ((947 >= GSL_INCLUDER_FIRST_CASE) && (947 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (947)))
+#define GSL_INCLUDER_CASE 947
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 948 */
+#if ((948 >= GSL_INCLUDER_FIRST_CASE) && (948 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (948)))
+#define GSL_INCLUDER_CASE 948
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 949 */
+#if ((949 >= GSL_INCLUDER_FIRST_CASE) && (949 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (949)))
+#define GSL_INCLUDER_CASE 949
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 950 */
+#if ((950 >= GSL_INCLUDER_FIRST_CASE) && (950 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (950)))
+#define GSL_INCLUDER_CASE 950
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 951 */
+#if ((951 >= GSL_INCLUDER_FIRST_CASE) && (951 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (951)))
+#define GSL_INCLUDER_CASE 951
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 952 */
+#if ((952 >= GSL_INCLUDER_FIRST_CASE) && (952 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (952)))
+#define GSL_INCLUDER_CASE 952
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 953 */
+#if ((953 >= GSL_INCLUDER_FIRST_CASE) && (953 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (953)))
+#define GSL_INCLUDER_CASE 953
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 954 */
+#if ((954 >= GSL_INCLUDER_FIRST_CASE) && (954 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (954)))
+#define GSL_INCLUDER_CASE 954
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 955 */
+#if ((955 >= GSL_INCLUDER_FIRST_CASE) && (955 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (955)))
+#define GSL_INCLUDER_CASE 955
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 956 */
+#if ((956 >= GSL_INCLUDER_FIRST_CASE) && (956 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (956)))
+#define GSL_INCLUDER_CASE 956
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 957 */
+#if ((957 >= GSL_INCLUDER_FIRST_CASE) && (957 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (957)))
+#define GSL_INCLUDER_CASE 957
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 958 */
+#if ((958 >= GSL_INCLUDER_FIRST_CASE) && (958 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (958)))
+#define GSL_INCLUDER_CASE 958
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 959 */
+#if ((959 >= GSL_INCLUDER_FIRST_CASE) && (959 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (959)))
+#define GSL_INCLUDER_CASE 959
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 960 */
+#if ((960 >= GSL_INCLUDER_FIRST_CASE) && (960 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (960)))
+#define GSL_INCLUDER_CASE 960
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 961 */
+#if ((961 >= GSL_INCLUDER_FIRST_CASE) && (961 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (961)))
+#define GSL_INCLUDER_CASE 961
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 962 */
+#if ((962 >= GSL_INCLUDER_FIRST_CASE) && (962 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (962)))
+#define GSL_INCLUDER_CASE 962
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 963 */
+#if ((963 >= GSL_INCLUDER_FIRST_CASE) && (963 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (963)))
+#define GSL_INCLUDER_CASE 963
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 964 */
+#if ((964 >= GSL_INCLUDER_FIRST_CASE) && (964 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (964)))
+#define GSL_INCLUDER_CASE 964
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 965 */
+#if ((965 >= GSL_INCLUDER_FIRST_CASE) && (965 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (965)))
+#define GSL_INCLUDER_CASE 965
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 966 */
+#if ((966 >= GSL_INCLUDER_FIRST_CASE) && (966 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (966)))
+#define GSL_INCLUDER_CASE 966
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 967 */
+#if ((967 >= GSL_INCLUDER_FIRST_CASE) && (967 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (967)))
+#define GSL_INCLUDER_CASE 967
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 968 */
+#if ((968 >= GSL_INCLUDER_FIRST_CASE) && (968 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (968)))
+#define GSL_INCLUDER_CASE 968
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 969 */
+#if ((969 >= GSL_INCLUDER_FIRST_CASE) && (969 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (969)))
+#define GSL_INCLUDER_CASE 969
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 970 */
+#if ((970 >= GSL_INCLUDER_FIRST_CASE) && (970 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (970)))
+#define GSL_INCLUDER_CASE 970
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 971 */
+#if ((971 >= GSL_INCLUDER_FIRST_CASE) && (971 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (971)))
+#define GSL_INCLUDER_CASE 971
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 972 */
+#if ((972 >= GSL_INCLUDER_FIRST_CASE) && (972 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (972)))
+#define GSL_INCLUDER_CASE 972
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 973 */
+#if ((973 >= GSL_INCLUDER_FIRST_CASE) && (973 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (973)))
+#define GSL_INCLUDER_CASE 973
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 974 */
+#if ((974 >= GSL_INCLUDER_FIRST_CASE) && (974 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (974)))
+#define GSL_INCLUDER_CASE 974
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 975 */
+#if ((975 >= GSL_INCLUDER_FIRST_CASE) && (975 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (975)))
+#define GSL_INCLUDER_CASE 975
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 976 */
+#if ((976 >= GSL_INCLUDER_FIRST_CASE) && (976 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (976)))
+#define GSL_INCLUDER_CASE 976
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 977 */
+#if ((977 >= GSL_INCLUDER_FIRST_CASE) && (977 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (977)))
+#define GSL_INCLUDER_CASE 977
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 978 */
+#if ((978 >= GSL_INCLUDER_FIRST_CASE) && (978 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (978)))
+#define GSL_INCLUDER_CASE 978
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 979 */
+#if ((979 >= GSL_INCLUDER_FIRST_CASE) && (979 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (979)))
+#define GSL_INCLUDER_CASE 979
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 980 */
+#if ((980 >= GSL_INCLUDER_FIRST_CASE) && (980 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (980)))
+#define GSL_INCLUDER_CASE 980
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 981 */
+#if ((981 >= GSL_INCLUDER_FIRST_CASE) && (981 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (981)))
+#define GSL_INCLUDER_CASE 981
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 982 */
+#if ((982 >= GSL_INCLUDER_FIRST_CASE) && (982 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (982)))
+#define GSL_INCLUDER_CASE 982
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 983 */
+#if ((983 >= GSL_INCLUDER_FIRST_CASE) && (983 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (983)))
+#define GSL_INCLUDER_CASE 983
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 984 */
+#if ((984 >= GSL_INCLUDER_FIRST_CASE) && (984 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (984)))
+#define GSL_INCLUDER_CASE 984
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 985 */
+#if ((985 >= GSL_INCLUDER_FIRST_CASE) && (985 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (985)))
+#define GSL_INCLUDER_CASE 985
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 986 */
+#if ((986 >= GSL_INCLUDER_FIRST_CASE) && (986 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (986)))
+#define GSL_INCLUDER_CASE 986
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 987 */
+#if ((987 >= GSL_INCLUDER_FIRST_CASE) && (987 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (987)))
+#define GSL_INCLUDER_CASE 987
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 988 */
+#if ((988 >= GSL_INCLUDER_FIRST_CASE) && (988 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (988)))
+#define GSL_INCLUDER_CASE 988
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 989 */
+#if ((989 >= GSL_INCLUDER_FIRST_CASE) && (989 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (989)))
+#define GSL_INCLUDER_CASE 989
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 990 */
+#if ((990 >= GSL_INCLUDER_FIRST_CASE) && (990 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (990)))
+#define GSL_INCLUDER_CASE 990
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 991 */
+#if ((991 >= GSL_INCLUDER_FIRST_CASE) && (991 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (991)))
+#define GSL_INCLUDER_CASE 991
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 992 */
+#if ((992 >= GSL_INCLUDER_FIRST_CASE) && (992 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (992)))
+#define GSL_INCLUDER_CASE 992
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 993 */
+#if ((993 >= GSL_INCLUDER_FIRST_CASE) && (993 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (993)))
+#define GSL_INCLUDER_CASE 993
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 994 */
+#if ((994 >= GSL_INCLUDER_FIRST_CASE) && (994 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (994)))
+#define GSL_INCLUDER_CASE 994
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 995 */
+#if ((995 >= GSL_INCLUDER_FIRST_CASE) && (995 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (995)))
+#define GSL_INCLUDER_CASE 995
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 996 */
+#if ((996 >= GSL_INCLUDER_FIRST_CASE) && (996 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (996)))
+#define GSL_INCLUDER_CASE 996
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 997 */
+#if ((997 >= GSL_INCLUDER_FIRST_CASE) && (997 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (997)))
+#define GSL_INCLUDER_CASE 997
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 998 */
+#if ((998 >= GSL_INCLUDER_FIRST_CASE) && (998 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (998)))
+#define GSL_INCLUDER_CASE 998
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 999 */
+#if ((999 >= GSL_INCLUDER_FIRST_CASE) && (999 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (999)))
+#define GSL_INCLUDER_CASE 999
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1000 */
+#if ((1000 >= GSL_INCLUDER_FIRST_CASE) && (1000 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1000)))
+#define GSL_INCLUDER_CASE 1000
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1001 */
+#if ((1001 >= GSL_INCLUDER_FIRST_CASE) && (1001 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1001)))
+#define GSL_INCLUDER_CASE 1001
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1002 */
+#if ((1002 >= GSL_INCLUDER_FIRST_CASE) && (1002 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1002)))
+#define GSL_INCLUDER_CASE 1002
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1003 */
+#if ((1003 >= GSL_INCLUDER_FIRST_CASE) && (1003 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1003)))
+#define GSL_INCLUDER_CASE 1003
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1004 */
+#if ((1004 >= GSL_INCLUDER_FIRST_CASE) && (1004 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1004)))
+#define GSL_INCLUDER_CASE 1004
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1005 */
+#if ((1005 >= GSL_INCLUDER_FIRST_CASE) && (1005 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1005)))
+#define GSL_INCLUDER_CASE 1005
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1006 */
+#if ((1006 >= GSL_INCLUDER_FIRST_CASE) && (1006 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1006)))
+#define GSL_INCLUDER_CASE 1006
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1007 */
+#if ((1007 >= GSL_INCLUDER_FIRST_CASE) && (1007 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1007)))
+#define GSL_INCLUDER_CASE 1007
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1008 */
+#if ((1008 >= GSL_INCLUDER_FIRST_CASE) && (1008 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1008)))
+#define GSL_INCLUDER_CASE 1008
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1009 */
+#if ((1009 >= GSL_INCLUDER_FIRST_CASE) && (1009 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1009)))
+#define GSL_INCLUDER_CASE 1009
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1010 */
+#if ((1010 >= GSL_INCLUDER_FIRST_CASE) && (1010 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1010)))
+#define GSL_INCLUDER_CASE 1010
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1011 */
+#if ((1011 >= GSL_INCLUDER_FIRST_CASE) && (1011 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1011)))
+#define GSL_INCLUDER_CASE 1011
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1012 */
+#if ((1012 >= GSL_INCLUDER_FIRST_CASE) && (1012 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1012)))
+#define GSL_INCLUDER_CASE 1012
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1013 */
+#if ((1013 >= GSL_INCLUDER_FIRST_CASE) && (1013 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1013)))
+#define GSL_INCLUDER_CASE 1013
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1014 */
+#if ((1014 >= GSL_INCLUDER_FIRST_CASE) && (1014 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1014)))
+#define GSL_INCLUDER_CASE 1014
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1015 */
+#if ((1015 >= GSL_INCLUDER_FIRST_CASE) && (1015 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1015)))
+#define GSL_INCLUDER_CASE 1015
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1016 */
+#if ((1016 >= GSL_INCLUDER_FIRST_CASE) && (1016 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1016)))
+#define GSL_INCLUDER_CASE 1016
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1017 */
+#if ((1017 >= GSL_INCLUDER_FIRST_CASE) && (1017 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1017)))
+#define GSL_INCLUDER_CASE 1017
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1018 */
+#if ((1018 >= GSL_INCLUDER_FIRST_CASE) && (1018 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1018)))
+#define GSL_INCLUDER_CASE 1018
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1019 */
+#if ((1019 >= GSL_INCLUDER_FIRST_CASE) && (1019 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1019)))
+#define GSL_INCLUDER_CASE 1019
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1020 */
+#if ((1020 >= GSL_INCLUDER_FIRST_CASE) && (1020 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1020)))
+#define GSL_INCLUDER_CASE 1020
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1021 */
+#if ((1021 >= GSL_INCLUDER_FIRST_CASE) && (1021 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1021)))
+#define GSL_INCLUDER_CASE 1021
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1022 */
+#if ((1022 >= GSL_INCLUDER_FIRST_CASE) && (1022 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1022)))
+#define GSL_INCLUDER_CASE 1022
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1023 */
+#if ((1023 >= GSL_INCLUDER_FIRST_CASE) && (1023 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1023)))
+#define GSL_INCLUDER_CASE 1023
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+/* 1024 */
+#if ((1024 >= GSL_INCLUDER_FIRST_CASE) && (1024 <= GSL_INCLUDER_LAST_CASE) && !(GSL_INCLUDER_REJECT (1024)))
+#define GSL_INCLUDER_CASE 1024
+#include GSL_INCLUDER_FILE
+#undef GSL_INCLUDER_CASE
+#endif
+
+GSL_INCLUDER_TABLE = {
+#if ((0 >= GSL_INCLUDER_FIRST_CASE) && (0 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (0))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 0),
+#endif
+#endif
+#if ((1 >= GSL_INCLUDER_FIRST_CASE) && (1 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1),
+#endif
+#endif
+#if ((2 >= GSL_INCLUDER_FIRST_CASE) && (2 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (2))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 2),
+#endif
+#endif
+#if ((3 >= GSL_INCLUDER_FIRST_CASE) && (3 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (3))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 3),
+#endif
+#endif
+#if ((4 >= GSL_INCLUDER_FIRST_CASE) && (4 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (4))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 4),
+#endif
+#endif
+#if ((5 >= GSL_INCLUDER_FIRST_CASE) && (5 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (5))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 5),
+#endif
+#endif
+#if ((6 >= GSL_INCLUDER_FIRST_CASE) && (6 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (6))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 6),
+#endif
+#endif
+#if ((7 >= GSL_INCLUDER_FIRST_CASE) && (7 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (7))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 7),
+#endif
+#endif
+#if ((8 >= GSL_INCLUDER_FIRST_CASE) && (8 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (8))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 8),
+#endif
+#endif
+#if ((9 >= GSL_INCLUDER_FIRST_CASE) && (9 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (9))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 9),
+#endif
+#endif
+#if ((10 >= GSL_INCLUDER_FIRST_CASE) && (10 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (10))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 10),
+#endif
+#endif
+#if ((11 >= GSL_INCLUDER_FIRST_CASE) && (11 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (11))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 11),
+#endif
+#endif
+#if ((12 >= GSL_INCLUDER_FIRST_CASE) && (12 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (12))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 12),
+#endif
+#endif
+#if ((13 >= GSL_INCLUDER_FIRST_CASE) && (13 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (13))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 13),
+#endif
+#endif
+#if ((14 >= GSL_INCLUDER_FIRST_CASE) && (14 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (14))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 14),
+#endif
+#endif
+#if ((15 >= GSL_INCLUDER_FIRST_CASE) && (15 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (15))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 15),
+#endif
+#endif
+#if ((16 >= GSL_INCLUDER_FIRST_CASE) && (16 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (16))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 16),
+#endif
+#endif
+#if ((17 >= GSL_INCLUDER_FIRST_CASE) && (17 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (17))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 17),
+#endif
+#endif
+#if ((18 >= GSL_INCLUDER_FIRST_CASE) && (18 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (18))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 18),
+#endif
+#endif
+#if ((19 >= GSL_INCLUDER_FIRST_CASE) && (19 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (19))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 19),
+#endif
+#endif
+#if ((20 >= GSL_INCLUDER_FIRST_CASE) && (20 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (20))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 20),
+#endif
+#endif
+#if ((21 >= GSL_INCLUDER_FIRST_CASE) && (21 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (21))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 21),
+#endif
+#endif
+#if ((22 >= GSL_INCLUDER_FIRST_CASE) && (22 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (22))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 22),
+#endif
+#endif
+#if ((23 >= GSL_INCLUDER_FIRST_CASE) && (23 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (23))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 23),
+#endif
+#endif
+#if ((24 >= GSL_INCLUDER_FIRST_CASE) && (24 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (24))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 24),
+#endif
+#endif
+#if ((25 >= GSL_INCLUDER_FIRST_CASE) && (25 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (25))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 25),
+#endif
+#endif
+#if ((26 >= GSL_INCLUDER_FIRST_CASE) && (26 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (26))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 26),
+#endif
+#endif
+#if ((27 >= GSL_INCLUDER_FIRST_CASE) && (27 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (27))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 27),
+#endif
+#endif
+#if ((28 >= GSL_INCLUDER_FIRST_CASE) && (28 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (28))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 28),
+#endif
+#endif
+#if ((29 >= GSL_INCLUDER_FIRST_CASE) && (29 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (29))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 29),
+#endif
+#endif
+#if ((30 >= GSL_INCLUDER_FIRST_CASE) && (30 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (30))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 30),
+#endif
+#endif
+#if ((31 >= GSL_INCLUDER_FIRST_CASE) && (31 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (31))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 31),
+#endif
+#endif
+#if ((32 >= GSL_INCLUDER_FIRST_CASE) && (32 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (32))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 32),
+#endif
+#endif
+#if ((33 >= GSL_INCLUDER_FIRST_CASE) && (33 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (33))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 33),
+#endif
+#endif
+#if ((34 >= GSL_INCLUDER_FIRST_CASE) && (34 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (34))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 34),
+#endif
+#endif
+#if ((35 >= GSL_INCLUDER_FIRST_CASE) && (35 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (35))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 35),
+#endif
+#endif
+#if ((36 >= GSL_INCLUDER_FIRST_CASE) && (36 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (36))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 36),
+#endif
+#endif
+#if ((37 >= GSL_INCLUDER_FIRST_CASE) && (37 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (37))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 37),
+#endif
+#endif
+#if ((38 >= GSL_INCLUDER_FIRST_CASE) && (38 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (38))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 38),
+#endif
+#endif
+#if ((39 >= GSL_INCLUDER_FIRST_CASE) && (39 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (39))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 39),
+#endif
+#endif
+#if ((40 >= GSL_INCLUDER_FIRST_CASE) && (40 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (40))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 40),
+#endif
+#endif
+#if ((41 >= GSL_INCLUDER_FIRST_CASE) && (41 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (41))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 41),
+#endif
+#endif
+#if ((42 >= GSL_INCLUDER_FIRST_CASE) && (42 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (42))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 42),
+#endif
+#endif
+#if ((43 >= GSL_INCLUDER_FIRST_CASE) && (43 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (43))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 43),
+#endif
+#endif
+#if ((44 >= GSL_INCLUDER_FIRST_CASE) && (44 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (44))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 44),
+#endif
+#endif
+#if ((45 >= GSL_INCLUDER_FIRST_CASE) && (45 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (45))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 45),
+#endif
+#endif
+#if ((46 >= GSL_INCLUDER_FIRST_CASE) && (46 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (46))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 46),
+#endif
+#endif
+#if ((47 >= GSL_INCLUDER_FIRST_CASE) && (47 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (47))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 47),
+#endif
+#endif
+#if ((48 >= GSL_INCLUDER_FIRST_CASE) && (48 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (48))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 48),
+#endif
+#endif
+#if ((49 >= GSL_INCLUDER_FIRST_CASE) && (49 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (49))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 49),
+#endif
+#endif
+#if ((50 >= GSL_INCLUDER_FIRST_CASE) && (50 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (50))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 50),
+#endif
+#endif
+#if ((51 >= GSL_INCLUDER_FIRST_CASE) && (51 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (51))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 51),
+#endif
+#endif
+#if ((52 >= GSL_INCLUDER_FIRST_CASE) && (52 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (52))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 52),
+#endif
+#endif
+#if ((53 >= GSL_INCLUDER_FIRST_CASE) && (53 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (53))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 53),
+#endif
+#endif
+#if ((54 >= GSL_INCLUDER_FIRST_CASE) && (54 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (54))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 54),
+#endif
+#endif
+#if ((55 >= GSL_INCLUDER_FIRST_CASE) && (55 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (55))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 55),
+#endif
+#endif
+#if ((56 >= GSL_INCLUDER_FIRST_CASE) && (56 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (56))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 56),
+#endif
+#endif
+#if ((57 >= GSL_INCLUDER_FIRST_CASE) && (57 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (57))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 57),
+#endif
+#endif
+#if ((58 >= GSL_INCLUDER_FIRST_CASE) && (58 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (58))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 58),
+#endif
+#endif
+#if ((59 >= GSL_INCLUDER_FIRST_CASE) && (59 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (59))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 59),
+#endif
+#endif
+#if ((60 >= GSL_INCLUDER_FIRST_CASE) && (60 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (60))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 60),
+#endif
+#endif
+#if ((61 >= GSL_INCLUDER_FIRST_CASE) && (61 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (61))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 61),
+#endif
+#endif
+#if ((62 >= GSL_INCLUDER_FIRST_CASE) && (62 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (62))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 62),
+#endif
+#endif
+#if ((63 >= GSL_INCLUDER_FIRST_CASE) && (63 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (63))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 63),
+#endif
+#endif
+#if ((64 >= GSL_INCLUDER_FIRST_CASE) && (64 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (64))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 64),
+#endif
+#endif
+#if ((65 >= GSL_INCLUDER_FIRST_CASE) && (65 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (65))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 65),
+#endif
+#endif
+#if ((66 >= GSL_INCLUDER_FIRST_CASE) && (66 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (66))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 66),
+#endif
+#endif
+#if ((67 >= GSL_INCLUDER_FIRST_CASE) && (67 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (67))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 67),
+#endif
+#endif
+#if ((68 >= GSL_INCLUDER_FIRST_CASE) && (68 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (68))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 68),
+#endif
+#endif
+#if ((69 >= GSL_INCLUDER_FIRST_CASE) && (69 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (69))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 69),
+#endif
+#endif
+#if ((70 >= GSL_INCLUDER_FIRST_CASE) && (70 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (70))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 70),
+#endif
+#endif
+#if ((71 >= GSL_INCLUDER_FIRST_CASE) && (71 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (71))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 71),
+#endif
+#endif
+#if ((72 >= GSL_INCLUDER_FIRST_CASE) && (72 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (72))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 72),
+#endif
+#endif
+#if ((73 >= GSL_INCLUDER_FIRST_CASE) && (73 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (73))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 73),
+#endif
+#endif
+#if ((74 >= GSL_INCLUDER_FIRST_CASE) && (74 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (74))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 74),
+#endif
+#endif
+#if ((75 >= GSL_INCLUDER_FIRST_CASE) && (75 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (75))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 75),
+#endif
+#endif
+#if ((76 >= GSL_INCLUDER_FIRST_CASE) && (76 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (76))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 76),
+#endif
+#endif
+#if ((77 >= GSL_INCLUDER_FIRST_CASE) && (77 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (77))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 77),
+#endif
+#endif
+#if ((78 >= GSL_INCLUDER_FIRST_CASE) && (78 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (78))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 78),
+#endif
+#endif
+#if ((79 >= GSL_INCLUDER_FIRST_CASE) && (79 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (79))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 79),
+#endif
+#endif
+#if ((80 >= GSL_INCLUDER_FIRST_CASE) && (80 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (80))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 80),
+#endif
+#endif
+#if ((81 >= GSL_INCLUDER_FIRST_CASE) && (81 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (81))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 81),
+#endif
+#endif
+#if ((82 >= GSL_INCLUDER_FIRST_CASE) && (82 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (82))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 82),
+#endif
+#endif
+#if ((83 >= GSL_INCLUDER_FIRST_CASE) && (83 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (83))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 83),
+#endif
+#endif
+#if ((84 >= GSL_INCLUDER_FIRST_CASE) && (84 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (84))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 84),
+#endif
+#endif
+#if ((85 >= GSL_INCLUDER_FIRST_CASE) && (85 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (85))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 85),
+#endif
+#endif
+#if ((86 >= GSL_INCLUDER_FIRST_CASE) && (86 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (86))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 86),
+#endif
+#endif
+#if ((87 >= GSL_INCLUDER_FIRST_CASE) && (87 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (87))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 87),
+#endif
+#endif
+#if ((88 >= GSL_INCLUDER_FIRST_CASE) && (88 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (88))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 88),
+#endif
+#endif
+#if ((89 >= GSL_INCLUDER_FIRST_CASE) && (89 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (89))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 89),
+#endif
+#endif
+#if ((90 >= GSL_INCLUDER_FIRST_CASE) && (90 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (90))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 90),
+#endif
+#endif
+#if ((91 >= GSL_INCLUDER_FIRST_CASE) && (91 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (91))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 91),
+#endif
+#endif
+#if ((92 >= GSL_INCLUDER_FIRST_CASE) && (92 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (92))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 92),
+#endif
+#endif
+#if ((93 >= GSL_INCLUDER_FIRST_CASE) && (93 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (93))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 93),
+#endif
+#endif
+#if ((94 >= GSL_INCLUDER_FIRST_CASE) && (94 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (94))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 94),
+#endif
+#endif
+#if ((95 >= GSL_INCLUDER_FIRST_CASE) && (95 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (95))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 95),
+#endif
+#endif
+#if ((96 >= GSL_INCLUDER_FIRST_CASE) && (96 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (96))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 96),
+#endif
+#endif
+#if ((97 >= GSL_INCLUDER_FIRST_CASE) && (97 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (97))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 97),
+#endif
+#endif
+#if ((98 >= GSL_INCLUDER_FIRST_CASE) && (98 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (98))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 98),
+#endif
+#endif
+#if ((99 >= GSL_INCLUDER_FIRST_CASE) && (99 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (99))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 99),
+#endif
+#endif
+#if ((100 >= GSL_INCLUDER_FIRST_CASE) && (100 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (100))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 100),
+#endif
+#endif
+#if ((101 >= GSL_INCLUDER_FIRST_CASE) && (101 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (101))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 101),
+#endif
+#endif
+#if ((102 >= GSL_INCLUDER_FIRST_CASE) && (102 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (102))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 102),
+#endif
+#endif
+#if ((103 >= GSL_INCLUDER_FIRST_CASE) && (103 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (103))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 103),
+#endif
+#endif
+#if ((104 >= GSL_INCLUDER_FIRST_CASE) && (104 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (104))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 104),
+#endif
+#endif
+#if ((105 >= GSL_INCLUDER_FIRST_CASE) && (105 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (105))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 105),
+#endif
+#endif
+#if ((106 >= GSL_INCLUDER_FIRST_CASE) && (106 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (106))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 106),
+#endif
+#endif
+#if ((107 >= GSL_INCLUDER_FIRST_CASE) && (107 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (107))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 107),
+#endif
+#endif
+#if ((108 >= GSL_INCLUDER_FIRST_CASE) && (108 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (108))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 108),
+#endif
+#endif
+#if ((109 >= GSL_INCLUDER_FIRST_CASE) && (109 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (109))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 109),
+#endif
+#endif
+#if ((110 >= GSL_INCLUDER_FIRST_CASE) && (110 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (110))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 110),
+#endif
+#endif
+#if ((111 >= GSL_INCLUDER_FIRST_CASE) && (111 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (111))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 111),
+#endif
+#endif
+#if ((112 >= GSL_INCLUDER_FIRST_CASE) && (112 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (112))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 112),
+#endif
+#endif
+#if ((113 >= GSL_INCLUDER_FIRST_CASE) && (113 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (113))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 113),
+#endif
+#endif
+#if ((114 >= GSL_INCLUDER_FIRST_CASE) && (114 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (114))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 114),
+#endif
+#endif
+#if ((115 >= GSL_INCLUDER_FIRST_CASE) && (115 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (115))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 115),
+#endif
+#endif
+#if ((116 >= GSL_INCLUDER_FIRST_CASE) && (116 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (116))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 116),
+#endif
+#endif
+#if ((117 >= GSL_INCLUDER_FIRST_CASE) && (117 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (117))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 117),
+#endif
+#endif
+#if ((118 >= GSL_INCLUDER_FIRST_CASE) && (118 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (118))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 118),
+#endif
+#endif
+#if ((119 >= GSL_INCLUDER_FIRST_CASE) && (119 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (119))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 119),
+#endif
+#endif
+#if ((120 >= GSL_INCLUDER_FIRST_CASE) && (120 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (120))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 120),
+#endif
+#endif
+#if ((121 >= GSL_INCLUDER_FIRST_CASE) && (121 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (121))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 121),
+#endif
+#endif
+#if ((122 >= GSL_INCLUDER_FIRST_CASE) && (122 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (122))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 122),
+#endif
+#endif
+#if ((123 >= GSL_INCLUDER_FIRST_CASE) && (123 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (123))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 123),
+#endif
+#endif
+#if ((124 >= GSL_INCLUDER_FIRST_CASE) && (124 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (124))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 124),
+#endif
+#endif
+#if ((125 >= GSL_INCLUDER_FIRST_CASE) && (125 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (125))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 125),
+#endif
+#endif
+#if ((126 >= GSL_INCLUDER_FIRST_CASE) && (126 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (126))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 126),
+#endif
+#endif
+#if ((127 >= GSL_INCLUDER_FIRST_CASE) && (127 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (127))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 127),
+#endif
+#endif
+#if ((128 >= GSL_INCLUDER_FIRST_CASE) && (128 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (128))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 128),
+#endif
+#endif
+#if ((129 >= GSL_INCLUDER_FIRST_CASE) && (129 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (129))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 129),
+#endif
+#endif
+#if ((130 >= GSL_INCLUDER_FIRST_CASE) && (130 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (130))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 130),
+#endif
+#endif
+#if ((131 >= GSL_INCLUDER_FIRST_CASE) && (131 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (131))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 131),
+#endif
+#endif
+#if ((132 >= GSL_INCLUDER_FIRST_CASE) && (132 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (132))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 132),
+#endif
+#endif
+#if ((133 >= GSL_INCLUDER_FIRST_CASE) && (133 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (133))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 133),
+#endif
+#endif
+#if ((134 >= GSL_INCLUDER_FIRST_CASE) && (134 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (134))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 134),
+#endif
+#endif
+#if ((135 >= GSL_INCLUDER_FIRST_CASE) && (135 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (135))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 135),
+#endif
+#endif
+#if ((136 >= GSL_INCLUDER_FIRST_CASE) && (136 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (136))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 136),
+#endif
+#endif
+#if ((137 >= GSL_INCLUDER_FIRST_CASE) && (137 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (137))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 137),
+#endif
+#endif
+#if ((138 >= GSL_INCLUDER_FIRST_CASE) && (138 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (138))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 138),
+#endif
+#endif
+#if ((139 >= GSL_INCLUDER_FIRST_CASE) && (139 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (139))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 139),
+#endif
+#endif
+#if ((140 >= GSL_INCLUDER_FIRST_CASE) && (140 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (140))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 140),
+#endif
+#endif
+#if ((141 >= GSL_INCLUDER_FIRST_CASE) && (141 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (141))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 141),
+#endif
+#endif
+#if ((142 >= GSL_INCLUDER_FIRST_CASE) && (142 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (142))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 142),
+#endif
+#endif
+#if ((143 >= GSL_INCLUDER_FIRST_CASE) && (143 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (143))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 143),
+#endif
+#endif
+#if ((144 >= GSL_INCLUDER_FIRST_CASE) && (144 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (144))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 144),
+#endif
+#endif
+#if ((145 >= GSL_INCLUDER_FIRST_CASE) && (145 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (145))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 145),
+#endif
+#endif
+#if ((146 >= GSL_INCLUDER_FIRST_CASE) && (146 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (146))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 146),
+#endif
+#endif
+#if ((147 >= GSL_INCLUDER_FIRST_CASE) && (147 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (147))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 147),
+#endif
+#endif
+#if ((148 >= GSL_INCLUDER_FIRST_CASE) && (148 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (148))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 148),
+#endif
+#endif
+#if ((149 >= GSL_INCLUDER_FIRST_CASE) && (149 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (149))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 149),
+#endif
+#endif
+#if ((150 >= GSL_INCLUDER_FIRST_CASE) && (150 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (150))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 150),
+#endif
+#endif
+#if ((151 >= GSL_INCLUDER_FIRST_CASE) && (151 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (151))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 151),
+#endif
+#endif
+#if ((152 >= GSL_INCLUDER_FIRST_CASE) && (152 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (152))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 152),
+#endif
+#endif
+#if ((153 >= GSL_INCLUDER_FIRST_CASE) && (153 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (153))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 153),
+#endif
+#endif
+#if ((154 >= GSL_INCLUDER_FIRST_CASE) && (154 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (154))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 154),
+#endif
+#endif
+#if ((155 >= GSL_INCLUDER_FIRST_CASE) && (155 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (155))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 155),
+#endif
+#endif
+#if ((156 >= GSL_INCLUDER_FIRST_CASE) && (156 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (156))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 156),
+#endif
+#endif
+#if ((157 >= GSL_INCLUDER_FIRST_CASE) && (157 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (157))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 157),
+#endif
+#endif
+#if ((158 >= GSL_INCLUDER_FIRST_CASE) && (158 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (158))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 158),
+#endif
+#endif
+#if ((159 >= GSL_INCLUDER_FIRST_CASE) && (159 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (159))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 159),
+#endif
+#endif
+#if ((160 >= GSL_INCLUDER_FIRST_CASE) && (160 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (160))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 160),
+#endif
+#endif
+#if ((161 >= GSL_INCLUDER_FIRST_CASE) && (161 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (161))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 161),
+#endif
+#endif
+#if ((162 >= GSL_INCLUDER_FIRST_CASE) && (162 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (162))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 162),
+#endif
+#endif
+#if ((163 >= GSL_INCLUDER_FIRST_CASE) && (163 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (163))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 163),
+#endif
+#endif
+#if ((164 >= GSL_INCLUDER_FIRST_CASE) && (164 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (164))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 164),
+#endif
+#endif
+#if ((165 >= GSL_INCLUDER_FIRST_CASE) && (165 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (165))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 165),
+#endif
+#endif
+#if ((166 >= GSL_INCLUDER_FIRST_CASE) && (166 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (166))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 166),
+#endif
+#endif
+#if ((167 >= GSL_INCLUDER_FIRST_CASE) && (167 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (167))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 167),
+#endif
+#endif
+#if ((168 >= GSL_INCLUDER_FIRST_CASE) && (168 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (168))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 168),
+#endif
+#endif
+#if ((169 >= GSL_INCLUDER_FIRST_CASE) && (169 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (169))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 169),
+#endif
+#endif
+#if ((170 >= GSL_INCLUDER_FIRST_CASE) && (170 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (170))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 170),
+#endif
+#endif
+#if ((171 >= GSL_INCLUDER_FIRST_CASE) && (171 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (171))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 171),
+#endif
+#endif
+#if ((172 >= GSL_INCLUDER_FIRST_CASE) && (172 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (172))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 172),
+#endif
+#endif
+#if ((173 >= GSL_INCLUDER_FIRST_CASE) && (173 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (173))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 173),
+#endif
+#endif
+#if ((174 >= GSL_INCLUDER_FIRST_CASE) && (174 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (174))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 174),
+#endif
+#endif
+#if ((175 >= GSL_INCLUDER_FIRST_CASE) && (175 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (175))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 175),
+#endif
+#endif
+#if ((176 >= GSL_INCLUDER_FIRST_CASE) && (176 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (176))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 176),
+#endif
+#endif
+#if ((177 >= GSL_INCLUDER_FIRST_CASE) && (177 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (177))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 177),
+#endif
+#endif
+#if ((178 >= GSL_INCLUDER_FIRST_CASE) && (178 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (178))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 178),
+#endif
+#endif
+#if ((179 >= GSL_INCLUDER_FIRST_CASE) && (179 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (179))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 179),
+#endif
+#endif
+#if ((180 >= GSL_INCLUDER_FIRST_CASE) && (180 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (180))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 180),
+#endif
+#endif
+#if ((181 >= GSL_INCLUDER_FIRST_CASE) && (181 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (181))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 181),
+#endif
+#endif
+#if ((182 >= GSL_INCLUDER_FIRST_CASE) && (182 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (182))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 182),
+#endif
+#endif
+#if ((183 >= GSL_INCLUDER_FIRST_CASE) && (183 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (183))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 183),
+#endif
+#endif
+#if ((184 >= GSL_INCLUDER_FIRST_CASE) && (184 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (184))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 184),
+#endif
+#endif
+#if ((185 >= GSL_INCLUDER_FIRST_CASE) && (185 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (185))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 185),
+#endif
+#endif
+#if ((186 >= GSL_INCLUDER_FIRST_CASE) && (186 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (186))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 186),
+#endif
+#endif
+#if ((187 >= GSL_INCLUDER_FIRST_CASE) && (187 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (187))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 187),
+#endif
+#endif
+#if ((188 >= GSL_INCLUDER_FIRST_CASE) && (188 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (188))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 188),
+#endif
+#endif
+#if ((189 >= GSL_INCLUDER_FIRST_CASE) && (189 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (189))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 189),
+#endif
+#endif
+#if ((190 >= GSL_INCLUDER_FIRST_CASE) && (190 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (190))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 190),
+#endif
+#endif
+#if ((191 >= GSL_INCLUDER_FIRST_CASE) && (191 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (191))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 191),
+#endif
+#endif
+#if ((192 >= GSL_INCLUDER_FIRST_CASE) && (192 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (192))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 192),
+#endif
+#endif
+#if ((193 >= GSL_INCLUDER_FIRST_CASE) && (193 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (193))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 193),
+#endif
+#endif
+#if ((194 >= GSL_INCLUDER_FIRST_CASE) && (194 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (194))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 194),
+#endif
+#endif
+#if ((195 >= GSL_INCLUDER_FIRST_CASE) && (195 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (195))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 195),
+#endif
+#endif
+#if ((196 >= GSL_INCLUDER_FIRST_CASE) && (196 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (196))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 196),
+#endif
+#endif
+#if ((197 >= GSL_INCLUDER_FIRST_CASE) && (197 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (197))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 197),
+#endif
+#endif
+#if ((198 >= GSL_INCLUDER_FIRST_CASE) && (198 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (198))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 198),
+#endif
+#endif
+#if ((199 >= GSL_INCLUDER_FIRST_CASE) && (199 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (199))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 199),
+#endif
+#endif
+#if ((200 >= GSL_INCLUDER_FIRST_CASE) && (200 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (200))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 200),
+#endif
+#endif
+#if ((201 >= GSL_INCLUDER_FIRST_CASE) && (201 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (201))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 201),
+#endif
+#endif
+#if ((202 >= GSL_INCLUDER_FIRST_CASE) && (202 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (202))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 202),
+#endif
+#endif
+#if ((203 >= GSL_INCLUDER_FIRST_CASE) && (203 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (203))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 203),
+#endif
+#endif
+#if ((204 >= GSL_INCLUDER_FIRST_CASE) && (204 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (204))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 204),
+#endif
+#endif
+#if ((205 >= GSL_INCLUDER_FIRST_CASE) && (205 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (205))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 205),
+#endif
+#endif
+#if ((206 >= GSL_INCLUDER_FIRST_CASE) && (206 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (206))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 206),
+#endif
+#endif
+#if ((207 >= GSL_INCLUDER_FIRST_CASE) && (207 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (207))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 207),
+#endif
+#endif
+#if ((208 >= GSL_INCLUDER_FIRST_CASE) && (208 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (208))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 208),
+#endif
+#endif
+#if ((209 >= GSL_INCLUDER_FIRST_CASE) && (209 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (209))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 209),
+#endif
+#endif
+#if ((210 >= GSL_INCLUDER_FIRST_CASE) && (210 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (210))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 210),
+#endif
+#endif
+#if ((211 >= GSL_INCLUDER_FIRST_CASE) && (211 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (211))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 211),
+#endif
+#endif
+#if ((212 >= GSL_INCLUDER_FIRST_CASE) && (212 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (212))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 212),
+#endif
+#endif
+#if ((213 >= GSL_INCLUDER_FIRST_CASE) && (213 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (213))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 213),
+#endif
+#endif
+#if ((214 >= GSL_INCLUDER_FIRST_CASE) && (214 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (214))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 214),
+#endif
+#endif
+#if ((215 >= GSL_INCLUDER_FIRST_CASE) && (215 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (215))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 215),
+#endif
+#endif
+#if ((216 >= GSL_INCLUDER_FIRST_CASE) && (216 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (216))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 216),
+#endif
+#endif
+#if ((217 >= GSL_INCLUDER_FIRST_CASE) && (217 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (217))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 217),
+#endif
+#endif
+#if ((218 >= GSL_INCLUDER_FIRST_CASE) && (218 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (218))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 218),
+#endif
+#endif
+#if ((219 >= GSL_INCLUDER_FIRST_CASE) && (219 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (219))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 219),
+#endif
+#endif
+#if ((220 >= GSL_INCLUDER_FIRST_CASE) && (220 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (220))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 220),
+#endif
+#endif
+#if ((221 >= GSL_INCLUDER_FIRST_CASE) && (221 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (221))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 221),
+#endif
+#endif
+#if ((222 >= GSL_INCLUDER_FIRST_CASE) && (222 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (222))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 222),
+#endif
+#endif
+#if ((223 >= GSL_INCLUDER_FIRST_CASE) && (223 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (223))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 223),
+#endif
+#endif
+#if ((224 >= GSL_INCLUDER_FIRST_CASE) && (224 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (224))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 224),
+#endif
+#endif
+#if ((225 >= GSL_INCLUDER_FIRST_CASE) && (225 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (225))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 225),
+#endif
+#endif
+#if ((226 >= GSL_INCLUDER_FIRST_CASE) && (226 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (226))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 226),
+#endif
+#endif
+#if ((227 >= GSL_INCLUDER_FIRST_CASE) && (227 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (227))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 227),
+#endif
+#endif
+#if ((228 >= GSL_INCLUDER_FIRST_CASE) && (228 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (228))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 228),
+#endif
+#endif
+#if ((229 >= GSL_INCLUDER_FIRST_CASE) && (229 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (229))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 229),
+#endif
+#endif
+#if ((230 >= GSL_INCLUDER_FIRST_CASE) && (230 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (230))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 230),
+#endif
+#endif
+#if ((231 >= GSL_INCLUDER_FIRST_CASE) && (231 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (231))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 231),
+#endif
+#endif
+#if ((232 >= GSL_INCLUDER_FIRST_CASE) && (232 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (232))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 232),
+#endif
+#endif
+#if ((233 >= GSL_INCLUDER_FIRST_CASE) && (233 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (233))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 233),
+#endif
+#endif
+#if ((234 >= GSL_INCLUDER_FIRST_CASE) && (234 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (234))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 234),
+#endif
+#endif
+#if ((235 >= GSL_INCLUDER_FIRST_CASE) && (235 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (235))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 235),
+#endif
+#endif
+#if ((236 >= GSL_INCLUDER_FIRST_CASE) && (236 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (236))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 236),
+#endif
+#endif
+#if ((237 >= GSL_INCLUDER_FIRST_CASE) && (237 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (237))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 237),
+#endif
+#endif
+#if ((238 >= GSL_INCLUDER_FIRST_CASE) && (238 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (238))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 238),
+#endif
+#endif
+#if ((239 >= GSL_INCLUDER_FIRST_CASE) && (239 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (239))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 239),
+#endif
+#endif
+#if ((240 >= GSL_INCLUDER_FIRST_CASE) && (240 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (240))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 240),
+#endif
+#endif
+#if ((241 >= GSL_INCLUDER_FIRST_CASE) && (241 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (241))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 241),
+#endif
+#endif
+#if ((242 >= GSL_INCLUDER_FIRST_CASE) && (242 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (242))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 242),
+#endif
+#endif
+#if ((243 >= GSL_INCLUDER_FIRST_CASE) && (243 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (243))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 243),
+#endif
+#endif
+#if ((244 >= GSL_INCLUDER_FIRST_CASE) && (244 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (244))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 244),
+#endif
+#endif
+#if ((245 >= GSL_INCLUDER_FIRST_CASE) && (245 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (245))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 245),
+#endif
+#endif
+#if ((246 >= GSL_INCLUDER_FIRST_CASE) && (246 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (246))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 246),
+#endif
+#endif
+#if ((247 >= GSL_INCLUDER_FIRST_CASE) && (247 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (247))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 247),
+#endif
+#endif
+#if ((248 >= GSL_INCLUDER_FIRST_CASE) && (248 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (248))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 248),
+#endif
+#endif
+#if ((249 >= GSL_INCLUDER_FIRST_CASE) && (249 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (249))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 249),
+#endif
+#endif
+#if ((250 >= GSL_INCLUDER_FIRST_CASE) && (250 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (250))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 250),
+#endif
+#endif
+#if ((251 >= GSL_INCLUDER_FIRST_CASE) && (251 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (251))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 251),
+#endif
+#endif
+#if ((252 >= GSL_INCLUDER_FIRST_CASE) && (252 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (252))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 252),
+#endif
+#endif
+#if ((253 >= GSL_INCLUDER_FIRST_CASE) && (253 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (253))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 253),
+#endif
+#endif
+#if ((254 >= GSL_INCLUDER_FIRST_CASE) && (254 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (254))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 254),
+#endif
+#endif
+#if ((255 >= GSL_INCLUDER_FIRST_CASE) && (255 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (255))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 255),
+#endif
+#endif
+#if ((256 >= GSL_INCLUDER_FIRST_CASE) && (256 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (256))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 256),
+#endif
+#endif
+#if ((257 >= GSL_INCLUDER_FIRST_CASE) && (257 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (257))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 257),
+#endif
+#endif
+#if ((258 >= GSL_INCLUDER_FIRST_CASE) && (258 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (258))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 258),
+#endif
+#endif
+#if ((259 >= GSL_INCLUDER_FIRST_CASE) && (259 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (259))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 259),
+#endif
+#endif
+#if ((260 >= GSL_INCLUDER_FIRST_CASE) && (260 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (260))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 260),
+#endif
+#endif
+#if ((261 >= GSL_INCLUDER_FIRST_CASE) && (261 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (261))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 261),
+#endif
+#endif
+#if ((262 >= GSL_INCLUDER_FIRST_CASE) && (262 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (262))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 262),
+#endif
+#endif
+#if ((263 >= GSL_INCLUDER_FIRST_CASE) && (263 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (263))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 263),
+#endif
+#endif
+#if ((264 >= GSL_INCLUDER_FIRST_CASE) && (264 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (264))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 264),
+#endif
+#endif
+#if ((265 >= GSL_INCLUDER_FIRST_CASE) && (265 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (265))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 265),
+#endif
+#endif
+#if ((266 >= GSL_INCLUDER_FIRST_CASE) && (266 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (266))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 266),
+#endif
+#endif
+#if ((267 >= GSL_INCLUDER_FIRST_CASE) && (267 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (267))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 267),
+#endif
+#endif
+#if ((268 >= GSL_INCLUDER_FIRST_CASE) && (268 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (268))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 268),
+#endif
+#endif
+#if ((269 >= GSL_INCLUDER_FIRST_CASE) && (269 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (269))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 269),
+#endif
+#endif
+#if ((270 >= GSL_INCLUDER_FIRST_CASE) && (270 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (270))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 270),
+#endif
+#endif
+#if ((271 >= GSL_INCLUDER_FIRST_CASE) && (271 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (271))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 271),
+#endif
+#endif
+#if ((272 >= GSL_INCLUDER_FIRST_CASE) && (272 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (272))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 272),
+#endif
+#endif
+#if ((273 >= GSL_INCLUDER_FIRST_CASE) && (273 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (273))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 273),
+#endif
+#endif
+#if ((274 >= GSL_INCLUDER_FIRST_CASE) && (274 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (274))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 274),
+#endif
+#endif
+#if ((275 >= GSL_INCLUDER_FIRST_CASE) && (275 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (275))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 275),
+#endif
+#endif
+#if ((276 >= GSL_INCLUDER_FIRST_CASE) && (276 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (276))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 276),
+#endif
+#endif
+#if ((277 >= GSL_INCLUDER_FIRST_CASE) && (277 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (277))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 277),
+#endif
+#endif
+#if ((278 >= GSL_INCLUDER_FIRST_CASE) && (278 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (278))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 278),
+#endif
+#endif
+#if ((279 >= GSL_INCLUDER_FIRST_CASE) && (279 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (279))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 279),
+#endif
+#endif
+#if ((280 >= GSL_INCLUDER_FIRST_CASE) && (280 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (280))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 280),
+#endif
+#endif
+#if ((281 >= GSL_INCLUDER_FIRST_CASE) && (281 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (281))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 281),
+#endif
+#endif
+#if ((282 >= GSL_INCLUDER_FIRST_CASE) && (282 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (282))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 282),
+#endif
+#endif
+#if ((283 >= GSL_INCLUDER_FIRST_CASE) && (283 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (283))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 283),
+#endif
+#endif
+#if ((284 >= GSL_INCLUDER_FIRST_CASE) && (284 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (284))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 284),
+#endif
+#endif
+#if ((285 >= GSL_INCLUDER_FIRST_CASE) && (285 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (285))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 285),
+#endif
+#endif
+#if ((286 >= GSL_INCLUDER_FIRST_CASE) && (286 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (286))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 286),
+#endif
+#endif
+#if ((287 >= GSL_INCLUDER_FIRST_CASE) && (287 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (287))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 287),
+#endif
+#endif
+#if ((288 >= GSL_INCLUDER_FIRST_CASE) && (288 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (288))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 288),
+#endif
+#endif
+#if ((289 >= GSL_INCLUDER_FIRST_CASE) && (289 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (289))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 289),
+#endif
+#endif
+#if ((290 >= GSL_INCLUDER_FIRST_CASE) && (290 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (290))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 290),
+#endif
+#endif
+#if ((291 >= GSL_INCLUDER_FIRST_CASE) && (291 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (291))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 291),
+#endif
+#endif
+#if ((292 >= GSL_INCLUDER_FIRST_CASE) && (292 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (292))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 292),
+#endif
+#endif
+#if ((293 >= GSL_INCLUDER_FIRST_CASE) && (293 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (293))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 293),
+#endif
+#endif
+#if ((294 >= GSL_INCLUDER_FIRST_CASE) && (294 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (294))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 294),
+#endif
+#endif
+#if ((295 >= GSL_INCLUDER_FIRST_CASE) && (295 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (295))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 295),
+#endif
+#endif
+#if ((296 >= GSL_INCLUDER_FIRST_CASE) && (296 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (296))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 296),
+#endif
+#endif
+#if ((297 >= GSL_INCLUDER_FIRST_CASE) && (297 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (297))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 297),
+#endif
+#endif
+#if ((298 >= GSL_INCLUDER_FIRST_CASE) && (298 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (298))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 298),
+#endif
+#endif
+#if ((299 >= GSL_INCLUDER_FIRST_CASE) && (299 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (299))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 299),
+#endif
+#endif
+#if ((300 >= GSL_INCLUDER_FIRST_CASE) && (300 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (300))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 300),
+#endif
+#endif
+#if ((301 >= GSL_INCLUDER_FIRST_CASE) && (301 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (301))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 301),
+#endif
+#endif
+#if ((302 >= GSL_INCLUDER_FIRST_CASE) && (302 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (302))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 302),
+#endif
+#endif
+#if ((303 >= GSL_INCLUDER_FIRST_CASE) && (303 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (303))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 303),
+#endif
+#endif
+#if ((304 >= GSL_INCLUDER_FIRST_CASE) && (304 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (304))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 304),
+#endif
+#endif
+#if ((305 >= GSL_INCLUDER_FIRST_CASE) && (305 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (305))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 305),
+#endif
+#endif
+#if ((306 >= GSL_INCLUDER_FIRST_CASE) && (306 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (306))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 306),
+#endif
+#endif
+#if ((307 >= GSL_INCLUDER_FIRST_CASE) && (307 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (307))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 307),
+#endif
+#endif
+#if ((308 >= GSL_INCLUDER_FIRST_CASE) && (308 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (308))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 308),
+#endif
+#endif
+#if ((309 >= GSL_INCLUDER_FIRST_CASE) && (309 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (309))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 309),
+#endif
+#endif
+#if ((310 >= GSL_INCLUDER_FIRST_CASE) && (310 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (310))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 310),
+#endif
+#endif
+#if ((311 >= GSL_INCLUDER_FIRST_CASE) && (311 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (311))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 311),
+#endif
+#endif
+#if ((312 >= GSL_INCLUDER_FIRST_CASE) && (312 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (312))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 312),
+#endif
+#endif
+#if ((313 >= GSL_INCLUDER_FIRST_CASE) && (313 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (313))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 313),
+#endif
+#endif
+#if ((314 >= GSL_INCLUDER_FIRST_CASE) && (314 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (314))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 314),
+#endif
+#endif
+#if ((315 >= GSL_INCLUDER_FIRST_CASE) && (315 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (315))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 315),
+#endif
+#endif
+#if ((316 >= GSL_INCLUDER_FIRST_CASE) && (316 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (316))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 316),
+#endif
+#endif
+#if ((317 >= GSL_INCLUDER_FIRST_CASE) && (317 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (317))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 317),
+#endif
+#endif
+#if ((318 >= GSL_INCLUDER_FIRST_CASE) && (318 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (318))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 318),
+#endif
+#endif
+#if ((319 >= GSL_INCLUDER_FIRST_CASE) && (319 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (319))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 319),
+#endif
+#endif
+#if ((320 >= GSL_INCLUDER_FIRST_CASE) && (320 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (320))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 320),
+#endif
+#endif
+#if ((321 >= GSL_INCLUDER_FIRST_CASE) && (321 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (321))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 321),
+#endif
+#endif
+#if ((322 >= GSL_INCLUDER_FIRST_CASE) && (322 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (322))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 322),
+#endif
+#endif
+#if ((323 >= GSL_INCLUDER_FIRST_CASE) && (323 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (323))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 323),
+#endif
+#endif
+#if ((324 >= GSL_INCLUDER_FIRST_CASE) && (324 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (324))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 324),
+#endif
+#endif
+#if ((325 >= GSL_INCLUDER_FIRST_CASE) && (325 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (325))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 325),
+#endif
+#endif
+#if ((326 >= GSL_INCLUDER_FIRST_CASE) && (326 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (326))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 326),
+#endif
+#endif
+#if ((327 >= GSL_INCLUDER_FIRST_CASE) && (327 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (327))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 327),
+#endif
+#endif
+#if ((328 >= GSL_INCLUDER_FIRST_CASE) && (328 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (328))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 328),
+#endif
+#endif
+#if ((329 >= GSL_INCLUDER_FIRST_CASE) && (329 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (329))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 329),
+#endif
+#endif
+#if ((330 >= GSL_INCLUDER_FIRST_CASE) && (330 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (330))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 330),
+#endif
+#endif
+#if ((331 >= GSL_INCLUDER_FIRST_CASE) && (331 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (331))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 331),
+#endif
+#endif
+#if ((332 >= GSL_INCLUDER_FIRST_CASE) && (332 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (332))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 332),
+#endif
+#endif
+#if ((333 >= GSL_INCLUDER_FIRST_CASE) && (333 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (333))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 333),
+#endif
+#endif
+#if ((334 >= GSL_INCLUDER_FIRST_CASE) && (334 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (334))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 334),
+#endif
+#endif
+#if ((335 >= GSL_INCLUDER_FIRST_CASE) && (335 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (335))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 335),
+#endif
+#endif
+#if ((336 >= GSL_INCLUDER_FIRST_CASE) && (336 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (336))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 336),
+#endif
+#endif
+#if ((337 >= GSL_INCLUDER_FIRST_CASE) && (337 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (337))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 337),
+#endif
+#endif
+#if ((338 >= GSL_INCLUDER_FIRST_CASE) && (338 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (338))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 338),
+#endif
+#endif
+#if ((339 >= GSL_INCLUDER_FIRST_CASE) && (339 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (339))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 339),
+#endif
+#endif
+#if ((340 >= GSL_INCLUDER_FIRST_CASE) && (340 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (340))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 340),
+#endif
+#endif
+#if ((341 >= GSL_INCLUDER_FIRST_CASE) && (341 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (341))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 341),
+#endif
+#endif
+#if ((342 >= GSL_INCLUDER_FIRST_CASE) && (342 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (342))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 342),
+#endif
+#endif
+#if ((343 >= GSL_INCLUDER_FIRST_CASE) && (343 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (343))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 343),
+#endif
+#endif
+#if ((344 >= GSL_INCLUDER_FIRST_CASE) && (344 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (344))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 344),
+#endif
+#endif
+#if ((345 >= GSL_INCLUDER_FIRST_CASE) && (345 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (345))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 345),
+#endif
+#endif
+#if ((346 >= GSL_INCLUDER_FIRST_CASE) && (346 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (346))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 346),
+#endif
+#endif
+#if ((347 >= GSL_INCLUDER_FIRST_CASE) && (347 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (347))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 347),
+#endif
+#endif
+#if ((348 >= GSL_INCLUDER_FIRST_CASE) && (348 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (348))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 348),
+#endif
+#endif
+#if ((349 >= GSL_INCLUDER_FIRST_CASE) && (349 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (349))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 349),
+#endif
+#endif
+#if ((350 >= GSL_INCLUDER_FIRST_CASE) && (350 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (350))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 350),
+#endif
+#endif
+#if ((351 >= GSL_INCLUDER_FIRST_CASE) && (351 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (351))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 351),
+#endif
+#endif
+#if ((352 >= GSL_INCLUDER_FIRST_CASE) && (352 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (352))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 352),
+#endif
+#endif
+#if ((353 >= GSL_INCLUDER_FIRST_CASE) && (353 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (353))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 353),
+#endif
+#endif
+#if ((354 >= GSL_INCLUDER_FIRST_CASE) && (354 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (354))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 354),
+#endif
+#endif
+#if ((355 >= GSL_INCLUDER_FIRST_CASE) && (355 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (355))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 355),
+#endif
+#endif
+#if ((356 >= GSL_INCLUDER_FIRST_CASE) && (356 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (356))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 356),
+#endif
+#endif
+#if ((357 >= GSL_INCLUDER_FIRST_CASE) && (357 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (357))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 357),
+#endif
+#endif
+#if ((358 >= GSL_INCLUDER_FIRST_CASE) && (358 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (358))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 358),
+#endif
+#endif
+#if ((359 >= GSL_INCLUDER_FIRST_CASE) && (359 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (359))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 359),
+#endif
+#endif
+#if ((360 >= GSL_INCLUDER_FIRST_CASE) && (360 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (360))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 360),
+#endif
+#endif
+#if ((361 >= GSL_INCLUDER_FIRST_CASE) && (361 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (361))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 361),
+#endif
+#endif
+#if ((362 >= GSL_INCLUDER_FIRST_CASE) && (362 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (362))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 362),
+#endif
+#endif
+#if ((363 >= GSL_INCLUDER_FIRST_CASE) && (363 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (363))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 363),
+#endif
+#endif
+#if ((364 >= GSL_INCLUDER_FIRST_CASE) && (364 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (364))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 364),
+#endif
+#endif
+#if ((365 >= GSL_INCLUDER_FIRST_CASE) && (365 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (365))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 365),
+#endif
+#endif
+#if ((366 >= GSL_INCLUDER_FIRST_CASE) && (366 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (366))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 366),
+#endif
+#endif
+#if ((367 >= GSL_INCLUDER_FIRST_CASE) && (367 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (367))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 367),
+#endif
+#endif
+#if ((368 >= GSL_INCLUDER_FIRST_CASE) && (368 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (368))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 368),
+#endif
+#endif
+#if ((369 >= GSL_INCLUDER_FIRST_CASE) && (369 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (369))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 369),
+#endif
+#endif
+#if ((370 >= GSL_INCLUDER_FIRST_CASE) && (370 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (370))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 370),
+#endif
+#endif
+#if ((371 >= GSL_INCLUDER_FIRST_CASE) && (371 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (371))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 371),
+#endif
+#endif
+#if ((372 >= GSL_INCLUDER_FIRST_CASE) && (372 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (372))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 372),
+#endif
+#endif
+#if ((373 >= GSL_INCLUDER_FIRST_CASE) && (373 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (373))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 373),
+#endif
+#endif
+#if ((374 >= GSL_INCLUDER_FIRST_CASE) && (374 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (374))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 374),
+#endif
+#endif
+#if ((375 >= GSL_INCLUDER_FIRST_CASE) && (375 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (375))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 375),
+#endif
+#endif
+#if ((376 >= GSL_INCLUDER_FIRST_CASE) && (376 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (376))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 376),
+#endif
+#endif
+#if ((377 >= GSL_INCLUDER_FIRST_CASE) && (377 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (377))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 377),
+#endif
+#endif
+#if ((378 >= GSL_INCLUDER_FIRST_CASE) && (378 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (378))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 378),
+#endif
+#endif
+#if ((379 >= GSL_INCLUDER_FIRST_CASE) && (379 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (379))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 379),
+#endif
+#endif
+#if ((380 >= GSL_INCLUDER_FIRST_CASE) && (380 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (380))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 380),
+#endif
+#endif
+#if ((381 >= GSL_INCLUDER_FIRST_CASE) && (381 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (381))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 381),
+#endif
+#endif
+#if ((382 >= GSL_INCLUDER_FIRST_CASE) && (382 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (382))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 382),
+#endif
+#endif
+#if ((383 >= GSL_INCLUDER_FIRST_CASE) && (383 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (383))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 383),
+#endif
+#endif
+#if ((384 >= GSL_INCLUDER_FIRST_CASE) && (384 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (384))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 384),
+#endif
+#endif
+#if ((385 >= GSL_INCLUDER_FIRST_CASE) && (385 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (385))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 385),
+#endif
+#endif
+#if ((386 >= GSL_INCLUDER_FIRST_CASE) && (386 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (386))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 386),
+#endif
+#endif
+#if ((387 >= GSL_INCLUDER_FIRST_CASE) && (387 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (387))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 387),
+#endif
+#endif
+#if ((388 >= GSL_INCLUDER_FIRST_CASE) && (388 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (388))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 388),
+#endif
+#endif
+#if ((389 >= GSL_INCLUDER_FIRST_CASE) && (389 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (389))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 389),
+#endif
+#endif
+#if ((390 >= GSL_INCLUDER_FIRST_CASE) && (390 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (390))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 390),
+#endif
+#endif
+#if ((391 >= GSL_INCLUDER_FIRST_CASE) && (391 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (391))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 391),
+#endif
+#endif
+#if ((392 >= GSL_INCLUDER_FIRST_CASE) && (392 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (392))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 392),
+#endif
+#endif
+#if ((393 >= GSL_INCLUDER_FIRST_CASE) && (393 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (393))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 393),
+#endif
+#endif
+#if ((394 >= GSL_INCLUDER_FIRST_CASE) && (394 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (394))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 394),
+#endif
+#endif
+#if ((395 >= GSL_INCLUDER_FIRST_CASE) && (395 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (395))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 395),
+#endif
+#endif
+#if ((396 >= GSL_INCLUDER_FIRST_CASE) && (396 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (396))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 396),
+#endif
+#endif
+#if ((397 >= GSL_INCLUDER_FIRST_CASE) && (397 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (397))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 397),
+#endif
+#endif
+#if ((398 >= GSL_INCLUDER_FIRST_CASE) && (398 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (398))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 398),
+#endif
+#endif
+#if ((399 >= GSL_INCLUDER_FIRST_CASE) && (399 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (399))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 399),
+#endif
+#endif
+#if ((400 >= GSL_INCLUDER_FIRST_CASE) && (400 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (400))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 400),
+#endif
+#endif
+#if ((401 >= GSL_INCLUDER_FIRST_CASE) && (401 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (401))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 401),
+#endif
+#endif
+#if ((402 >= GSL_INCLUDER_FIRST_CASE) && (402 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (402))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 402),
+#endif
+#endif
+#if ((403 >= GSL_INCLUDER_FIRST_CASE) && (403 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (403))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 403),
+#endif
+#endif
+#if ((404 >= GSL_INCLUDER_FIRST_CASE) && (404 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (404))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 404),
+#endif
+#endif
+#if ((405 >= GSL_INCLUDER_FIRST_CASE) && (405 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (405))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 405),
+#endif
+#endif
+#if ((406 >= GSL_INCLUDER_FIRST_CASE) && (406 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (406))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 406),
+#endif
+#endif
+#if ((407 >= GSL_INCLUDER_FIRST_CASE) && (407 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (407))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 407),
+#endif
+#endif
+#if ((408 >= GSL_INCLUDER_FIRST_CASE) && (408 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (408))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 408),
+#endif
+#endif
+#if ((409 >= GSL_INCLUDER_FIRST_CASE) && (409 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (409))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 409),
+#endif
+#endif
+#if ((410 >= GSL_INCLUDER_FIRST_CASE) && (410 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (410))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 410),
+#endif
+#endif
+#if ((411 >= GSL_INCLUDER_FIRST_CASE) && (411 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (411))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 411),
+#endif
+#endif
+#if ((412 >= GSL_INCLUDER_FIRST_CASE) && (412 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (412))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 412),
+#endif
+#endif
+#if ((413 >= GSL_INCLUDER_FIRST_CASE) && (413 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (413))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 413),
+#endif
+#endif
+#if ((414 >= GSL_INCLUDER_FIRST_CASE) && (414 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (414))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 414),
+#endif
+#endif
+#if ((415 >= GSL_INCLUDER_FIRST_CASE) && (415 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (415))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 415),
+#endif
+#endif
+#if ((416 >= GSL_INCLUDER_FIRST_CASE) && (416 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (416))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 416),
+#endif
+#endif
+#if ((417 >= GSL_INCLUDER_FIRST_CASE) && (417 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (417))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 417),
+#endif
+#endif
+#if ((418 >= GSL_INCLUDER_FIRST_CASE) && (418 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (418))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 418),
+#endif
+#endif
+#if ((419 >= GSL_INCLUDER_FIRST_CASE) && (419 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (419))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 419),
+#endif
+#endif
+#if ((420 >= GSL_INCLUDER_FIRST_CASE) && (420 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (420))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 420),
+#endif
+#endif
+#if ((421 >= GSL_INCLUDER_FIRST_CASE) && (421 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (421))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 421),
+#endif
+#endif
+#if ((422 >= GSL_INCLUDER_FIRST_CASE) && (422 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (422))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 422),
+#endif
+#endif
+#if ((423 >= GSL_INCLUDER_FIRST_CASE) && (423 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (423))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 423),
+#endif
+#endif
+#if ((424 >= GSL_INCLUDER_FIRST_CASE) && (424 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (424))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 424),
+#endif
+#endif
+#if ((425 >= GSL_INCLUDER_FIRST_CASE) && (425 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (425))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 425),
+#endif
+#endif
+#if ((426 >= GSL_INCLUDER_FIRST_CASE) && (426 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (426))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 426),
+#endif
+#endif
+#if ((427 >= GSL_INCLUDER_FIRST_CASE) && (427 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (427))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 427),
+#endif
+#endif
+#if ((428 >= GSL_INCLUDER_FIRST_CASE) && (428 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (428))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 428),
+#endif
+#endif
+#if ((429 >= GSL_INCLUDER_FIRST_CASE) && (429 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (429))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 429),
+#endif
+#endif
+#if ((430 >= GSL_INCLUDER_FIRST_CASE) && (430 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (430))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 430),
+#endif
+#endif
+#if ((431 >= GSL_INCLUDER_FIRST_CASE) && (431 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (431))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 431),
+#endif
+#endif
+#if ((432 >= GSL_INCLUDER_FIRST_CASE) && (432 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (432))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 432),
+#endif
+#endif
+#if ((433 >= GSL_INCLUDER_FIRST_CASE) && (433 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (433))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 433),
+#endif
+#endif
+#if ((434 >= GSL_INCLUDER_FIRST_CASE) && (434 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (434))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 434),
+#endif
+#endif
+#if ((435 >= GSL_INCLUDER_FIRST_CASE) && (435 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (435))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 435),
+#endif
+#endif
+#if ((436 >= GSL_INCLUDER_FIRST_CASE) && (436 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (436))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 436),
+#endif
+#endif
+#if ((437 >= GSL_INCLUDER_FIRST_CASE) && (437 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (437))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 437),
+#endif
+#endif
+#if ((438 >= GSL_INCLUDER_FIRST_CASE) && (438 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (438))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 438),
+#endif
+#endif
+#if ((439 >= GSL_INCLUDER_FIRST_CASE) && (439 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (439))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 439),
+#endif
+#endif
+#if ((440 >= GSL_INCLUDER_FIRST_CASE) && (440 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (440))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 440),
+#endif
+#endif
+#if ((441 >= GSL_INCLUDER_FIRST_CASE) && (441 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (441))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 441),
+#endif
+#endif
+#if ((442 >= GSL_INCLUDER_FIRST_CASE) && (442 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (442))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 442),
+#endif
+#endif
+#if ((443 >= GSL_INCLUDER_FIRST_CASE) && (443 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (443))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 443),
+#endif
+#endif
+#if ((444 >= GSL_INCLUDER_FIRST_CASE) && (444 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (444))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 444),
+#endif
+#endif
+#if ((445 >= GSL_INCLUDER_FIRST_CASE) && (445 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (445))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 445),
+#endif
+#endif
+#if ((446 >= GSL_INCLUDER_FIRST_CASE) && (446 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (446))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 446),
+#endif
+#endif
+#if ((447 >= GSL_INCLUDER_FIRST_CASE) && (447 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (447))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 447),
+#endif
+#endif
+#if ((448 >= GSL_INCLUDER_FIRST_CASE) && (448 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (448))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 448),
+#endif
+#endif
+#if ((449 >= GSL_INCLUDER_FIRST_CASE) && (449 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (449))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 449),
+#endif
+#endif
+#if ((450 >= GSL_INCLUDER_FIRST_CASE) && (450 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (450))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 450),
+#endif
+#endif
+#if ((451 >= GSL_INCLUDER_FIRST_CASE) && (451 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (451))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 451),
+#endif
+#endif
+#if ((452 >= GSL_INCLUDER_FIRST_CASE) && (452 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (452))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 452),
+#endif
+#endif
+#if ((453 >= GSL_INCLUDER_FIRST_CASE) && (453 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (453))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 453),
+#endif
+#endif
+#if ((454 >= GSL_INCLUDER_FIRST_CASE) && (454 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (454))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 454),
+#endif
+#endif
+#if ((455 >= GSL_INCLUDER_FIRST_CASE) && (455 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (455))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 455),
+#endif
+#endif
+#if ((456 >= GSL_INCLUDER_FIRST_CASE) && (456 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (456))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 456),
+#endif
+#endif
+#if ((457 >= GSL_INCLUDER_FIRST_CASE) && (457 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (457))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 457),
+#endif
+#endif
+#if ((458 >= GSL_INCLUDER_FIRST_CASE) && (458 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (458))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 458),
+#endif
+#endif
+#if ((459 >= GSL_INCLUDER_FIRST_CASE) && (459 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (459))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 459),
+#endif
+#endif
+#if ((460 >= GSL_INCLUDER_FIRST_CASE) && (460 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (460))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 460),
+#endif
+#endif
+#if ((461 >= GSL_INCLUDER_FIRST_CASE) && (461 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (461))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 461),
+#endif
+#endif
+#if ((462 >= GSL_INCLUDER_FIRST_CASE) && (462 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (462))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 462),
+#endif
+#endif
+#if ((463 >= GSL_INCLUDER_FIRST_CASE) && (463 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (463))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 463),
+#endif
+#endif
+#if ((464 >= GSL_INCLUDER_FIRST_CASE) && (464 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (464))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 464),
+#endif
+#endif
+#if ((465 >= GSL_INCLUDER_FIRST_CASE) && (465 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (465))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 465),
+#endif
+#endif
+#if ((466 >= GSL_INCLUDER_FIRST_CASE) && (466 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (466))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 466),
+#endif
+#endif
+#if ((467 >= GSL_INCLUDER_FIRST_CASE) && (467 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (467))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 467),
+#endif
+#endif
+#if ((468 >= GSL_INCLUDER_FIRST_CASE) && (468 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (468))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 468),
+#endif
+#endif
+#if ((469 >= GSL_INCLUDER_FIRST_CASE) && (469 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (469))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 469),
+#endif
+#endif
+#if ((470 >= GSL_INCLUDER_FIRST_CASE) && (470 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (470))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 470),
+#endif
+#endif
+#if ((471 >= GSL_INCLUDER_FIRST_CASE) && (471 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (471))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 471),
+#endif
+#endif
+#if ((472 >= GSL_INCLUDER_FIRST_CASE) && (472 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (472))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 472),
+#endif
+#endif
+#if ((473 >= GSL_INCLUDER_FIRST_CASE) && (473 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (473))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 473),
+#endif
+#endif
+#if ((474 >= GSL_INCLUDER_FIRST_CASE) && (474 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (474))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 474),
+#endif
+#endif
+#if ((475 >= GSL_INCLUDER_FIRST_CASE) && (475 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (475))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 475),
+#endif
+#endif
+#if ((476 >= GSL_INCLUDER_FIRST_CASE) && (476 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (476))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 476),
+#endif
+#endif
+#if ((477 >= GSL_INCLUDER_FIRST_CASE) && (477 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (477))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 477),
+#endif
+#endif
+#if ((478 >= GSL_INCLUDER_FIRST_CASE) && (478 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (478))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 478),
+#endif
+#endif
+#if ((479 >= GSL_INCLUDER_FIRST_CASE) && (479 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (479))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 479),
+#endif
+#endif
+#if ((480 >= GSL_INCLUDER_FIRST_CASE) && (480 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (480))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 480),
+#endif
+#endif
+#if ((481 >= GSL_INCLUDER_FIRST_CASE) && (481 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (481))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 481),
+#endif
+#endif
+#if ((482 >= GSL_INCLUDER_FIRST_CASE) && (482 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (482))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 482),
+#endif
+#endif
+#if ((483 >= GSL_INCLUDER_FIRST_CASE) && (483 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (483))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 483),
+#endif
+#endif
+#if ((484 >= GSL_INCLUDER_FIRST_CASE) && (484 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (484))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 484),
+#endif
+#endif
+#if ((485 >= GSL_INCLUDER_FIRST_CASE) && (485 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (485))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 485),
+#endif
+#endif
+#if ((486 >= GSL_INCLUDER_FIRST_CASE) && (486 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (486))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 486),
+#endif
+#endif
+#if ((487 >= GSL_INCLUDER_FIRST_CASE) && (487 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (487))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 487),
+#endif
+#endif
+#if ((488 >= GSL_INCLUDER_FIRST_CASE) && (488 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (488))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 488),
+#endif
+#endif
+#if ((489 >= GSL_INCLUDER_FIRST_CASE) && (489 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (489))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 489),
+#endif
+#endif
+#if ((490 >= GSL_INCLUDER_FIRST_CASE) && (490 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (490))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 490),
+#endif
+#endif
+#if ((491 >= GSL_INCLUDER_FIRST_CASE) && (491 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (491))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 491),
+#endif
+#endif
+#if ((492 >= GSL_INCLUDER_FIRST_CASE) && (492 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (492))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 492),
+#endif
+#endif
+#if ((493 >= GSL_INCLUDER_FIRST_CASE) && (493 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (493))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 493),
+#endif
+#endif
+#if ((494 >= GSL_INCLUDER_FIRST_CASE) && (494 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (494))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 494),
+#endif
+#endif
+#if ((495 >= GSL_INCLUDER_FIRST_CASE) && (495 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (495))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 495),
+#endif
+#endif
+#if ((496 >= GSL_INCLUDER_FIRST_CASE) && (496 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (496))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 496),
+#endif
+#endif
+#if ((497 >= GSL_INCLUDER_FIRST_CASE) && (497 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (497))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 497),
+#endif
+#endif
+#if ((498 >= GSL_INCLUDER_FIRST_CASE) && (498 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (498))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 498),
+#endif
+#endif
+#if ((499 >= GSL_INCLUDER_FIRST_CASE) && (499 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (499))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 499),
+#endif
+#endif
+#if ((500 >= GSL_INCLUDER_FIRST_CASE) && (500 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (500))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 500),
+#endif
+#endif
+#if ((501 >= GSL_INCLUDER_FIRST_CASE) && (501 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (501))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 501),
+#endif
+#endif
+#if ((502 >= GSL_INCLUDER_FIRST_CASE) && (502 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (502))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 502),
+#endif
+#endif
+#if ((503 >= GSL_INCLUDER_FIRST_CASE) && (503 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (503))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 503),
+#endif
+#endif
+#if ((504 >= GSL_INCLUDER_FIRST_CASE) && (504 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (504))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 504),
+#endif
+#endif
+#if ((505 >= GSL_INCLUDER_FIRST_CASE) && (505 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (505))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 505),
+#endif
+#endif
+#if ((506 >= GSL_INCLUDER_FIRST_CASE) && (506 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (506))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 506),
+#endif
+#endif
+#if ((507 >= GSL_INCLUDER_FIRST_CASE) && (507 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (507))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 507),
+#endif
+#endif
+#if ((508 >= GSL_INCLUDER_FIRST_CASE) && (508 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (508))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 508),
+#endif
+#endif
+#if ((509 >= GSL_INCLUDER_FIRST_CASE) && (509 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (509))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 509),
+#endif
+#endif
+#if ((510 >= GSL_INCLUDER_FIRST_CASE) && (510 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (510))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 510),
+#endif
+#endif
+#if ((511 >= GSL_INCLUDER_FIRST_CASE) && (511 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (511))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 511),
+#endif
+#endif
+#if ((512 >= GSL_INCLUDER_FIRST_CASE) && (512 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (512))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 512),
+#endif
+#endif
+#if ((513 >= GSL_INCLUDER_FIRST_CASE) && (513 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (513))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 513),
+#endif
+#endif
+#if ((514 >= GSL_INCLUDER_FIRST_CASE) && (514 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (514))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 514),
+#endif
+#endif
+#if ((515 >= GSL_INCLUDER_FIRST_CASE) && (515 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (515))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 515),
+#endif
+#endif
+#if ((516 >= GSL_INCLUDER_FIRST_CASE) && (516 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (516))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 516),
+#endif
+#endif
+#if ((517 >= GSL_INCLUDER_FIRST_CASE) && (517 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (517))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 517),
+#endif
+#endif
+#if ((518 >= GSL_INCLUDER_FIRST_CASE) && (518 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (518))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 518),
+#endif
+#endif
+#if ((519 >= GSL_INCLUDER_FIRST_CASE) && (519 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (519))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 519),
+#endif
+#endif
+#if ((520 >= GSL_INCLUDER_FIRST_CASE) && (520 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (520))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 520),
+#endif
+#endif
+#if ((521 >= GSL_INCLUDER_FIRST_CASE) && (521 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (521))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 521),
+#endif
+#endif
+#if ((522 >= GSL_INCLUDER_FIRST_CASE) && (522 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (522))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 522),
+#endif
+#endif
+#if ((523 >= GSL_INCLUDER_FIRST_CASE) && (523 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (523))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 523),
+#endif
+#endif
+#if ((524 >= GSL_INCLUDER_FIRST_CASE) && (524 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (524))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 524),
+#endif
+#endif
+#if ((525 >= GSL_INCLUDER_FIRST_CASE) && (525 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (525))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 525),
+#endif
+#endif
+#if ((526 >= GSL_INCLUDER_FIRST_CASE) && (526 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (526))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 526),
+#endif
+#endif
+#if ((527 >= GSL_INCLUDER_FIRST_CASE) && (527 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (527))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 527),
+#endif
+#endif
+#if ((528 >= GSL_INCLUDER_FIRST_CASE) && (528 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (528))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 528),
+#endif
+#endif
+#if ((529 >= GSL_INCLUDER_FIRST_CASE) && (529 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (529))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 529),
+#endif
+#endif
+#if ((530 >= GSL_INCLUDER_FIRST_CASE) && (530 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (530))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 530),
+#endif
+#endif
+#if ((531 >= GSL_INCLUDER_FIRST_CASE) && (531 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (531))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 531),
+#endif
+#endif
+#if ((532 >= GSL_INCLUDER_FIRST_CASE) && (532 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (532))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 532),
+#endif
+#endif
+#if ((533 >= GSL_INCLUDER_FIRST_CASE) && (533 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (533))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 533),
+#endif
+#endif
+#if ((534 >= GSL_INCLUDER_FIRST_CASE) && (534 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (534))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 534),
+#endif
+#endif
+#if ((535 >= GSL_INCLUDER_FIRST_CASE) && (535 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (535))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 535),
+#endif
+#endif
+#if ((536 >= GSL_INCLUDER_FIRST_CASE) && (536 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (536))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 536),
+#endif
+#endif
+#if ((537 >= GSL_INCLUDER_FIRST_CASE) && (537 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (537))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 537),
+#endif
+#endif
+#if ((538 >= GSL_INCLUDER_FIRST_CASE) && (538 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (538))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 538),
+#endif
+#endif
+#if ((539 >= GSL_INCLUDER_FIRST_CASE) && (539 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (539))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 539),
+#endif
+#endif
+#if ((540 >= GSL_INCLUDER_FIRST_CASE) && (540 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (540))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 540),
+#endif
+#endif
+#if ((541 >= GSL_INCLUDER_FIRST_CASE) && (541 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (541))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 541),
+#endif
+#endif
+#if ((542 >= GSL_INCLUDER_FIRST_CASE) && (542 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (542))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 542),
+#endif
+#endif
+#if ((543 >= GSL_INCLUDER_FIRST_CASE) && (543 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (543))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 543),
+#endif
+#endif
+#if ((544 >= GSL_INCLUDER_FIRST_CASE) && (544 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (544))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 544),
+#endif
+#endif
+#if ((545 >= GSL_INCLUDER_FIRST_CASE) && (545 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (545))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 545),
+#endif
+#endif
+#if ((546 >= GSL_INCLUDER_FIRST_CASE) && (546 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (546))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 546),
+#endif
+#endif
+#if ((547 >= GSL_INCLUDER_FIRST_CASE) && (547 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (547))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 547),
+#endif
+#endif
+#if ((548 >= GSL_INCLUDER_FIRST_CASE) && (548 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (548))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 548),
+#endif
+#endif
+#if ((549 >= GSL_INCLUDER_FIRST_CASE) && (549 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (549))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 549),
+#endif
+#endif
+#if ((550 >= GSL_INCLUDER_FIRST_CASE) && (550 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (550))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 550),
+#endif
+#endif
+#if ((551 >= GSL_INCLUDER_FIRST_CASE) && (551 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (551))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 551),
+#endif
+#endif
+#if ((552 >= GSL_INCLUDER_FIRST_CASE) && (552 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (552))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 552),
+#endif
+#endif
+#if ((553 >= GSL_INCLUDER_FIRST_CASE) && (553 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (553))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 553),
+#endif
+#endif
+#if ((554 >= GSL_INCLUDER_FIRST_CASE) && (554 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (554))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 554),
+#endif
+#endif
+#if ((555 >= GSL_INCLUDER_FIRST_CASE) && (555 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (555))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 555),
+#endif
+#endif
+#if ((556 >= GSL_INCLUDER_FIRST_CASE) && (556 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (556))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 556),
+#endif
+#endif
+#if ((557 >= GSL_INCLUDER_FIRST_CASE) && (557 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (557))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 557),
+#endif
+#endif
+#if ((558 >= GSL_INCLUDER_FIRST_CASE) && (558 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (558))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 558),
+#endif
+#endif
+#if ((559 >= GSL_INCLUDER_FIRST_CASE) && (559 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (559))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 559),
+#endif
+#endif
+#if ((560 >= GSL_INCLUDER_FIRST_CASE) && (560 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (560))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 560),
+#endif
+#endif
+#if ((561 >= GSL_INCLUDER_FIRST_CASE) && (561 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (561))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 561),
+#endif
+#endif
+#if ((562 >= GSL_INCLUDER_FIRST_CASE) && (562 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (562))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 562),
+#endif
+#endif
+#if ((563 >= GSL_INCLUDER_FIRST_CASE) && (563 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (563))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 563),
+#endif
+#endif
+#if ((564 >= GSL_INCLUDER_FIRST_CASE) && (564 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (564))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 564),
+#endif
+#endif
+#if ((565 >= GSL_INCLUDER_FIRST_CASE) && (565 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (565))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 565),
+#endif
+#endif
+#if ((566 >= GSL_INCLUDER_FIRST_CASE) && (566 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (566))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 566),
+#endif
+#endif
+#if ((567 >= GSL_INCLUDER_FIRST_CASE) && (567 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (567))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 567),
+#endif
+#endif
+#if ((568 >= GSL_INCLUDER_FIRST_CASE) && (568 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (568))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 568),
+#endif
+#endif
+#if ((569 >= GSL_INCLUDER_FIRST_CASE) && (569 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (569))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 569),
+#endif
+#endif
+#if ((570 >= GSL_INCLUDER_FIRST_CASE) && (570 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (570))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 570),
+#endif
+#endif
+#if ((571 >= GSL_INCLUDER_FIRST_CASE) && (571 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (571))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 571),
+#endif
+#endif
+#if ((572 >= GSL_INCLUDER_FIRST_CASE) && (572 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (572))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 572),
+#endif
+#endif
+#if ((573 >= GSL_INCLUDER_FIRST_CASE) && (573 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (573))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 573),
+#endif
+#endif
+#if ((574 >= GSL_INCLUDER_FIRST_CASE) && (574 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (574))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 574),
+#endif
+#endif
+#if ((575 >= GSL_INCLUDER_FIRST_CASE) && (575 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (575))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 575),
+#endif
+#endif
+#if ((576 >= GSL_INCLUDER_FIRST_CASE) && (576 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (576))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 576),
+#endif
+#endif
+#if ((577 >= GSL_INCLUDER_FIRST_CASE) && (577 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (577))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 577),
+#endif
+#endif
+#if ((578 >= GSL_INCLUDER_FIRST_CASE) && (578 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (578))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 578),
+#endif
+#endif
+#if ((579 >= GSL_INCLUDER_FIRST_CASE) && (579 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (579))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 579),
+#endif
+#endif
+#if ((580 >= GSL_INCLUDER_FIRST_CASE) && (580 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (580))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 580),
+#endif
+#endif
+#if ((581 >= GSL_INCLUDER_FIRST_CASE) && (581 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (581))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 581),
+#endif
+#endif
+#if ((582 >= GSL_INCLUDER_FIRST_CASE) && (582 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (582))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 582),
+#endif
+#endif
+#if ((583 >= GSL_INCLUDER_FIRST_CASE) && (583 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (583))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 583),
+#endif
+#endif
+#if ((584 >= GSL_INCLUDER_FIRST_CASE) && (584 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (584))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 584),
+#endif
+#endif
+#if ((585 >= GSL_INCLUDER_FIRST_CASE) && (585 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (585))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 585),
+#endif
+#endif
+#if ((586 >= GSL_INCLUDER_FIRST_CASE) && (586 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (586))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 586),
+#endif
+#endif
+#if ((587 >= GSL_INCLUDER_FIRST_CASE) && (587 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (587))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 587),
+#endif
+#endif
+#if ((588 >= GSL_INCLUDER_FIRST_CASE) && (588 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (588))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 588),
+#endif
+#endif
+#if ((589 >= GSL_INCLUDER_FIRST_CASE) && (589 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (589))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 589),
+#endif
+#endif
+#if ((590 >= GSL_INCLUDER_FIRST_CASE) && (590 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (590))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 590),
+#endif
+#endif
+#if ((591 >= GSL_INCLUDER_FIRST_CASE) && (591 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (591))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 591),
+#endif
+#endif
+#if ((592 >= GSL_INCLUDER_FIRST_CASE) && (592 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (592))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 592),
+#endif
+#endif
+#if ((593 >= GSL_INCLUDER_FIRST_CASE) && (593 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (593))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 593),
+#endif
+#endif
+#if ((594 >= GSL_INCLUDER_FIRST_CASE) && (594 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (594))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 594),
+#endif
+#endif
+#if ((595 >= GSL_INCLUDER_FIRST_CASE) && (595 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (595))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 595),
+#endif
+#endif
+#if ((596 >= GSL_INCLUDER_FIRST_CASE) && (596 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (596))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 596),
+#endif
+#endif
+#if ((597 >= GSL_INCLUDER_FIRST_CASE) && (597 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (597))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 597),
+#endif
+#endif
+#if ((598 >= GSL_INCLUDER_FIRST_CASE) && (598 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (598))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 598),
+#endif
+#endif
+#if ((599 >= GSL_INCLUDER_FIRST_CASE) && (599 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (599))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 599),
+#endif
+#endif
+#if ((600 >= GSL_INCLUDER_FIRST_CASE) && (600 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (600))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 600),
+#endif
+#endif
+#if ((601 >= GSL_INCLUDER_FIRST_CASE) && (601 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (601))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 601),
+#endif
+#endif
+#if ((602 >= GSL_INCLUDER_FIRST_CASE) && (602 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (602))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 602),
+#endif
+#endif
+#if ((603 >= GSL_INCLUDER_FIRST_CASE) && (603 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (603))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 603),
+#endif
+#endif
+#if ((604 >= GSL_INCLUDER_FIRST_CASE) && (604 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (604))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 604),
+#endif
+#endif
+#if ((605 >= GSL_INCLUDER_FIRST_CASE) && (605 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (605))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 605),
+#endif
+#endif
+#if ((606 >= GSL_INCLUDER_FIRST_CASE) && (606 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (606))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 606),
+#endif
+#endif
+#if ((607 >= GSL_INCLUDER_FIRST_CASE) && (607 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (607))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 607),
+#endif
+#endif
+#if ((608 >= GSL_INCLUDER_FIRST_CASE) && (608 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (608))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 608),
+#endif
+#endif
+#if ((609 >= GSL_INCLUDER_FIRST_CASE) && (609 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (609))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 609),
+#endif
+#endif
+#if ((610 >= GSL_INCLUDER_FIRST_CASE) && (610 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (610))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 610),
+#endif
+#endif
+#if ((611 >= GSL_INCLUDER_FIRST_CASE) && (611 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (611))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 611),
+#endif
+#endif
+#if ((612 >= GSL_INCLUDER_FIRST_CASE) && (612 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (612))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 612),
+#endif
+#endif
+#if ((613 >= GSL_INCLUDER_FIRST_CASE) && (613 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (613))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 613),
+#endif
+#endif
+#if ((614 >= GSL_INCLUDER_FIRST_CASE) && (614 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (614))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 614),
+#endif
+#endif
+#if ((615 >= GSL_INCLUDER_FIRST_CASE) && (615 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (615))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 615),
+#endif
+#endif
+#if ((616 >= GSL_INCLUDER_FIRST_CASE) && (616 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (616))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 616),
+#endif
+#endif
+#if ((617 >= GSL_INCLUDER_FIRST_CASE) && (617 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (617))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 617),
+#endif
+#endif
+#if ((618 >= GSL_INCLUDER_FIRST_CASE) && (618 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (618))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 618),
+#endif
+#endif
+#if ((619 >= GSL_INCLUDER_FIRST_CASE) && (619 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (619))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 619),
+#endif
+#endif
+#if ((620 >= GSL_INCLUDER_FIRST_CASE) && (620 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (620))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 620),
+#endif
+#endif
+#if ((621 >= GSL_INCLUDER_FIRST_CASE) && (621 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (621))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 621),
+#endif
+#endif
+#if ((622 >= GSL_INCLUDER_FIRST_CASE) && (622 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (622))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 622),
+#endif
+#endif
+#if ((623 >= GSL_INCLUDER_FIRST_CASE) && (623 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (623))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 623),
+#endif
+#endif
+#if ((624 >= GSL_INCLUDER_FIRST_CASE) && (624 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (624))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 624),
+#endif
+#endif
+#if ((625 >= GSL_INCLUDER_FIRST_CASE) && (625 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (625))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 625),
+#endif
+#endif
+#if ((626 >= GSL_INCLUDER_FIRST_CASE) && (626 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (626))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 626),
+#endif
+#endif
+#if ((627 >= GSL_INCLUDER_FIRST_CASE) && (627 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (627))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 627),
+#endif
+#endif
+#if ((628 >= GSL_INCLUDER_FIRST_CASE) && (628 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (628))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 628),
+#endif
+#endif
+#if ((629 >= GSL_INCLUDER_FIRST_CASE) && (629 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (629))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 629),
+#endif
+#endif
+#if ((630 >= GSL_INCLUDER_FIRST_CASE) && (630 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (630))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 630),
+#endif
+#endif
+#if ((631 >= GSL_INCLUDER_FIRST_CASE) && (631 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (631))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 631),
+#endif
+#endif
+#if ((632 >= GSL_INCLUDER_FIRST_CASE) && (632 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (632))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 632),
+#endif
+#endif
+#if ((633 >= GSL_INCLUDER_FIRST_CASE) && (633 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (633))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 633),
+#endif
+#endif
+#if ((634 >= GSL_INCLUDER_FIRST_CASE) && (634 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (634))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 634),
+#endif
+#endif
+#if ((635 >= GSL_INCLUDER_FIRST_CASE) && (635 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (635))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 635),
+#endif
+#endif
+#if ((636 >= GSL_INCLUDER_FIRST_CASE) && (636 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (636))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 636),
+#endif
+#endif
+#if ((637 >= GSL_INCLUDER_FIRST_CASE) && (637 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (637))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 637),
+#endif
+#endif
+#if ((638 >= GSL_INCLUDER_FIRST_CASE) && (638 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (638))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 638),
+#endif
+#endif
+#if ((639 >= GSL_INCLUDER_FIRST_CASE) && (639 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (639))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 639),
+#endif
+#endif
+#if ((640 >= GSL_INCLUDER_FIRST_CASE) && (640 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (640))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 640),
+#endif
+#endif
+#if ((641 >= GSL_INCLUDER_FIRST_CASE) && (641 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (641))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 641),
+#endif
+#endif
+#if ((642 >= GSL_INCLUDER_FIRST_CASE) && (642 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (642))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 642),
+#endif
+#endif
+#if ((643 >= GSL_INCLUDER_FIRST_CASE) && (643 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (643))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 643),
+#endif
+#endif
+#if ((644 >= GSL_INCLUDER_FIRST_CASE) && (644 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (644))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 644),
+#endif
+#endif
+#if ((645 >= GSL_INCLUDER_FIRST_CASE) && (645 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (645))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 645),
+#endif
+#endif
+#if ((646 >= GSL_INCLUDER_FIRST_CASE) && (646 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (646))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 646),
+#endif
+#endif
+#if ((647 >= GSL_INCLUDER_FIRST_CASE) && (647 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (647))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 647),
+#endif
+#endif
+#if ((648 >= GSL_INCLUDER_FIRST_CASE) && (648 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (648))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 648),
+#endif
+#endif
+#if ((649 >= GSL_INCLUDER_FIRST_CASE) && (649 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (649))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 649),
+#endif
+#endif
+#if ((650 >= GSL_INCLUDER_FIRST_CASE) && (650 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (650))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 650),
+#endif
+#endif
+#if ((651 >= GSL_INCLUDER_FIRST_CASE) && (651 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (651))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 651),
+#endif
+#endif
+#if ((652 >= GSL_INCLUDER_FIRST_CASE) && (652 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (652))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 652),
+#endif
+#endif
+#if ((653 >= GSL_INCLUDER_FIRST_CASE) && (653 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (653))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 653),
+#endif
+#endif
+#if ((654 >= GSL_INCLUDER_FIRST_CASE) && (654 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (654))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 654),
+#endif
+#endif
+#if ((655 >= GSL_INCLUDER_FIRST_CASE) && (655 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (655))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 655),
+#endif
+#endif
+#if ((656 >= GSL_INCLUDER_FIRST_CASE) && (656 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (656))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 656),
+#endif
+#endif
+#if ((657 >= GSL_INCLUDER_FIRST_CASE) && (657 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (657))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 657),
+#endif
+#endif
+#if ((658 >= GSL_INCLUDER_FIRST_CASE) && (658 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (658))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 658),
+#endif
+#endif
+#if ((659 >= GSL_INCLUDER_FIRST_CASE) && (659 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (659))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 659),
+#endif
+#endif
+#if ((660 >= GSL_INCLUDER_FIRST_CASE) && (660 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (660))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 660),
+#endif
+#endif
+#if ((661 >= GSL_INCLUDER_FIRST_CASE) && (661 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (661))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 661),
+#endif
+#endif
+#if ((662 >= GSL_INCLUDER_FIRST_CASE) && (662 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (662))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 662),
+#endif
+#endif
+#if ((663 >= GSL_INCLUDER_FIRST_CASE) && (663 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (663))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 663),
+#endif
+#endif
+#if ((664 >= GSL_INCLUDER_FIRST_CASE) && (664 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (664))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 664),
+#endif
+#endif
+#if ((665 >= GSL_INCLUDER_FIRST_CASE) && (665 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (665))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 665),
+#endif
+#endif
+#if ((666 >= GSL_INCLUDER_FIRST_CASE) && (666 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (666))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 666),
+#endif
+#endif
+#if ((667 >= GSL_INCLUDER_FIRST_CASE) && (667 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (667))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 667),
+#endif
+#endif
+#if ((668 >= GSL_INCLUDER_FIRST_CASE) && (668 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (668))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 668),
+#endif
+#endif
+#if ((669 >= GSL_INCLUDER_FIRST_CASE) && (669 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (669))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 669),
+#endif
+#endif
+#if ((670 >= GSL_INCLUDER_FIRST_CASE) && (670 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (670))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 670),
+#endif
+#endif
+#if ((671 >= GSL_INCLUDER_FIRST_CASE) && (671 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (671))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 671),
+#endif
+#endif
+#if ((672 >= GSL_INCLUDER_FIRST_CASE) && (672 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (672))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 672),
+#endif
+#endif
+#if ((673 >= GSL_INCLUDER_FIRST_CASE) && (673 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (673))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 673),
+#endif
+#endif
+#if ((674 >= GSL_INCLUDER_FIRST_CASE) && (674 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (674))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 674),
+#endif
+#endif
+#if ((675 >= GSL_INCLUDER_FIRST_CASE) && (675 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (675))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 675),
+#endif
+#endif
+#if ((676 >= GSL_INCLUDER_FIRST_CASE) && (676 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (676))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 676),
+#endif
+#endif
+#if ((677 >= GSL_INCLUDER_FIRST_CASE) && (677 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (677))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 677),
+#endif
+#endif
+#if ((678 >= GSL_INCLUDER_FIRST_CASE) && (678 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (678))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 678),
+#endif
+#endif
+#if ((679 >= GSL_INCLUDER_FIRST_CASE) && (679 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (679))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 679),
+#endif
+#endif
+#if ((680 >= GSL_INCLUDER_FIRST_CASE) && (680 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (680))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 680),
+#endif
+#endif
+#if ((681 >= GSL_INCLUDER_FIRST_CASE) && (681 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (681))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 681),
+#endif
+#endif
+#if ((682 >= GSL_INCLUDER_FIRST_CASE) && (682 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (682))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 682),
+#endif
+#endif
+#if ((683 >= GSL_INCLUDER_FIRST_CASE) && (683 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (683))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 683),
+#endif
+#endif
+#if ((684 >= GSL_INCLUDER_FIRST_CASE) && (684 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (684))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 684),
+#endif
+#endif
+#if ((685 >= GSL_INCLUDER_FIRST_CASE) && (685 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (685))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 685),
+#endif
+#endif
+#if ((686 >= GSL_INCLUDER_FIRST_CASE) && (686 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (686))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 686),
+#endif
+#endif
+#if ((687 >= GSL_INCLUDER_FIRST_CASE) && (687 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (687))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 687),
+#endif
+#endif
+#if ((688 >= GSL_INCLUDER_FIRST_CASE) && (688 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (688))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 688),
+#endif
+#endif
+#if ((689 >= GSL_INCLUDER_FIRST_CASE) && (689 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (689))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 689),
+#endif
+#endif
+#if ((690 >= GSL_INCLUDER_FIRST_CASE) && (690 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (690))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 690),
+#endif
+#endif
+#if ((691 >= GSL_INCLUDER_FIRST_CASE) && (691 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (691))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 691),
+#endif
+#endif
+#if ((692 >= GSL_INCLUDER_FIRST_CASE) && (692 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (692))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 692),
+#endif
+#endif
+#if ((693 >= GSL_INCLUDER_FIRST_CASE) && (693 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (693))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 693),
+#endif
+#endif
+#if ((694 >= GSL_INCLUDER_FIRST_CASE) && (694 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (694))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 694),
+#endif
+#endif
+#if ((695 >= GSL_INCLUDER_FIRST_CASE) && (695 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (695))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 695),
+#endif
+#endif
+#if ((696 >= GSL_INCLUDER_FIRST_CASE) && (696 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (696))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 696),
+#endif
+#endif
+#if ((697 >= GSL_INCLUDER_FIRST_CASE) && (697 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (697))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 697),
+#endif
+#endif
+#if ((698 >= GSL_INCLUDER_FIRST_CASE) && (698 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (698))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 698),
+#endif
+#endif
+#if ((699 >= GSL_INCLUDER_FIRST_CASE) && (699 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (699))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 699),
+#endif
+#endif
+#if ((700 >= GSL_INCLUDER_FIRST_CASE) && (700 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (700))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 700),
+#endif
+#endif
+#if ((701 >= GSL_INCLUDER_FIRST_CASE) && (701 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (701))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 701),
+#endif
+#endif
+#if ((702 >= GSL_INCLUDER_FIRST_CASE) && (702 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (702))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 702),
+#endif
+#endif
+#if ((703 >= GSL_INCLUDER_FIRST_CASE) && (703 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (703))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 703),
+#endif
+#endif
+#if ((704 >= GSL_INCLUDER_FIRST_CASE) && (704 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (704))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 704),
+#endif
+#endif
+#if ((705 >= GSL_INCLUDER_FIRST_CASE) && (705 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (705))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 705),
+#endif
+#endif
+#if ((706 >= GSL_INCLUDER_FIRST_CASE) && (706 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (706))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 706),
+#endif
+#endif
+#if ((707 >= GSL_INCLUDER_FIRST_CASE) && (707 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (707))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 707),
+#endif
+#endif
+#if ((708 >= GSL_INCLUDER_FIRST_CASE) && (708 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (708))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 708),
+#endif
+#endif
+#if ((709 >= GSL_INCLUDER_FIRST_CASE) && (709 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (709))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 709),
+#endif
+#endif
+#if ((710 >= GSL_INCLUDER_FIRST_CASE) && (710 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (710))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 710),
+#endif
+#endif
+#if ((711 >= GSL_INCLUDER_FIRST_CASE) && (711 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (711))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 711),
+#endif
+#endif
+#if ((712 >= GSL_INCLUDER_FIRST_CASE) && (712 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (712))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 712),
+#endif
+#endif
+#if ((713 >= GSL_INCLUDER_FIRST_CASE) && (713 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (713))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 713),
+#endif
+#endif
+#if ((714 >= GSL_INCLUDER_FIRST_CASE) && (714 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (714))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 714),
+#endif
+#endif
+#if ((715 >= GSL_INCLUDER_FIRST_CASE) && (715 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (715))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 715),
+#endif
+#endif
+#if ((716 >= GSL_INCLUDER_FIRST_CASE) && (716 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (716))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 716),
+#endif
+#endif
+#if ((717 >= GSL_INCLUDER_FIRST_CASE) && (717 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (717))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 717),
+#endif
+#endif
+#if ((718 >= GSL_INCLUDER_FIRST_CASE) && (718 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (718))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 718),
+#endif
+#endif
+#if ((719 >= GSL_INCLUDER_FIRST_CASE) && (719 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (719))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 719),
+#endif
+#endif
+#if ((720 >= GSL_INCLUDER_FIRST_CASE) && (720 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (720))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 720),
+#endif
+#endif
+#if ((721 >= GSL_INCLUDER_FIRST_CASE) && (721 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (721))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 721),
+#endif
+#endif
+#if ((722 >= GSL_INCLUDER_FIRST_CASE) && (722 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (722))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 722),
+#endif
+#endif
+#if ((723 >= GSL_INCLUDER_FIRST_CASE) && (723 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (723))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 723),
+#endif
+#endif
+#if ((724 >= GSL_INCLUDER_FIRST_CASE) && (724 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (724))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 724),
+#endif
+#endif
+#if ((725 >= GSL_INCLUDER_FIRST_CASE) && (725 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (725))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 725),
+#endif
+#endif
+#if ((726 >= GSL_INCLUDER_FIRST_CASE) && (726 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (726))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 726),
+#endif
+#endif
+#if ((727 >= GSL_INCLUDER_FIRST_CASE) && (727 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (727))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 727),
+#endif
+#endif
+#if ((728 >= GSL_INCLUDER_FIRST_CASE) && (728 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (728))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 728),
+#endif
+#endif
+#if ((729 >= GSL_INCLUDER_FIRST_CASE) && (729 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (729))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 729),
+#endif
+#endif
+#if ((730 >= GSL_INCLUDER_FIRST_CASE) && (730 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (730))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 730),
+#endif
+#endif
+#if ((731 >= GSL_INCLUDER_FIRST_CASE) && (731 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (731))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 731),
+#endif
+#endif
+#if ((732 >= GSL_INCLUDER_FIRST_CASE) && (732 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (732))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 732),
+#endif
+#endif
+#if ((733 >= GSL_INCLUDER_FIRST_CASE) && (733 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (733))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 733),
+#endif
+#endif
+#if ((734 >= GSL_INCLUDER_FIRST_CASE) && (734 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (734))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 734),
+#endif
+#endif
+#if ((735 >= GSL_INCLUDER_FIRST_CASE) && (735 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (735))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 735),
+#endif
+#endif
+#if ((736 >= GSL_INCLUDER_FIRST_CASE) && (736 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (736))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 736),
+#endif
+#endif
+#if ((737 >= GSL_INCLUDER_FIRST_CASE) && (737 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (737))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 737),
+#endif
+#endif
+#if ((738 >= GSL_INCLUDER_FIRST_CASE) && (738 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (738))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 738),
+#endif
+#endif
+#if ((739 >= GSL_INCLUDER_FIRST_CASE) && (739 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (739))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 739),
+#endif
+#endif
+#if ((740 >= GSL_INCLUDER_FIRST_CASE) && (740 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (740))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 740),
+#endif
+#endif
+#if ((741 >= GSL_INCLUDER_FIRST_CASE) && (741 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (741))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 741),
+#endif
+#endif
+#if ((742 >= GSL_INCLUDER_FIRST_CASE) && (742 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (742))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 742),
+#endif
+#endif
+#if ((743 >= GSL_INCLUDER_FIRST_CASE) && (743 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (743))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 743),
+#endif
+#endif
+#if ((744 >= GSL_INCLUDER_FIRST_CASE) && (744 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (744))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 744),
+#endif
+#endif
+#if ((745 >= GSL_INCLUDER_FIRST_CASE) && (745 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (745))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 745),
+#endif
+#endif
+#if ((746 >= GSL_INCLUDER_FIRST_CASE) && (746 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (746))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 746),
+#endif
+#endif
+#if ((747 >= GSL_INCLUDER_FIRST_CASE) && (747 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (747))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 747),
+#endif
+#endif
+#if ((748 >= GSL_INCLUDER_FIRST_CASE) && (748 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (748))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 748),
+#endif
+#endif
+#if ((749 >= GSL_INCLUDER_FIRST_CASE) && (749 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (749))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 749),
+#endif
+#endif
+#if ((750 >= GSL_INCLUDER_FIRST_CASE) && (750 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (750))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 750),
+#endif
+#endif
+#if ((751 >= GSL_INCLUDER_FIRST_CASE) && (751 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (751))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 751),
+#endif
+#endif
+#if ((752 >= GSL_INCLUDER_FIRST_CASE) && (752 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (752))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 752),
+#endif
+#endif
+#if ((753 >= GSL_INCLUDER_FIRST_CASE) && (753 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (753))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 753),
+#endif
+#endif
+#if ((754 >= GSL_INCLUDER_FIRST_CASE) && (754 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (754))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 754),
+#endif
+#endif
+#if ((755 >= GSL_INCLUDER_FIRST_CASE) && (755 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (755))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 755),
+#endif
+#endif
+#if ((756 >= GSL_INCLUDER_FIRST_CASE) && (756 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (756))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 756),
+#endif
+#endif
+#if ((757 >= GSL_INCLUDER_FIRST_CASE) && (757 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (757))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 757),
+#endif
+#endif
+#if ((758 >= GSL_INCLUDER_FIRST_CASE) && (758 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (758))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 758),
+#endif
+#endif
+#if ((759 >= GSL_INCLUDER_FIRST_CASE) && (759 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (759))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 759),
+#endif
+#endif
+#if ((760 >= GSL_INCLUDER_FIRST_CASE) && (760 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (760))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 760),
+#endif
+#endif
+#if ((761 >= GSL_INCLUDER_FIRST_CASE) && (761 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (761))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 761),
+#endif
+#endif
+#if ((762 >= GSL_INCLUDER_FIRST_CASE) && (762 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (762))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 762),
+#endif
+#endif
+#if ((763 >= GSL_INCLUDER_FIRST_CASE) && (763 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (763))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 763),
+#endif
+#endif
+#if ((764 >= GSL_INCLUDER_FIRST_CASE) && (764 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (764))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 764),
+#endif
+#endif
+#if ((765 >= GSL_INCLUDER_FIRST_CASE) && (765 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (765))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 765),
+#endif
+#endif
+#if ((766 >= GSL_INCLUDER_FIRST_CASE) && (766 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (766))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 766),
+#endif
+#endif
+#if ((767 >= GSL_INCLUDER_FIRST_CASE) && (767 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (767))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 767),
+#endif
+#endif
+#if ((768 >= GSL_INCLUDER_FIRST_CASE) && (768 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (768))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 768),
+#endif
+#endif
+#if ((769 >= GSL_INCLUDER_FIRST_CASE) && (769 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (769))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 769),
+#endif
+#endif
+#if ((770 >= GSL_INCLUDER_FIRST_CASE) && (770 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (770))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 770),
+#endif
+#endif
+#if ((771 >= GSL_INCLUDER_FIRST_CASE) && (771 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (771))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 771),
+#endif
+#endif
+#if ((772 >= GSL_INCLUDER_FIRST_CASE) && (772 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (772))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 772),
+#endif
+#endif
+#if ((773 >= GSL_INCLUDER_FIRST_CASE) && (773 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (773))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 773),
+#endif
+#endif
+#if ((774 >= GSL_INCLUDER_FIRST_CASE) && (774 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (774))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 774),
+#endif
+#endif
+#if ((775 >= GSL_INCLUDER_FIRST_CASE) && (775 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (775))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 775),
+#endif
+#endif
+#if ((776 >= GSL_INCLUDER_FIRST_CASE) && (776 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (776))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 776),
+#endif
+#endif
+#if ((777 >= GSL_INCLUDER_FIRST_CASE) && (777 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (777))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 777),
+#endif
+#endif
+#if ((778 >= GSL_INCLUDER_FIRST_CASE) && (778 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (778))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 778),
+#endif
+#endif
+#if ((779 >= GSL_INCLUDER_FIRST_CASE) && (779 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (779))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 779),
+#endif
+#endif
+#if ((780 >= GSL_INCLUDER_FIRST_CASE) && (780 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (780))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 780),
+#endif
+#endif
+#if ((781 >= GSL_INCLUDER_FIRST_CASE) && (781 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (781))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 781),
+#endif
+#endif
+#if ((782 >= GSL_INCLUDER_FIRST_CASE) && (782 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (782))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 782),
+#endif
+#endif
+#if ((783 >= GSL_INCLUDER_FIRST_CASE) && (783 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (783))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 783),
+#endif
+#endif
+#if ((784 >= GSL_INCLUDER_FIRST_CASE) && (784 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (784))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 784),
+#endif
+#endif
+#if ((785 >= GSL_INCLUDER_FIRST_CASE) && (785 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (785))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 785),
+#endif
+#endif
+#if ((786 >= GSL_INCLUDER_FIRST_CASE) && (786 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (786))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 786),
+#endif
+#endif
+#if ((787 >= GSL_INCLUDER_FIRST_CASE) && (787 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (787))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 787),
+#endif
+#endif
+#if ((788 >= GSL_INCLUDER_FIRST_CASE) && (788 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (788))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 788),
+#endif
+#endif
+#if ((789 >= GSL_INCLUDER_FIRST_CASE) && (789 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (789))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 789),
+#endif
+#endif
+#if ((790 >= GSL_INCLUDER_FIRST_CASE) && (790 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (790))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 790),
+#endif
+#endif
+#if ((791 >= GSL_INCLUDER_FIRST_CASE) && (791 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (791))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 791),
+#endif
+#endif
+#if ((792 >= GSL_INCLUDER_FIRST_CASE) && (792 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (792))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 792),
+#endif
+#endif
+#if ((793 >= GSL_INCLUDER_FIRST_CASE) && (793 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (793))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 793),
+#endif
+#endif
+#if ((794 >= GSL_INCLUDER_FIRST_CASE) && (794 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (794))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 794),
+#endif
+#endif
+#if ((795 >= GSL_INCLUDER_FIRST_CASE) && (795 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (795))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 795),
+#endif
+#endif
+#if ((796 >= GSL_INCLUDER_FIRST_CASE) && (796 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (796))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 796),
+#endif
+#endif
+#if ((797 >= GSL_INCLUDER_FIRST_CASE) && (797 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (797))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 797),
+#endif
+#endif
+#if ((798 >= GSL_INCLUDER_FIRST_CASE) && (798 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (798))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 798),
+#endif
+#endif
+#if ((799 >= GSL_INCLUDER_FIRST_CASE) && (799 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (799))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 799),
+#endif
+#endif
+#if ((800 >= GSL_INCLUDER_FIRST_CASE) && (800 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (800))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 800),
+#endif
+#endif
+#if ((801 >= GSL_INCLUDER_FIRST_CASE) && (801 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (801))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 801),
+#endif
+#endif
+#if ((802 >= GSL_INCLUDER_FIRST_CASE) && (802 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (802))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 802),
+#endif
+#endif
+#if ((803 >= GSL_INCLUDER_FIRST_CASE) && (803 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (803))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 803),
+#endif
+#endif
+#if ((804 >= GSL_INCLUDER_FIRST_CASE) && (804 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (804))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 804),
+#endif
+#endif
+#if ((805 >= GSL_INCLUDER_FIRST_CASE) && (805 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (805))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 805),
+#endif
+#endif
+#if ((806 >= GSL_INCLUDER_FIRST_CASE) && (806 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (806))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 806),
+#endif
+#endif
+#if ((807 >= GSL_INCLUDER_FIRST_CASE) && (807 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (807))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 807),
+#endif
+#endif
+#if ((808 >= GSL_INCLUDER_FIRST_CASE) && (808 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (808))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 808),
+#endif
+#endif
+#if ((809 >= GSL_INCLUDER_FIRST_CASE) && (809 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (809))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 809),
+#endif
+#endif
+#if ((810 >= GSL_INCLUDER_FIRST_CASE) && (810 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (810))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 810),
+#endif
+#endif
+#if ((811 >= GSL_INCLUDER_FIRST_CASE) && (811 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (811))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 811),
+#endif
+#endif
+#if ((812 >= GSL_INCLUDER_FIRST_CASE) && (812 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (812))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 812),
+#endif
+#endif
+#if ((813 >= GSL_INCLUDER_FIRST_CASE) && (813 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (813))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 813),
+#endif
+#endif
+#if ((814 >= GSL_INCLUDER_FIRST_CASE) && (814 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (814))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 814),
+#endif
+#endif
+#if ((815 >= GSL_INCLUDER_FIRST_CASE) && (815 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (815))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 815),
+#endif
+#endif
+#if ((816 >= GSL_INCLUDER_FIRST_CASE) && (816 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (816))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 816),
+#endif
+#endif
+#if ((817 >= GSL_INCLUDER_FIRST_CASE) && (817 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (817))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 817),
+#endif
+#endif
+#if ((818 >= GSL_INCLUDER_FIRST_CASE) && (818 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (818))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 818),
+#endif
+#endif
+#if ((819 >= GSL_INCLUDER_FIRST_CASE) && (819 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (819))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 819),
+#endif
+#endif
+#if ((820 >= GSL_INCLUDER_FIRST_CASE) && (820 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (820))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 820),
+#endif
+#endif
+#if ((821 >= GSL_INCLUDER_FIRST_CASE) && (821 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (821))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 821),
+#endif
+#endif
+#if ((822 >= GSL_INCLUDER_FIRST_CASE) && (822 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (822))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 822),
+#endif
+#endif
+#if ((823 >= GSL_INCLUDER_FIRST_CASE) && (823 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (823))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 823),
+#endif
+#endif
+#if ((824 >= GSL_INCLUDER_FIRST_CASE) && (824 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (824))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 824),
+#endif
+#endif
+#if ((825 >= GSL_INCLUDER_FIRST_CASE) && (825 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (825))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 825),
+#endif
+#endif
+#if ((826 >= GSL_INCLUDER_FIRST_CASE) && (826 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (826))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 826),
+#endif
+#endif
+#if ((827 >= GSL_INCLUDER_FIRST_CASE) && (827 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (827))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 827),
+#endif
+#endif
+#if ((828 >= GSL_INCLUDER_FIRST_CASE) && (828 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (828))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 828),
+#endif
+#endif
+#if ((829 >= GSL_INCLUDER_FIRST_CASE) && (829 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (829))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 829),
+#endif
+#endif
+#if ((830 >= GSL_INCLUDER_FIRST_CASE) && (830 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (830))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 830),
+#endif
+#endif
+#if ((831 >= GSL_INCLUDER_FIRST_CASE) && (831 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (831))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 831),
+#endif
+#endif
+#if ((832 >= GSL_INCLUDER_FIRST_CASE) && (832 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (832))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 832),
+#endif
+#endif
+#if ((833 >= GSL_INCLUDER_FIRST_CASE) && (833 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (833))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 833),
+#endif
+#endif
+#if ((834 >= GSL_INCLUDER_FIRST_CASE) && (834 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (834))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 834),
+#endif
+#endif
+#if ((835 >= GSL_INCLUDER_FIRST_CASE) && (835 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (835))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 835),
+#endif
+#endif
+#if ((836 >= GSL_INCLUDER_FIRST_CASE) && (836 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (836))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 836),
+#endif
+#endif
+#if ((837 >= GSL_INCLUDER_FIRST_CASE) && (837 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (837))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 837),
+#endif
+#endif
+#if ((838 >= GSL_INCLUDER_FIRST_CASE) && (838 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (838))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 838),
+#endif
+#endif
+#if ((839 >= GSL_INCLUDER_FIRST_CASE) && (839 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (839))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 839),
+#endif
+#endif
+#if ((840 >= GSL_INCLUDER_FIRST_CASE) && (840 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (840))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 840),
+#endif
+#endif
+#if ((841 >= GSL_INCLUDER_FIRST_CASE) && (841 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (841))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 841),
+#endif
+#endif
+#if ((842 >= GSL_INCLUDER_FIRST_CASE) && (842 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (842))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 842),
+#endif
+#endif
+#if ((843 >= GSL_INCLUDER_FIRST_CASE) && (843 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (843))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 843),
+#endif
+#endif
+#if ((844 >= GSL_INCLUDER_FIRST_CASE) && (844 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (844))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 844),
+#endif
+#endif
+#if ((845 >= GSL_INCLUDER_FIRST_CASE) && (845 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (845))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 845),
+#endif
+#endif
+#if ((846 >= GSL_INCLUDER_FIRST_CASE) && (846 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (846))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 846),
+#endif
+#endif
+#if ((847 >= GSL_INCLUDER_FIRST_CASE) && (847 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (847))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 847),
+#endif
+#endif
+#if ((848 >= GSL_INCLUDER_FIRST_CASE) && (848 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (848))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 848),
+#endif
+#endif
+#if ((849 >= GSL_INCLUDER_FIRST_CASE) && (849 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (849))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 849),
+#endif
+#endif
+#if ((850 >= GSL_INCLUDER_FIRST_CASE) && (850 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (850))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 850),
+#endif
+#endif
+#if ((851 >= GSL_INCLUDER_FIRST_CASE) && (851 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (851))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 851),
+#endif
+#endif
+#if ((852 >= GSL_INCLUDER_FIRST_CASE) && (852 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (852))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 852),
+#endif
+#endif
+#if ((853 >= GSL_INCLUDER_FIRST_CASE) && (853 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (853))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 853),
+#endif
+#endif
+#if ((854 >= GSL_INCLUDER_FIRST_CASE) && (854 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (854))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 854),
+#endif
+#endif
+#if ((855 >= GSL_INCLUDER_FIRST_CASE) && (855 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (855))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 855),
+#endif
+#endif
+#if ((856 >= GSL_INCLUDER_FIRST_CASE) && (856 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (856))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 856),
+#endif
+#endif
+#if ((857 >= GSL_INCLUDER_FIRST_CASE) && (857 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (857))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 857),
+#endif
+#endif
+#if ((858 >= GSL_INCLUDER_FIRST_CASE) && (858 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (858))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 858),
+#endif
+#endif
+#if ((859 >= GSL_INCLUDER_FIRST_CASE) && (859 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (859))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 859),
+#endif
+#endif
+#if ((860 >= GSL_INCLUDER_FIRST_CASE) && (860 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (860))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 860),
+#endif
+#endif
+#if ((861 >= GSL_INCLUDER_FIRST_CASE) && (861 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (861))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 861),
+#endif
+#endif
+#if ((862 >= GSL_INCLUDER_FIRST_CASE) && (862 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (862))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 862),
+#endif
+#endif
+#if ((863 >= GSL_INCLUDER_FIRST_CASE) && (863 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (863))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 863),
+#endif
+#endif
+#if ((864 >= GSL_INCLUDER_FIRST_CASE) && (864 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (864))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 864),
+#endif
+#endif
+#if ((865 >= GSL_INCLUDER_FIRST_CASE) && (865 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (865))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 865),
+#endif
+#endif
+#if ((866 >= GSL_INCLUDER_FIRST_CASE) && (866 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (866))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 866),
+#endif
+#endif
+#if ((867 >= GSL_INCLUDER_FIRST_CASE) && (867 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (867))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 867),
+#endif
+#endif
+#if ((868 >= GSL_INCLUDER_FIRST_CASE) && (868 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (868))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 868),
+#endif
+#endif
+#if ((869 >= GSL_INCLUDER_FIRST_CASE) && (869 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (869))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 869),
+#endif
+#endif
+#if ((870 >= GSL_INCLUDER_FIRST_CASE) && (870 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (870))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 870),
+#endif
+#endif
+#if ((871 >= GSL_INCLUDER_FIRST_CASE) && (871 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (871))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 871),
+#endif
+#endif
+#if ((872 >= GSL_INCLUDER_FIRST_CASE) && (872 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (872))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 872),
+#endif
+#endif
+#if ((873 >= GSL_INCLUDER_FIRST_CASE) && (873 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (873))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 873),
+#endif
+#endif
+#if ((874 >= GSL_INCLUDER_FIRST_CASE) && (874 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (874))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 874),
+#endif
+#endif
+#if ((875 >= GSL_INCLUDER_FIRST_CASE) && (875 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (875))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 875),
+#endif
+#endif
+#if ((876 >= GSL_INCLUDER_FIRST_CASE) && (876 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (876))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 876),
+#endif
+#endif
+#if ((877 >= GSL_INCLUDER_FIRST_CASE) && (877 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (877))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 877),
+#endif
+#endif
+#if ((878 >= GSL_INCLUDER_FIRST_CASE) && (878 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (878))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 878),
+#endif
+#endif
+#if ((879 >= GSL_INCLUDER_FIRST_CASE) && (879 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (879))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 879),
+#endif
+#endif
+#if ((880 >= GSL_INCLUDER_FIRST_CASE) && (880 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (880))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 880),
+#endif
+#endif
+#if ((881 >= GSL_INCLUDER_FIRST_CASE) && (881 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (881))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 881),
+#endif
+#endif
+#if ((882 >= GSL_INCLUDER_FIRST_CASE) && (882 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (882))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 882),
+#endif
+#endif
+#if ((883 >= GSL_INCLUDER_FIRST_CASE) && (883 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (883))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 883),
+#endif
+#endif
+#if ((884 >= GSL_INCLUDER_FIRST_CASE) && (884 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (884))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 884),
+#endif
+#endif
+#if ((885 >= GSL_INCLUDER_FIRST_CASE) && (885 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (885))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 885),
+#endif
+#endif
+#if ((886 >= GSL_INCLUDER_FIRST_CASE) && (886 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (886))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 886),
+#endif
+#endif
+#if ((887 >= GSL_INCLUDER_FIRST_CASE) && (887 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (887))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 887),
+#endif
+#endif
+#if ((888 >= GSL_INCLUDER_FIRST_CASE) && (888 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (888))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 888),
+#endif
+#endif
+#if ((889 >= GSL_INCLUDER_FIRST_CASE) && (889 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (889))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 889),
+#endif
+#endif
+#if ((890 >= GSL_INCLUDER_FIRST_CASE) && (890 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (890))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 890),
+#endif
+#endif
+#if ((891 >= GSL_INCLUDER_FIRST_CASE) && (891 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (891))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 891),
+#endif
+#endif
+#if ((892 >= GSL_INCLUDER_FIRST_CASE) && (892 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (892))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 892),
+#endif
+#endif
+#if ((893 >= GSL_INCLUDER_FIRST_CASE) && (893 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (893))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 893),
+#endif
+#endif
+#if ((894 >= GSL_INCLUDER_FIRST_CASE) && (894 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (894))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 894),
+#endif
+#endif
+#if ((895 >= GSL_INCLUDER_FIRST_CASE) && (895 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (895))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 895),
+#endif
+#endif
+#if ((896 >= GSL_INCLUDER_FIRST_CASE) && (896 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (896))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 896),
+#endif
+#endif
+#if ((897 >= GSL_INCLUDER_FIRST_CASE) && (897 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (897))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 897),
+#endif
+#endif
+#if ((898 >= GSL_INCLUDER_FIRST_CASE) && (898 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (898))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 898),
+#endif
+#endif
+#if ((899 >= GSL_INCLUDER_FIRST_CASE) && (899 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (899))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 899),
+#endif
+#endif
+#if ((900 >= GSL_INCLUDER_FIRST_CASE) && (900 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (900))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 900),
+#endif
+#endif
+#if ((901 >= GSL_INCLUDER_FIRST_CASE) && (901 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (901))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 901),
+#endif
+#endif
+#if ((902 >= GSL_INCLUDER_FIRST_CASE) && (902 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (902))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 902),
+#endif
+#endif
+#if ((903 >= GSL_INCLUDER_FIRST_CASE) && (903 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (903))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 903),
+#endif
+#endif
+#if ((904 >= GSL_INCLUDER_FIRST_CASE) && (904 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (904))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 904),
+#endif
+#endif
+#if ((905 >= GSL_INCLUDER_FIRST_CASE) && (905 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (905))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 905),
+#endif
+#endif
+#if ((906 >= GSL_INCLUDER_FIRST_CASE) && (906 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (906))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 906),
+#endif
+#endif
+#if ((907 >= GSL_INCLUDER_FIRST_CASE) && (907 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (907))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 907),
+#endif
+#endif
+#if ((908 >= GSL_INCLUDER_FIRST_CASE) && (908 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (908))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 908),
+#endif
+#endif
+#if ((909 >= GSL_INCLUDER_FIRST_CASE) && (909 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (909))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 909),
+#endif
+#endif
+#if ((910 >= GSL_INCLUDER_FIRST_CASE) && (910 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (910))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 910),
+#endif
+#endif
+#if ((911 >= GSL_INCLUDER_FIRST_CASE) && (911 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (911))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 911),
+#endif
+#endif
+#if ((912 >= GSL_INCLUDER_FIRST_CASE) && (912 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (912))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 912),
+#endif
+#endif
+#if ((913 >= GSL_INCLUDER_FIRST_CASE) && (913 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (913))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 913),
+#endif
+#endif
+#if ((914 >= GSL_INCLUDER_FIRST_CASE) && (914 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (914))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 914),
+#endif
+#endif
+#if ((915 >= GSL_INCLUDER_FIRST_CASE) && (915 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (915))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 915),
+#endif
+#endif
+#if ((916 >= GSL_INCLUDER_FIRST_CASE) && (916 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (916))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 916),
+#endif
+#endif
+#if ((917 >= GSL_INCLUDER_FIRST_CASE) && (917 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (917))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 917),
+#endif
+#endif
+#if ((918 >= GSL_INCLUDER_FIRST_CASE) && (918 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (918))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 918),
+#endif
+#endif
+#if ((919 >= GSL_INCLUDER_FIRST_CASE) && (919 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (919))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 919),
+#endif
+#endif
+#if ((920 >= GSL_INCLUDER_FIRST_CASE) && (920 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (920))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 920),
+#endif
+#endif
+#if ((921 >= GSL_INCLUDER_FIRST_CASE) && (921 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (921))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 921),
+#endif
+#endif
+#if ((922 >= GSL_INCLUDER_FIRST_CASE) && (922 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (922))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 922),
+#endif
+#endif
+#if ((923 >= GSL_INCLUDER_FIRST_CASE) && (923 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (923))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 923),
+#endif
+#endif
+#if ((924 >= GSL_INCLUDER_FIRST_CASE) && (924 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (924))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 924),
+#endif
+#endif
+#if ((925 >= GSL_INCLUDER_FIRST_CASE) && (925 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (925))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 925),
+#endif
+#endif
+#if ((926 >= GSL_INCLUDER_FIRST_CASE) && (926 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (926))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 926),
+#endif
+#endif
+#if ((927 >= GSL_INCLUDER_FIRST_CASE) && (927 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (927))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 927),
+#endif
+#endif
+#if ((928 >= GSL_INCLUDER_FIRST_CASE) && (928 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (928))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 928),
+#endif
+#endif
+#if ((929 >= GSL_INCLUDER_FIRST_CASE) && (929 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (929))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 929),
+#endif
+#endif
+#if ((930 >= GSL_INCLUDER_FIRST_CASE) && (930 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (930))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 930),
+#endif
+#endif
+#if ((931 >= GSL_INCLUDER_FIRST_CASE) && (931 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (931))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 931),
+#endif
+#endif
+#if ((932 >= GSL_INCLUDER_FIRST_CASE) && (932 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (932))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 932),
+#endif
+#endif
+#if ((933 >= GSL_INCLUDER_FIRST_CASE) && (933 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (933))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 933),
+#endif
+#endif
+#if ((934 >= GSL_INCLUDER_FIRST_CASE) && (934 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (934))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 934),
+#endif
+#endif
+#if ((935 >= GSL_INCLUDER_FIRST_CASE) && (935 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (935))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 935),
+#endif
+#endif
+#if ((936 >= GSL_INCLUDER_FIRST_CASE) && (936 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (936))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 936),
+#endif
+#endif
+#if ((937 >= GSL_INCLUDER_FIRST_CASE) && (937 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (937))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 937),
+#endif
+#endif
+#if ((938 >= GSL_INCLUDER_FIRST_CASE) && (938 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (938))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 938),
+#endif
+#endif
+#if ((939 >= GSL_INCLUDER_FIRST_CASE) && (939 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (939))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 939),
+#endif
+#endif
+#if ((940 >= GSL_INCLUDER_FIRST_CASE) && (940 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (940))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 940),
+#endif
+#endif
+#if ((941 >= GSL_INCLUDER_FIRST_CASE) && (941 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (941))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 941),
+#endif
+#endif
+#if ((942 >= GSL_INCLUDER_FIRST_CASE) && (942 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (942))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 942),
+#endif
+#endif
+#if ((943 >= GSL_INCLUDER_FIRST_CASE) && (943 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (943))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 943),
+#endif
+#endif
+#if ((944 >= GSL_INCLUDER_FIRST_CASE) && (944 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (944))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 944),
+#endif
+#endif
+#if ((945 >= GSL_INCLUDER_FIRST_CASE) && (945 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (945))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 945),
+#endif
+#endif
+#if ((946 >= GSL_INCLUDER_FIRST_CASE) && (946 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (946))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 946),
+#endif
+#endif
+#if ((947 >= GSL_INCLUDER_FIRST_CASE) && (947 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (947))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 947),
+#endif
+#endif
+#if ((948 >= GSL_INCLUDER_FIRST_CASE) && (948 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (948))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 948),
+#endif
+#endif
+#if ((949 >= GSL_INCLUDER_FIRST_CASE) && (949 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (949))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 949),
+#endif
+#endif
+#if ((950 >= GSL_INCLUDER_FIRST_CASE) && (950 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (950))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 950),
+#endif
+#endif
+#if ((951 >= GSL_INCLUDER_FIRST_CASE) && (951 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (951))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 951),
+#endif
+#endif
+#if ((952 >= GSL_INCLUDER_FIRST_CASE) && (952 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (952))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 952),
+#endif
+#endif
+#if ((953 >= GSL_INCLUDER_FIRST_CASE) && (953 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (953))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 953),
+#endif
+#endif
+#if ((954 >= GSL_INCLUDER_FIRST_CASE) && (954 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (954))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 954),
+#endif
+#endif
+#if ((955 >= GSL_INCLUDER_FIRST_CASE) && (955 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (955))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 955),
+#endif
+#endif
+#if ((956 >= GSL_INCLUDER_FIRST_CASE) && (956 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (956))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 956),
+#endif
+#endif
+#if ((957 >= GSL_INCLUDER_FIRST_CASE) && (957 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (957))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 957),
+#endif
+#endif
+#if ((958 >= GSL_INCLUDER_FIRST_CASE) && (958 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (958))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 958),
+#endif
+#endif
+#if ((959 >= GSL_INCLUDER_FIRST_CASE) && (959 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (959))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 959),
+#endif
+#endif
+#if ((960 >= GSL_INCLUDER_FIRST_CASE) && (960 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (960))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 960),
+#endif
+#endif
+#if ((961 >= GSL_INCLUDER_FIRST_CASE) && (961 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (961))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 961),
+#endif
+#endif
+#if ((962 >= GSL_INCLUDER_FIRST_CASE) && (962 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (962))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 962),
+#endif
+#endif
+#if ((963 >= GSL_INCLUDER_FIRST_CASE) && (963 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (963))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 963),
+#endif
+#endif
+#if ((964 >= GSL_INCLUDER_FIRST_CASE) && (964 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (964))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 964),
+#endif
+#endif
+#if ((965 >= GSL_INCLUDER_FIRST_CASE) && (965 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (965))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 965),
+#endif
+#endif
+#if ((966 >= GSL_INCLUDER_FIRST_CASE) && (966 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (966))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 966),
+#endif
+#endif
+#if ((967 >= GSL_INCLUDER_FIRST_CASE) && (967 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (967))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 967),
+#endif
+#endif
+#if ((968 >= GSL_INCLUDER_FIRST_CASE) && (968 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (968))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 968),
+#endif
+#endif
+#if ((969 >= GSL_INCLUDER_FIRST_CASE) && (969 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (969))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 969),
+#endif
+#endif
+#if ((970 >= GSL_INCLUDER_FIRST_CASE) && (970 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (970))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 970),
+#endif
+#endif
+#if ((971 >= GSL_INCLUDER_FIRST_CASE) && (971 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (971))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 971),
+#endif
+#endif
+#if ((972 >= GSL_INCLUDER_FIRST_CASE) && (972 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (972))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 972),
+#endif
+#endif
+#if ((973 >= GSL_INCLUDER_FIRST_CASE) && (973 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (973))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 973),
+#endif
+#endif
+#if ((974 >= GSL_INCLUDER_FIRST_CASE) && (974 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (974))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 974),
+#endif
+#endif
+#if ((975 >= GSL_INCLUDER_FIRST_CASE) && (975 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (975))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 975),
+#endif
+#endif
+#if ((976 >= GSL_INCLUDER_FIRST_CASE) && (976 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (976))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 976),
+#endif
+#endif
+#if ((977 >= GSL_INCLUDER_FIRST_CASE) && (977 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (977))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 977),
+#endif
+#endif
+#if ((978 >= GSL_INCLUDER_FIRST_CASE) && (978 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (978))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 978),
+#endif
+#endif
+#if ((979 >= GSL_INCLUDER_FIRST_CASE) && (979 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (979))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 979),
+#endif
+#endif
+#if ((980 >= GSL_INCLUDER_FIRST_CASE) && (980 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (980))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 980),
+#endif
+#endif
+#if ((981 >= GSL_INCLUDER_FIRST_CASE) && (981 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (981))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 981),
+#endif
+#endif
+#if ((982 >= GSL_INCLUDER_FIRST_CASE) && (982 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (982))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 982),
+#endif
+#endif
+#if ((983 >= GSL_INCLUDER_FIRST_CASE) && (983 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (983))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 983),
+#endif
+#endif
+#if ((984 >= GSL_INCLUDER_FIRST_CASE) && (984 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (984))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 984),
+#endif
+#endif
+#if ((985 >= GSL_INCLUDER_FIRST_CASE) && (985 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (985))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 985),
+#endif
+#endif
+#if ((986 >= GSL_INCLUDER_FIRST_CASE) && (986 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (986))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 986),
+#endif
+#endif
+#if ((987 >= GSL_INCLUDER_FIRST_CASE) && (987 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (987))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 987),
+#endif
+#endif
+#if ((988 >= GSL_INCLUDER_FIRST_CASE) && (988 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (988))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 988),
+#endif
+#endif
+#if ((989 >= GSL_INCLUDER_FIRST_CASE) && (989 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (989))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 989),
+#endif
+#endif
+#if ((990 >= GSL_INCLUDER_FIRST_CASE) && (990 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (990))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 990),
+#endif
+#endif
+#if ((991 >= GSL_INCLUDER_FIRST_CASE) && (991 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (991))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 991),
+#endif
+#endif
+#if ((992 >= GSL_INCLUDER_FIRST_CASE) && (992 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (992))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 992),
+#endif
+#endif
+#if ((993 >= GSL_INCLUDER_FIRST_CASE) && (993 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (993))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 993),
+#endif
+#endif
+#if ((994 >= GSL_INCLUDER_FIRST_CASE) && (994 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (994))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 994),
+#endif
+#endif
+#if ((995 >= GSL_INCLUDER_FIRST_CASE) && (995 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (995))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 995),
+#endif
+#endif
+#if ((996 >= GSL_INCLUDER_FIRST_CASE) && (996 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (996))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 996),
+#endif
+#endif
+#if ((997 >= GSL_INCLUDER_FIRST_CASE) && (997 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (997))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 997),
+#endif
+#endif
+#if ((998 >= GSL_INCLUDER_FIRST_CASE) && (998 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (998))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 998),
+#endif
+#endif
+#if ((999 >= GSL_INCLUDER_FIRST_CASE) && (999 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (999))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 999),
+#endif
+#endif
+#if ((1000 >= GSL_INCLUDER_FIRST_CASE) && (1000 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1000))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1000),
+#endif
+#endif
+#if ((1001 >= GSL_INCLUDER_FIRST_CASE) && (1001 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1001))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1001),
+#endif
+#endif
+#if ((1002 >= GSL_INCLUDER_FIRST_CASE) && (1002 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1002))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1002),
+#endif
+#endif
+#if ((1003 >= GSL_INCLUDER_FIRST_CASE) && (1003 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1003))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1003),
+#endif
+#endif
+#if ((1004 >= GSL_INCLUDER_FIRST_CASE) && (1004 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1004))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1004),
+#endif
+#endif
+#if ((1005 >= GSL_INCLUDER_FIRST_CASE) && (1005 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1005))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1005),
+#endif
+#endif
+#if ((1006 >= GSL_INCLUDER_FIRST_CASE) && (1006 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1006))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1006),
+#endif
+#endif
+#if ((1007 >= GSL_INCLUDER_FIRST_CASE) && (1007 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1007))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1007),
+#endif
+#endif
+#if ((1008 >= GSL_INCLUDER_FIRST_CASE) && (1008 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1008))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1008),
+#endif
+#endif
+#if ((1009 >= GSL_INCLUDER_FIRST_CASE) && (1009 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1009))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1009),
+#endif
+#endif
+#if ((1010 >= GSL_INCLUDER_FIRST_CASE) && (1010 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1010))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1010),
+#endif
+#endif
+#if ((1011 >= GSL_INCLUDER_FIRST_CASE) && (1011 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1011))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1011),
+#endif
+#endif
+#if ((1012 >= GSL_INCLUDER_FIRST_CASE) && (1012 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1012))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1012),
+#endif
+#endif
+#if ((1013 >= GSL_INCLUDER_FIRST_CASE) && (1013 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1013))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1013),
+#endif
+#endif
+#if ((1014 >= GSL_INCLUDER_FIRST_CASE) && (1014 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1014))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1014),
+#endif
+#endif
+#if ((1015 >= GSL_INCLUDER_FIRST_CASE) && (1015 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1015))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1015),
+#endif
+#endif
+#if ((1016 >= GSL_INCLUDER_FIRST_CASE) && (1016 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1016))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1016),
+#endif
+#endif
+#if ((1017 >= GSL_INCLUDER_FIRST_CASE) && (1017 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1017))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1017),
+#endif
+#endif
+#if ((1018 >= GSL_INCLUDER_FIRST_CASE) && (1018 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1018))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1018),
+#endif
+#endif
+#if ((1019 >= GSL_INCLUDER_FIRST_CASE) && (1019 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1019))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1019),
+#endif
+#endif
+#if ((1020 >= GSL_INCLUDER_FIRST_CASE) && (1020 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1020))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1020),
+#endif
+#endif
+#if ((1021 >= GSL_INCLUDER_FIRST_CASE) && (1021 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1021))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1021),
+#endif
+#endif
+#if ((1022 >= GSL_INCLUDER_FIRST_CASE) && (1022 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1022))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1022),
+#endif
+#endif
+#if ((1023 >= GSL_INCLUDER_FIRST_CASE) && (1023 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1023))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1023),
+#endif
+#endif
+#if ((1024 >= GSL_INCLUDER_FIRST_CASE) && (1024 <= GSL_INCLUDER_LAST_CASE))
+#if (GSL_INCLUDER_REJECT (1024))
+ NULL,
+#else
+ GSL_INCLUDER_MAKE_FUNC (GSL_INCLUDER_NAME, 1024),
+#endif
+#endif
+};
+
+#undef GSL_INCLUDER_REJECT
+#undef GSL_INCLUDER_FUNC
+#undef GSL_INCLUDER_CONCAT3
+#undef GSL_INCLUDER_MAKE_FUNC
+#undef GSL_INCLUDER_FIRST_CASE
+#undef GSL_INCLUDER_LAST_CASE
+#undef GSL_INCLUDER_NAME
+#undef GSL_INCLUDER_TABLE
+#undef GSL_INCLUDER_FILE
diff --git a/flow/gsl/gslloader-gslwave.c b/flow/gsl/gslloader-gslwave.c
new file mode 100644
index 0000000..e851a12
--- /dev/null
+++ b/flow/gsl/gslloader-gslwave.c
@@ -0,0 +1,701 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001, 2002 Tim Janik
+ *
+ * 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.
+ */
+#include "gslloader.h"
+
+#include "gsldatahandle.h"
+#include "gslmath.h"
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+
+#define GSL_DEBUG_LOADER g_message
+
+#define parse_or_return(scanner, token) { guint _t = (token); \
+ if (g_scanner_get_next_token (scanner) != _t) \
+ return _t; \
+ }
+
+
+/* --- token types --- */
+typedef enum
+{
+ /* wave tokens */
+ GSL_WAVE_TOKEN_WAVE = 512,
+ GSL_WAVE_TOKEN_CHUNK,
+ GSL_WAVE_TOKEN_NAME,
+ GSL_WAVE_TOKEN_BYTE_ORDER,
+ GSL_WAVE_TOKEN_FORMAT,
+ GSL_WAVE_TOKEN_N_CHANNELS,
+ GSL_WAVE_TOKEN_MIX_FREQ,
+ GSL_WAVE_TOKEN_OSC_FREQ,
+ GSL_WAVE_TOKEN_MIDI_NOTE,
+ GSL_WAVE_TOKEN_FILE,
+ GSL_WAVE_TOKEN_INDEX,
+ GSL_WAVE_TOKEN_BOFFSET,
+ GSL_WAVE_TOKEN_N_VALUES,
+ GSL_WAVE_TOKEN_LOOP_TYPE,
+ GSL_WAVE_TOKEN_LOOP_START,
+ GSL_WAVE_TOKEN_LOOP_END,
+ GSL_WAVE_TOKEN_LOOP_COUNT,
+ GSL_WAVE_TOKEN_LAST_FIELD,
+ /* data tokens */
+ GSL_WAVE_TOKEN_BIG_ENDIAN = 768,
+ GSL_WAVE_TOKEN_BIG,
+ GSL_WAVE_TOKEN_LITTLE_ENDIAN,
+ GSL_WAVE_TOKEN_LITTLE,
+ GSL_WAVE_TOKEN_SIGNED_8,
+ GSL_WAVE_TOKEN_SIGNED_12,
+ GSL_WAVE_TOKEN_SIGNED_16,
+ GSL_WAVE_TOKEN_UNSIGNED_8,
+ GSL_WAVE_TOKEN_UNSIGNED_12,
+ GSL_WAVE_TOKEN_UNSIGNED_16,
+ GSL_WAVE_TOKEN_FLOAT,
+ GSL_WAVE_TOKEN_NONE,
+ GSL_WAVE_TOKEN_JUMP,
+ GSL_WAVE_TOKEN_PINGPONG,
+ GSL_WAVE_TOKEN_LAST_DATA
+} GslWaveTokenType;
+
+
+/* --- structures --- */
+typedef struct
+{
+ GslWaveFileInfo wfi;
+ gchar *cwd;
+} FileInfo;
+
+typedef struct
+{
+ GslWaveDsc wdsc;
+ GslWaveFormatType format;
+ guint byte_order;
+ gfloat dfl_mix_freq;
+} WaveDsc;
+
+
+/* --- tokens --- */
+static const char *wave_tokens_512[] = {
+ "wave", "chunk", "name", "byte_order",
+ "format", "n_channels", "mix_freq", "osc_freq",
+ "midi_note", "file", "index", "boffset",
+ "n_values", "loop_type", "loop_start", "loop_end",
+ "loop_count",
+};
+static const char *wave_tokens_768[] = {
+ "big_endian", "big", "little_endian", "little",
+ "signed_8", "signed_12", "signed_16",
+ "unsigned_8", "unsigned_12", "unsigned_16",
+ "float", "none", "jump", "pingpong",
+};
+
+
+/* --- functions --- */
+static const gchar*
+gsl_wave_token (GslWaveTokenType token)
+{
+ if (token >= 768)
+ {
+ token -= 768;
+ return token > sizeof (wave_tokens_768) / sizeof (wave_tokens_768[0]) ? NULL : wave_tokens_768[token];
+ }
+ else
+ {
+ token -= 512;
+ return token > sizeof (wave_tokens_512) / sizeof (wave_tokens_512[0]) ? NULL : wave_tokens_512[token];
+ }
+}
+
+static GTokenType
+gslwave_skip_rest_statement (GScanner *scanner,
+ guint level)
+{
+ g_return_val_if_fail (scanner != NULL, G_TOKEN_ERROR);
+
+ while (level)
+ {
+ g_scanner_get_next_token (scanner);
+ switch (scanner->token)
+ {
+ case G_TOKEN_EOF: case G_TOKEN_ERROR: return '}';
+ case '(': case '{': case '[': level++; break;
+ case ')': case '}': case ']': level--; break;
+ default: break;
+ }
+ }
+
+ return G_TOKEN_NONE;
+}
+
+static GslWaveFileInfo*
+gslwave_load_file_info (gpointer data,
+ const gchar *_file_name,
+ GslErrorType *error_p)
+{
+ FileInfo *fi = NULL;
+ gboolean in_wave = FALSE, abort = FALSE;
+ GslRing *wave_names = NULL;
+ GScanner *scanner;
+ gchar *cwd, *file_name;
+ gint fd;
+ guint i;
+
+ if (g_path_is_absolute (_file_name))
+ {
+ gchar *p = strrchr (_file_name, G_DIR_SEPARATOR);
+
+ g_assert (p != NULL);
+ cwd = g_strndup (_file_name, p - _file_name + 1);
+ file_name = g_strdup (_file_name);
+ }
+ else
+ {
+ cwd = g_get_current_dir ();
+ file_name = g_strdup_printf ("%s%c%s", cwd, G_DIR_SEPARATOR, _file_name);
+ }
+
+ fd = open (file_name, O_RDONLY);
+ if (fd < 0)
+ {
+ *error_p = GSL_ERROR_OPEN_FAILED;
+ g_free (cwd);
+ g_free (file_name);
+ return NULL;
+ }
+
+ scanner = g_scanner_new (NULL);
+ scanner->config->symbol_2_token = TRUE;
+ g_scanner_scope_add_symbol (scanner, 0, "wave", GUINT_TO_POINTER (GSL_WAVE_TOKEN_WAVE));
+ g_scanner_scope_add_symbol (scanner, 0, "name", GUINT_TO_POINTER (GSL_WAVE_TOKEN_NAME));
+ g_scanner_input_file (scanner, fd);
+ while (!abort)
+ {
+ g_scanner_get_next_token (scanner);
+ switch (scanner->token)
+ {
+ case GSL_WAVE_TOKEN_WAVE:
+ if (g_scanner_peek_next_token (scanner) == '{')
+ {
+ g_scanner_get_next_token (scanner); /* eat '{' */
+ in_wave = TRUE;
+ }
+ break;
+ case '{':
+ if (gslwave_skip_rest_statement (scanner, 1) != G_TOKEN_NONE)
+ abort = TRUE;
+ break;
+ case GSL_WAVE_TOKEN_NAME:
+ if (in_wave && g_scanner_peek_next_token (scanner) == '=')
+ {
+ g_scanner_get_next_token (scanner); /* eat '=' */
+ if (g_scanner_peek_next_token (scanner) == G_TOKEN_STRING)
+ {
+ gchar *wave_name;
+
+ g_scanner_get_next_token (scanner); /* eat string */
+ wave_name = g_strdup (scanner->value.v_string);
+ if (gslwave_skip_rest_statement (scanner, 1) == G_TOKEN_NONE)
+ {
+ in_wave = FALSE;
+ wave_names = gsl_ring_append (wave_names, wave_name);
+ }
+ else
+ {
+ g_free (wave_name);
+ abort = TRUE;
+ }
+ }
+ }
+ break;
+ default:
+ if (scanner->token == G_TOKEN_EOF || scanner->token == G_TOKEN_ERROR)
+ abort = TRUE;
+ break;
+ }
+ }
+ g_scanner_destroy (scanner);
+ close (fd);
+
+ if (wave_names)
+ {
+ GslRing *ring;
+
+ fi = gsl_new_struct0 (FileInfo, 1);
+ fi->wfi.n_waves = gsl_ring_length (wave_names);
+ fi->wfi.waves = g_malloc0 (sizeof (fi->wfi.waves[0]) * fi->wfi.n_waves);
+ for (i = 0, ring = wave_names; i < fi->wfi.n_waves; i++, ring = ring->next)
+ fi->wfi.waves[i].name = ring->data;
+ gsl_ring_free (wave_names);
+ fi->cwd = cwd;
+ }
+ else
+ g_free (cwd);
+ g_free (file_name);
+
+ /* FIXME: empty wave error? */
+
+ return fi ? &fi->wfi : NULL;
+}
+
+static void
+gslwave_free_file_info (gpointer data,
+ GslWaveFileInfo *file_info)
+{
+ FileInfo *fi = (FileInfo*) file_info;
+ guint i;
+
+ for (i = 0; i < fi->wfi.n_waves; i++)
+ g_free (fi->wfi.waves[i].name);
+ g_free (fi->wfi.waves);
+ g_free (fi->cwd);
+ gsl_delete_struct (FileInfo, fi);
+}
+
+static guint
+gslwave_parse_chunk_dsc (GScanner *scanner,
+ GslWaveChunkDsc *chunk)
+{
+ parse_or_return (scanner, '{');
+ do
+ switch (g_scanner_get_next_token (scanner))
+ {
+ case '}':
+ return G_TOKEN_NONE;
+ default:
+ return '}';
+ case GSL_WAVE_TOKEN_FILE:
+ parse_or_return (scanner, '=');
+ parse_or_return (scanner, G_TOKEN_STRING);
+ g_free (chunk->loader_data1); /* file_name */
+ chunk->loader_data1 = g_strdup (scanner->value.v_string);
+ break;
+ case GSL_WAVE_TOKEN_INDEX:
+ parse_or_return (scanner, '=');
+ parse_or_return (scanner, G_TOKEN_STRING);
+ g_free (chunk->loader_data2); /* wave_name */
+ chunk->loader_data2 = g_strdup (scanner->value.v_string);
+ break;
+ case GSL_WAVE_TOKEN_MIX_FREQ:
+ parse_or_return (scanner, '=');
+ switch (g_scanner_get_next_token (scanner))
+ {
+ case G_TOKEN_FLOAT: chunk->mix_freq = scanner->value.v_float; break;
+ case G_TOKEN_INT: chunk->mix_freq = scanner->value.v_int; break;
+ default: return G_TOKEN_FLOAT;
+ }
+ break;
+ case GSL_WAVE_TOKEN_OSC_FREQ:
+ parse_or_return (scanner, '=');
+ switch (g_scanner_get_next_token (scanner))
+ {
+ case G_TOKEN_FLOAT: chunk->osc_freq = scanner->value.v_float; break;
+ case G_TOKEN_INT: chunk->osc_freq = scanner->value.v_int; break;
+ default: return G_TOKEN_FLOAT;
+ }
+ break;
+ case GSL_WAVE_TOKEN_MIDI_NOTE:
+ parse_or_return (scanner, '=');
+ parse_or_return (scanner, G_TOKEN_INT);
+ chunk->osc_freq = gsl_temp_freq (gsl_get_config ()->kammer_freq,
+ scanner->value.v_int - gsl_get_config ()->midi_kammer_note);
+ break;
+ case GSL_WAVE_TOKEN_BOFFSET:
+ parse_or_return (scanner, '=');
+ parse_or_return (scanner, G_TOKEN_INT);
+ chunk->loader_offset = scanner->value.v_int; /* byte_offset */
+ break;
+ case GSL_WAVE_TOKEN_N_VALUES:
+ parse_or_return (scanner, '=');
+ parse_or_return (scanner, G_TOKEN_INT);
+ chunk->loader_length = scanner->value.v_int; /* n_values */
+ break;
+ case GSL_WAVE_TOKEN_LOOP_TYPE:
+ parse_or_return (scanner, '=');
+ switch (g_scanner_get_next_token (scanner))
+ {
+ case GSL_WAVE_TOKEN_NONE: chunk->loop_type = GSL_WAVE_LOOP_NONE; break;
+ case GSL_WAVE_TOKEN_JUMP: chunk->loop_type = GSL_WAVE_LOOP_JUMP; break;
+ case GSL_WAVE_TOKEN_PINGPONG: chunk->loop_type = GSL_WAVE_LOOP_PINGPONG; break;
+ default: return GSL_WAVE_TOKEN_JUMP;
+ }
+ break;
+ case GSL_WAVE_TOKEN_LOOP_START:
+ parse_or_return (scanner, '=');
+ parse_or_return (scanner, G_TOKEN_INT);
+ chunk->loop_start = scanner->value.v_int;
+ break;
+ case GSL_WAVE_TOKEN_LOOP_END:
+ parse_or_return (scanner, '=');
+ parse_or_return (scanner, G_TOKEN_INT);
+ chunk->loop_end = scanner->value.v_int;
+ break;
+ case GSL_WAVE_TOKEN_LOOP_COUNT:
+ parse_or_return (scanner, '=');
+ parse_or_return (scanner, G_TOKEN_INT);
+ chunk->loop_count = scanner->value.v_int;
+ break;
+ }
+ while (TRUE);
+}
+
+static guint
+gslwave_parse_wave_dsc (GScanner *scanner,
+ WaveDsc *dsc,
+ const gchar *wave_name)
+{
+ parse_or_return (scanner, '{');
+ do
+ switch (g_scanner_get_next_token (scanner))
+ {
+ guint i, token;
+ case '}':
+ return G_TOKEN_NONE;
+ default:
+ return '}';
+ case GSL_WAVE_TOKEN_NAME:
+ if (dsc->wdsc.name)
+ return '}';
+ parse_or_return (scanner, '=');
+ parse_or_return (scanner, G_TOKEN_STRING);
+ if (wave_name)
+ {
+ if (strcmp (wave_name, scanner->value.v_string) == 0)
+ dsc->wdsc.name = g_strdup (scanner->value.v_string);
+ else
+ return gslwave_skip_rest_statement (scanner, 1);
+ }
+ else
+ dsc->wdsc.name = g_strdup (scanner->value.v_string);
+ break;
+ case GSL_WAVE_TOKEN_CHUNK:
+ if (g_scanner_peek_next_token (scanner) != '{')
+ parse_or_return (scanner, '{');
+ i = dsc->wdsc.n_chunks++;
+ dsc->wdsc.chunks = g_realloc (dsc->wdsc.chunks, sizeof (dsc->wdsc.chunks[0]) * dsc->wdsc.n_chunks);
+ memset (dsc->wdsc.chunks + i, 0, sizeof (dsc->wdsc.chunks[0]) * 1);
+ dsc->wdsc.chunks[i].mix_freq = dsc->dfl_mix_freq;
+ dsc->wdsc.chunks[i].osc_freq = dsc->dfl_mix_freq; /* we check this later */
+ dsc->wdsc.chunks[i].loop_type = GSL_WAVE_LOOP_JUMP;
+ dsc->wdsc.chunks[i].loop_start = GSL_MAXLONG;
+ dsc->wdsc.chunks[i].loop_end = -1;
+ dsc->wdsc.chunks[i].loop_count = 1000000; /* FIXME */
+ dsc->wdsc.chunks[i].loader_offset = 0; /* offset in bytes */
+ dsc->wdsc.chunks[i].loader_length = 0; /* length in n_values */
+ dsc->wdsc.chunks[i].loader_data1 = NULL; /* file_name */
+ dsc->wdsc.chunks[i].loader_data2 = NULL; /* wave_name */
+ token = gslwave_parse_chunk_dsc (scanner, dsc->wdsc.chunks + i);
+ if (token != G_TOKEN_NONE)
+ return token;
+ if (dsc->wdsc.chunks[i].loop_end < dsc->wdsc.chunks[i].loop_start)
+ {
+ dsc->wdsc.chunks[i].loop_type = GSL_WAVE_LOOP_NONE;
+ dsc->wdsc.chunks[i].loop_start = 0;
+ dsc->wdsc.chunks[i].loop_end = 0;
+ dsc->wdsc.chunks[i].loop_count = 0;
+ }
+ if (dsc->wdsc.chunks[i].osc_freq >= dsc->wdsc.chunks[i].mix_freq / 2.)
+ g_scanner_error (scanner, "wave chunk \"%s\" mixing frequency is invalid: mix_freq=%f osc_freq=%f",
+ dsc->wdsc.chunks[i].loader_data1 ? (gchar*) dsc->wdsc.chunks[i].loader_data1 : "",
+ dsc->wdsc.chunks[i].mix_freq,
+ dsc->wdsc.chunks[i].osc_freq);
+ break;
+ case GSL_WAVE_TOKEN_BYTE_ORDER:
+ parse_or_return (scanner, '=');
+ token = g_scanner_get_next_token (scanner);
+ switch (token)
+ {
+ case GSL_WAVE_TOKEN_LITTLE_ENDIAN:
+ case GSL_WAVE_TOKEN_LITTLE: dsc->byte_order = G_LITTLE_ENDIAN; break;
+ case GSL_WAVE_TOKEN_BIG_ENDIAN:
+ case GSL_WAVE_TOKEN_BIG: dsc->byte_order = G_BIG_ENDIAN; break;
+ default: return GSL_WAVE_TOKEN_LITTLE_ENDIAN;
+ }
+ break;
+ case GSL_WAVE_TOKEN_FORMAT:
+ parse_or_return (scanner, '=');
+ token = g_scanner_get_next_token (scanner);
+ switch (token)
+ {
+ case GSL_WAVE_TOKEN_SIGNED_8: dsc->format = GSL_WAVE_FORMAT_SIGNED_8; break;
+ case GSL_WAVE_TOKEN_SIGNED_12: dsc->format = GSL_WAVE_FORMAT_SIGNED_12; break;
+ case GSL_WAVE_TOKEN_SIGNED_16: dsc->format = GSL_WAVE_FORMAT_SIGNED_16; break;
+ case GSL_WAVE_TOKEN_UNSIGNED_8: dsc->format = GSL_WAVE_FORMAT_UNSIGNED_8; break;
+ case GSL_WAVE_TOKEN_UNSIGNED_12: dsc->format = GSL_WAVE_FORMAT_UNSIGNED_12; break;
+ case GSL_WAVE_TOKEN_UNSIGNED_16: dsc->format = GSL_WAVE_FORMAT_UNSIGNED_16; break;
+ case GSL_WAVE_TOKEN_FLOAT: dsc->format = GSL_WAVE_FORMAT_FLOAT; break;
+ default: return GSL_WAVE_TOKEN_SIGNED_16;
+ }
+ break;
+ case GSL_WAVE_TOKEN_N_CHANNELS:
+ parse_or_return (scanner, '=');
+ parse_or_return (scanner, G_TOKEN_INT);
+ dsc->wdsc.n_channels = scanner->value.v_int;
+ if (dsc->wdsc.n_channels < 1)
+ return G_TOKEN_INT;
+ break;
+ case GSL_WAVE_TOKEN_MIX_FREQ:
+ parse_or_return (scanner, '=');
+ switch (g_scanner_get_next_token (scanner))
+ {
+ case G_TOKEN_FLOAT: dsc->dfl_mix_freq = scanner->value.v_float; break;
+ case G_TOKEN_INT: dsc->dfl_mix_freq = scanner->value.v_int; break;
+ default: return G_TOKEN_FLOAT;
+ }
+ break;
+ }
+ while (TRUE);
+}
+
+static void
+gslwave_wave_dsc_free (WaveDsc *dsc)
+{
+ guint i;
+
+ for (i = 0; i < dsc->wdsc.n_chunks; i++)
+ {
+ g_free (dsc->wdsc.chunks[i].loader_data1); /* file_name */
+ g_free (dsc->wdsc.chunks[i].loader_data2); /* wave_name */
+ }
+ g_free (dsc->wdsc.chunks);
+ g_free (dsc->wdsc.name);
+ gsl_delete_struct (WaveDsc, dsc);
+}
+
+static GslWaveDsc*
+gslwave_load_wave_dsc (gpointer data,
+ GslWaveFileInfo *file_info,
+ guint nth_wave,
+ GslErrorType *error_p)
+{
+ GScanner *scanner;
+ WaveDsc *dsc;
+ guint token, i;
+ gint fd;
+
+ fd = open (file_info->file_name, O_RDONLY);
+ if (fd < 0)
+ {
+ *error_p = GSL_ERROR_OPEN_FAILED;
+ return NULL;
+ }
+
+ scanner = g_scanner_new (NULL);
+ scanner->config->symbol_2_token = TRUE;
+ scanner->input_name = file_info->file_name;
+ g_scanner_input_file (scanner, fd);
+ for (i = GSL_WAVE_TOKEN_WAVE; i < GSL_WAVE_TOKEN_LAST_FIELD; i++)
+ g_scanner_scope_add_symbol (scanner, 0, gsl_wave_token (i), GUINT_TO_POINTER (i));
+ for (i = GSL_WAVE_TOKEN_BIG_ENDIAN; i < GSL_WAVE_TOKEN_LAST_DATA; i++)
+ g_scanner_scope_add_symbol (scanner, 0, gsl_wave_token (i), GUINT_TO_POINTER (i));
+
+ continue_scanning:
+ dsc = gsl_new_struct0 (WaveDsc, 1);
+ dsc->wdsc.name = NULL;
+ dsc->wdsc.n_chunks = 0;
+ dsc->wdsc.chunks = NULL;
+ dsc->wdsc.n_channels = 1;
+ dsc->format = GSL_WAVE_FORMAT_SIGNED_16;
+ dsc->byte_order = G_LITTLE_ENDIAN;
+ dsc->dfl_mix_freq = 44100;
+ if (g_scanner_get_next_token (scanner) != GSL_WAVE_TOKEN_WAVE)
+ token = GSL_WAVE_TOKEN_WAVE;
+ else
+ token = gslwave_parse_wave_dsc (scanner, dsc, file_info->waves[nth_wave].name);
+ if (token != G_TOKEN_NONE || scanner->parse_errors)
+ {
+ gslwave_wave_dsc_free (dsc);
+ dsc = NULL;
+ if (!scanner->parse_errors)
+ g_scanner_unexp_token (scanner, token, "identifier", "keyword", NULL, "discarding wave", TRUE); /* FIXME */
+ }
+ else
+ {
+ if (dsc->wdsc.n_chunks && dsc->wdsc.name)
+ {
+ /* found the correctly named wave and parsed it */
+ }
+ else
+ {
+ /* got invalid/wrong wave */
+ gslwave_wave_dsc_free (dsc);
+ dsc = NULL;
+ goto continue_scanning; /* next attempt */
+ }
+ }
+ g_scanner_destroy (scanner);
+ close (fd);
+
+ return dsc ? &dsc->wdsc : NULL;
+}
+
+static void
+gslwave_free_wave_dsc (gpointer data,
+ GslWaveDsc *wave_dsc)
+{
+ WaveDsc *dsc = (WaveDsc*) wave_dsc;
+
+ gslwave_wave_dsc_free (dsc);
+}
+
+static GslDataHandle*
+gslwave_load_singlechunk_wave (GslWaveFileInfo *fi,
+ const gchar *wave_name,
+ GslErrorType *error_p)
+{
+ GslWaveDsc *wdsc;
+ guint i;
+
+ if (fi->n_waves == 1 && !wave_name)
+ i = 0;
+ else if (!wave_name)
+ {
+ /* don't know which wave to pick */
+ *error_p = GSL_ERROR_FORMAT_INVALID;
+ return NULL;
+ }
+ else /* find named wave */
+ for (i = 0; i < fi->n_waves; i++)
+ if (strcmp (fi->waves[i].name, wave_name) == 0)
+ break;
+ if (i >= fi->n_waves)
+ {
+ *error_p = GSL_ERROR_NOT_FOUND;
+ return NULL;
+ }
+
+ wdsc = gsl_wave_dsc_load (fi, i, error_p);
+ if (!wdsc)
+ return NULL;
+
+ if (wdsc->n_chunks == 1)
+ {
+ GslDataHandle *dhandle = gsl_wave_handle_create (wdsc, 0, error_p);
+
+ gsl_wave_dsc_free (wdsc);
+ return dhandle;
+ }
+
+ /* this is ridiculous, letting the chunk of a wave
+ * point to a wave with multiple chunks...
+ */
+ gsl_wave_dsc_free (wdsc);
+ *error_p = GSL_ERROR_FORMAT_INVALID;
+ return NULL;
+}
+
+static GslDataHandle*
+gslwave_create_chunk_handle (gpointer data,
+ GslWaveDsc *wave_dsc,
+ guint nth_chunk,
+ GslErrorType *error_p)
+{
+ WaveDsc *dsc = (WaveDsc*) wave_dsc;
+ FileInfo *fi = (FileInfo*) dsc->wdsc.file_info;
+ GslWaveChunkDsc *chunk = wave_dsc->chunks + nth_chunk;
+
+ if (chunk->loader_data1) /* file_name */
+ {
+ GslDataHandle *dhandle;
+ GslWaveFileInfo *cfi;
+ gchar *string;
+
+
+ /* construct chunk file name from (hopefully) relative path
+ */
+ if (g_path_is_absolute (chunk->loader_data1))
+ string = g_strdup (chunk->loader_data1);
+ else
+ string = g_strdup_printf ("%s%c%s", fi->cwd, G_DIR_SEPARATOR, (char*) chunk->loader_data1);
+
+
+ /* first, try to load the chunk via registered loaders
+ */
+ cfi = gsl_wave_file_info_load (string, error_p);
+ if (cfi)
+ {
+ /* FIXME: there's a potential attack here, in letting a single chunk
+ * wave's chunk point to its own wave. this'll trigger recursions until
+ * stack overflow
+ */
+ dhandle = gslwave_load_singlechunk_wave (cfi,
+ chunk->loader_data2, /* wave_name */
+ error_p);
+ gsl_wave_file_info_unref (cfi);
+ g_free (string);
+ return dhandle;
+ }
+
+
+ /* didn't work, assume it's a raw sample
+ */
+ if (chunk->loader_data2) /* wave_name */
+ {
+ /* raw samples don't give names to their data */
+ *error_p = GSL_ERROR_NOT_FOUND;
+ g_free (string);
+ return NULL;
+ }
+ dhandle = gsl_wave_handle_new (string, /* file_name */
+ dsc->wdsc.n_channels,
+ dsc->format,
+ dsc->byte_order,
+ chunk->loader_offset, /* byte_offset */
+ chunk->loader_length > 0 /* n_values */
+ ? chunk->loader_length
+ : -1);
+ *error_p = dhandle ? GSL_ERROR_NONE : GSL_ERROR_IO;
+ g_free (string);
+ return dhandle;
+ }
+ else
+ {
+ /* no file_name specified */
+ *error_p = GSL_ERROR_NOT_FOUND;
+ return NULL;
+ }
+}
+
+void
+_gsl_init_loader_gslwave (void)
+{
+ static const gchar *file_exts[] = { "gslwave", NULL, };
+ static const gchar *mime_types[] = { "audio/x-gslwave", NULL, };
+ static const gchar *magics[] = { "0 string #GslWave", NULL, };
+ static GslLoader loader = {
+ "GslWave",
+ file_exts,
+ mime_types,
+ magics,
+ 0, /* priority */
+ NULL,
+ gslwave_load_file_info,
+ gslwave_free_file_info,
+ gslwave_load_wave_dsc,
+ gslwave_free_wave_dsc,
+ gslwave_create_chunk_handle,
+ };
+ static gboolean initialized = FALSE;
+
+ g_assert (initialized == FALSE);
+ initialized = TRUE;
+
+ gsl_loader_register (&loader);
+}
diff --git a/flow/gsl/gslloader-mad.c b/flow/gsl/gslloader-mad.c
new file mode 100644
index 0000000..984aa39
--- /dev/null
+++ b/flow/gsl/gslloader-mad.c
@@ -0,0 +1,210 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2002 Tim Janik
+ *
+ * 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.
+ */
+#include "gsl/gslloader.h"
+
+#include <gsl/gsldatahandle.h>
+#include "gsldatahandle-mad.h"
+
+#include <unistd.h>
+
+
+/* --- structures --- */
+typedef struct
+{
+ GslWaveFileInfo wfi;
+ guint n_channels;
+ gfloat mix_freq;
+ gfloat osc_freq;
+} FileInfo;
+
+
+/* --- functions --- */
+static GslWaveFileInfo*
+mad_load_file_info (gpointer data,
+ const gchar *file_name,
+ GslErrorType *error_p)
+{
+ FileInfo *fi;
+ guint n_channels;
+ gfloat mix_freq;
+ GslErrorType error;
+
+ error = gsl_data_handle_mad_testopen (file_name, &n_channels, &mix_freq);
+ if (error)
+ {
+ *error_p = error;
+ return NULL;
+ }
+
+ fi = gsl_new_struct0 (FileInfo, 1);
+ fi->wfi.n_waves = 1; /* we support only a single MPEG stream */
+ fi->wfi.waves = g_malloc0 (sizeof (fi->wfi.waves[0]) * fi->wfi.n_waves);
+ fi->wfi.waves[0].name = g_strdup (file_name);
+ fi->n_channels = n_channels;
+ fi->mix_freq = mix_freq;
+ fi->osc_freq = 440.0; /* FIXME */
+
+ return &fi->wfi;
+}
+
+static void
+mad_free_file_info (gpointer data,
+ GslWaveFileInfo *file_info)
+{
+ FileInfo *fi = (FileInfo*) file_info;
+ guint i;
+
+ for (i = 0; i < fi->wfi.n_waves; i++)
+ g_free (fi->wfi.waves[i].name);
+ g_free (fi->wfi.waves);
+ gsl_delete_struct (FileInfo, fi);
+}
+
+static GslWaveDsc*
+mad_load_wave_dsc (gpointer data,
+ GslWaveFileInfo *file_info,
+ guint nth_wave,
+ GslErrorType *error_p)
+{
+ FileInfo *fi = (FileInfo*) file_info;
+ GslWaveDsc *wdsc = gsl_new_struct0 (GslWaveDsc, 1);
+
+ wdsc->name = g_strdup (fi->wfi.waves[0].name);
+ wdsc->n_channels = fi->n_channels;
+ wdsc->n_chunks = 1;
+ wdsc->chunks = g_new0 (GslWaveChunkDsc, 1);
+ wdsc->chunks[0].osc_freq = fi->osc_freq;
+ wdsc->chunks[0].mix_freq = fi->mix_freq;
+
+ return wdsc;
+}
+
+static void
+mad_free_wave_dsc (gpointer data,
+ GslWaveDsc *wdsc)
+{
+ g_free (wdsc->name);
+ g_free (wdsc->chunks);
+ gsl_delete_struct (GslWaveDsc, wdsc);
+}
+
+static GslDataHandle*
+mad_create_chunk_handle (gpointer data,
+ GslWaveDsc *wdsc,
+ guint nth_chunk,
+ GslErrorType *error_p)
+{
+ FileInfo *fi = (FileInfo*) wdsc->file_info;
+ GslDataHandle *dhandle;
+
+ g_return_val_if_fail (nth_chunk == 0, NULL);
+
+ dhandle = gsl_data_handle_new_mad (fi->wfi.file_name);
+
+ if (!dhandle)
+ *error_p = GSL_ERROR_OPEN_FAILED;
+ return dhandle;
+}
+
+
+#define MAGIC_MPEG_HEADER "0 beshort &0xffe0\n" /* MPEG */ \
+ "2 ubyte&0x0c <0x0c\n" /* valid samplefreq */ \
+ "2 ubyte&0xf0 <0xf0\n" /* valid bitrate */
+#define MAGIC_MPEG10_I (MAGIC_MPEG_HEADER \
+ "1 byte&0x18 =0x18\n" /* 1.0 */ \
+ "1 byte&0x06 =0x06\n" /* I */)
+#define MAGIC_MPEG10_II (MAGIC_MPEG_HEADER \
+ "1 byte&0x18 =0x18\n" /* 1.0 */ \
+ "1 byte&0x06 =0x04\n" /* II */)
+#define MAGIC_MPEG10_III (MAGIC_MPEG_HEADER \
+ "1 byte&0x18 =0x18\n" /* 1.0 */ \
+ "1 byte&0x06 =0x02\n" /* III */)
+#define MAGIC_MPEG20_I (MAGIC_MPEG_HEADER \
+ "1 byte&0x18 =0x10\n" /* 2.0 */ \
+ "1 byte&0x06 =0x06\n" /* I */)
+#define MAGIC_MPEG20_II (MAGIC_MPEG_HEADER \
+ "1 byte&0x18 =0x10\n" /* 2.0 */ \
+ "1 byte&0x06 =0x04\n" /* II */)
+#define MAGIC_MPEG20_III (MAGIC_MPEG_HEADER \
+ "1 byte&0x18 =0x10\n" /* 2.0 */ \
+ "1 byte&0x06 =0x02\n" /* III */)
+#define MAGIC_MPEG25_I (MAGIC_MPEG_HEADER \
+ "1 byte&0x18 =0x00\n" /* 2.5 */ \
+ "1 byte&0x06 =0x06\n" /* I */)
+#define MAGIC_MPEG25_II (MAGIC_MPEG_HEADER \
+ "1 byte&0x18 =0x00\n" /* 2.5 */ \
+ "1 byte&0x06 =0x04\n" /* II */)
+#define MAGIC_MPEG25_III (MAGIC_MPEG_HEADER \
+ "1 byte&0x18 =0x00\n" /* 2.5 */ \
+ "1 byte&0x06 =0x02\n" /* III */)
+#define MAGIC_RIFF_MPEG ("0 string RIFF\n" \
+ "8 string WAVE\n" \
+ "12 string fmt\\s\n" /* "fmt " */ \
+ "20 leshort 80\n" /* format: MPEG */)
+#define MAGIC_RIFF_MPEG_III ("0 string RIFF\n" \
+ "8 string WAVE\n" \
+ "12 string fmt\\s\n" /* "fmt " */ \
+ "20 leshort 85\n" /* format: MPEG III */)
+#define MAGIC_MPEG_ID3 ("0 string ID3\n" /* ID3v2 tag for mp3 */ \
+ "3 ubyte <0xff\n" /* major version */ \
+ "4 ubyte <0xff\n" /* revision */)
+
+void
+_gsl_init_loader_mad (void)
+{
+ static const gchar *file_exts[] = {
+ "mp1", "mp2", "mp3",
+ NULL,
+ };
+ static const gchar *mime_types[] = {
+ "audio/mp3", "audio/x-mp3", "audio/mpg3", "audio/x-mpg3", "audio/mpeg3", "audio/x-mpeg3",
+ "audio/mp2", "audio/x-mp2", "audio/mpg2", "audio/x-mpg2", "audio/mpeg2", "audio/x-mpeg2",
+ "audio/mp1", "audio/x-mp1", "audio/mpg1", "audio/x-mpg1", "audio/mpeg1", "audio/x-mpeg1",
+ "audio/mpeg", "audio/x-mpeg",
+ NULL,
+ };
+ static const gchar *magics[] = {
+ MAGIC_MPEG10_I, MAGIC_MPEG10_II, MAGIC_MPEG10_III,
+ MAGIC_MPEG20_I, MAGIC_MPEG20_II, MAGIC_MPEG20_III,
+ MAGIC_MPEG25_I, MAGIC_MPEG25_II, MAGIC_MPEG25_III,
+ MAGIC_RIFF_MPEG, MAGIC_RIFF_MPEG_III,
+ MAGIC_MPEG_ID3,
+ NULL,
+ };
+ static GslLoader loader = {
+ "MPEG Audio (MAD: MPEG 1.0/2.0/2.5 Layer III/II/I Decoder)",
+ file_exts,
+ mime_types,
+ magics,
+ 0, /* priority */
+ NULL,
+ mad_load_file_info,
+ mad_free_file_info,
+ mad_load_wave_dsc,
+ mad_free_wave_dsc,
+ mad_create_chunk_handle,
+ };
+ static gboolean initialized = FALSE;
+
+ g_assert (initialized == FALSE);
+ initialized = TRUE;
+
+ if (GSL_HAVE_LIBMAD)
+ gsl_loader_register (&loader);
+}
diff --git a/flow/gsl/gslloader-oggvorbis.c b/flow/gsl/gslloader-oggvorbis.c
new file mode 100644
index 0000000..3ec3d88
--- /dev/null
+++ b/flow/gsl/gslloader-oggvorbis.c
@@ -0,0 +1,178 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 1998, 2000, 2001 Tim Janik
+ *
+ * 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.
+ */
+#include "gsl/gslloader.h"
+
+#if GSL_HAVE_OGGVORBIS
+#include <gsl/gsldatahandle.h>
+#include "gsldatahandle-vorbis.h"
+
+#include <vorbis/vorbisfile.h>
+#include <string.h>
+#include <unistd.h>
+
+
+/* --- structures --- */
+typedef struct
+{
+ GslWaveFileInfo wfi;
+ OggVorbis_File ofile;
+} FileInfo;
+
+
+/* --- functions --- */
+static GslWaveFileInfo*
+oggv_load_file_info (gpointer data,
+ const gchar *file_name,
+ GslErrorType *error_p)
+{
+ FileInfo *fi = gsl_new_struct0 (FileInfo, 1);
+ FILE *file;
+ gint err, i;
+
+ file = fopen (file_name, "r");
+ if (!file)
+ {
+ *error_p = GSL_ERROR_OPEN_FAILED;
+ return NULL;
+ }
+
+ fi = gsl_new_struct0 (FileInfo, 1);
+ err = ov_open (file, &fi->ofile, NULL, 0);
+ if (err)
+ {
+ fclose (file);
+ gsl_delete_struct (FileInfo, fi);
+ *error_p = GSL_ERROR_CODEC_FAILURE;
+ return NULL;
+ }
+
+ fi->wfi.n_waves = ov_streams (&fi->ofile);
+ fi->wfi.waves = g_malloc0 (sizeof (fi->wfi.waves[0]) * fi->wfi.n_waves);
+ for (i = 0; i < fi->wfi.n_waves; i++)
+ {
+ vorbis_comment *vc = ov_comment (&fi->ofile, i);
+ guint n;
+
+ for (n = 0; n < vc->comments; n++)
+ if (strcmp (vc->user_comments[n], "title=") == 0)
+ break;
+ if (n < vc->comments)
+ fi->wfi.waves[i].name = g_strdup (vc->user_comments[n] + 6);
+ else
+ fi->wfi.waves[i].name = g_strdup_printf ("Unnamed-%u", i);
+ }
+
+ return &fi->wfi;
+}
+
+static void
+oggv_free_file_info (gpointer data,
+ GslWaveFileInfo *file_info)
+{
+ FileInfo *fi = (FileInfo*) file_info;
+ guint i;
+
+ for (i = 0; i < fi->wfi.n_waves; i++)
+ g_free (fi->wfi.waves[i].name);
+ g_free (fi->wfi.waves);
+ ov_clear (&fi->ofile);
+ gsl_delete_struct (FileInfo, fi);
+}
+
+static GslWaveDsc*
+oggv_load_wave_dsc (gpointer data,
+ GslWaveFileInfo *file_info,
+ guint nth_wave,
+ GslErrorType *error_p)
+{
+ FileInfo *fi = (FileInfo*) file_info;
+ GslWaveDsc *wdsc = gsl_new_struct0 (GslWaveDsc, 1);
+ vorbis_info *vi = ov_info (&fi->ofile, nth_wave);
+
+ wdsc->name = g_strdup (fi->wfi.waves[nth_wave].name);
+ wdsc->n_channels = vi->channels;
+ wdsc->n_chunks = 1;
+ wdsc->chunks = g_new0 (GslWaveChunkDsc, 1);
+ wdsc->chunks[0].osc_freq = 440.0; /* FIXME */
+ wdsc->chunks[0].mix_freq = vi->rate;
+ wdsc->chunks[0].loader_offset = nth_wave; /* lbitstream */
+
+ return wdsc;
+}
+
+static void
+oggv_free_wave_dsc (gpointer data,
+ GslWaveDsc *wdsc)
+{
+ g_free (wdsc->name);
+ g_free (wdsc->chunks);
+ gsl_delete_struct (GslWaveDsc, wdsc);
+}
+
+static GslDataHandle*
+oggv_create_chunk_handle (gpointer data,
+ GslWaveDsc *wdsc,
+ guint nth_chunk,
+ GslErrorType *error_p)
+{
+ FileInfo *fi = (FileInfo*) wdsc->file_info;
+ GslDataHandle *dhandle;
+
+ g_return_val_if_fail (nth_chunk == 0, NULL);
+
+ dhandle = gsl_data_handle_new_ogg_vorbis (fi->wfi.file_name,
+ wdsc->chunks[0].loader_offset); /* lbitstream */
+ if (!dhandle)
+ *error_p = GSL_ERROR_OPEN_FAILED;
+ return dhandle;
+}
+
+void
+_gsl_init_loader_oggvorbis (void)
+{
+ static const gchar *file_exts[] = { "ogg", NULL, };
+ static const gchar *mime_types[] = { "application/x-ogg", "audio/x-vorbis", "audio/x-ogg", NULL, };
+ static const gchar *magics[] = { "0 string OggS\n" "29 string vorbis", NULL, };
+ static GslLoader loader = {
+ "Ogg/Vorbis",
+ file_exts,
+ mime_types,
+ magics,
+ 0, /* priority */
+ NULL,
+ oggv_load_file_info,
+ oggv_free_file_info,
+ oggv_load_wave_dsc,
+ oggv_free_wave_dsc,
+ oggv_create_chunk_handle,
+ };
+ static gboolean initialized = FALSE;
+
+ g_assert (initialized == FALSE);
+ initialized = TRUE;
+
+ gsl_loader_register (&loader);
+}
+#else
+void
+_gsl_init_loader_oggvorbis (void)
+{
+ /* dummy */
+}
+#endif /* GSL_HAVE_OGGVORBIS */
diff --git a/flow/gsl/gslloader-wav.c b/flow/gsl/gslloader-wav.c
new file mode 100644
index 0000000..d0a1c1e
--- /dev/null
+++ b/flow/gsl/gslloader-wav.c
@@ -0,0 +1,442 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 1998, 2000, 2001 Tim Janik
+ *
+ * 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.
+ */
+#include "gslloader.h"
+
+#include "gsldatahandle.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+
+/* load routine for the RIFF/WAVE sample format
+ * ref.: C't 01/1993 pp. 213
+ */
+
+typedef guint32 DWord;
+typedef guint16 Word;
+#define DWORD_FROM_BE GUINT32_FROM_BE
+#define DWORD_FROM_LE GUINT32_FROM_LE
+#define WORD_FROM_LE GUINT16_FROM_LE
+
+
+/* --- debugging and errors --- */
+#define WAV_DEBUG GSL_DEBUG_FUNCTION (GSL_MSG_DATA_HANDLE, "WAV")
+#define WAV_MSG GSL_MESSAGE_FUNCTION (GSL_MSG_DATA_HANDLE, "WAV")
+
+
+/* --- functions --- */
+typedef struct
+{
+ DWord main_chunk; /* 'RIFF', big endian as int */
+ DWord file_length; /* file length */
+ DWord chunk_type; /* 'WAVE', big endian as int */
+} WavHeader;
+static GslErrorType
+wav_read_header (gint fd,
+ WavHeader *header)
+{
+ guint n_bytes;
+
+ memset (header, 0, sizeof (*header));
+
+ /* read header contents */
+ n_bytes = 4 + 4 + 4;
+ g_assert (n_bytes == sizeof (*header));
+ if (read (fd, header, n_bytes) != n_bytes)
+ {
+ WAV_DEBUG ("failed to read WavHeader");
+ return GSL_ERROR_IO;
+ }
+
+ /* endianess corrections */
+ header->main_chunk = DWORD_FROM_BE (header->main_chunk);
+ header->file_length = DWORD_FROM_LE (header->file_length);
+ header->chunk_type = DWORD_FROM_BE (header->chunk_type);
+
+ /* validation */
+ if (header->main_chunk != ('R' << 24 | 'I' << 16 | 'F' << 8 | 'F'))
+ {
+ WAV_DEBUG ("unmatched token 'RIFF'");
+ return GSL_ERROR_FORMAT_INVALID;
+ }
+ if (header->file_length < 40)
+ {
+ WAV_DEBUG ("file length (%u) too small", header->file_length);
+ return GSL_ERROR_FORMAT_INVALID;
+ }
+ if (header->chunk_type != ('W' << 24 | 'A' << 16 | 'V' << 8 | 'E'))
+ {
+ WAV_DEBUG ("unmatched token 'WAVE'");
+ return GSL_ERROR_FORMAT_INVALID;
+ }
+
+ return GSL_ERROR_NONE;
+}
+
+typedef struct
+{
+ DWord sub_chunk; /* 'fmt ', big endian as int */
+ DWord length; /* sub chunk length, must be 16 */
+ Word format; /* 1 for PCM */
+ Word n_channels; /* 1 = Mono, 2 = Stereo */
+ DWord sample_freq;
+ DWord byte_per_second;
+ Word byte_per_sample; /* 1 = 8bit, 2 = 16bit */
+ Word bit_per_sample; /* 8, 12 or 16 */
+} FmtHeader;
+static GslErrorType
+wav_read_fmt_header (gint fd,
+ FmtHeader *header)
+{
+ guint n_bytes;
+
+ memset (header, 0, sizeof (*header));
+
+ /* read header contents */
+ n_bytes = 4 + 4 + 2 + 2 + 4 + 4 + 2 + 2;
+ g_assert (n_bytes == sizeof (*header));
+ if (read (fd, header, n_bytes) != n_bytes)
+ {
+ WAV_DEBUG ("failed to read FmtHeader");
+ return GSL_ERROR_IO;
+ }
+
+ /* endianess corrections */
+ header->sub_chunk = DWORD_FROM_BE (header->sub_chunk);
+ header->length = DWORD_FROM_LE (header->length);
+ header->format = WORD_FROM_LE (header->format);
+ header->n_channels = WORD_FROM_LE (header->n_channels);
+ header->sample_freq = DWORD_FROM_LE (header->sample_freq);
+ header->byte_per_second = DWORD_FROM_LE (header->byte_per_second);
+ header->byte_per_sample = WORD_FROM_LE (header->byte_per_sample);
+ header->bit_per_sample = WORD_FROM_LE (header->bit_per_sample);
+
+ /* validation */
+ if (header->sub_chunk != ('f' << 24 | 'm' << 16 | 't' << 8 | ' '))
+ {
+ WAV_DEBUG ("unmatched token 'fmt '");
+ return GSL_ERROR_FORMAT_UNKNOWN;
+ }
+ if (header->format != 1 /* PCM */ ||
+ header->n_channels > 2 || header->n_channels < 1)
+ {
+ WAV_DEBUG ("invalid format (%u) or n_channels (%u)", header->format, header->n_channels);
+ return GSL_ERROR_FORMAT_UNKNOWN;
+ }
+ if (header->length < 16)
+ {
+ WAV_DEBUG ("WAVE header too short (%u)", header->length);
+ return GSL_ERROR_FORMAT_INVALID;
+ }
+ if (header->sample_freq < 1378 || header->sample_freq > 96000)
+ {
+ WAV_DEBUG ("invalid sample_freq (%u)", header->sample_freq);
+ return GSL_ERROR_FORMAT_UNKNOWN;
+ }
+ if (header->byte_per_sample < 1 || header->byte_per_sample > 4 ||
+ (header->bit_per_sample != 8 && header->bit_per_sample != 12 && header->bit_per_sample != 16))
+ {
+ WAV_DEBUG ("invalid byte_per_sample (%u) or bit_per_sample (%u)", header->byte_per_sample, header->bit_per_sample);
+ return GSL_ERROR_FORMAT_UNKNOWN;
+ }
+ if (header->byte_per_second != header->sample_freq * header->byte_per_sample ||
+ header->byte_per_sample != (header->bit_per_sample + 7) / 8 * header->n_channels)
+ {
+ WAV_DEBUG ("invalid byte_per_second (%u!=%u) or byte_per_sample (%u!=%u)",
+ header->byte_per_second, header->sample_freq * header->byte_per_sample,
+ header->byte_per_sample, (header->bit_per_sample + 7) / 8 * header->n_channels);
+ return GSL_ERROR_FORMAT_INVALID;
+ }
+ if (header->length > 16)
+ {
+ guint n;
+
+ WAV_DEBUG ("WAVE header too long (%u)", header->length);
+
+ n = header->length - 16;
+ while (n)
+ {
+ guint8 junk[64];
+ guint l = MIN (n, 64);
+
+ l = read (fd, junk, l);
+ if (l < 1 || l > n)
+ {
+ WAV_DEBUG ("failed to read FmtHeader");
+ return GSL_ERROR_IO;
+ }
+ n -= l;
+ }
+
+ WAV_MSG (GSL_ERROR_CONTENT_GLITCH, "skipping %u bytes of junk in WAVE header", header->length - 16);
+ }
+
+ return GSL_ERROR_NONE;
+}
+
+typedef struct
+{
+ DWord data_chunk; /* 'data', big endian as int */
+ DWord data_length;
+} DataHeader;
+static GslErrorType
+wav_read_data_header (gint fd,
+ DataHeader *header,
+ guint byte_alignment)
+{
+ guint n_bytes;
+
+ memset (header, 0, sizeof (*header));
+
+ /* read header contents */
+ n_bytes = 4 + 4;
+ g_assert (n_bytes == sizeof (*header));
+ if (read (fd, header, n_bytes) != n_bytes)
+ {
+ WAV_DEBUG ("failed to read DataHeader");
+ return GSL_ERROR_IO;
+ }
+
+ /* endianess corrections */
+ header->data_chunk = DWORD_FROM_BE (header->data_chunk);
+ header->data_length = DWORD_FROM_LE (header->data_length);
+
+ /* validation */
+ if (header->data_chunk != ('d' << 24 | 'a' << 16 | 't' << 8 | 'a'))
+ {
+ guchar chunk[5];
+ gchar *esc;
+
+ chunk[0] = header->data_chunk >> 24;
+ chunk[1] = (header->data_chunk >> 16) & 0xff;
+ chunk[2] = (header->data_chunk >> 8) & 0xff;
+ chunk[3] = header->data_chunk & 0xff;
+ chunk[4] = 0;
+ esc = g_strescape (chunk, NULL);
+
+ /* skip chunk and retry */
+ WAV_DEBUG ("ignoring sub-chunk '%s'", esc);
+ g_free (esc);
+ if (lseek (fd, header->data_length, SEEK_CUR) < 0)
+ {
+ WAV_DEBUG ("failed to seek while skipping sub-chunk");
+ return GSL_ERROR_IO;
+ }
+ return wav_read_data_header (fd, header, byte_alignment);
+ }
+ if (header->data_length < 1 || header->data_length % byte_alignment != 0)
+ {
+ WAV_DEBUG ("invalid data length (%u) or alignment (%u)",
+ header->data_length, header->data_length % byte_alignment);
+ return GSL_ERROR_FORMAT_INVALID;
+ }
+
+ return GSL_ERROR_NONE;
+}
+
+typedef struct
+{
+ GslWaveFileInfo wfi;
+ gint fd;
+} FileInfo;
+
+static GslWaveFileInfo*
+wav_load_file_info (gpointer data,
+ const gchar *file_name,
+ GslErrorType *error_p)
+{
+ WavHeader wav_header;
+ FileInfo *fi;
+ gint fd;
+
+ fd = open (file_name, O_RDONLY);
+ if (fd < 0)
+ {
+ *error_p = GSL_ERROR_OPEN_FAILED;
+ return NULL;
+ }
+
+ *error_p = wav_read_header (fd, &wav_header);
+ if (*error_p)
+ {
+ close (fd);
+ return NULL;
+ }
+
+ fi = gsl_new_struct0 (FileInfo, 1);
+ fi->wfi.n_waves = 1;
+ fi->wfi.waves = g_malloc0 (sizeof (fi->wfi.waves[0]) * fi->wfi.n_waves);
+ fi->wfi.waves[0].name = g_strdup (file_name);
+ fi->fd = fd;
+
+ return &fi->wfi;
+}
+
+static void
+wav_free_file_info (gpointer data,
+ GslWaveFileInfo *file_info)
+{
+ FileInfo *fi = (FileInfo*) file_info;
+
+ g_free (fi->wfi.waves[0].name);
+ g_free (fi->wfi.waves);
+ close (fi->fd);
+ gsl_delete_struct (FileInfo, fi);
+}
+
+typedef struct
+{
+ GslWaveDsc wdsc;
+ GslLong data_offset;
+ GslLong n_values;
+ GslWaveFormatType format;
+} WaveDsc;
+
+static GslWaveDsc*
+wav_load_wave_dsc (gpointer data,
+ GslWaveFileInfo *file_info,
+ guint nth_wave,
+ GslErrorType *error_p)
+{
+ FileInfo *fi = (FileInfo*) file_info;
+ DataHeader data_header;
+ FmtHeader fmt_header;
+ WaveDsc *dsc;
+ GslWaveFormatType format;
+ GslLong data_offset, data_width;
+
+ g_return_val_if_fail (nth_wave == 0, NULL);
+
+ if (lseek (fi->fd, sizeof (WavHeader), SEEK_SET) != sizeof (WavHeader))
+ {
+ WAV_DEBUG ("failed to seek to end of WavHeader");
+ *error_p = GSL_ERROR_IO;
+ return NULL;
+ }
+
+ *error_p = wav_read_fmt_header (fi->fd, &fmt_header);
+ if (*error_p)
+ return NULL;
+
+ data_width = (fmt_header.bit_per_sample + 7) / 8;
+ *error_p = wav_read_data_header (fi->fd, &data_header, data_width * fmt_header.n_channels);
+ data_offset = lseek (fi->fd, 0, SEEK_CUR);
+ if (data_offset < sizeof (WavHeader) && !*error_p)
+ {
+ WAV_DEBUG ("failed to seek to start of data");
+ *error_p = GSL_ERROR_IO;
+ }
+ if (*error_p)
+ return NULL;
+
+ switch (fmt_header.bit_per_sample)
+ {
+ case 8: format = GSL_WAVE_FORMAT_UNSIGNED_8; break;
+ case 12: format = GSL_WAVE_FORMAT_SIGNED_12; break;
+ case 16: format = GSL_WAVE_FORMAT_SIGNED_16; break;
+ default:
+ WAV_DEBUG ("unrecognized sample width (%u)", fmt_header.bit_per_sample);
+ *error_p = GSL_ERROR_FORMAT_UNKNOWN;
+ return NULL;
+ }
+ if (0)
+ WAV_DEBUG ("n_channels: %d sample_freq: %d bit_width: %u",
+ fmt_header.n_channels, fmt_header.sample_freq, fmt_header.bit_per_sample);
+
+ dsc = gsl_new_struct0 (WaveDsc, 1);
+ dsc->wdsc.name = g_strdup (fi->wfi.waves[0].name);
+ dsc->wdsc.n_channels = fmt_header.n_channels;
+ dsc->wdsc.n_chunks = 1;
+ dsc->wdsc.chunks = g_malloc0 (sizeof (dsc->wdsc.chunks[0]) * dsc->wdsc.n_chunks);
+ dsc->wdsc.chunks[0].mix_freq = fmt_header.sample_freq;
+ dsc->wdsc.chunks[0].osc_freq = 440.0; /* FIXME */
+ dsc->data_offset = data_offset;
+ dsc->n_values = data_header.data_length / data_width;
+ dsc->format = format;
+
+ return &dsc->wdsc;
+}
+
+static void
+wav_free_wave_dsc (gpointer data,
+ GslWaveDsc *wave_dsc)
+{
+ WaveDsc *dsc = (WaveDsc*) wave_dsc;
+
+ g_free (dsc->wdsc.name);
+ g_free (dsc->wdsc.chunks);
+ gsl_delete_struct (WaveDsc, dsc);
+}
+
+static GslDataHandle*
+wav_create_chunk_handle (gpointer data,
+ GslWaveDsc *wave_dsc,
+ guint nth_chunk,
+ GslErrorType *error_p)
+{
+ WaveDsc *dsc = (WaveDsc*) wave_dsc;
+ GslDataHandle *dhandle;
+
+ g_return_val_if_fail (nth_chunk == 0, NULL);
+
+ dhandle = gsl_wave_handle_new (dsc->wdsc.file_info->file_name,
+ dsc->wdsc.n_channels,
+ dsc->format, G_LITTLE_ENDIAN,
+ dsc->data_offset, dsc->n_values);
+ return dhandle;
+}
+
+void
+_gsl_init_loader_wav (void)
+{
+ static const gchar *file_exts[] = { "wav", NULL, };
+ static const gchar *mime_types[] = { "audio/wav", "audio/x-wav", NULL, };
+ static const gchar *magics[] = {
+ (
+ "0 string RIFF\n"
+ "8 string WAVE\n"
+ "12 string fmt\\s\n" /* expect "fmt " */
+ "16 lelong >15\n" /* expect valid sub chunk length */
+ "20 leshort =1\n" /* expect PCM format */
+ ),
+ NULL,
+ };
+ static GslLoader loader = {
+ "RIFF, WAVE audio, PCM",
+ file_exts,
+ mime_types,
+ magics,
+ 0, /* priority */
+ NULL,
+ wav_load_file_info,
+ wav_free_file_info,
+ wav_load_wave_dsc,
+ wav_free_wave_dsc,
+ wav_create_chunk_handle,
+ };
+ static gboolean initialized = FALSE;
+
+ g_assert (initialized == FALSE);
+ initialized = TRUE;
+
+ gsl_loader_register (&loader);
+}
diff --git a/flow/gsl/gslloader.c b/flow/gsl/gslloader.c
new file mode 100644
index 0000000..002e39f
--- /dev/null
+++ b/flow/gsl/gslloader.c
@@ -0,0 +1,335 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001-2002 Tim Janik and Stefan Westerfeld
+ *
+ * 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 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.
+ */
+#include "gslloader.h"
+
+#include "gslcommon.h"
+#include "gsldatahandle.h"
+#include "gslmagic.h"
+#include <string.h>
+
+
+/* --- variables --- */
+static GslLoader *gsl_loader_list = NULL;
+static GslRing *gsl_magic_list = NULL;
+
+
+/* --- functions --- */
+static GslLoader*
+loader_find_by_name (const gchar *name)
+{
+ GslLoader *loader;
+
+ for (loader = gsl_loader_list; loader != NULL; loader = loader->next)
+ if (strcmp (name, loader->name) == 0)
+ return loader;
+ return NULL;
+}
+
+void
+gsl_loader_register (GslLoader *loader)
+{
+ g_return_if_fail (loader != NULL);
+ g_return_if_fail (loader->name != NULL);
+ g_return_if_fail (loader->extensions || loader->mime_types || loader->magic_specs);
+ g_return_if_fail (loader_find_by_name (loader->name) == NULL);
+ g_return_if_fail (loader->next == NULL);
+ g_return_if_fail (loader->load_file_info != NULL);
+ g_return_if_fail (loader->free_file_info != NULL);
+ g_return_if_fail (loader->load_wave_dsc != NULL);
+ g_return_if_fail (loader->free_wave_dsc != NULL);
+ g_return_if_fail (loader->create_chunk_handle != NULL);
+
+ loader->next = gsl_loader_list;
+ gsl_loader_list = loader;
+
+ if (loader->magic_specs)
+ {
+ GslMagic *magic;
+ guint i, j;
+
+ for (i = 0; loader->magic_specs[i]; i++)
+ {
+ if (loader->extensions)
+ for (j = 0; loader->extensions[j]; j++)
+ {
+ magic = gsl_magic_create (loader, loader->priority,
+ loader->extensions[j], loader->magic_specs[i]);
+ gsl_magic_list = gsl_ring_append (gsl_magic_list, magic);
+ }
+ else
+ {
+ magic = gsl_magic_create (loader, loader->priority,
+ NULL, loader->magic_specs[i]);
+ gsl_magic_list = gsl_ring_append (gsl_magic_list, magic);
+ }
+ }
+ }
+}
+
+GslLoader*
+gsl_loader_match (const gchar *file_name)
+{
+ GslMagic *magic;
+
+ g_return_val_if_fail (file_name != NULL, NULL);
+
+ magic = gsl_magic_list_match_file (gsl_magic_list, file_name);
+ if (magic)
+ return magic->data;
+
+ return NULL;
+}
+
+GslWaveFileInfo*
+gsl_wave_file_info_load (const gchar *file_name,
+ GslErrorType *error_p)
+{
+ GslWaveFileInfo *finfo = NULL;
+ GslErrorType error = GSL_ERROR_NONE;
+ GslLoader *loader;
+
+ if (error_p)
+ *error_p = GSL_ERROR_INTERNAL;
+ g_return_val_if_fail (file_name != NULL, NULL);
+
+ loader = gsl_loader_match (file_name);
+ if (loader)
+ {
+ finfo = loader->load_file_info (loader->data, file_name, &error);
+ if (error && finfo)
+ {
+ /* loaders shouldn't do this */
+ loader->free_file_info (loader->data, finfo);
+ finfo = NULL;
+ }
+ if (!finfo && !error)
+ error = GSL_ERROR_FILE_EMPTY; /* FIXME: try next loader */
+ if (finfo)
+ {
+ if (finfo->n_waves > 0)
+ {
+ guint i;
+
+ g_return_val_if_fail (finfo->loader == NULL, NULL);
+ g_return_val_if_fail (finfo->file_name == NULL, NULL);
+
+ for (i = 0; i < finfo->n_waves; i++)
+ g_return_val_if_fail (finfo->waves[i].name != NULL, NULL);
+
+ finfo->file_name = g_strdup (file_name);
+ finfo->loader = loader;
+ finfo->ref_count = 1;
+ }
+ else
+ {
+ loader->free_file_info (loader->data, finfo);
+ finfo = NULL;
+ error = GSL_ERROR_FILE_EMPTY; /* FIXME: try next loader */
+ }
+ }
+ }
+ else /* no loader match */
+ {
+ /* try to provide appropriate error code */
+ error = gsl_check_file (file_name, "rf");
+ if (!error)
+ error = GSL_ERROR_FORMAT_UNKNOWN;
+ }
+
+ if (error_p)
+ *error_p = error;
+
+ return finfo;
+}
+
+void
+gsl_wave_file_info_unref (GslWaveFileInfo *wave_file_info)
+{
+ g_return_if_fail (wave_file_info != NULL);
+ g_return_if_fail (wave_file_info->ref_count > 0);
+
+ wave_file_info->ref_count--;
+ if (!wave_file_info->ref_count)
+ {
+ GslLoader *loader = wave_file_info->loader;
+
+ g_free (wave_file_info->file_name);
+ wave_file_info->file_name = NULL;
+ wave_file_info->loader = NULL;
+
+ loader->free_file_info (loader->data, wave_file_info);
+ }
+}
+
+GslWaveFileInfo*
+gsl_wave_file_info_ref (GslWaveFileInfo *wave_file_info)
+{
+ g_return_val_if_fail (wave_file_info != NULL, NULL);
+ g_return_val_if_fail (wave_file_info->ref_count > 0, NULL);
+
+ wave_file_info->ref_count++;
+
+ return wave_file_info;
+}
+
+GslWaveDsc*
+gsl_wave_dsc_load (GslWaveFileInfo *wave_file_info,
+ guint nth_wave,
+ GslErrorType *error_p)
+{
+ GslErrorType error = GSL_ERROR_NONE;
+ GslWaveDsc *wdsc;
+ GslLoader *loader;
+
+ if (error_p)
+ *error_p = GSL_ERROR_INTERNAL;
+ g_return_val_if_fail (wave_file_info != NULL, NULL);
+ g_return_val_if_fail (wave_file_info->loader != NULL, NULL);
+ g_return_val_if_fail (nth_wave < wave_file_info->n_waves, NULL);
+
+ loader = wave_file_info->loader;
+ wdsc = loader->load_wave_dsc (loader->data, wave_file_info, nth_wave,&error);
+
+ if (error && wdsc)
+ {
+ /* loaders shouldn't do this */
+ loader->free_wave_dsc (loader->data, wdsc);
+ wdsc = NULL;
+ }
+ if (!wdsc && !error)
+ error = GSL_ERROR_FILE_EMPTY;
+ if (wdsc)
+ {
+ if (wdsc->n_chunks > 0)
+ {
+ g_return_val_if_fail (wdsc->file_info == NULL, NULL);
+ g_return_val_if_fail (wdsc->name && strcmp (wdsc->name, wave_file_info->waves[nth_wave].name) == 0, NULL);
+
+ wdsc->file_info = wave_file_info;
+ gsl_wave_file_info_ref (wave_file_info);
+ }
+ else
+ {
+ loader->free_wave_dsc (loader->data, wdsc);
+ wdsc = NULL;
+ error = GSL_ERROR_FILE_EMPTY;
+ }
+ }
+
+ if (error_p)
+ *error_p = error;
+
+ return wdsc;
+}
+
+void
+gsl_wave_dsc_free (GslWaveDsc *wave_dsc)
+{
+ GslWaveFileInfo *file_info;
+
+ g_return_if_fail (wave_dsc != NULL);
+ g_return_if_fail (wave_dsc->file_info != NULL);
+
+ file_info = wave_dsc->file_info;
+ wave_dsc->file_info = NULL;
+
+ file_info->loader->free_wave_dsc (file_info->loader->data, wave_dsc);
+
+ gsl_wave_file_info_unref (file_info);
+}
+
+GslDataHandle*
+gsl_wave_handle_create (GslWaveDsc *wave_dsc,
+ guint nth_chunk,
+ GslErrorType *error_p)
+{
+ GslErrorType error = GSL_ERROR_NONE;
+ GslDataHandle *dhandle;
+ GslLoader *loader;
+
+ if (error_p)
+ *error_p = GSL_ERROR_INTERNAL;
+ g_return_val_if_fail (wave_dsc != NULL, NULL);
+ g_return_val_if_fail (wave_dsc->file_info != NULL, NULL);
+ g_return_val_if_fail (nth_chunk < wave_dsc->n_chunks, NULL);
+
+ loader = wave_dsc->file_info->loader;
+
+ dhandle = loader->create_chunk_handle (loader->data,
+ wave_dsc,
+ nth_chunk,
+ &error);
+ if (error && dhandle)
+ {
+ /* loaders shouldn't do this */
+ gsl_data_handle_unref (dhandle);
+ dhandle = NULL;
+ }
+ if (!dhandle && !error)
+ error = GSL_ERROR_FORMAT_INVALID;
+
+ if (error_p)
+ *error_p = error;
+
+ return dhandle;
+}
+
+GslWaveChunk*
+gsl_wave_chunk_create (GslWaveDsc *wave_dsc,
+ guint nth_chunk,
+ GslErrorType *error_p)
+{
+ GslDataHandle *dhandle;
+ GslDataCache *dcache;
+ GslWaveChunk *wchunk;
+
+ if (error_p)
+ *error_p = GSL_ERROR_INTERNAL;
+ g_return_val_if_fail (wave_dsc != NULL, NULL);
+ g_return_val_if_fail (nth_chunk < wave_dsc->n_chunks, NULL);
+
+ dhandle = gsl_wave_handle_create (wave_dsc, nth_chunk, error_p);
+ if (!dhandle)
+ return NULL;
+
+ if (error_p)
+ *error_p = GSL_ERROR_IO;
+
+ /* FIXME: we essentially create a dcache for each wchunk here ;( */
+
+ dcache = gsl_data_cache_from_dhandle (dhandle, gsl_get_config ()->wave_chunk_padding * wave_dsc->n_channels);
+ gsl_data_handle_unref (dhandle);
+ if (!dcache)
+ return NULL;
+ /* dcache keeps dhandle alive */
+
+ wchunk = gsl_wave_chunk_new (dcache,
+ wave_dsc->chunks[nth_chunk].osc_freq,
+ wave_dsc->chunks[nth_chunk].mix_freq,
+ wave_dsc->chunks[nth_chunk].loop_type,
+ wave_dsc->chunks[nth_chunk].loop_start,
+ wave_dsc->chunks[nth_chunk].loop_end,
+ wave_dsc->chunks[nth_chunk].loop_count);
+ gsl_data_cache_unref (dcache);
+
+ if (error_p && wchunk)
+ *error_p = GSL_ERROR_NONE;
+
+ return wchunk;
+}
diff --git a/flow/gsl/gslloader.h b/flow/gsl/gslloader.h
new file mode 100644
index 0000000..e4b391c
--- /dev/null
+++ b/flow/gsl/gslloader.h
@@ -0,0 +1,136 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001-2002 Tim Janik and Stefan Westerfeld
+ *
+ * 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 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.
+ */
+#ifndef __GSL_LOADER_H__
+#define __GSL_LOADER_H__
+
+#include <gsl/gsldefs.h>
+#include <gsl/gslcommon.h>
+#include <gsl/gslwavechunk.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+
+typedef struct _GslWaveFileInfo GslWaveFileInfo;
+typedef struct _GslWaveDsc GslWaveDsc;
+typedef struct _GslWaveChunkDsc GslWaveChunkDsc;
+
+/* --- structures --- */
+struct _GslWaveFileInfo
+{
+ guint n_waves;
+ struct {
+ gchar *name;
+ } *waves;
+
+ /*< private >*/
+ gchar *file_name;
+ GslLoader *loader;
+ guint ref_count;
+};
+struct _GslWaveDsc
+{
+ gchar *name;
+ guint n_chunks;
+ GslWaveChunkDsc *chunks;
+ guint n_channels;
+ /*< private >*/
+ GslWaveFileInfo *file_info;
+};
+struct _GslWaveChunkDsc
+{
+ gfloat osc_freq;
+ gfloat mix_freq;
+ GslWaveLoopType loop_type;
+ GslLong loop_start; /* sample offset */
+ GslLong loop_end; /* sample offset */
+ guint loop_count;
+ /* loader-specific */
+ GslLong loader_offset;
+ GslLong loader_length;
+ gpointer loader_data1; /* generic pointers for more data */
+ gpointer loader_data2;
+};
+
+
+/* --- functions --- */
+GslWaveFileInfo* gsl_wave_file_info_load (const gchar *file_name,
+ GslErrorType *error);
+GslWaveFileInfo* gsl_wave_file_info_ref (GslWaveFileInfo *wave_file_info);
+void gsl_wave_file_info_unref (GslWaveFileInfo *wave_file_info);
+GslWaveDsc* gsl_wave_dsc_load (GslWaveFileInfo *wave_file_info,
+ guint nth_wave,
+ GslErrorType *error);
+void gsl_wave_dsc_free (GslWaveDsc *wave_dsc);
+GslDataHandle* gsl_wave_handle_create (GslWaveDsc *wave_dsc,
+ guint nth_chunk,
+ GslErrorType *error);
+GslWaveChunk* gsl_wave_chunk_create (GslWaveDsc *wave_dsc,
+ guint nth_chunk,
+ GslErrorType *error);
+
+
+/* --- loader impl --- */
+struct _GslLoader
+{
+ const gchar *name; /* format/loader name, e.g. "GslWave" or "WAVE audio, RIFF (little-endian)" */
+
+ /* at least one of the
+ * following three must
+ * be non-NULL
+ */
+ const gchar **extensions; /* e.g.: "mp3", "ogg" or "gslwave" */
+ const gchar **mime_types; /* e.g.: "audio/x-mpg3" or "audio/x-wav" */
+ const gchar **magic_specs; /* e.g.: "0 string RIFF\n8 string WAVE\n" or "0 string #GslWave\n" */
+
+ gint priority; /* -100=high, +100=low, 0=default */
+
+ /*< private >*/
+ gpointer data;
+ GslWaveFileInfo* (*load_file_info) (gpointer data,
+ const gchar *file_name,
+ GslErrorType *error);
+ void (*free_file_info) (gpointer data,
+ GslWaveFileInfo *file_info);
+ GslWaveDsc* (*load_wave_dsc) (gpointer data,
+ GslWaveFileInfo *file_info,
+ guint nth_wave,
+ GslErrorType *error);
+ void (*free_wave_dsc) (gpointer data,
+ GslWaveDsc *wave_dsc);
+ GslDataHandle* (*create_chunk_handle) (gpointer data,
+ GslWaveDsc *wave_dsc,
+ guint nth_chunk,
+ GslErrorType *error);
+ GslLoader *next; /* must be NULL */
+};
+
+void gsl_loader_register (GslLoader *loader);
+GslLoader* gsl_loader_match (const gchar *file_name);
+
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_LOADER_H__ */
diff --git a/flow/gsl/gslmagic.c b/flow/gsl/gslmagic.c
new file mode 100644
index 0000000..29486e3
--- /dev/null
+++ b/flow/gsl/gslmagic.c
@@ -0,0 +1,711 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2000-2002 Tim Janik
+ *
+ * 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 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.
+ */
+#include "gslmagic.h"
+
+#include "gslcommon.h"
+
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+
+/* --- defines --- */
+#define BFILE_BSIZE (768) /* amount of buffering */
+#define MAX_MAGIC_STRING (256) /* must be < BFILE_BSIZE / 2 */
+
+
+/* --- typedefs & structures --- */
+typedef struct _Magic Magic;
+typedef struct _BFile BFile;
+struct _BFile
+{
+ gint fd;
+ guint file_size;
+ guint8 header[BFILE_BSIZE];
+ guint offset;
+ guint8 buffer[BFILE_BSIZE];
+};
+
+
+/* --- prototypes --- */
+static Magic* magic_create (gchar *magic_string,
+ const gchar *original);
+static gboolean magic_match_file (BFile *bfile,
+ Magic *magics);
+static gboolean bfile_open (BFile *bfile,
+ const gchar *file_name);
+static gboolean bfile_read (BFile *bfile,
+ guint offset,
+ void *mem,
+ guint n_bytes);
+static void bfile_close (BFile *bfile);
+static guint bfile_get_size (BFile *bfile);
+
+
+/* --- functions --- */
+GslMagic*
+gsl_magic_list_match_file (GslRing *magic_list,
+ const gchar *file_name)
+{
+ GslMagic *rmagic = NULL;
+ BFile bfile = { -1, };
+
+ g_return_val_if_fail (file_name != NULL, NULL);
+
+ if (bfile_open (&bfile, file_name))
+ {
+ gchar *extension = strrchr (file_name, '.');
+ gint rpriority = G_MAXINT;
+ GslRing *node;
+
+ /* we do a quick scan by extension first */
+ if (!rmagic && extension)
+ for (node = magic_list; node; node = gsl_ring_walk (magic_list, node))
+ {
+ GslMagic *magic = node->data;
+
+ if (!magic->extension
+ || strcmp (magic->extension, extension) != 0
+ || rpriority < magic->priority
+ || (rmagic && rpriority == magic->priority))
+ continue;
+ if (magic_match_file (&bfile, magic->match_list))
+ {
+ rmagic = magic;
+ rpriority = rmagic->priority;
+ }
+ }
+ /* then we do a normal walk but skip extension matches */
+ if (!rmagic && extension)
+ for (node = magic_list; node; node = gsl_ring_walk (magic_list, node))
+ {
+ GslMagic *magic = node->data;
+
+ if ((magic->extension && strcmp (magic->extension, extension) == 0)
+ || rpriority < magic->priority
+ || (rmagic && rpriority == magic->priority))
+ continue;
+ if (magic_match_file (&bfile, magic->match_list))
+ {
+ rmagic = magic;
+ rpriority = rmagic->priority;
+ }
+ }
+ /* for no extension, we do a full walk */
+ if (!rmagic && !extension)
+ for (node = magic_list; node; node = gsl_ring_walk (magic_list, node))
+ {
+ GslMagic *magic = node->data;
+
+ if (rpriority < magic->priority ||
+ (rmagic && rpriority == magic->priority))
+ continue;
+ if (magic_match_file (&bfile, magic->match_list))
+ {
+ rmagic = magic;
+ rpriority = rmagic->priority;
+ }
+ }
+ bfile_close (&bfile);
+ }
+
+ return rmagic;
+}
+
+GslMagic*
+gsl_magic_create (gpointer data,
+ gint priority,
+ const gchar *extension,
+ const gchar *magic_spec)
+{
+ GslMagic *magic;
+ Magic *match_list;
+ gchar *magic_string;
+
+ g_return_val_if_fail (magic_spec != NULL, NULL);
+
+ magic_string = g_strdup (magic_spec);
+ match_list = magic_create (magic_string, magic_spec);
+ g_free (magic_string);
+ if (!match_list)
+ return NULL;
+
+ magic = g_new (GslMagic, 1);
+ magic->data = data;
+ magic->extension = g_strdup (extension);
+ magic->priority = priority;
+ magic->match_list = match_list;
+
+ return magic;
+}
+
+
+/* --- Magic creation/checking --- */
+typedef enum
+{
+ MAGIC_CHECK_ANY,
+ MAGIC_CHECK_INT_EQUAL,
+ MAGIC_CHECK_INT_GREATER,
+ MAGIC_CHECK_INT_SMALLER,
+ MAGIC_CHECK_UINT_GREATER,
+ MAGIC_CHECK_UINT_SMALLER,
+ MAGIC_CHECK_UINT_ZEROS,
+ MAGIC_CHECK_UINT_ONES,
+ MAGIC_CHECK_STRING_EQUAL,
+ MAGIC_CHECK_STRING_GREATER,
+ MAGIC_CHECK_STRING_SMALLER
+} MagicCheckType;
+typedef union
+{
+ gint32 v_int32;
+ guint32 v_uint32;
+ gchar *v_string;
+} MagicData;
+struct _Magic
+{
+ Magic *next;
+ gulong offset;
+ guint data_size;
+ MagicCheckType magic_check;
+ guint32 data_mask;
+ MagicData value;
+ guint read_string : 1;
+ guint read_size : 1;
+ guint need_swap : 1;
+ guint cmp_unsigned : 1;
+};
+static const gchar *magic_field_delims = " \t,";
+static const gchar *magic_string_delims = " \t\n\r";
+
+static gboolean
+magic_parse_test (Magic *magic,
+ const gchar *string)
+{
+ if (!magic->read_string)
+ {
+ gchar *f = NULL;
+
+ if (string[0] == '<' || string[0] == '>')
+ {
+ if (magic->cmp_unsigned)
+ magic->magic_check = string[0] == '<' ? MAGIC_CHECK_UINT_SMALLER : MAGIC_CHECK_UINT_GREATER;
+ else
+ magic->magic_check = string[0] == '<' ? MAGIC_CHECK_INT_SMALLER : MAGIC_CHECK_INT_GREATER;
+ string += 1;
+ }
+ else if (string[0] == '^' || string[0] == '&')
+ {
+ magic->magic_check = string[0] == '&' ? MAGIC_CHECK_UINT_ONES : MAGIC_CHECK_UINT_ZEROS;
+ string += 1;
+ }
+ else if (string[0] == 'x')
+ {
+ magic->magic_check = MAGIC_CHECK_ANY;
+ string += 1;
+ }
+ else
+ {
+ string += string[0] == '=';
+ magic->magic_check = MAGIC_CHECK_INT_EQUAL;
+ }
+ if (string[0] == '0')
+ magic->value.v_int32 = strtol (string, &f, string[1] == 'x' ? 16 : 8);
+ else
+ magic->value.v_int32 = strtol (string, &f, 10);
+
+ return *string == 0 || !f || *f == 0;
+ }
+ else
+ {
+ gchar tmp_string[MAX_MAGIC_STRING + 1];
+ guint n = 0;
+
+ if (string[0] == '<' || string[0] == '>')
+ {
+ magic->magic_check = string[0] == '<' ? MAGIC_CHECK_STRING_SMALLER : MAGIC_CHECK_STRING_GREATER;
+ string += 1;
+ }
+ else
+ {
+ string += string[0] == '=';
+ magic->magic_check = MAGIC_CHECK_STRING_EQUAL;
+ }
+ while (n < MAX_MAGIC_STRING && string[n] && !strchr (magic_string_delims, string[n]))
+ {
+ if (string[n] != '\\')
+ tmp_string[n] = string[n];
+ else switch ((++string)[n])
+ {
+ case '\\': tmp_string[n] = '\\'; break;
+ case 't': tmp_string[n] = '\t'; break;
+ case 'n': tmp_string[n] = '\n'; break;
+ case 'r': tmp_string[n] = '\r'; break;
+ case 'b': tmp_string[n] = '\b'; break;
+ case 'f': tmp_string[n] = '\f'; break;
+ case 's': tmp_string[n] = ' '; break;
+ case 'e': tmp_string[n] = 27; break;
+ default:
+ if (string[n] >= '0' && string[n] <= '7')
+ {
+ tmp_string[n] = string[n] - '0';
+ if (string[n + 1] >= '0' && string[n + 1] <= '7')
+ {
+ string += 1;
+ tmp_string[n] *= 8;
+ tmp_string[n] += string[n] - '0';
+ if (string[n + 1] >= '0' && string[n + 1] <= '7')
+ {
+ string += 1;
+ tmp_string[n] *= 8;
+ tmp_string[n] += string[n] - '0';
+ }
+ }
+ }
+ else
+ tmp_string[n] = string[n];
+ break;
+ }
+ n++;
+ }
+ tmp_string[n] = 0;
+ magic->data_size = n;
+ magic->value.v_string = g_strdup (tmp_string);
+
+ return TRUE;
+ }
+}
+
+static gboolean
+magic_parse_type (Magic *magic,
+ const gchar *string)
+{
+ gchar *f = NULL;
+
+ if (string[0] == 'u')
+ {
+ string += 1;
+ magic->cmp_unsigned = TRUE;
+ }
+ if (strncmp (string, "byte", 4) == 0)
+ {
+ string += 4;
+ magic->data_size = 1;
+ }
+ else if (strncmp (string, "short", 5) == 0)
+ {
+ string += 5;
+ magic->data_size = 2;
+ }
+ else if (strncmp (string, "leshort", 7) == 0)
+ {
+ string += 7;
+ magic->data_size = 2;
+ magic->need_swap = G_BYTE_ORDER != G_LITTLE_ENDIAN;
+ }
+ else if (strncmp (string, "beshort", 7) == 0)
+ {
+ string += 7;
+ magic->data_size = 2;
+ magic->need_swap = G_BYTE_ORDER != G_BIG_ENDIAN;
+ }
+ else if (strncmp (string, "long", 4) == 0)
+ {
+ string += 4;
+ magic->data_size = 4;
+ }
+ else if (strncmp (string, "lelong", 6) == 0)
+ {
+ string += 6;
+ magic->data_size = 4;
+ magic->need_swap = G_BYTE_ORDER != G_LITTLE_ENDIAN;
+ }
+ else if (strncmp (string, "belong", 6) == 0)
+ {
+ string += 6;
+ magic->data_size = 4;
+ magic->need_swap = G_BYTE_ORDER != G_BIG_ENDIAN;
+ }
+#if 0
+ else if (strncmp (string, "size", 4) == 0)
+ {
+ string += 4;
+ magic->data_size = 4;
+ magic->read_size = TRUE;
+ magic->cmp_unsigned = TRUE;
+ }
+#endif
+ else if (strncmp (string, "string", 6) == 0)
+ {
+ string += 6;
+ magic->data_size = 0;
+ magic->read_string = TRUE;
+ }
+ if (string[0] == '&')
+ {
+ string += 1;
+ if (string[0] == '0')
+ magic->data_mask = strtol (string, &f, string[1] == 'x' ? 16 : 8);
+ else
+ magic->data_mask = strtol (string, &f, 10);
+ if (f && *f != 0)
+ return FALSE;
+ while (*string)
+ string++;
+ }
+ else
+ magic->data_mask = 0xffffffff;
+
+ return *string == 0;
+}
+
+static gboolean
+magic_parse_offset (Magic *magic,
+ gchar *string)
+{
+ gchar *f = NULL;
+
+ if (string[0] == '0')
+ magic->offset = strtol (string, &f, string[1] == 'x' ? 16 : 8);
+ else
+ magic->offset = strtol (string, &f, 10);
+
+ return !f || *f == 0;
+}
+
+static Magic*
+magic_create (gchar *magic_string,
+ const gchar *original)
+#define SKIP_CLEAN(s) { while (*s && !strchr(magic_field_delims, *s)) s++; \
+ while (*s && strchr(magic_field_delims, *s)) \
+ *(s++)=0;}
+{
+ Magic *magics = NULL;
+ gchar *p = magic_string;
+
+ while (p && *p)
+ {
+ gchar *next_line;
+
+ if (*p == '#' || *p == '\n')
+ {
+ next_line = strchr (p, '\n');
+ if (next_line)
+ next_line++;
+ }
+ else
+ {
+ Magic *tmp = magics;
+
+ magics = g_new0 (Magic, 1);
+ magics->next = tmp;
+
+ magic_string = p;
+ SKIP_CLEAN (p);
+ if (!magic_parse_offset (magics, magic_string))
+ {
+ g_warning ("unable to parse magic offset \"%s\" from \"%s\"", magic_string, original);
+ return NULL;
+ }
+ magic_string = p;
+ SKIP_CLEAN (p);
+ if (!magic_parse_type (magics, magic_string))
+ {
+ g_warning ("unable to parse magic type \"%s\" from \"%s\"", magic_string, original);
+ return NULL;
+ }
+ magic_string = p;
+ next_line = strchr (magic_string, '\n');
+ if (next_line)
+ *(next_line++) = 0;
+ if (!magics->read_string)
+ SKIP_CLEAN (p);
+ if (!magic_parse_test (magics, magic_string))
+ {
+ g_warning ("unable to parse magic test \"%s\" from \"%s\"", magic_string, original);
+ return NULL;
+ }
+ }
+ p = next_line;
+ }
+
+ return magics;
+}
+
+static gboolean
+magic_check_data (Magic *magic,
+ MagicData *data)
+{
+ gint cmp = 0;
+
+ switch (magic->magic_check)
+ {
+ guint l;
+ case MAGIC_CHECK_ANY:
+ cmp = 1;
+ break;
+ case MAGIC_CHECK_INT_EQUAL:
+ data->v_int32 &= magic->data_mask;
+ cmp = data->v_int32 == magic->value.v_int32;
+ break;
+ case MAGIC_CHECK_INT_GREATER:
+ data->v_int32 &= magic->data_mask;
+ cmp = data->v_int32 > magic->value.v_int32;
+ break;
+ case MAGIC_CHECK_INT_SMALLER:
+ data->v_int32 &= magic->data_mask;
+ cmp = data->v_int32 < magic->value.v_int32;
+ break;
+ case MAGIC_CHECK_UINT_GREATER:
+ data->v_uint32 &= magic->data_mask;
+ cmp = data->v_uint32 > magic->value.v_uint32;
+ break;
+ case MAGIC_CHECK_UINT_SMALLER:
+ data->v_uint32 &= magic->data_mask;
+ cmp = data->v_uint32 < magic->value.v_uint32;
+ break;
+ case MAGIC_CHECK_UINT_ZEROS:
+ data->v_uint32 &= magic->data_mask;
+ cmp = (data->v_int32 & magic->value.v_int32) == 0;
+ break;
+ case MAGIC_CHECK_UINT_ONES:
+ data->v_uint32 &= magic->data_mask;
+ cmp = (data->v_int32 & magic->value.v_int32) == magic->value.v_int32;
+ break;
+ case MAGIC_CHECK_STRING_EQUAL:
+ l = magic->data_size < 1 ? strlen (data->v_string) : magic->data_size;
+ cmp = strncmp (data->v_string, magic->value.v_string, l) == 0;
+ break;
+ case MAGIC_CHECK_STRING_GREATER:
+ l = magic->data_size < 1 ? strlen (data->v_string) : magic->data_size;
+ cmp = strncmp (data->v_string, magic->value.v_string, l) > 0;
+ break;
+ case MAGIC_CHECK_STRING_SMALLER:
+ l = magic->data_size < 1 ? strlen (data->v_string) : magic->data_size;
+ cmp = strncmp (data->v_string, magic->value.v_string, l) < 0;
+ break;
+ }
+
+ return cmp > 0;
+}
+
+static inline gboolean
+magic_read_data (BFile *bfile,
+ Magic *magic,
+ MagicData *data)
+{
+ guint file_size = bfile_get_size (bfile);
+
+ if (magic->read_size)
+ data->v_uint32 = file_size;
+ else if (magic->read_string)
+ {
+ guint l = magic->data_size;
+
+ if (l < 1 || l > MAX_MAGIC_STRING)
+ l = MIN (MAX_MAGIC_STRING, file_size - magic->offset);
+ if (!bfile_read (bfile, magic->offset, data->v_string, l))
+ return FALSE;
+ data->v_string[MAX (l, 0)] = 0;
+ }
+ else
+ {
+ if (magic->data_size == 4)
+ {
+ guint32 uint32 = 0;
+
+ if (!bfile_read (bfile, magic->offset, &uint32, 4))
+ return FALSE;
+ if (magic->need_swap)
+ data->v_uint32 = GUINT32_SWAP_LE_BE (uint32);
+ else
+ data->v_uint32 = uint32;
+ }
+ else if (magic->data_size == 2)
+ {
+ guint16 uint16 = 0;
+
+ if (!bfile_read (bfile, magic->offset, &uint16, 2))
+ return FALSE;
+ if (magic->need_swap)
+ uint16 = GUINT16_SWAP_LE_BE (uint16);
+ if (magic->cmp_unsigned)
+ data->v_uint32 = uint16;
+ else
+ data->v_int32 = (signed) uint16;
+ }
+ else if (magic->data_size == 1)
+ {
+ guint8 uint8;
+
+ if (!bfile_read (bfile, magic->offset, &uint8, 1))
+ return FALSE;
+ if (magic->cmp_unsigned)
+ data->v_uint32 = uint8;
+ else
+ data->v_int32 = (signed) uint8;
+ }
+ else
+ g_assert_not_reached ();
+ }
+
+ return TRUE;
+}
+
+static gboolean
+magic_match_file (BFile *bfile,
+ Magic *magics)
+{
+ g_return_val_if_fail (bfile != NULL, FALSE);
+ g_return_val_if_fail (magics != NULL, FALSE);
+
+ do
+ {
+ gchar data_string[MAX_MAGIC_STRING + 1];
+ MagicData data;
+
+ if (magics->read_string)
+ data.v_string = data_string;
+ else
+ data.v_uint32 = 0;
+
+ if (!magic_read_data (bfile, magics, &data) ||
+ !magic_check_data (magics, &data))
+ return FALSE;
+ magics = magics->next;
+ }
+ while (magics);
+
+ return TRUE;
+}
+
+
+/* --- buffered file, optimized for magic checks --- */
+static gboolean
+bfile_open (BFile *bfile,
+ const gchar *file_name)
+{
+ struct stat buf = { 0, };
+ gint ret;
+
+ g_return_val_if_fail (bfile != NULL, FALSE);
+ g_return_val_if_fail (bfile->fd < 0, FALSE);
+ g_return_val_if_fail (file_name != NULL, FALSE);
+
+ bfile->fd = open (file_name, O_RDONLY);
+ if (bfile->fd < 0)
+ return FALSE;
+
+ do
+ ret = fstat (bfile->fd, &buf);
+ while (ret < 0 && errno == EINTR);
+ if (ret < 0)
+ {
+ bfile_close (bfile);
+ return FALSE;
+ }
+ bfile->file_size = buf.st_size;
+
+ do
+ ret = read (bfile->fd, bfile->header, BFILE_BSIZE);
+ while (ret < 0 && errno == EINTR);
+ if (ret < 0)
+ {
+ bfile_close (bfile);
+ return FALSE;
+ }
+
+ bfile->offset = 0;
+ memcpy (bfile->buffer, bfile->header, BFILE_BSIZE);
+
+ return TRUE;
+}
+
+static gboolean
+bfile_read (BFile *bfile,
+ guint offset,
+ void *mem,
+ guint n_bytes)
+{
+ guint end = offset + n_bytes;
+ gint ret;
+
+ g_return_val_if_fail (bfile != NULL, FALSE);
+ g_return_val_if_fail (n_bytes < BFILE_BSIZE / 2, FALSE);
+
+ if (end > bfile->file_size || bfile->fd < 0)
+ return FALSE;
+
+ if (end < BFILE_BSIZE)
+ {
+ memcpy (mem, bfile->header + offset, n_bytes);
+ return TRUE;
+ }
+ if (offset >= bfile->offset && end < bfile->offset + BFILE_BSIZE)
+ {
+ memcpy (mem, bfile->buffer + offset - bfile->offset, n_bytes);
+ return TRUE;
+ }
+
+ bfile->offset = offset - BFILE_BSIZE / 8;
+ do
+ ret = lseek (bfile->fd, bfile->offset, SEEK_SET);
+ while (ret < 0 && errno == EINTR);
+ if (ret < 0)
+ {
+ bfile_close (bfile);
+ return FALSE;
+ }
+ do
+ ret = read (bfile->fd, bfile->buffer, BFILE_BSIZE);
+ while (ret < 0 && errno == EINTR);
+ if (ret < 0)
+ {
+ bfile_close (bfile);
+ return FALSE;
+ }
+ if (offset >= bfile->offset && end < bfile->offset + BFILE_BSIZE)
+ {
+ memcpy (mem, bfile->buffer + offset - bfile->offset, n_bytes);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static guint
+bfile_get_size (BFile *bfile)
+{
+ g_return_val_if_fail (bfile != NULL, 0);
+
+ return bfile->fd >= 0 ? bfile->file_size : 0;
+}
+
+static void
+bfile_close (BFile *bfile)
+{
+ g_return_if_fail (bfile != NULL);
+
+ if (bfile->fd >= 0)
+ close (bfile->fd);
+ bfile->fd = -1;
+}
diff --git a/flow/gsl/gslmagic.h b/flow/gsl/gslmagic.h
new file mode 100644
index 0000000..41961bd
--- /dev/null
+++ b/flow/gsl/gslmagic.h
@@ -0,0 +1,72 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2000-2002 Tim Janik
+ *
+ * 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 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.
+ */
+#ifndef __GSL_MAGIC_H__
+#define __GSL_MAGIC_H__
+
+#include <gsl/gsldefs.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+
+/* --- structures --- */
+struct _GslMagic
+{
+ gpointer data;
+ gchar *extension;
+
+ /*< private >*/
+ gint priority;
+ gpointer match_list;
+};
+
+
+/* match entity with:
+ * prefix,
+ * extension,
+ * magic_spec
+ *
+ * where prefix has absolute preference, and extension is just
+ * a _hint_ for magic_spec match order, unless magic_spec==NULL
+ *
+ * no prefix for save handlers. (?) just extension matches.
+ *
+ * need pre-parse functionality, to figure name and type of a
+ * file's contents.
+ */
+
+
+/* --- prototypes --- */
+GslMagic* gsl_magic_create (gpointer data,
+ gint priority,
+ const gchar *extension,
+ const gchar *magic_spec);
+GslMagic* gsl_magic_list_match_file (GslRing *magic_list,
+ const gchar *file_name);
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_MAGIC_H__ */
diff --git a/flow/gsl/gslmakefile.inc b/flow/gsl/gslmakefile.inc
new file mode 100644
index 0000000..9787b7d
--- /dev/null
+++ b/flow/gsl/gslmakefile.inc
@@ -0,0 +1,87 @@
+# this makefile defines:
+#
+# GSL_C_SRC C source files which need to be added to *_SOURCES
+# GSL_NOINST_PROGS GSL test programs, needs to be added to noinst_PROGRAMS
+#
+# this makefile supports:
+#
+# GSL_progs_ldadd add link options to this varibale, which are required
+# to link GSL_NOINST_PROGS targets
+# gslincludedir directory to install public headers into if not empty
+#
+# this makefile introduces:
+#
+# gsltestoutput: make target to generate a sample set of test data
+
+# make sure gslincludedir= is defined
+# GSL targets
+GSL_H_SRC = gslcommon.h gsldatacache.h gsldatahandle.h gsldefs.h \
+ gslloader.h gslmath.h gslfilter.h gsldatautils.h gsldatahandle-vorbis.h \
+ gslconvert.h gslfft.h gslieee754.h gslsignal.h gslmagic.h \
+ gslengine.h gslwaveosc.h gslwavechunk.h gsldatahandle-mad.h \
+ gslosctable.h gsloscillator.h
+GSL_C_SRC = gsldatacache.c gsldatahandle.c gslwavechunk.c gsldatahandle-vorbis.c \
+ gslmath.c gslfilter.c gslcommon.c gsldatautils.c gslmagic.c \
+ gslloader-wav.c gslloader-gslwave.c gslloader-mad.c gslloader-oggvorbis.c \
+ gslconvert.c gslfft.c gslsignal.c gslloader.c gslwaveosc.c \
+ gslengine.c gsloputil.c gslopmaster.c gslopschedule.c gsldatahandle-mad.c \
+ gslosctable.c gsloscillator.c
+GSL_EXTRA_SRC = gslconfig.h gsloputil.h gslopmaster.h gslopnode.h \
+ gslopschedule.h gslincluder.c gslwaveosc-aux.c gsloscillator-aux.c
+GSL_EXTRA_DAT = gsl.gnuplot gsl-mplan.txt gslarrows gslwave.header gslglib.c gslglib.h gsl-fftgen.pl
+EXTRA_DIST += $(GSL_H_SRC) $(GSL_EXTRA_SRC) $(GSL_EXTRA_DAT)
+
+GSL_NOINST_PROGS = gslwchunk gsltests gslffttest
+gslwchunk_SOURCES = gslwchunk.c
+gslwchunk_LDADD = $(GSL_progs_ldadd)
+gslwchunk_LDFLAGS = $(USE_THREADS)
+gsltests_SOURCES = gsltests.c
+gsltests_LDADD = $(GSL_progs_ldadd)
+gsltests_LDFLAGS = $(USE_THREADS)
+gslffttest_SOURCES = gslffttest.c
+gslffttest_LDADD = $(GSL_progs_ldadd)
+gslffttest_LDFLAGS = $(USE_THREADS)
+
+$(srcdir)/gslfft.c: $(srcdir)/gsl-fftgen.pl $(srcdir)/gsl-fftconf.sh
+ cd $(srcdir) && ./gsl-fftconf.sh 'perl ./gsl-fftgen.pl' \"gslfft.h\" >gslfft.c
+MAINTAINERCLEANFILES += gslfft.c
+
+$(srcdir)/gslwchunk.c: gslconfig.h
+$(srcdir)/gsltests.c: gslconfig.h
+$(srcdir)/gslffttest.c: gslconfig.h
+# $(OBJECTS): gslconfig.h
+
+gsl_public_HEADERS = $(GSL_H_SRC) gslconfig.h
+gsl_publicdir = $(gslincludedir)
+
+.PHONY: gsltestoutput
+
+gsltestoutput:
+ @./gsltests blp 7 0.3 0.1211
+ @./gsltests bhp 12 1.8332 0.1033
+ @./gsltests bbp 14 0.5 0.6 0.1033
+ @./gsltests bbs 12 1.5 1.6 0.2
+ @./gsltests t1l 7 0.3 0.0125
+ @./gsltests t1h 8 1.8332 0.1033
+ @./gsltests t1p 6 0.5 0.6 0.1033
+ @./gsltests t1s 8 1.4 1.5 0.25
+ @./gsltests t2l 13 0.1 1.1 0.176
+ @./gsltests t2h 10 1.14 1.2 0.0763
+ @./gsltests t2p 14 0.7 0.8 1.3 0.0763
+ @./gsltests t2p 10 0.9 1.2 1.4 0.15
+ @./gsltests t2s 10 0.9 1.2 1.1 0.15
+ @echo -n "plot [0:pi] [-96:1]"
+ @echo -n " dB(BL7(Z(x))),"
+ @echo -n " dB(BH12(Z(x))),"
+ @echo -n " dB(BP14(Z(x))),"
+ @echo -n " dB(BS12(Z(x))),"
+ @echo -n " dB(T1L7(Z(x))),"
+ @echo -n " dB(T1H8(Z(x))),"
+ @echo -n " dB(T1P6(Z(x))),"
+ @echo -n " dB(T1S8(Z(x))),"
+ @echo -n " dB(T2L13(Z(x))),"
+ @echo -n " dB(T2H10(Z(x))),"
+ @echo -n " dB(T2P14(Z(x))),"
+ @echo -n " dB(T2P10(Z(x))),"
+ @echo -n " dB(T2S10(Z(x))),"
+ @echo " -3"
diff --git a/flow/gsl/gslmath.c b/flow/gsl/gslmath.c
new file mode 100644
index 0000000..97ac675
--- /dev/null
+++ b/flow/gsl/gslmath.c
@@ -0,0 +1,1085 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001 Stefan Westerfeld and Tim Janik
+ *
+ * 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.
+ */
+#include "gslmath.h"
+
+#include <string.h>
+#include <stdio.h>
+
+
+#define RING_BUFFER_LENGTH (16)
+#define PRINTF_DIGITS "1270"
+#define FLOAT_STRING_SIZE (2048)
+
+
+/* factorization constants: 2^(1/12), ln(2^(1/12)) and 2^(1/(12*6))
+ * retrived with:
+ #include <stl.h>
+ #include <complex.h>
+ typedef long double ld;
+
+ int main (void)
+ {
+ ld r, l;
+
+ cout.precision(256);
+
+ r = pow ((ld) 2, (ld) 1 / (ld) 12);
+ cout << "2^(1/12) =\n";
+ cout << "2^" << (ld) 1 / (ld) 12 << " =\n";
+ cout << r << "\n";
+
+ l = log (r);
+ cout << "ln(2^(1/12)) =\n";
+ cout << "ln(" << r << ") =\n";
+ cout << l << "\n";
+
+ r = pow ((ld) 2, (ld) 1 / (ld) 72);
+ cout << "2^(1/72) =\n";
+ cout << "2^" << (ld) 1 / (ld) 72 << " =\n";
+ cout << r << "\n";
+
+ return 0;
+ }
+*/
+
+
+/* --- prototypes --- */
+static void zrhqr (double a[], int m, double rtr[], double rti[]);
+static double rf (double x, double y, double z);
+static double ellf (double phi, double ak);
+static void sncndn (double uu, double emmc, double *sn_p, double *cn_p, double *dn_p);
+static void sncndnC (GslComplex uu, GslComplex emmc, GslComplex *sn_p, GslComplex *cn_p, GslComplex *dn_p);
+static GslComplex rfC (GslComplex x, GslComplex y, GslComplex z);
+
+
+/* --- functions --- */
+static inline char*
+pretty_print_double (char *str,
+ double d)
+{
+ char *s= str;
+
+ sprintf (s, "%."PRINTF_DIGITS"f", d);
+ while (*s) s++;
+ while (s[-1] == '0' && s[-2] != '.')
+ s--;
+ *s = 0;
+ return s;
+}
+
+char*
+gsl_complex_list (unsigned int n_points,
+ GslComplex *points,
+ const char *indent)
+{
+ static unsigned int rbi = 0;
+ static char* rbuffer[RING_BUFFER_LENGTH] = { NULL, };
+ char *s, *tbuffer = g_newa (char, (FLOAT_STRING_SIZE * 2 * n_points));
+ unsigned int i;
+
+ rbi++; if (rbi >= RING_BUFFER_LENGTH) rbi -= RING_BUFFER_LENGTH;
+ if (rbuffer[rbi] != NULL)
+ g_free (rbuffer[rbi]);
+ s = tbuffer;
+ for (i = 0; i < n_points; i++)
+ {
+ *s = 0;
+ if (indent)
+ strcat (s, indent);
+ while (*s) s++;
+ s = pretty_print_double (s, points[i].re);
+ *s++ = ' ';
+ s = pretty_print_double (s, points[i].im);
+ *s++ = '\n';
+ }
+ *s++ = 0;
+ rbuffer[rbi] = g_strdup (tbuffer);
+ return rbuffer[rbi];
+}
+
+char*
+gsl_complex_str (GslComplex c)
+{
+ static unsigned int rbi = 0;
+ static char* rbuffer[RING_BUFFER_LENGTH] = { NULL, };
+ char *s, tbuffer[FLOAT_STRING_SIZE * 2];
+
+ rbi++; if (rbi >= RING_BUFFER_LENGTH) rbi -= RING_BUFFER_LENGTH;
+ if (rbuffer[rbi] != NULL)
+ g_free (rbuffer[rbi]);
+ s = tbuffer;
+ *s++ = '{';
+ s = pretty_print_double (s, c.re);
+ *s++ = ',';
+ *s++ = ' ';
+ s = pretty_print_double (s, c.im);
+ *s++ = '}';
+ *s++ = 0;
+ rbuffer[rbi] = g_strdup (tbuffer);
+ return rbuffer[rbi];
+}
+
+char*
+gsl_poly_str (unsigned int degree,
+ double *a,
+ const char *var)
+{
+ static unsigned int rbi = 0;
+ static char* rbuffer[RING_BUFFER_LENGTH] = { NULL, };
+ char *s, *tbuffer = g_newa (char, degree * FLOAT_STRING_SIZE);
+ unsigned int i;
+
+ if (!var)
+ var = "x";
+ rbi++; if (rbi >= RING_BUFFER_LENGTH) rbi -= RING_BUFFER_LENGTH;
+ if (rbuffer[rbi] != NULL)
+ g_free (rbuffer[rbi]);
+ s = tbuffer;
+ *s++ = '(';
+ s = pretty_print_double (s, a[0]);
+ for (i = 1; i <= degree; i++)
+ {
+ *s++ = '+';
+ *s = 0; strcat (s, var); while (*s) s++;
+ *s++ = '*';
+ *s++ = '(';
+ s = pretty_print_double (s, a[i]);
+ }
+ while (i--)
+ *s++ = ')';
+ *s++ = 0;
+ rbuffer[rbi] = g_strdup (tbuffer);
+ return rbuffer[rbi];
+}
+
+char*
+gsl_poly_str1 (unsigned int degree,
+ double *a,
+ const char *var)
+{
+ static unsigned int rbi = 0;
+ static char* rbuffer[RING_BUFFER_LENGTH] = { NULL, };
+ char *s, *tbuffer = g_newa (char, degree * FLOAT_STRING_SIZE);
+ unsigned int i, need_plus = 0;
+
+ if (!var)
+ var = "x";
+ rbi++; if (rbi >= RING_BUFFER_LENGTH) rbi -= RING_BUFFER_LENGTH;
+ if (rbuffer[rbi] != NULL)
+ g_free (rbuffer[rbi]);
+ s = tbuffer;
+ *s++ = '(';
+ if (a[0] != 0.0)
+ {
+ s = pretty_print_double (s, a[0]);
+ need_plus = 1;
+ }
+ for (i = 1; i <= degree; i++)
+ {
+ if (a[i] == 0.0)
+ continue;
+ if (need_plus)
+ {
+ *s++ = ' ';
+ *s++ = '+';
+ *s++ = ' ';
+ }
+ if (a[i] != 1.0)
+ {
+ s = pretty_print_double (s, a[i]);
+ *s++ = '*';
+ }
+ *s = 0;
+ strcat (s, var);
+ while (*s) s++;
+ if (i > 1)
+ {
+ *s++ = '*';
+ *s++ = '*';
+ sprintf (s, "%u", i);
+ while (*s) s++;
+ }
+ need_plus = 1;
+ }
+ *s++ = ')';
+ *s++ = 0;
+ rbuffer[rbi] = g_strdup (tbuffer);
+ return rbuffer[rbi];
+}
+
+void
+gsl_complex_gnuplot (const char *file_name,
+ unsigned int n_points,
+ GslComplex *points)
+{
+ FILE *fout = fopen (file_name, "w");
+
+ fputs (gsl_complex_list (n_points, points, ""), fout);
+ fclose (fout);
+}
+
+double
+gsl_temp_freq (double kammer_freq,
+ int halftone_delta)
+{
+ double factor;
+
+ factor = pow (GSL_2_POW_1_DIV_12, halftone_delta);
+
+ return kammer_freq * factor;
+}
+
+void
+gsl_poly_from_re_roots (unsigned int degree,
+ double *a,
+ GslComplex *roots)
+{
+ unsigned int i;
+
+ /* initialize polynomial */
+ a[1] = 1;
+ a[0] = -roots[0].re;
+ /* monomial factor multiplication */
+ for (i = 1; i < degree; i++)
+ {
+ unsigned int j;
+
+ a[i + 1] = a[i];
+ for (j = i; j >= 1; j--)
+ a[j] = a[j - 1] - a[j] * roots[i].re;
+ a[0] *= -roots[i].re;
+ }
+}
+
+void
+gsl_cpoly_from_roots (unsigned int degree,
+ GslComplex *c,
+ GslComplex *roots)
+{
+ unsigned int i;
+
+ /* initialize polynomial */
+ c[1].re = 1;
+ c[1].im = 0;
+ c[0].re = -roots[0].re;
+ c[0].im = -roots[0].im;
+ /* monomial factor multiplication */
+ for (i = 1; i < degree; i++)
+ {
+ GslComplex r = gsl_complex (-roots[i].re, -roots[i].im);
+ unsigned int j;
+
+ c[i + 1] = c[i];
+ for (j = i; j >= 1; j--)
+ c[j] = gsl_complex_add (c[j - 1], gsl_complex_mul (c[j], r));
+ c[0] = gsl_complex_mul (c[0], r);
+ }
+}
+
+void
+gsl_poly_complex_roots (unsigned int degree,
+ double *a, /* [0..degree] (degree+1 elements) */
+ GslComplex *roots) /* [degree] */
+{
+ double *roots_re = g_newa (double, 1 + degree);
+ double *roots_im = g_newa (double, 1 + degree);
+ unsigned int i;
+
+ zrhqr (a, degree, roots_re, roots_im);
+ for (i = 0; i < degree; i++)
+ {
+ roots[i].re = roots_re[1 + i];
+ roots[i].im = roots_im[1 + i];
+ }
+}
+
+double
+gsl_ellip_rf (double x,
+ double y,
+ double z)
+{
+ return rf (x, y, z);
+}
+
+double
+gsl_ellip_F (double phi,
+ double ak)
+{
+ return ellf (phi, ak);
+}
+
+double
+gsl_ellip_sn (double u,
+ double emmc)
+{
+ double sn;
+
+ sncndn (u, emmc, &sn, NULL, NULL);
+ return sn;
+}
+
+double
+gsl_ellip_asn (double y,
+ double emmc)
+{
+ return y * rf (1.0 - y * y, 1.0 - y * y * (1.0 - emmc), 1.0);
+}
+
+GslComplex
+gsl_complex_ellip_asn (GslComplex y,
+ GslComplex emmc)
+{
+ return gsl_complex_mul (y,
+ rfC (gsl_complex_sub (gsl_complex (1.0, 0),
+ gsl_complex_mul (y, y)),
+ gsl_complex_sub (gsl_complex (1.0, 0),
+ gsl_complex_mul3 (y, y, gsl_complex_sub (gsl_complex (1.0, 0),
+ emmc))),
+ gsl_complex (1.0, 0)));
+}
+
+GslComplex
+gsl_complex_ellip_sn (GslComplex u,
+ GslComplex emmc)
+{
+ GslComplex sn;
+
+ sncndnC (u, emmc, &sn, NULL, NULL);
+ return sn;
+}
+
+double
+gsl_bit_depth_epsilon (guint n_bits)
+{
+ /* epsilon for various bit depths, based on significance of one bit,
+ * minus fudge. created with:
+ * { echo "scale=40"; for i in `seq 1 32` ; do echo "1/2^$i - 10^-($i+1)" ; done } | bc | sed 's/$/,/'
+ */
+ static const double bit_epsilons[] = {
+ .4900000000000000000000000000000000000000,
+ .2490000000000000000000000000000000000000,
+ .1249000000000000000000000000000000000000,
+ .0624900000000000000000000000000000000000,
+ .0312490000000000000000000000000000000000,
+ .0156249000000000000000000000000000000000,
+ .0078124900000000000000000000000000000000,
+ .0039062490000000000000000000000000000000,
+ .0019531249000000000000000000000000000000,
+ .0009765624900000000000000000000000000000,
+ .0004882812490000000000000000000000000000,
+ .0002441406249000000000000000000000000000,
+ .0001220703124900000000000000000000000000,
+ .0000610351562490000000000000000000000000,
+ .0000305175781249000000000000000000000000,
+ .0000152587890624900000000000000000000000,
+ .0000076293945312490000000000000000000000,
+ .0000038146972656249000000000000000000000,
+ .0000019073486328124900000000000000000000,
+ .0000009536743164062490000000000000000000,
+ .0000004768371582031249000000000000000000,
+ .0000002384185791015624900000000000000000,
+ .0000001192092895507812490000000000000000,
+ .0000000596046447753906249000000000000000,
+ .0000000298023223876953124900000000000000,
+ .0000000149011611938476562490000000000000,
+ .0000000074505805969238281249000000000000,
+ .0000000037252902984619140624900000000000,
+ .0000000018626451492309570312490000000000,
+ .0000000009313225746154785156249000000000,
+ .0000000004656612873077392578124900000000,
+ .0000000002328306436538696289062490000000,
+ };
+
+ return bit_epsilons[CLAMP (n_bits, 1, 32) - 1];
+}
+
+
+/* --- Numerical Receipes --- */
+#define gsl_complex_rmul(scale, c) gsl_complex_scale (c, scale)
+#define ONE gsl_complex (1.0, 0)
+#define SIGN(a,b) ((b) >= 0.0 ? fabs (a) : -fabs(a))
+static inline int IMAX (int i1, int i2) { return i1 > i2 ? i1 : i2; }
+static inline double DMIN (double d1, double d2) { return d1 < d2 ? d1 : d2; }
+static inline double DMAX (double d1, double d2) { return d1 > d2 ? d1 : d2; }
+static inline double DSQR (double d) { return d == 0.0 ? 0.0 : d * d; }
+#define nrerror(error) g_error ("NR-ERROR: %s", (error))
+static inline double* vector (long nl, long nh)
+ /* allocate a vector with subscript range v[nl..nh] */
+{
+ double *v = g_new (double, nh - nl + 1 + 1);
+ return v - nl + 1;
+}
+static inline void free_vector (double *v, long nl, long nh)
+{
+ g_free (v + nl - 1);
+}
+static inline double** matrix (long nrl, long nrh, long ncl, long nch)
+ /* allocate a matrix with subscript range m[nrl..nrh][ncl..nch] */
+{
+ long i, nrow = nrh - nrl + 1, ncol = nch - ncl + 1;
+ double **m = g_new (double*, nrow + 1);
+ m += 1;
+ m -= nrl;
+ m[nrl] = g_new (double, nrow * ncol + 1);
+ m[nrl] += 1;
+ m[nrl] -= ncl;
+ for (i = nrl + 1; i <= nrh; i++)
+ m[i] = m[i - 1] + ncol;
+ return m;
+}
+static inline void free_matrix (double **m, long nrl, long nrh, long ncl, long nch)
+{
+ g_free (m[nrl] + ncl - 1);
+ g_free (m + nrl - 1);
+}
+
+static void
+poldiv (double u[], int n, double v[], int nv, double q[], double r[])
+ /* Given the n+1 coefficients of a polynomial of degree n in u[0..n], and the nv+1 coefficients
+ of another polynomial of degree nv in v[0..nv], divide the polynomial u by the polynomial
+ v ("u"/"v") giving a quotient polynomial whose coefficients are returned in q[0..n], and a
+ remainder polynomial whose coefficients are returned in r[0..n]. The elements r[nv..n]
+ and q[n-nv+1..n] are returned as zero. */
+{
+ int k,j;
+
+ for (j=0;j<=n;j++) {
+ r[j]=u[j];
+ q[j]=0.0;
+ }for (k=n-nv;k>=0;k--) {
+ q[k]=r[nv+k]/v[nv];
+ for (j=nv+k-1;j>=k;j--) r[j] -= q[k]*v[j-k];
+ }for (j=nv;j<=n;j++) r[j]=0.0;
+}
+
+#define MAX_ITER_BASE 9 /* TIMJ: was 3 */
+#define MAX_ITER_FAC 20 /* TIMJ: was 10 */
+static void
+hqr (double **a, int n, double wr[], double wi[])
+ /* Finds all eigenvalues of an upper Hessenberg matrix a[1..n][1..n]. On input a can be
+ exactly as output from elmhes §11.5; on output it is destroyed. The real and imaginary parts
+ of the eigenvalues are returned in wr[1..n] and wi[1..n], respectively. */
+{
+ int nn,m,l,k,j,its,i,mmin;
+ double z,y,x,w,v,u,t,s,r,q,p,anorm;
+ r=q=p=0; /* TIMJ: silence compiler */
+
+ anorm=0.0; /* Compute matrix norm for possible use in lo- */
+ for (i=1;i<=n;i++) /* cating single small subdiagonal element. */
+ for (j=IMAX (i-1,1);j<=n;j++)
+ anorm += fabs (a[i][j]);
+ nn=n;
+ t=0.0; /* Gets changed only by an exceptional shift. */
+ while (nn >= 1) { /* Begin search for next eigenvalue. */
+ its=0;
+ do {for (l=nn;l>=2;l--) { /* Begin iteration: look for single small subdi- */
+ s=fabs (a[l-1][l-1])+fabs (a[l][l]); /* agonal element. */
+ if (s == 0.0) s=anorm;
+ if ((double)(fabs (a[l][l-1]) + s) == s) break;
+ }
+ x=a[nn][nn];
+ if (l == nn) { /* One root found. */
+ wr[nn]=x+t;
+ wi[nn--]=0.0;
+ } else {
+ y=a[nn-1][nn-1];
+ w=a[nn][nn-1]*a[nn-1][nn];
+ if (l == (nn-1)) { /* Two roots found... */
+ p=0.5*(y-x);
+ q=p*p+w;
+ z=sqrt (fabs (q));
+ x += t;
+ if (q >= 0.0) { /* ...a real pair. */
+ z=p+SIGN (z,p);
+ wr[nn-1]=wr[nn]=x+z;
+ if (z) wr[nn]=x-w/z;
+ wi[nn-1]=wi[nn]=0.0;
+ } else { /* ...a complex pair. */
+ wr[nn-1]=wr[nn]=x+p;
+ wi[nn-1]= -(wi[nn]=z);
+ }
+ nn -= 2;
+ } else { /* No roots found. Continue iteration. */
+ if (its == MAX_ITER_BASE * MAX_ITER_FAC)
+ nrerror ("Too many iterations in hqr");
+ if (its && !(its%MAX_ITER_FAC)) { /* Form exceptional shift. */
+ t += x;
+ for (i=1;i<=nn;i++) a[i][i] -= x;
+ s=fabs (a[nn][nn-1])+fabs (a[nn-1][nn-2]);
+ y=x=0.75*s;
+ w = -0.4375*s*s;
+ }
+ ++its;
+ for (m=(nn-2);m>=l;m--) { /* Form shift and then look for */
+ z=a[m][m]; /* 2 consecutive small sub- */
+ r=x-z; /* diagonal elements. */
+ s=y-z;
+ p=(r*s-w)/a[m+1][m]+a[m][m+1]; /* Equation (11.6.23). */
+ q=a[m+1][m+1]-z-r-s;
+ r=a[m+2][m+1];
+ s=fabs (p)+fabs (q)+fabs (r); /* Scale to prevent overflow or */
+ p /= s; /* underflow. */
+ q /= s;
+ r /= s;
+ if (m == l) break;
+ u=fabs (a[m][m-1])*(fabs (q)+fabs (r));
+ v=fabs (p)*(fabs (a[m-1][m-1])+fabs (z)+fabs (a[m+1][m+1]));
+ if ((double)(u+v) == v)
+ break; /* Equation (11.6.26). */
+ }
+ for (i=m+2;i<=nn;i++) {
+ a[i][i-2]=0.0;
+ if (i != (m+2))
+ a[i][i-3]=0.0;
+ }
+ for (k=m;k<=nn-1;k++) {
+ /* Double QR step on rows l to nn and columns m to nn. */
+ if (k != m) {
+ p=a[k][k-1]; /* Begin setup of Householder */
+ q=a[k+1][k-1]; /* vector. */
+ r=0.0;
+ if (k != (nn-1)) r=a[k+2][k-1];
+ if ((x=fabs (p)+fabs (q)+fabs (r)) != 0.0) {
+ p /= x; /* Scale to prevent overflow or */
+ q /= x; /* underflow. */
+ r /= x;
+ }
+ }
+ if ((s=SIGN (sqrt (p*p+q*q+r*r),p)) != 0.0) {
+ if (k == m) {
+ if (l != m)
+ a[k][k-1] = -a[k][k-1];
+ } else
+ a[k][k-1] = -s*x;
+ p += s; /* Equations (11.6.24). */
+ x=p/s;
+ y=q/s;
+ z=r/s;
+ q /= p;
+ r /= p;
+ for (j=k;j<=nn;j++) { /* Row modification. */
+ p=a[k][j]+q*a[k+1][j];
+ if (k != (nn-1)) {
+ p += r*a[k+2][j];
+ a[k+2][j] -= p*z;
+ }
+ a[k+1][j] -= p*y;
+ a[k][j] -= p*x;
+ }
+ mmin = nn<k+3 ? nn : k+3;
+ for (i=l;i<=mmin;i++) { /* Column modification. */
+ p=x*a[i][k]+y*a[i][k+1];
+ if (k != (nn-1)) {
+ p += z*a[i][k+2];
+ a[i][k+2] -= p*r;
+ }a[i][k+1] -= p*q;
+ a[i][k] -= p;
+ }
+ }
+ }
+ }
+ }
+ } while (l < nn-1);
+ }
+}
+
+#define RADIX 2.0
+static void
+balanc (double **a, int n)
+ /* Given a matrix a[1..n][1..n], this routine replaces it by a balanced matrix with identical
+ eigenvalues. A symmetric matrix is already balanced and is unaffected by this procedure. The
+ parameter RADIX should be the machine's floating-point radix. */
+{
+ int last,j,i;
+ double s,r,g,f,c,sqrdx;
+
+ sqrdx=RADIX*RADIX;
+ last=0;
+ while (last == 0) {
+ last=1;
+ for (i=1;i<=n;i++) { /* Calculate row and column norms. */
+ r=c=0.0;
+ for (j=1;j<=n;j++)
+ if (j != i) {
+ c += fabs (a[j][i]);
+ r += fabs (a[i][j]);
+ }
+ if (c && r) { /* If both are nonzero, */
+ g=r/RADIX;
+ f=1.0;
+ s=c+r;
+ while (c<g) { /* find the integer power of the machine radix that */
+ f *= RADIX; /* comes closest to balancing the matrix. */
+ c *= sqrdx;
+ }
+ g=r*RADIX;
+ while (c>g) {
+ f /= RADIX;
+ c /= sqrdx;
+ }
+ if ((c+r)/f < 0.95*s) {
+ last=0;
+ g=1.0/f;
+ for (j=1;j<=n;j++)
+ a[i][j] *= g; /* Apply similarity transformation */
+ for (j=1;j<=n;j++) a[j][i] *= f;
+ }
+ }
+ }
+ }
+}
+
+#define MAX_DEGREE 50
+
+static void
+zrhqr (double a[], int m, double rtr[], double rti[])
+ /* Find all the roots of a polynomial with real coefficients, E(i=0..m) a(i)x^i, given the degree m
+ and the coefficients a[0..m]. The method is to construct an upper Hessenberg matrix whose
+ eigenvalues are the desired roots, and then use the routines balanc and hqr. The real and
+ imaginary parts of the roots are returned in rtr[1..m] and rti[1..m], respectively. */
+{
+ int j,k;
+ double **hess,xr,xi;
+
+ hess=matrix (1,MAX_DEGREE,1,MAX_DEGREE);
+ if (m > MAX_DEGREE || a[m] == 0.0 || /* TIMJ: */ fabs (a[m]) < 1e-15 )
+ nrerror ("bad args in zrhqr");
+ for (k=1;k<=m;k++) /* Construct the matrix. */
+ {
+ hess[1][k] = -a[m-k]/a[m];
+ for (j=2;j<=m;j++)
+ hess[j][k]=0.0;
+ if (k != m)
+ hess[k+1][k]=1.0;
+ }
+ balanc (hess,m); /* Find its eigenvalues. */
+ hqr (hess,m,rtr,rti);
+ if (0) /* TIMJ: don't need sorting */
+ for (j=2;j<=m;j++)
+ { /* Sort roots by their real parts by straight insertion. */
+ xr=rtr[j];
+ xi=rti[j];
+ for (k=j-1;k>=1;k--)
+ {
+ if (rtr[k] <= xr)
+ break;
+ rtr[k+1]=rtr[k];
+ rti[k+1]=rti[k];
+ }
+ rtr[k+1]=xr;
+ rti[k+1]=xi;
+ }
+ free_matrix (hess,1,MAX_DEGREE,1,MAX_DEGREE);
+}
+
+
+#define EPSS 2.0e-16 /* TIMJ, was(float): 1.0e-7 */
+#define MR 8
+#define MT 100 /* TIMJ: was: 10 */
+#define MAXIT (MT*MR)
+/* Here EPSS is the estimated fractional roundoff error. We try to break (rare) limit cycles with
+ MR different fractional values, once every MT steps, for MAXIT total allowed iterations. */
+
+static void
+laguer (GslComplex a[], int m, GslComplex *x, int *its)
+ /* Given the degree m and the m+1 complex coefficients a[0..m] of the polynomial mi=0 a[i]xi,
+ and given a complex value x, this routine improves x by Laguerre's method until it converges,
+ within the achievable roundoff limit, to a root of the given polynomial. The number of iterations
+ taken is returned as its. */
+{
+ int iter,j;
+ double abx,abp,abm,err;
+ GslComplex dx,x1,b,d,f,g,h,sq,gp,gm,g2;
+ static double frac[MR+1] = {0.0,0.5,0.25,0.75,0.13,0.38,0.62,0.88,1.0};
+ /* Fractions used to break a limit cycle. */
+
+ for (iter=1;iter<=MAXIT;iter++)
+ { /* Loop over iterations up to allowed maximum. */
+ *its=iter;
+ b=a[m];
+ err=gsl_complex_abs (b);
+ d=f=gsl_complex (0.0,0.0);
+ abx=gsl_complex_abs (*x);
+ for (j=m-1;j>=0;j--)
+ { /* Efficient computation of the polynomial and */
+ f=gsl_complex_add (gsl_complex_mul (*x,f),d); /* its first two derivatives. */
+ d=gsl_complex_add (gsl_complex_mul (*x,d),b);
+ b=gsl_complex_add (gsl_complex_mul (*x,b),a[j]);
+ err=gsl_complex_abs (b)+abx*err;
+ }
+ err *= EPSS;
+ /* Estimate of roundoff error in evaluating polynomial. */
+ if (gsl_complex_abs (b) <= err)
+ return; /* We are on the root. */
+ g=gsl_complex_div (d,b); /* The generic case: use Laguerre's formula. */
+ g2=gsl_complex_mul (g,g);
+ h=gsl_complex_sub (g2,gsl_complex_rmul (2.0,gsl_complex_div (f,b)));
+ sq=gsl_complex_sqrt (gsl_complex_rmul ((double) (m-1),gsl_complex_sub (gsl_complex_rmul ((double) m,h),g2)));
+ gp=gsl_complex_add (g,sq);
+ gm=gsl_complex_sub (g,sq);
+ abp=gsl_complex_abs (gp);
+ abm=gsl_complex_abs (gm);
+ if (abp < abm)
+ gp=gm;
+ dx=((DMAX (abp,abm) > 0.0 ? gsl_complex_div (gsl_complex ((double) m,0.0),gp)
+ : gsl_complex_rmul (1+abx,gsl_complex (cos ((double)iter),sin ((double)iter)))));
+ x1=gsl_complex_sub (*x,dx);
+ if (x->re == x1.re && x->im == x1.im)
+ return; /* Converged. */
+ if (iter % MT) *x=x1;
+ else *x=gsl_complex_sub (*x,gsl_complex_rmul (frac[iter/MT],dx));
+ /* Every so often we take a fractional step, to break any limit cycle (itself a rare occurrence). */
+ }
+ nrerror ("too many iterations in laguer");
+ /* Very unusual - can occur only for complex roots. Try a different starting guess for the root. */
+}
+
+/* Here is a driver routine that calls laguer in succession for each root, performs
+ the deflation, optionally polishes the roots by the same Laguerre method - if you
+ are not going to polish in some other way - and finally sorts the roots by their real
+ parts. (We will use this routine in Chapter 13.) */
+
+#define EPS 4.0e-15 /* TIMJ, was(float): 2.0e-6 */
+#define MAXM 100
+/* A small number, and maximum anticipated value of m. */
+
+static void
+zroots (GslComplex a[], int m, GslComplex roots[], int polish)
+ /* Given the degree m and the m+1 complex coefficients a[0..m] of the polynomial mi=0 a (i)xi,
+ this routine successively calls laguer and finds all m complex roots in roots[1..m]. The
+ boolean variable polish should be input as true (1) if polishing (also by Laguerre's method)
+ is desired, false (0) if the roots will be subsequently polished by other means. */
+{
+ int i,its,j,jj;
+ GslComplex x,b,c,ad[MAXM];
+
+ for (j=0;j<=m;j++) ad[j]=a[j]; /* Copy of coefficients for successive deflation. */
+ for (j=m;j>=1;j--) /* Loop over each root to be found. */
+ {
+ x=gsl_complex (0.0,0.0); /* Start at zero to favor convergence to small- */
+ laguer (ad,j,&x,&its); /* est remaining root, and find the root. */
+ if (fabs (x.im) <= 2.0*EPS*fabs (x.re))
+ x.im=0.0;
+ roots[j]=x;
+ b=ad[j]; /* Forward deflation. */
+ for (jj=j-1;jj>=0;jj--)
+ {
+ c=ad[jj];
+ ad[jj]=b;
+ b=gsl_complex_add (gsl_complex_mul (x,b),c);
+ }
+ }
+ if (polish)
+ for (j=1;j<=m;j++) /* Polish the roots using the undeflated coeffi- */
+ laguer (a,m,&roots[j],&its); /* cients. */
+ for (j=2;j<=m;j++) /* Sort roots by their real parts by straight insertion */
+ {
+ x=roots[j];
+ for (i=j-1;i>=1;i--) {
+ if (roots[i].re <= x.re)
+ break;
+ roots[i+1]=roots[i];
+ }
+ roots[i+1]=x;
+ }
+}
+
+#define ITMAX 20 /* At most ITMAX iterations. */
+#define TINY 2.0-15 /* TIMJ, was (float): 1.0e-6 */
+
+static void
+qroot (double p[], int n, double *b, double *c, double eps)
+ /* Given n+1 coefficients p[0..n] of a polynomial of degree n, and trial values for the coefficients
+ of a quadratic factor x*x+b*x+c, improve the solution until the coefficients b,c change by less
+ than eps. The routine poldiv §5.3 is used. */
+{
+ int iter;
+ double sc,sb,s,rc,rb,r,dv,delc,delb;
+ double *q,*qq,*rem;
+ double d[3];
+
+ q=vector (0,n);
+ qq=vector (0,n);
+ rem=vector (0,n);
+ d[2]=1.0;
+ for (iter=1;iter<=ITMAX;iter++)
+ {
+ d[1]=(*b);
+ d[0]=(*c);
+ poldiv (p,n,d,2,q,rem);
+ s=rem[0]; /* First division r,s. */
+ r=rem[1];
+ poldiv (q,(n-1),d,2,qq,rem);
+ sb = -(*c)*(rc = -rem[1]); /* Second division partial r,s with respect to */
+ rb = -(*b)*rc+(sc = -rem[0]); /* c. */
+ dv=1.0/(sb*rc-sc*rb); /* Solve 2x2 equation. */
+ delb=(r*sc-s*rc)*dv;
+ delc=(-r*sb+s*rb)*dv;
+ *b += (delb=(r*sc-s*rc)*dv);
+ *c += (delc=(-r*sb+s*rb)*dv);
+ if ((fabs (delb) <= eps*fabs (*b) || fabs (*b) < TINY)
+ && (fabs (delc) <= eps*fabs (*c) || fabs (*c) < TINY))
+ {
+ free_vector (rem,0,n); /* Coefficients converged. */
+ free_vector (qq,0,n);
+ free_vector (q,0,n);
+ return;
+ }
+ }
+ nrerror ("Too many iterations in routine qroot");
+}
+
+#define SNCNDN_CA 0.0003 /* The accuracy is the square of SNCNDN_CA. */
+static void
+sncndn (double uu, double emmc, double *sn_p, double *cn_p, double *dn_p)
+ /* Returns the Jacobian elliptic functions sn(u, kc), cn(u, kc), and dn(u, kc). Here uu = u, while
+ emmc = k2c. */
+{
+ double a,b,c,d,emc,u,sn,cn,dn;
+ double em[14],en[14];
+ int i,ii,l,bo;
+ d=0; /* TIMJ: shutup compiler */
+
+ emc=emmc;
+ u=uu;
+ if (emc) {
+ bo=(emc < 0.0);
+ if (bo) {
+ d=1.0-emc;
+ emc /= -1.0/d;
+ u *= (d=sqrt(d));
+ }a=1.0;
+ dn=1.0;
+ for (i=1;i<=13;i++) {
+ l=i;
+ em[i]=a;
+ en[i]=(emc=sqrt(emc));
+ c=0.5*(a+emc);
+ if (fabs(a-emc) <= SNCNDN_CA*a) break;
+ emc *= a;
+ a=c;
+ }u *= c;
+ sn=sin(u);
+ cn=cos(u);
+ if (sn) {
+ a=cn/sn;
+ c *= a;
+ for (ii=l;ii>=1;ii--) {
+ b=em[ii];
+ a *= c;
+ c *= dn;
+ dn=(en[ii]+a)/(b+a);
+ a=c/b;
+ }a=1.0/sqrt(c*c+1.0);
+ sn=(sn >= 0.0 ? a : -a);
+ cn=c*sn;
+ }if (bo) {
+ a=dn;
+ dn=cn;
+ cn=a;
+ sn /= d;
+ }
+ } else {
+ cn=1.0/cosh(u);
+ dn=cn;
+ sn=tanh(u);
+ }
+ if (sn_p)
+ *sn_p = sn;
+ if (cn_p)
+ *cn_p = cn;
+ if (dn_p)
+ *dn_p = dn;
+}
+
+static void
+sncndnC (GslComplex uu, GslComplex emmc, GslComplex *sn_p, GslComplex *cn_p, GslComplex *dn_p)
+{
+ GslComplex a,b,c,d,emc,u,sn,cn,dn;
+ GslComplex em[14],en[14];
+ int i,ii,l,bo;
+
+ emc=emmc;
+ u=uu;
+ if (emc.re || emc.im) /* gsl_complex_abs (emc)) */
+ {
+ /* bo=gsl_complex_abs (emc) < 0.0; */
+ bo=emc.re < 0.0;
+ if (bo) {
+ d=gsl_complex_sub (ONE, emc);
+ emc = gsl_complex_div (emc, gsl_complex_div (gsl_complex (-1.0, 0), d));
+ d = gsl_complex_sqrt (d);
+ u = gsl_complex_mul (u, d);
+ }
+ a=ONE; dn=ONE;
+ for (i=1;i<=13;i++) {
+ l=i;
+ em[i]=a;
+ emc = gsl_complex_sqrt (emc);
+ en[i]=emc;
+ c = gsl_complex_mul (gsl_complex (0.5, 0), gsl_complex_add (a, emc));
+ if (gsl_complex_abs (gsl_complex_sub (a, emc)) <=
+ gsl_complex_abs (gsl_complex_mul (gsl_complex (SNCNDN_CA, 0), a)))
+ break;
+ emc = gsl_complex_mul (emc, a);
+ a=c;
+ }
+ u = gsl_complex_mul (u, c);
+ sn = gsl_complex_sin (u);
+ cn = gsl_complex_cos (u);
+ if (sn.re) /* gsl_complex_abs (sn)) */
+ {
+ a= gsl_complex_div (cn, sn);
+ c = gsl_complex_mul (c, a);
+ for (ii=l;ii>=1;ii--) {
+ b = em[ii];
+ a = gsl_complex_mul (a, c);
+ c = gsl_complex_mul (c, dn);
+ dn = gsl_complex_div (gsl_complex_add (en[ii], a), gsl_complex_add (b, a));
+ a = gsl_complex_div (c, b);
+ }
+ a = gsl_complex_div (ONE, gsl_complex_sqrt (gsl_complex_add (ONE, gsl_complex_mul (c, c))));
+ if (sn.re >= 0.0) /* gsl_complex_arg (sn) >= 0.0) */
+ sn = a;
+ else
+ {
+ sn.re = -a.re;
+ sn.im = a.im;
+ }
+ cn = gsl_complex_mul (c, sn);
+ }
+ if (bo) {
+ a=dn;
+ dn=cn;
+ cn=a;
+ sn = gsl_complex_div (sn, d);
+ }
+ } else {
+ cn=gsl_complex_div (ONE, gsl_complex_cosh (u));
+ dn=cn;
+ sn=gsl_complex_tanh (u);
+ }
+ if (sn_p)
+ *sn_p = sn;
+ if (cn_p)
+ *cn_p = cn;
+ if (dn_p)
+ *dn_p = dn;
+}
+
+#define RF_ERRTOL 0.0025 /* TIMJ, was(float): 0.08 */
+#define RF_TINY 2.2e-307 /* TIMJ, was(float): 1.5e-38 */
+#define RF_BIG 1.5e+307 /* TIMJ, was(float): 3.0e37 */
+#define RF_THIRD (1.0/3.0)
+#define RF_C1 (1.0/24.0)
+#define RF_C2 0.1
+#define RF_C3 (3.0/44.0)
+#define RF_C4 (1.0/14.0)
+
+static double
+rf (double x, double y, double z)
+ /* Computes Carlson's elliptic integral of the first kind, RF (x, y, z). x, y, and z must be nonneg-
+ ative, and at most one can be zero. RF_TINY must be at least 5 times the machine underflow limit,
+ RF_BIG at most one fifth the machine overflow limit. */
+{
+ double alamb,ave,delx,dely,delz,e2,e3,sqrtx,sqrty,sqrtz,xt,yt,zt;
+
+ if (1 /* TIMJ: add verbose checks */)
+ {
+ if (DMIN (DMIN (x, y), z) < 0.0)
+ nrerror ("rf: x,y,z have to be positive");
+ if (DMIN (DMIN (x + y, x + z), y + z) < RF_TINY)
+ nrerror ("rf: only one of x,y,z may be 0");
+ if (DMAX (DMAX (x, y), z) > RF_BIG)
+ nrerror ("rf: at least one of x,y,z is too big");
+ }
+ if (DMIN(DMIN(x,y),z) < 0.0 || DMIN(DMIN(x+y,x+z),y+z) < RF_TINY ||
+ DMAX(DMAX(x,y),z) > RF_BIG)
+ nrerror("invalid arguments in rf");
+ xt=x;
+ yt=y;
+ zt=z;
+ do {
+ sqrtx=sqrt(xt);
+ sqrty=sqrt(yt);
+ sqrtz=sqrt(zt);
+ alamb=sqrtx*(sqrty+sqrtz)+sqrty*sqrtz;
+ xt=0.25*(xt+alamb);
+ yt=0.25*(yt+alamb);
+ zt=0.25*(zt+alamb);
+ ave=RF_THIRD*(xt+yt+zt);
+ delx=(ave-xt)/ave;
+ dely=(ave-yt)/ave;
+ delz=(ave-zt)/ave;
+ } while (DMAX(DMAX(fabs(delx),fabs(dely)),fabs(delz)) > RF_ERRTOL);
+ e2=delx*dely-delz*delz;
+ e3=delx*dely*delz;
+ return (1.0+(RF_C1*e2-RF_C2-RF_C3*e3)*e2+RF_C4*e3)/sqrt(ave);
+}
+
+static GslComplex
+rfC (GslComplex x, GslComplex y, GslComplex z)
+{
+ GslComplex alamb,ave,delx,dely,delz,e2,e3,sqrtx,sqrty,sqrtz,xt,yt,zt;
+ GslComplex RFC_C1 = {1.0/24.0, 0}, RFC_C2 = {0.1, 0}, RFC_C3 = {3.0/44.0, 0}, RFC_C4 = {1.0/14.0, 0};
+
+ if (DMIN (DMIN (gsl_complex_abs (x), gsl_complex_abs (y)), gsl_complex_abs (z)) < 0.0)
+ nrerror ("rf: x,y,z have to be positive");
+ if (DMIN (DMIN (gsl_complex_abs (x) + gsl_complex_abs (y), gsl_complex_abs (x) + gsl_complex_abs (z)),
+ gsl_complex_abs (y) + gsl_complex_abs (z)) < RF_TINY)
+ nrerror ("rf: only one of x,y,z may be 0");
+ if (DMAX (DMAX (gsl_complex_abs (x), gsl_complex_abs (y)), gsl_complex_abs (z)) > RF_BIG)
+ nrerror ("rf: at least one of x,y,z is too big");
+ xt=x;
+ yt=y;
+ zt=z;
+ do {
+ sqrtx = gsl_complex_sqrt (xt);
+ sqrty = gsl_complex_sqrt (yt);
+ sqrtz = gsl_complex_sqrt (zt);
+ alamb = gsl_complex_add (gsl_complex_mul (sqrtx, gsl_complex_add (sqrty, sqrtz)), gsl_complex_mul (sqrty, sqrtz));
+ xt = gsl_complex_mul (gsl_complex (0.25, 0), gsl_complex_add (xt, alamb));
+ yt = gsl_complex_mul (gsl_complex (0.25, 0), gsl_complex_add (yt, alamb));
+ zt = gsl_complex_mul (gsl_complex (0.25, 0), gsl_complex_add (zt, alamb));
+ ave = gsl_complex_mul (gsl_complex (RF_THIRD, 0), gsl_complex_add3 (xt, yt, zt));
+ delx = gsl_complex_div (gsl_complex_sub (ave, xt), ave);
+ dely = gsl_complex_div (gsl_complex_sub (ave, yt), ave);
+ delz = gsl_complex_div (gsl_complex_sub (ave, zt), ave);
+ /* } while (DMAX (DMAX (fabs (delx.re), fabs (dely.re)), fabs (delz.re)) > RF_ERRTOL); */
+ } while (DMAX (DMAX (gsl_complex_abs (delx), gsl_complex_abs (dely)), gsl_complex_abs (delz)) > RF_ERRTOL);
+ e2 = gsl_complex_sub (gsl_complex_mul (delx, dely), gsl_complex_mul (delz, delz));
+ e3 = gsl_complex_mul3 (delx, dely, delz);
+ return gsl_complex_div (gsl_complex_add3 (gsl_complex (1.0, 0),
+ gsl_complex_mul (e2,
+ gsl_complex_sub3 (gsl_complex_mul (RFC_C1, e2),
+ RFC_C2,
+ gsl_complex_mul (RFC_C3, e3))),
+ gsl_complex_mul (RFC_C4, e3)),
+ gsl_complex_sqrt (ave));
+}
+
+
+static double
+ellf (double phi, double ak)
+ /* Legendre elliptic integral of the 1st kind F(phi, k), evaluated using Carlson's function RF.
+ The argument ranges are 0 <= phi <= pi/2, 0 <= k*sin(phi) <= 1. */
+{
+ double s=sin(phi);
+ return s*rf(DSQR(cos(phi)),(1.0-s*ak)*(1.0+s*ak),1.0);
+}
diff --git a/flow/gsl/gslmath.h b/flow/gsl/gslmath.h
new file mode 100644
index 0000000..b690a54
--- /dev/null
+++ b/flow/gsl/gslmath.h
@@ -0,0 +1,518 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001 Stefan Westerfeld and Tim Janik
+ *
+ * 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.
+ */
+#ifndef __GSL_MATH_H__
+#define __GSL_MATH_H__
+
+#include <gsl/gslieee754.h>
+#include <gsl/gsldefs.h>
+#include <math.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* --- constants --- */
+#define GSL_PI (3.1415926535897932384626433832795029 /* pi */)
+#define GSL_PI_DIV_2 (1.5707963267948966192313216916397514 /* pi/2 */)
+#define GSL_PI_DIV_4 (0.7853981633974483096156608458198757 /* pi/4 */)
+#define GSL_1_DIV_PI (0.3183098861837906715377675267450287 /* 1/pi */)
+#define GSL_2_DIV_PI (0.6366197723675813430755350534900574 /* 2/pi */)
+#define GSL_2_DIV_SQRT_PI (1.1283791670955125738961589031215452 /* 2/sqrt(pi) */)
+#define GSL_SQRT2 (1.4142135623730950488016887242096981 /* sqrt(2) */)
+#define GSL_1_DIV_SQRT2 (0.7071067811865475244008443621048490 /* 1/sqrt(2) */)
+#define GSL_E (2.7182818284590452353602874713526625 /* e */)
+#define GSL_LOG2E (1.4426950408889634073599246810018922 /* log_2(e) */)
+#define GSL_LOG10E (0.4342944819032518276511289189166051 /* log_10(e) */)
+#define GSL_LN2 (0.6931471805599453094172321214581766 /* ln(2) */)
+#define GSL_LN10 (2.3025850929940456840179914546843642 /* ln(10) */)
+#define GSL_2_POW_1_DIV_12 (1.0594630943592952645618252949463417 /* 2^(1/12) */)
+#define GSL_2_POW_1_DIV_72 (1.0096735332285108621925214011186051 /* 2^(1/72) */)
+#define GSL_LN_2_POW_1_DIV_12 (0.0577622650466621091181026767881814 /* ln(2^(1/12)) */)
+#define GSL_LN_2_POW_1_DIV_72 (0.0096270441744436848530171127980302 /* ln(2^(1/72)) */)
+#define GSL_LOG2_10 (3.3219280948873623478703194294893902 /* log_2(10) */)
+#define GSL_LOG2POW20_10 (0.1660964047443681173935159714744695 /* log_2(10)/20 */)
+
+
+/* --- structures --- */
+struct _GslComplex
+{
+ double re;
+ double im;
+};
+
+
+/* --- float/double signbit extraction --- */
+#ifdef signbit
+# define gsl_float_sign(dblflt) (signbit (dblflt))
+#else
+# define gsl_float_sign(dblflt) ((dblflt) < -0.0) /* good enough for us */
+#endif
+
+
+/* --- complex numbers --- */
+static inline GslComplex gsl_complex (double re,
+ double im);
+static inline GslComplex gsl_complex_polar (double abs,
+ double arg);
+static inline GslComplex gsl_complex_add (GslComplex c1,
+ GslComplex c2);
+static inline GslComplex gsl_complex_add3 (GslComplex c1,
+ GslComplex c2,
+ GslComplex c3);
+static inline GslComplex gsl_complex_sub (GslComplex c1,
+ GslComplex c2);
+static inline GslComplex gsl_complex_sub3 (GslComplex c1,
+ GslComplex c2,
+ GslComplex c3);
+static inline GslComplex gsl_complex_scale (GslComplex c1,
+ double scale);
+static inline GslComplex gsl_complex_mul (GslComplex c1,
+ GslComplex c2);
+static inline GslComplex gsl_complex_mul3 (GslComplex c1,
+ GslComplex c2,
+ GslComplex c3);
+static inline GslComplex gsl_complex_div (GslComplex a,
+ GslComplex b);
+static inline GslComplex gsl_complex_reciprocal (GslComplex c);
+static inline GslComplex gsl_complex_sqrt (GslComplex z);
+static inline GslComplex gsl_complex_conj (GslComplex c); /* {re, -im} */
+static inline GslComplex gsl_complex_id (GslComplex c);
+static inline GslComplex gsl_complex_inv (GslComplex c); /* {-re, -im} */
+static inline double gsl_complex_abs (GslComplex c);
+static inline double gsl_complex_arg (GslComplex c);
+static inline GslComplex gsl_complex_sin (GslComplex c);
+static inline GslComplex gsl_complex_cos (GslComplex c);
+static inline GslComplex gsl_complex_tan (GslComplex c);
+static inline GslComplex gsl_complex_sinh (GslComplex c);
+static inline GslComplex gsl_complex_cosh (GslComplex c);
+static inline GslComplex gsl_complex_tanh (GslComplex c);
+char* gsl_complex_str (GslComplex c);
+char* gsl_complex_list (unsigned int n_points,
+ GslComplex *points,
+ const char *indent);
+void gsl_complex_gnuplot (const char *file_name,
+ unsigned int n_points,
+ GslComplex *points);
+
+
+/* --- polynomials --- */
+/* example, degree=2: 5+2x+7x^2 => a[0..degree] = { 5, 2, 7 } */
+static inline void gsl_poly_add (unsigned int degree,
+ double *a, /* a[0..degree] */
+ double *b);
+static inline void gsl_poly_sub (unsigned int order,
+ double *a, /* [0..degree] */
+ double *b);
+static inline void gsl_poly_mul (double *p, /* out:[0..aorder+border] */
+ unsigned int aorder,
+ const double *a, /* in:[0..aorder] */
+ unsigned int border,
+ const double *b); /* in:[0..border] */
+static inline void gsl_poly_scale (unsigned int order,
+ double *a, /* [0..degree] */
+ double scale);
+static inline void gsl_poly_xscale (unsigned int order,
+ double *a, /* [0..degree] */
+ double xscale);
+static inline double gsl_poly_eval (unsigned int degree,
+ double *a, /* [0..degree] */
+ double x);
+void gsl_poly_complex_roots (unsigned int poly_degree,
+ double *a, /* [0..degree] (degree+1 elements) */
+ GslComplex *roots); /* [degree] */
+void gsl_poly_from_re_roots (unsigned int poly_degree,
+ double *a, /* [0..degree] */
+ GslComplex *roots);
+void gsl_cpoly_from_roots (unsigned int poly_degree,
+ GslComplex *c, /* [0..degree] */
+ GslComplex *roots);
+static inline void gsl_cpoly_mul_monomial (unsigned int degree, /* _new_ degree */
+ GslComplex *c, /* in:[0..degree-1] out:[0..degree] */
+ GslComplex root); /* c(x) *= (x^1 - root) */
+static inline void gsl_cpoly_mul_reciprocal (unsigned int degree, /* _new_ degree */
+ GslComplex *c, /* in:[0..degree-1] out:[0..degree] */
+ GslComplex root); /* c(x) *= (1 - root * x^-1) */
+static inline void gsl_cpoly_mul (GslComplex *p, /* out:[0..aorder+border] */
+ unsigned int aorder,
+ GslComplex *a, /* in:[0..aorder] */
+ unsigned int border,
+ GslComplex *b); /* in:[0..border] */
+
+char* gsl_poly_str (unsigned int degree,
+ double *a,
+ const char *var);
+char* gsl_poly_str1 (unsigned int degree,
+ double *a,
+ const char *var);
+
+
+/* --- transformations --- */
+double gsl_temp_freq (double kammer_freq,
+ int halftone_delta);
+
+
+/* --- miscellaneous --- */
+double gsl_bit_depth_epsilon (guint n_bits); /* 1..32 */
+
+
+/* --- ellipses --- */
+double gsl_ellip_rf (double x,
+ double y,
+ double z);
+double gsl_ellip_F (double phi,
+ double ak);
+double gsl_ellip_sn (double u,
+ double emmc);
+double gsl_ellip_asn (double y,
+ double emmc);
+GslComplex gsl_complex_ellip_asn (GslComplex y,
+ GslComplex emmc);
+GslComplex gsl_complex_ellip_sn (GslComplex u,
+ GslComplex emmc);
+
+
+/* --- implementations --- */
+static inline GslComplex
+gsl_complex (double re,
+ double im)
+{
+ GslComplex r;
+ r.re = re;
+ r.im = im;
+ return r;
+}
+static inline GslComplex
+gsl_complex_polar (double abs,
+ double arg)
+{
+ return gsl_complex (abs * cos (arg), abs * sin (arg));
+}
+static inline GslComplex
+gsl_complex_add (GslComplex c1,
+ GslComplex c2)
+{
+ return gsl_complex (c1.re + c2.re, c1.im + c2.im);
+}
+static inline GslComplex
+gsl_complex_add3 (GslComplex c1,
+ GslComplex c2,
+ GslComplex c3)
+{
+ return gsl_complex (c1.re + c2.re + c3.re, c1.im + c2.im + c3.im);
+}
+static inline GslComplex
+gsl_complex_sub (GslComplex c1,
+ GslComplex c2)
+{
+ return gsl_complex (c1.re - c2.re, c1.im - c2.im);
+}
+static inline GslComplex
+gsl_complex_sub3 (GslComplex c1,
+ GslComplex c2,
+ GslComplex c3)
+{
+ return gsl_complex (c1.re - c2.re - c3.re, c1.im - c2.im - c3.im);
+}
+static inline GslComplex
+gsl_complex_scale (GslComplex c1,
+ double scale)
+{
+ return gsl_complex (c1.re * scale, c1.im * scale);
+}
+static inline GslComplex
+gsl_complex_mul (GslComplex c1,
+ GslComplex c2)
+{
+ return gsl_complex (c1.re * c2.re - c1.im * c2.im, c1.re * c2.im + c1.im * c2.re);
+}
+static inline GslComplex
+gsl_complex_mul3 (GslComplex c1,
+ GslComplex c2,
+ GslComplex c3)
+{
+ double aec = c1.re * c2.re * c3.re;
+ double bde = c1.im * c2.im * c3.re;
+ double adf = c1.re * c2.im * c3.im;
+ double bcf = c1.im * c2.re * c3.im;
+ double ade = c1.re * c2.im * c3.re;
+ double bce = c1.im * c2.re * c3.re;
+ double acf = c1.re * c2.re * c3.im;
+ double bdf = c1.im * c2.im * c3.im;
+
+ return gsl_complex (aec - bde - adf - bcf, ade + bce + acf - bdf);
+}
+static inline GslComplex
+gsl_complex_div (GslComplex a,
+ GslComplex b)
+{
+ GslComplex c;
+ if (fabs (b.re) >= fabs (b.im))
+ {
+ double r = b.im / b.re, den = b.re + r * b.im;
+ c.re = (a.re + r * a.im) / den;
+ c.im = (a.im - r * a.re) / den;
+ }
+ else
+ {
+ double r = b.re / b.im, den = b.im + r * b.re;
+ c.re = (a.re * r + a.im) / den;
+ c.im = (a.im * r - a.re) / den;
+ }
+ return c;
+}
+static inline GslComplex
+gsl_complex_reciprocal (GslComplex c)
+{
+ if (fabs (c.re) >= fabs (c.im))
+ {
+ double r = c.im / c.re, den = c.re + r * c.im;
+ c.re = 1. / den;
+ c.im = - r / den;
+ }
+ else
+ {
+ double r = c.re / c.im, den = c.im + r * c.re;
+ c.re = r / den;
+ c.im = - 1. / den;
+ }
+ return c;
+}
+static inline GslComplex
+gsl_complex_sqrt (GslComplex z)
+{
+ if (z.re == 0.0 && z.im == 0.0)
+ return z;
+ else
+ {
+ GslComplex c;
+ double w, x = fabs (z.re), y = fabs (z.im);
+ if (x >= y)
+ {
+ double r = y / x;
+ w = sqrt (x) * sqrt (0.5 * (1.0 + sqrt (1.0 + r * r)));
+ }
+ else
+ {
+ double r = x / y;
+ w = sqrt (y) * sqrt (0.5 * (r + sqrt (1.0 + r * r)));
+ }
+ if (z.re >= 0.0)
+ {
+ c.re = w;
+ c.im = z.im / (2.0 * w);
+ }
+ else
+ {
+ c.im = z.im >= 0 ? w : -w;
+ c.re = z.im / (2.0 * c.im);
+ }
+ return c;
+ }
+}
+static inline GslComplex
+gsl_complex_conj (GslComplex c)
+{
+ return gsl_complex (c.re, -c.im);
+}
+static inline GslComplex
+gsl_complex_inv (GslComplex c)
+{
+ return gsl_complex (-c.re, -c.im);
+}
+static inline GslComplex
+gsl_complex_id (GslComplex c)
+{
+ return c;
+}
+static inline double
+gsl_complex_abs (GslComplex c)
+{
+ /* compute (a^2 + b^2)^(1/2) without destructive underflow or overflow */
+ double absa = fabs (c.re), absb = fabs (c.im);
+ return (absa > absb ?
+ absb == 0.0 ? absa :
+ absa * sqrt (1.0 + (absb / absa) * (absb / absa)) :
+ absb == 0.0 ? 0.0 :
+ absb * sqrt (1.0 + (absa / absb) * (absa / absb)));
+}
+static inline double
+gsl_complex_arg (GslComplex c)
+{
+ double a = atan2 (c.im, c.re);
+ return a;
+}
+static inline GslComplex
+gsl_complex_sin (GslComplex c)
+{
+ return gsl_complex (sin (c.re) * cosh (c.im), cos (c.re) * sinh (c.im));
+}
+static inline GslComplex
+gsl_complex_cos (GslComplex c)
+{
+ return gsl_complex (cos (c.re) * cosh (c.im), - sin (c.re) * sinh (c.im));
+}
+static inline GslComplex
+gsl_complex_tan (GslComplex c)
+{
+ return gsl_complex_div (gsl_complex (tan (c.re), tanh (c.im)),
+ gsl_complex (1.0, -tan (c.re) * tanh (c.im)));
+}
+static inline GslComplex
+gsl_complex_sinh (GslComplex c)
+{
+ return gsl_complex (sinh (c.re) * cos (c.im), cosh (c.re) * sin (c.im));
+}
+static inline GslComplex
+gsl_complex_cosh (GslComplex c)
+{
+ return gsl_complex (cosh (c.re) * cos (c.im), sinh (c.re) * sin (c.im));
+}
+static inline GslComplex
+gsl_complex_tanh (GslComplex c)
+{
+ return gsl_complex_div (gsl_complex_sinh (c),
+ gsl_complex_cosh (c));
+}
+static inline void
+gsl_poly_add (unsigned int degree,
+ double *a,
+ double *b)
+{
+ unsigned int i;
+
+ for (i = 0; i <= degree; i++)
+ a[i] += b[i];
+}
+static inline void
+gsl_poly_sub (unsigned int degree,
+ double *a,
+ double *b)
+{
+ unsigned int i;
+
+ for (i = 0; i <= degree; i++)
+ a[i] -= b[i];
+}
+static inline void
+gsl_poly_mul (double *p, /* out:[0..aorder+border] */
+ unsigned int aorder,
+ const double *a, /* in:[0..aorder] */
+ unsigned int border,
+ const double *b) /* in:[0..border] */
+{
+ unsigned int i;
+
+ for (i = aorder + border; i > 0; i--)
+ {
+ unsigned int j;
+ double t = 0;
+
+ for (j = i - MIN (border, i); j <= MIN (aorder, i); j++)
+ t += a[j] * b[i - j];
+ p[i] = t;
+ }
+ p[0] = a[0] * b[0];
+}
+static inline void
+gsl_cpoly_mul_monomial (unsigned int degree,
+ GslComplex *c,
+ GslComplex root)
+{
+ unsigned int j;
+
+ c[degree] = c[degree - 1];
+ for (j = degree - 1; j >= 1; j--)
+ c[j] = gsl_complex_sub (c[j - 1], gsl_complex_mul (c[j], root));
+ c[0] = gsl_complex_mul (c[0], gsl_complex_inv (root));
+}
+static inline void
+gsl_cpoly_mul_reciprocal (unsigned int degree,
+ GslComplex *c,
+ GslComplex root)
+{
+ unsigned int j;
+
+ c[degree] = gsl_complex_mul (c[degree - 1], gsl_complex_inv (root));
+ for (j = degree - 1; j >= 1; j--)
+ c[j] = gsl_complex_sub (c[j], gsl_complex_mul (c[j - 1], root));
+ /* c[0] = c[0]; */
+}
+static inline void
+gsl_cpoly_mul (GslComplex *p, /* [0..aorder+border] */
+ unsigned int aorder,
+ GslComplex *a,
+ unsigned int border,
+ GslComplex *b)
+{
+ unsigned int i;
+
+ for (i = aorder + border; i > 0; i--)
+ {
+ GslComplex t;
+ unsigned int j;
+
+ t = gsl_complex (0, 0);
+ for (j = i - MIN (i, border); j <= MIN (aorder, i); j++)
+ t = gsl_complex_add (t, gsl_complex_mul (a[j], b[i - j]));
+ p[i] = t;
+ }
+ p[0] = gsl_complex_mul (a[0], b[0]);
+}
+static inline void
+gsl_poly_scale (unsigned int degree,
+ double *a,
+ double scale)
+{
+ unsigned int i;
+
+ for (i = 0; i <= degree; i++)
+ a[i] *= scale;
+}
+static inline void
+gsl_poly_xscale (unsigned int degree,
+ double *a,
+ double xscale)
+{
+ double scale = xscale;
+ unsigned int i;
+
+ for (i = 1; i <= degree; i++)
+ {
+ a[i] *= scale;
+ scale *= xscale;
+ }
+}
+static inline double
+gsl_poly_eval (unsigned int degree,
+ double *a,
+ double x)
+{
+ double sum = a[degree];
+
+ while (degree--)
+ sum = sum * x + a[degree];
+ return sum;
+}
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_MATH_H__ */ /* vim: set ts=8 sw=2 sts=2: */
diff --git a/flow/gsl/gslmathtest.c b/flow/gsl/gslmathtest.c
new file mode 100644
index 0000000..55130aa
--- /dev/null
+++ b/flow/gsl/gslmathtest.c
@@ -0,0 +1,334 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001 Stefan Westerfeld and Tim Janik
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <gsl/gslmath.h>
+#include <gsl/gslfilter.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define PREC "15"
+
+static void
+usage (char *s)
+{
+ printf ("usage: gslmathtest %s\n", s);
+ exit (1);
+}
+
+int
+main (int argc,
+ char *argv[])
+{
+ gchar *arg;
+
+ if (argc < 2)
+ goto abort;
+
+ if (strcmp (argv[1], "rf") == 0)
+ {
+ double x, y, z;
+ if (argc != 5)
+ usage ("rf <x> <y> <z>");
+ x = atof (argv[2]);
+ y = atof (argv[3]);
+ z = atof (argv[4]);
+
+ printf ("rf(%f, %f, %f) = %."PREC"f\n", x, y, z, gsl_ellip_rf (x, y, z));
+ }
+ else if (strcmp (argv[1], "F") == 0)
+ {
+ double phi, ak;
+ if (argc != 4)
+ usage ("F <phi> <ak>");
+ phi = atof (argv[2]);
+ ak = atof (argv[3]);
+
+ printf ("F(%f, %f) = %."PREC"f\n", phi, ak, gsl_ellip_F (phi, ak));
+ }
+ else if (strcmp (argv[1], "sn") == 0)
+ {
+ double u, emmc;
+ if (argc != 4)
+ usage ("sn <u> <emmc>");
+ u = atof (argv[2]);
+ emmc = atof (argv[3]);
+
+ printf ("sn(%f, %f) = %."PREC"f\n", u, emmc, gsl_ellip_sn (u, emmc));
+ }
+ else if (strcmp (argv[1], "snc") == 0)
+ {
+ GslComplex u, emmc;
+ if (argc != 6)
+ usage ("sn <u.re> <u.im> <emmc.re> <emmc.im>");
+ u.re = atof (argv[2]);
+ u.im = atof (argv[3]);
+ emmc.re = atof (argv[4]);
+ emmc.im = atof (argv[5]);
+
+ printf ("snc(%s, %s) = %s\n",
+ gsl_complex_str (u),
+ gsl_complex_str (emmc),
+ gsl_complex_str (gsl_complex_ellip_sn (u, emmc)));
+ }
+ else if (strcmp (argv[1], "sci_snc") == 0)
+ {
+ GslComplex u, k2;
+ if (argc != 6)
+ usage ("sci_sn <u.re> <u.im> <k2.re> <k2.im>");
+ u.re = atof (argv[2]);
+ u.im = atof (argv[3]);
+ k2.re = atof (argv[4]);
+ k2.im = atof (argv[5]);
+
+ printf ("sci_snc(%s, %s) = %s\n",
+ gsl_complex_str (u),
+ gsl_complex_str (k2),
+ gsl_complex_str (gsl_complex_ellip_sn (u, gsl_complex_sub (gsl_complex (1.0, 0), k2))));
+ }
+ else if (strcmp (argv[1], "asn") == 0)
+ {
+ double y, emmc;
+ if (argc != 4)
+ usage ("asn <y> <emmc>");
+ y = atof (argv[2]);
+ emmc = atof (argv[3]);
+
+ printf ("asn(%f, %f) = %."PREC"f\n", y, emmc, gsl_ellip_asn (y, emmc));
+ }
+ else if (strcmp (argv[1], "asnc") == 0)
+ {
+ GslComplex y, emmc;
+ if (argc != 6)
+ usage ("asnc <y.re> <y.im> <emmc.re> <emmc.im>");
+ y.re = atof (argv[2]);
+ y.im = atof (argv[3]);
+ emmc.re = atof (argv[4]);
+ emmc.im = atof (argv[5]);
+
+ printf ("asnc(%s, %s) = %s\n",
+ gsl_complex_str (y), gsl_complex_str (emmc),
+ gsl_complex_str (gsl_complex_ellip_asn (y, emmc)));
+ printf ("asn(%f, %f = %."PREC"f\n",
+ y.re, emmc.re, gsl_ellip_asn (y.re, emmc.re));
+ }
+ else if (strcmp (argv[1], "sci_sn") == 0)
+ {
+ double u, k2;
+ if (argc != 4)
+ usage ("sci_sn <u> <k2>");
+ u = atof (argv[2]);
+ k2 = atof (argv[3]);
+
+ printf ("sci_sn(%f, %f) = %."PREC"f\n", u, k2, gsl_ellip_sn (u, 1.0 - k2));
+ }
+ else if (strcmp (argv[1], "sci_asn") == 0)
+ {
+ double y, k2;
+ if (argc != 4)
+ usage ("sci_asn <y> <k2>");
+ y = atof (argv[2]);
+ k2 = atof (argv[3]);
+
+ printf ("sci_asn(%f, %f) = %."PREC"f\n", y, k2, gsl_ellip_asn (y, 1.0 - k2));
+ }
+ else if (strcmp (argv[1], "sci_asnc") == 0)
+ {
+ GslComplex y, k2;
+ if (argc != 6)
+ usage ("sci_asnc <y.re> <y.im> <k2.re> <k2.im>");
+ y.re = atof (argv[2]);
+ y.im = atof (argv[3]);
+ k2.re = atof (argv[4]);
+ k2.im = atof (argv[5]);
+
+ printf ("sci_asnc(%s, %s) = %s\n",
+ gsl_complex_str (y), gsl_complex_str (k2),
+ gsl_complex_str (gsl_complex_ellip_asn (y, gsl_complex_sub (gsl_complex (1.0, 0), k2))));
+ printf ("asn(%f, %f = %."PREC"f\n",
+ y.re, k2.re, gsl_ellip_asn (y.re, 1.0 - k2.re));
+ }
+ else if (strcmp (argv[1], "sin") == 0)
+ {
+ GslComplex phi;
+ if (argc != 4)
+ usage ("sin <phi.re> <phi.im>");
+ phi.re = atof (argv[2]);
+ phi.im = atof (argv[3]);
+
+ printf ("sin(%s) = %s\n",
+ gsl_complex_str (phi),
+ gsl_complex_str (gsl_complex_sin (phi)));
+ }
+ else if (strcmp (argv[1], "cos") == 0)
+ {
+ GslComplex phi;
+ if (argc != 4)
+ usage ("cos <phi.re> <phi.im>");
+ phi.re = atof (argv[2]);
+ phi.im = atof (argv[3]);
+
+ printf ("cos(%s) = %s\n",
+ gsl_complex_str (phi),
+ gsl_complex_str (gsl_complex_cos (phi)));
+ }
+ else if (strcmp (argv[1], "tan") == 0)
+ {
+ GslComplex phi;
+ if (argc != 4)
+ usage ("tan <phi.re> <phi.im>");
+ phi.re = atof (argv[2]);
+ phi.im = atof (argv[3]);
+
+ printf ("tan(%s) = %s\n",
+ gsl_complex_str (phi),
+ gsl_complex_str (gsl_complex_tan (phi)));
+ }
+ else if (strcmp (argv[1], "sinh") == 0)
+ {
+ GslComplex phi;
+ if (argc != 4)
+ usage ("sinh <phi.re> <phi.im>");
+ phi.re = atof (argv[2]);
+ phi.im = atof (argv[3]);
+
+ printf ("sinh(%s) = %s\n",
+ gsl_complex_str (phi),
+ gsl_complex_str (gsl_complex_sinh (phi)));
+ }
+ else if (strcmp (argv[1], "cosh") == 0)
+ {
+ GslComplex phi;
+ if (argc != 4)
+ usage ("cosh <phi.re> <phi.im>");
+ phi.re = atof (argv[2]);
+ phi.im = atof (argv[3]);
+
+ printf ("cosh(%s) = %s\n",
+ gsl_complex_str (phi),
+ gsl_complex_str (gsl_complex_cosh (phi)));
+ }
+ else if (strcmp (argv[1], "tanh") == 0)
+ {
+ GslComplex phi;
+ if (argc != 4)
+ usage ("tanh <phi.re> <phi.im>");
+ phi.re = atof (argv[2]);
+ phi.im = atof (argv[3]);
+
+ printf ("tanh(%s) = %s\n",
+ gsl_complex_str (phi),
+ gsl_complex_str (gsl_complex_tanh (phi)));
+ }
+ else if (strcmp (argv[1], "t1") == 0)
+ {
+ guint order;
+ double f, e;
+ if (argc != 5)
+ usage ("t1 <order> <freq> <epsilon>");
+ order = atoi (argv[2]);
+ f = atof (argv[3]);
+ e = atof (argv[4]);
+ f *= GSL_PI / 2.;
+ e = gsl_trans_zepsilon2ss (e);
+ {
+ double a[order + 1], b[order + 1];
+ gsl_filter_tscheb1 (order, f, e, a, b);
+ g_print ("# Tschebyscheff Type1 order=%u freq=%f s^2epsilon=%f norm0=%f:\n",
+ order, f, e,
+ gsl_poly_eval (order, a, 1) / gsl_poly_eval (order, b, 1));
+ g_print ("H%u(z)=%s/%s\n", order,
+ gsl_poly_str (order, a, "z"),
+ gsl_poly_str (order, b, "z"));
+ }
+ }
+ else if (strcmp (argv[1], "t2") == 0)
+ {
+ guint order;
+ double fc, fr, e;
+ if (argc != 6)
+ usage ("t1 <order> <freqc> <freqr> <epsilon>");
+ order = atoi (argv[2]);
+ fc = atof (argv[3]);
+ fr = atof (argv[4]);
+ e = atof (argv[5]);
+ fc *= GSL_PI / 2.;
+ fr *= GSL_PI / 2.;
+ e = gsl_trans_zepsilon2ss (e);
+ {
+ double a[order + 1], b[order + 1];
+ gsl_filter_tscheb2 (order, fc, fr, e, a, b);
+ g_print ("# Tschebyscheff Type2 order=%u freq_c=%f freq_r=%f s^2epsilon=%f norm=%f:\n",
+ order, fc, fr, e,
+ gsl_poly_eval (order, a, 1) / gsl_poly_eval (order, b, 1));
+ g_print ("H%u(z)=%s/%s\n", order,
+ gsl_poly_str (order, a, "z"),
+ gsl_poly_str (order, b, "z"));
+ }
+ }
+ else if (strncmp (argv[1], "test", 4) == 0)
+ {
+ guint order;
+ arg = argv[1] + 4;
+ if (argc != argc)
+ usage ("test");
+ order = 2;
+ {
+ double a[100] = { 1, 2, 1 }, b[100] = { 1, -3./2., 0.5 };
+ g_print ("# Test order=%u norm=%f:\n",
+ order,
+ gsl_poly_eval (order, a, 1) / gsl_poly_eval (order, b, 1));
+ g_print ("H%u(z)=%s/%s\n", order,
+ gsl_poly_str (order, a, "z"),
+ gsl_poly_str (order, b, "z"));
+ if (*arg)
+ {
+ GslComplex root, roots[100];
+ guint i;
+
+ if (*arg == 'r')
+ {
+ g_print ("#roots:\n");
+ gsl_poly_complex_roots (order, a, roots);
+ for (i = 0; i < order; i++)
+ {
+ root = gsl_complex_div (gsl_complex (1, 0), roots[i]);
+ g_print ("%+.14f %+.14f # %.14f\n", root.re, root.im, gsl_complex_abs (root));
+ }
+ }
+ if (*arg == 'p')
+ {
+ g_print ("#poles:\n");
+ gsl_poly_complex_roots (order, b, roots);
+ for (i = 0; i < order; i++)
+ {
+ root = gsl_complex_div (gsl_complex (1, 0), roots[i]);
+ g_print ("%+.14f %+.14f # %.14f\n", root.re, root.im, gsl_complex_abs (root));
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ abort:
+ usage ("{rf|F|sn|snc|sci_sn|sci_snc|asn|asnc|sci_asn|sci_asnc|sin(h)|cos(h)|tan(h)|t1|t2} ...");
+ }
+
+ return 0;
+}
diff --git a/flow/gsl/gslopmaster.c b/flow/gsl/gslopmaster.c
new file mode 100644
index 0000000..f71ec3d
--- /dev/null
+++ b/flow/gsl/gslopmaster.c
@@ -0,0 +1,783 @@
+/* GSL Engine - Flow module operation engine
+ * Copyright (C) 2001 Tim Janik
+ *
+ * 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.
+ */
+#include <string.h>
+#include <sys/poll.h>
+#include <sys/time.h>
+#include <errno.h>
+
+#include "gslopmaster.h"
+
+#include "gslcommon.h"
+#include "gslopnode.h"
+#include "gsloputil.h"
+#include "gslopschedule.h"
+#include "gslieee754.h"
+
+
+
+#define NODE_FLAG_RECONNECT(node) G_STMT_START { (node)->reconnected = (node)->module.klass->reconnect != NULL; } G_STMT_END
+
+
+/* --- time stamping (debugging) --- */
+#define ToyprofStamp struct timeval
+#define toyprof_clock_name() ("Glibc gettimeofday(2)")
+#define toyprof_stampinit() /* nothing */
+#define toyprof_stamp(st) gettimeofday (&(st), 0)
+#define toyprof_stamp_ticks() (1000000)
+static inline guint64
+toyprof_elapsed (ToyprofStamp fstamp,
+ ToyprofStamp lstamp)
+{
+ guint64 first = fstamp.tv_sec * toyprof_stamp_ticks () + fstamp.tv_usec;
+ guint64 last = lstamp.tv_sec * toyprof_stamp_ticks () + lstamp.tv_usec;
+ return last - first;
+}
+
+
+/* --- typedefs & structures --- */
+typedef struct _Poll Poll;
+struct _Poll
+{
+ Poll *next;
+ GslPollFunc poll_func;
+ gpointer data;
+ guint n_fds;
+ GPollFD *fds;
+ GslFreeFunc free_func;
+};
+
+
+/* --- prototypes --- */
+static void master_schedule_discard (void);
+
+
+/* --- variables --- */
+static gboolean master_need_reflow = FALSE;
+static gboolean master_need_process = FALSE;
+static EngineNode *master_consumer_list = NULL;
+const gfloat gsl_engine_master_zero_block[GSL_STREAM_MAX_VALUES] = { 0, }; /* FIXME */
+static Poll *master_poll_list = NULL;
+static guint master_n_pollfds = 0;
+static guint master_pollfds_changed = FALSE;
+static GPollFD master_pollfds[GSL_ENGINE_MAX_POLLFDS];
+static EngineSchedule *master_schedule = NULL;
+
+
+/* --- functions --- */
+static void
+add_consumer (EngineNode *node)
+{
+ g_return_if_fail (ENGINE_NODE_IS_CONSUMER (node) && node->toplevel_next == NULL && node->integrated);
+
+ node->toplevel_next = master_consumer_list;
+ master_consumer_list = node;
+}
+
+static void
+remove_consumer (EngineNode *node)
+{
+ EngineNode *tmp, *last = NULL;
+
+ g_return_if_fail (!ENGINE_NODE_IS_CONSUMER (node) || !node->integrated);
+
+ for (tmp = master_consumer_list; tmp; last = tmp, tmp = last->toplevel_next)
+ if (tmp == node)
+ break;
+ g_return_if_fail (tmp != NULL);
+ if (last)
+ last->toplevel_next = node->toplevel_next;
+ else
+ master_consumer_list = node->toplevel_next;
+ node->toplevel_next = NULL;
+}
+
+static void
+master_idisconnect_node (EngineNode *node,
+ guint istream)
+{
+ EngineNode *src_node = node->inputs[istream].src_node;
+ guint ostream = node->inputs[istream].src_stream;
+ gboolean was_consumer;
+
+ g_assert (ostream < ENGINE_NODE_N_OSTREAMS (src_node) &&
+ src_node->outputs[ostream].n_outputs > 0); /* these checks better pass */
+
+ node->inputs[istream].src_node = NULL;
+ node->inputs[istream].src_stream = ~0;
+ node->module.istreams[istream].connected = FALSE;
+ was_consumer = ENGINE_NODE_IS_CONSUMER (src_node);
+ src_node->outputs[ostream].n_outputs -= 1;
+ src_node->module.ostreams[ostream].connected = src_node->outputs[ostream].n_outputs > 0;
+ src_node->output_nodes = gsl_ring_remove (src_node->output_nodes, node);
+ NODE_FLAG_RECONNECT (node);
+ NODE_FLAG_RECONNECT (src_node);
+ /* add to consumer list */
+ if (!was_consumer && ENGINE_NODE_IS_CONSUMER (src_node))
+ add_consumer (src_node);
+}
+
+static void
+master_jdisconnect_node (EngineNode *node,
+ guint jstream,
+ guint con)
+{
+ EngineNode *src_node = node->jinputs[jstream][con].src_node;
+ guint i, ostream = node->jinputs[jstream][con].src_stream;
+ gboolean was_consumer;
+
+ g_assert (ostream < ENGINE_NODE_N_OSTREAMS (src_node) &&
+ node->module.jstreams[jstream].n_connections > 0 &&
+ src_node->outputs[ostream].n_outputs > 0); /* these checks better pass */
+
+ i = --node->module.jstreams[jstream].n_connections;
+ node->jinputs[jstream][con] = node->jinputs[jstream][i];
+ node->module.jstreams[jstream].values[i] = NULL; /* float**values 0-termination */
+ was_consumer = ENGINE_NODE_IS_CONSUMER (src_node);
+ src_node->outputs[ostream].n_outputs -= 1;
+ src_node->module.ostreams[ostream].connected = src_node->outputs[ostream].n_outputs > 0;
+ src_node->output_nodes = gsl_ring_remove (src_node->output_nodes, node);
+ NODE_FLAG_RECONNECT (node);
+ NODE_FLAG_RECONNECT (src_node);
+ /* add to consumer list */
+ if (!was_consumer && ENGINE_NODE_IS_CONSUMER (src_node))
+ add_consumer (src_node);
+}
+
+static void
+master_disconnect_node_outputs (EngineNode *src_node,
+ EngineNode *dest_node)
+{
+ gint i, j;
+
+ for (i = 0; i < ENGINE_NODE_N_ISTREAMS (dest_node); i++)
+ if (dest_node->inputs[i].src_node == src_node)
+ master_idisconnect_node (dest_node, i);
+ for (j = 0; j < ENGINE_NODE_N_JSTREAMS (dest_node); j++)
+ for (i = 0; i < dest_node->module.jstreams[j].n_connections; i++)
+ if (dest_node->jinputs[j][i].src_node == src_node)
+ master_jdisconnect_node (dest_node, j, i--);
+}
+
+static void
+master_process_job (GslJob *job)
+{
+ switch (job->job_id)
+ {
+ EngineNode *node, *src_node;
+ Poll *poll, *poll_last;
+ guint istream, jstream, ostream, con;
+ EngineFlowJob *fjob;
+ gboolean was_consumer;
+ case ENGINE_JOB_INTEGRATE:
+ node = job->data.node;
+ JOB_DEBUG ("integrate(%p)", node);
+ g_return_if_fail (node->integrated == FALSE);
+ g_return_if_fail (node->sched_tag == FALSE);
+ _engine_mnl_integrate (node);
+ if (ENGINE_NODE_IS_CONSUMER (node))
+ add_consumer (node);
+ node->counter = 0;
+ NODE_FLAG_RECONNECT (node);
+ master_need_reflow |= TRUE;
+ break;
+ case ENGINE_JOB_DISCARD:
+ /* FIXME: free pending flow jobs */
+ node = job->data.node;
+ JOB_DEBUG ("discard(%p)", node);
+ g_return_if_fail (node->integrated == TRUE);
+ /* disconnect inputs */
+ for (istream = 0; istream < ENGINE_NODE_N_ISTREAMS (node); istream++)
+ if (node->inputs[istream].src_node)
+ master_idisconnect_node (node, istream);
+ for (jstream = 0; jstream < ENGINE_NODE_N_JSTREAMS (node); jstream++)
+ while (node->module.jstreams[jstream].n_connections)
+ master_jdisconnect_node (node, jstream, node->module.jstreams[jstream].n_connections - 1);
+ /* disconnect outputs */
+ while (node->output_nodes)
+ master_disconnect_node_outputs (node, node->output_nodes->data);
+ /* remove from consumer list */
+ if (ENGINE_NODE_IS_CONSUMER (node))
+ {
+ _engine_mnl_remove (node);
+ remove_consumer (node);
+ }
+ else
+ _engine_mnl_remove (node);
+ node->counter = 0;
+ master_need_reflow |= TRUE;
+ master_schedule_discard (); /* discard schedule so node may be freed */
+ break;
+ case ENGINE_JOB_SET_CONSUMER:
+ case ENGINE_JOB_UNSET_CONSUMER:
+ node = job->data.node;
+ JOB_DEBUG ("toggle_consumer(%p)", node);
+ was_consumer = ENGINE_NODE_IS_CONSUMER (node);
+ node->is_consumer = job->job_id == ENGINE_JOB_SET_CONSUMER;
+ if (was_consumer != ENGINE_NODE_IS_CONSUMER (node))
+ {
+ if (ENGINE_NODE_IS_CONSUMER (node))
+ add_consumer (node);
+ else
+ remove_consumer (node);
+ master_need_reflow |= TRUE;
+ }
+ break;
+ case ENGINE_JOB_ICONNECT:
+ node = job->data.connection.dest_node;
+ src_node = job->data.connection.src_node;
+ istream = job->data.connection.dest_ijstream;
+ ostream = job->data.connection.src_ostream;
+ JOB_DEBUG ("connect(%p,%u,%p,%u)", node, istream, src_node, ostream);
+ g_return_if_fail (node->integrated == TRUE);
+ g_return_if_fail (src_node->integrated == TRUE);
+ g_return_if_fail (node->inputs[istream].src_node == NULL);
+ node->inputs[istream].src_node = src_node;
+ node->inputs[istream].src_stream = ostream;
+ node->module.istreams[istream].connected = TRUE;
+ /* remove from consumer list */
+ was_consumer = ENGINE_NODE_IS_CONSUMER (src_node);
+ src_node->outputs[ostream].n_outputs += 1;
+ src_node->module.ostreams[ostream].connected = TRUE;
+ src_node->output_nodes = gsl_ring_append (src_node->output_nodes, node);
+ NODE_FLAG_RECONNECT (node);
+ NODE_FLAG_RECONNECT (src_node);
+ src_node->counter = 0; /* FIXME: counter reset? */
+ if (was_consumer && !ENGINE_NODE_IS_CONSUMER (src_node))
+ remove_consumer (src_node);
+ master_need_reflow |= TRUE;
+ break;
+ case ENGINE_JOB_JCONNECT:
+ node = job->data.connection.dest_node;
+ src_node = job->data.connection.src_node;
+ jstream = job->data.connection.dest_ijstream;
+ ostream = job->data.connection.src_ostream;
+ JOB_DEBUG ("jconnect(%p,%u,%p,%u)", node, jstream, src_node, ostream);
+ g_return_if_fail (node->integrated == TRUE);
+ g_return_if_fail (src_node->integrated == TRUE);
+ con = node->module.jstreams[jstream].n_connections++;
+ node->jinputs[jstream] = g_renew (EngineJInput, node->jinputs[jstream], node->module.jstreams[jstream].n_connections);
+ node->module.jstreams[jstream].values = g_renew (const gfloat*, node->module.jstreams[jstream].values, node->module.jstreams[jstream].n_connections + 1);
+ node->module.jstreams[jstream].values[node->module.jstreams[jstream].n_connections] = NULL; /* float**values 0-termination */
+ node->jinputs[jstream][con].src_node = src_node;
+ node->jinputs[jstream][con].src_stream = ostream;
+ /* remove from consumer list */
+ was_consumer = ENGINE_NODE_IS_CONSUMER (src_node);
+ src_node->outputs[ostream].n_outputs += 1;
+ src_node->module.ostreams[ostream].connected = TRUE;
+ src_node->output_nodes = gsl_ring_append (src_node->output_nodes, node);
+ NODE_FLAG_RECONNECT (node);
+ NODE_FLAG_RECONNECT (src_node);
+ src_node->counter = 0; /* FIXME: counter reset? */
+ if (was_consumer && !ENGINE_NODE_IS_CONSUMER (src_node))
+ remove_consumer (src_node);
+ master_need_reflow |= TRUE;
+ break;
+ case ENGINE_JOB_IDISCONNECT:
+ node = job->data.connection.dest_node;
+ JOB_DEBUG ("idisconnect(%p,%u)", node, job->data.connection.dest_ijstream);
+ g_return_if_fail (node->integrated == TRUE);
+ g_return_if_fail (node->inputs[job->data.connection.dest_ijstream].src_node != NULL);
+ master_idisconnect_node (node, job->data.connection.dest_ijstream);
+ master_need_reflow |= TRUE;
+ break;
+ case ENGINE_JOB_JDISCONNECT:
+ node = job->data.connection.dest_node;
+ jstream = job->data.connection.dest_ijstream;
+ src_node = job->data.connection.src_node;
+ ostream = job->data.connection.src_ostream;
+ JOB_DEBUG ("jdisconnect(%p,%u,%p,%u)", node, jstream, src_node, ostream);
+ g_return_if_fail (node->integrated == TRUE);
+ g_return_if_fail (node->module.jstreams[jstream].n_connections > 0);
+ for (con = 0; con < node->module.jstreams[jstream].n_connections; con++)
+ if (node->jinputs[jstream][con].src_node == src_node &&
+ node->jinputs[jstream][con].src_stream == ostream)
+ break;
+ if (con < node->module.jstreams[jstream].n_connections)
+ {
+ master_jdisconnect_node (node, jstream, con);
+ master_need_reflow |= TRUE;
+ }
+ else
+ g_warning ("jdisconnect(dest:%p,%u,src:%p,%u): no such connection", node, jstream, src_node, ostream);
+ break;
+ case ENGINE_JOB_ACCESS:
+ node = job->data.access.node;
+ JOB_DEBUG ("access node(%p): %p(%p)", node, job->data.access.access_func, job->data.access.data);
+ g_return_if_fail (node->integrated == TRUE);
+ job->data.access.access_func (&node->module, job->data.access.data);
+ break;
+ case ENGINE_JOB_FLOW_JOB:
+ node = job->data.flow_job.node;
+ fjob = job->data.flow_job.fjob;
+ JOB_DEBUG ("add flow_job(%p,%p)", node, fjob);
+ g_return_if_fail (node->integrated == TRUE);
+ job->data.flow_job.fjob = NULL; /* ownership taken over */
+ _engine_node_insert_flow_job (node, fjob);
+ _engine_mnl_reorder (node);
+ break;
+ case ENGINE_JOB_DEBUG:
+ JOB_DEBUG ("debug");
+ g_printerr ("JOB-DEBUG: %s\n", job->data.debug);
+ break;
+ case ENGINE_JOB_ADD_POLL:
+ JOB_DEBUG ("add poll %p(%p,%u)", job->data.poll.poll_func, job->data.poll.data, job->data.poll.n_fds);
+ if (job->data.poll.n_fds + master_n_pollfds > GSL_ENGINE_MAX_POLLFDS)
+ g_error ("adding poll job exceeds maximum number of poll-fds (%u > %u)",
+ job->data.poll.n_fds + master_n_pollfds, GSL_ENGINE_MAX_POLLFDS);
+ poll = gsl_new_struct0 (Poll, 1);
+ poll->poll_func = job->data.poll.poll_func;
+ poll->data = job->data.poll.data;
+ poll->free_func = job->data.poll.free_func;
+ job->data.poll.free_func = NULL; /* don't free data this round */
+ poll->n_fds = job->data.poll.n_fds;
+ poll->fds = poll->n_fds ? master_pollfds + master_n_pollfds : master_pollfds;
+ master_n_pollfds += poll->n_fds;
+ if (poll->n_fds)
+ master_pollfds_changed = TRUE;
+ memcpy (poll->fds, job->data.poll.fds, sizeof (poll->fds[0]) * poll->n_fds);
+ poll->next = master_poll_list;
+ master_poll_list = poll;
+ break;
+ case ENGINE_JOB_REMOVE_POLL:
+ JOB_DEBUG ("remove poll %p(%p)", job->data.poll.poll_func, job->data.poll.data);
+ for (poll = master_poll_list, poll_last = NULL; poll; poll_last = poll, poll = poll_last->next)
+ if (poll->poll_func == job->data.poll.poll_func && poll->data == job->data.poll.data)
+ {
+ if (poll_last)
+ poll_last->next = poll->next;
+ else
+ master_poll_list = poll->next;
+ break;
+ }
+ if (poll)
+ {
+ job->data.poll.free_func = poll->free_func; /* free data with job */
+ poll_last = poll;
+ if (poll_last->n_fds)
+ {
+ for (poll = master_poll_list; poll; poll = poll->next)
+ if (poll->fds > poll_last->fds)
+ poll->fds -= poll_last->n_fds;
+ g_memmove (poll_last->fds, poll_last->fds + poll_last->n_fds,
+ ((guint8*) (master_pollfds + master_n_pollfds)) -
+ ((guint8*) (poll_last->fds + poll_last->n_fds)));
+ master_n_pollfds -= poll_last->n_fds;
+ master_pollfds_changed = TRUE;
+ }
+ gsl_delete_struct (Poll, poll_last);
+ }
+ else
+ g_warning (G_STRLOC ": failed to remove unknown poll function %p(%p)",
+ job->data.poll.poll_func, job->data.poll.data);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ JOB_DEBUG ("done");
+}
+
+static void
+master_poll_check (glong *timeout_p,
+ gboolean check_with_revents)
+{
+ gboolean need_processing = FALSE;
+ Poll *poll;
+
+ if (master_need_process || *timeout_p == 0)
+ {
+ master_need_process = TRUE;
+ return;
+ }
+ for (poll = master_poll_list; poll; poll = poll->next)
+ {
+ glong timeout = -1;
+
+ if (poll->poll_func (poll->data, gsl_engine_block_size (), &timeout,
+ poll->n_fds, poll->n_fds ? poll->fds : NULL, check_with_revents)
+ || timeout == 0)
+ {
+ need_processing |= TRUE;
+ *timeout_p = 0;
+ break;
+ }
+ else if (timeout > 0)
+ *timeout_p = *timeout_p < 0 ? timeout : MIN (*timeout_p, timeout);
+ }
+ master_need_process = need_processing;
+}
+
+static inline guint64
+master_handle_flow_jobs (EngineNode *node,
+ guint64 max_tick)
+{
+ EngineFlowJob *fjob = _engine_node_pop_flow_job (node, max_tick);
+
+ if_reject (fjob)
+ do
+ {
+ g_printerr ("FJob: at:%lld from:%lld \n", node->counter, fjob->any.tick_stamp);
+ switch (fjob->fjob_id)
+ {
+ case ENGINE_FLOW_JOB_ACCESS:
+ fjob->access.access_func (&node->module, fjob->access.data);
+ break;
+ default:
+ g_assert_not_reached (); /* FIXME */
+ }
+ fjob = _engine_node_pop_flow_job (node, max_tick);
+ }
+ while (fjob);
+
+ return _engine_node_peek_flow_job_stamp (node);
+}
+
+static void
+master_process_locked_node (EngineNode *node,
+ guint n_values)
+{
+ guint64 final_counter = GSL_TICK_STAMP + n_values;
+
+ while (node->counter < final_counter)
+ {
+ guint64 next_counter = master_handle_flow_jobs (node, node->counter);
+ guint64 new_counter = MIN (next_counter, final_counter);
+ guint i, j, diff = node->counter - GSL_TICK_STAMP;
+
+ for (i = 0; i < ENGINE_NODE_N_ISTREAMS (node); i++)
+ {
+ EngineNode *inode = node->inputs[i].src_node;
+
+ if (inode)
+ {
+ ENGINE_NODE_LOCK (inode);
+ if (inode->counter < final_counter)
+ master_process_locked_node (inode, final_counter - node->counter);
+ node->module.istreams[i].values = inode->outputs[node->inputs[i].src_stream].buffer;
+ node->module.istreams[i].values += diff;
+ ENGINE_NODE_UNLOCK (inode);
+ }
+ else
+ node->module.istreams[i].values = gsl_engine_master_zero_block;
+ }
+ for (j = 0; j < ENGINE_NODE_N_JSTREAMS (node); j++)
+ for (i = 0; i < node->module.jstreams[j].n_connections; i++)
+ {
+ EngineNode *inode = node->jinputs[j][i].src_node;
+
+ ENGINE_NODE_LOCK (inode);
+ if (inode->counter < final_counter)
+ master_process_locked_node (inode, final_counter - node->counter);
+ node->module.jstreams[j].values[i] = inode->outputs[node->jinputs[j][i].src_stream].buffer;
+ node->module.jstreams[j].values[i] += diff;
+ ENGINE_NODE_UNLOCK (inode);
+ }
+ for (i = 0; i < ENGINE_NODE_N_OSTREAMS (node); i++)
+ node->module.ostreams[i].values = node->outputs[i].buffer + diff;
+ if_reject (node->reconnected)
+ {
+ node->module.klass->reconnect (&node->module);
+ node->reconnected = FALSE;
+ }
+ node->module.klass->process (&node->module, new_counter - node->counter);
+ for (i = 0; i < ENGINE_NODE_N_OSTREAMS (node); i++)
+ {
+ /* FIXME: this takes the worst possible performance hit to support virtualization */
+ if (node->module.ostreams[i].values != node->outputs[i].buffer + diff)
+ memcpy (node->outputs[i].buffer + diff, node->module.ostreams[i].values,
+ (new_counter - node->counter) * sizeof (gfloat));
+ }
+ node->counter = new_counter;
+ }
+}
+
+static GslLong gsl_profile_modules = 0; /* set to 1 in gdb to get profile output */
+
+static void
+master_process_flow (void)
+{
+ guint64 new_counter = GSL_TICK_STAMP + gsl_engine_block_size ();
+ GslLong profile_maxtime = 0;
+ GslLong profile_modules = gsl_profile_modules;
+ EngineNode *profile_node = NULL;
+
+ g_return_if_fail (master_need_process == TRUE);
+
+ g_assert (gsl_fpu_okround () == TRUE);
+
+ MAS_DEBUG ("process_flow");
+ if (master_schedule)
+ {
+ EngineNode *node;
+
+ _engine_schedule_restart (master_schedule);
+ _engine_set_schedule (master_schedule);
+
+ node = _engine_pop_unprocessed_node ();
+ while (node)
+ {
+ ToyprofStamp profile_stamp1, profile_stamp2;
+
+ if_reject (profile_modules)
+ toyprof_stamp (profile_stamp1);
+
+ master_process_locked_node (node, gsl_engine_block_size ());
+
+ if_reject (profile_modules)
+ {
+ GslLong duration;
+
+ toyprof_stamp (profile_stamp2);
+ duration = toyprof_elapsed (profile_stamp1, profile_stamp2);
+ if (duration > profile_maxtime)
+ {
+ profile_maxtime = duration;
+ profile_node = node;
+ }
+ }
+
+ _engine_push_processed_node (node);
+ node = _engine_pop_unprocessed_node ();
+ }
+
+ if_reject (profile_modules)
+ {
+ if (profile_node)
+ {
+ if (profile_maxtime > profile_modules)
+ g_print ("Excess Node: %p Duration: %lu usecs ((void(*)())%p) \n",
+ profile_node, profile_maxtime, profile_node->module.klass->process);
+ else
+ g_print ("Slowest Node: %p Duration: %lu usecs ((void(*)())%p) \r",
+ profile_node, profile_maxtime, profile_node->module.klass->process);
+ }
+ }
+
+ /* walk unscheduled nodes which have flow jobs */
+ node = _engine_mnl_head ();
+ while (node && GSL_MNL_HEAD_NODE (node))
+ {
+ EngineNode *tmp = node->mnl_next;
+ EngineFlowJob *fjob = _engine_node_pop_flow_job (node, new_counter);
+
+ if (fjob)
+ {
+ while (fjob)
+ {
+ g_printerr ("ignoring flow_job %p\n", fjob);
+ fjob = _engine_node_pop_flow_job (node, new_counter);
+ }
+ _engine_mnl_reorder (node);
+ }
+ node = tmp;
+ }
+
+ /* nothing new to process, wait on slaves */
+ _engine_wait_on_unprocessed ();
+
+ _engine_unset_schedule (master_schedule);
+ _gsl_tick_stamp_inc ();
+ _engine_recycle_const_values ();
+ }
+ master_need_process = FALSE;
+}
+
+static void
+master_reschedule_flow (void)
+{
+ EngineNode *node;
+
+ g_return_if_fail (master_need_reflow == TRUE);
+
+ MAS_DEBUG ("flow_reschedule");
+ if (!master_schedule)
+ master_schedule = _engine_schedule_new ();
+ else
+ {
+ _engine_schedule_unsecure (master_schedule);
+ _engine_schedule_clear (master_schedule);
+ }
+ for (node = master_consumer_list; node; node = node->toplevel_next)
+ _engine_schedule_consumer_node (master_schedule, node);
+ _engine_schedule_secure (master_schedule);
+ master_need_reflow = FALSE;
+}
+
+static void
+master_schedule_discard (void)
+{
+ g_return_if_fail (master_need_reflow == TRUE);
+
+ if (master_schedule)
+ {
+ _engine_schedule_unsecure (master_schedule);
+ _engine_schedule_destroy (master_schedule);
+ master_schedule = NULL;
+ }
+}
+
+
+/* --- MasterThread main loop --- */
+gboolean
+_engine_master_prepare (GslEngineLoop *loop)
+{
+ gboolean need_dispatch;
+ guint i;
+
+ g_return_val_if_fail (loop != NULL, FALSE);
+
+ /* setup and clear pollfds here already, so master_poll_check() gets no junk (and IRIX can't handle non-0 revents) */
+ loop->fds_changed = master_pollfds_changed;
+ master_pollfds_changed = FALSE;
+ loop->n_fds = master_n_pollfds;
+ loop->fds = master_pollfds;
+ for (i = 0; i < loop->n_fds; i++)
+ loop->fds[i].revents = 0;
+ loop->revents_filled = FALSE;
+
+ loop->timeout = -1;
+ /* cached checks first */
+ need_dispatch = master_need_reflow || master_need_process;
+ /* lengthy query */
+ if (!need_dispatch)
+ need_dispatch = _engine_job_pending ();
+ /* invoke custom poll checks */
+ if (!need_dispatch)
+ {
+ master_poll_check (&loop->timeout, FALSE);
+ need_dispatch = master_need_process;
+ }
+ if (need_dispatch)
+ loop->timeout = 0;
+
+ MAS_DEBUG ("PREPARE: need_dispatch=%u timeout=%6ld n_fds=%u",
+ need_dispatch,
+ loop->timeout, loop->n_fds);
+
+ return need_dispatch;
+}
+
+gboolean
+_engine_master_check (const GslEngineLoop *loop)
+{
+ gboolean need_dispatch;
+
+ g_return_val_if_fail (loop != NULL, FALSE);
+ g_return_val_if_fail (loop->n_fds == master_n_pollfds, FALSE);
+ g_return_val_if_fail (loop->fds == master_pollfds, FALSE);
+ if (loop->n_fds)
+ g_return_val_if_fail (loop->revents_filled == TRUE, FALSE);
+
+ /* cached checks first */
+ need_dispatch = master_need_reflow || master_need_process;
+ /* lengthy query */
+ if (!need_dispatch)
+ need_dispatch = _engine_job_pending ();
+ /* invoke custom poll checks */
+ if (!need_dispatch)
+ {
+ glong dummy = -1;
+
+ master_poll_check (&dummy, TRUE);
+ need_dispatch = master_need_process;
+ }
+
+ MAS_DEBUG ("CHECK: need_dispatch=%u", need_dispatch);
+
+ return need_dispatch;
+}
+
+void
+_engine_master_dispatch_jobs (void)
+{
+ GslJob *job;
+
+ job = _engine_pop_job ();
+ while (job)
+ {
+ master_process_job (job);
+ job = _engine_pop_job (); /* have to process _all_ jobs */
+ }
+}
+
+void
+_engine_master_dispatch (void)
+{
+ /* processing has prime priority, but we can't process the
+ * network, until all jobs have been handled and if necessary
+ * rescheduled the network.
+ * that's why we have to handle everything at once and can't
+ * preliminarily return after just handling jobs or rescheduling.
+ */
+ _engine_master_dispatch_jobs ();
+ if (master_need_reflow)
+ master_reschedule_flow ();
+ if (master_need_process)
+ master_process_flow ();
+}
+
+void
+_engine_master_thread (gpointer data)
+{
+ gboolean run = TRUE;
+
+ /* assert sane configuration checks, since we're simply casting structures */
+ g_assert (sizeof (struct pollfd) == sizeof (GPollFD) &&
+ G_STRUCT_OFFSET (GPollFD, fd) == G_STRUCT_OFFSET (struct pollfd, fd) &&
+ G_STRUCT_OFFSET (GPollFD, events) == G_STRUCT_OFFSET (struct pollfd, events) &&
+ G_STRUCT_OFFSET (GPollFD, revents) == G_STRUCT_OFFSET (struct pollfd, revents));
+
+ /* add the thread wakeup pipe to master pollfds, so we get woken
+ * up in time (even though we evaluate the pipe contents later)
+ */
+ gsl_thread_get_pollfd (master_pollfds);
+ master_n_pollfds += 1;
+ master_pollfds_changed = TRUE;
+
+ toyprof_stampinit ();
+
+ while (run)
+ {
+ GslEngineLoop loop;
+ gboolean need_dispatch;
+
+ need_dispatch = _engine_master_prepare (&loop);
+
+ if (!need_dispatch)
+ {
+ gint err;
+
+ err = poll ((struct pollfd*) loop.fds, loop.n_fds, loop.timeout);
+
+ if (err >= 0)
+ loop.revents_filled = TRUE;
+ else
+ g_printerr (G_STRLOC ": poll() error: %s\n", g_strerror (errno));
+
+ if (loop.revents_filled)
+ need_dispatch = _engine_master_check (&loop);
+ }
+
+ if (need_dispatch)
+ _engine_master_dispatch ();
+
+ /* handle thread pollfd messages */
+ run = gsl_thread_sleep (0);
+ }
+}
+/* vim:set ts=8 sts=2 sw=2: */
diff --git a/flow/gsl/gslopmaster.h b/flow/gsl/gslopmaster.h
new file mode 100644
index 0000000..69cc3f8
--- /dev/null
+++ b/flow/gsl/gslopmaster.h
@@ -0,0 +1,42 @@
+/* GSL Engine - Flow module operation engine
+ * Copyright (C) 2001 Tim Janik
+ *
+ * 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.
+ */
+#ifndef __GSL_ENGINE_MASTER_H__
+#define __GSL_ENGINE_MASTER_H__
+
+#include <gsl/gslengine.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* --- internal (EngineThread) --- */
+gboolean _engine_master_prepare (GslEngineLoop *loop);
+gboolean _engine_master_check (const GslEngineLoop *loop);
+void _engine_master_dispatch_jobs (void);
+void _engine_master_dispatch (void);
+void _engine_master_thread (gpointer data);
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_ENGINE_MASTER_H__ */
diff --git a/flow/gsl/gslopnode.h b/flow/gsl/gslopnode.h
new file mode 100644
index 0000000..3e236e5
--- /dev/null
+++ b/flow/gsl/gslopnode.h
@@ -0,0 +1,247 @@
+/* GSL Engine - Flow module operation engine
+ * Copyright (C) 2001 Tim Janik
+ *
+ * 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.
+ */
+#ifndef __GSL_ENGINE_NODE_H__
+#define __GSL_ENGINE_NODE_H__
+
+#include "gslengine.h"
+#include "gsloputil.h"
+#include "gslcommon.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+
+#define ENGINE_NODE(module) ((EngineNode*) (module))
+#define ENGINE_NODE_N_OSTREAMS(node) ((node)->module.klass->n_ostreams)
+#define ENGINE_NODE_N_ISTREAMS(node) ((node)->module.klass->n_istreams)
+#define ENGINE_NODE_N_JSTREAMS(node) ((node)->module.klass->n_jstreams)
+#define ENGINE_NODE_IS_CONSUMER(node) ((node)->is_consumer && \
+ (node)->output_nodes == NULL)
+#define ENGINE_NODE_IS_DEFERRED(node) (FALSE)
+#define ENGINE_NODE_IS_SCHEDULED(node) (ENGINE_NODE (node)->sched_tag)
+#define ENGINE_NODE_IS_CHEAP(node) (((node)->module.klass->mflags & GSL_COST_CHEAP) != 0)
+#define ENGINE_NODE_IS_EXPENSIVE(node) (((node)->module.klass->mflags & GSL_COST_EXPENSIVE) != 0)
+#define ENGINE_NODE_LOCK(node) gsl_rec_mutex_lock (&(node)->rec_mutex)
+#define ENGINE_NODE_UNLOCK(node) gsl_rec_mutex_unlock (&(node)->rec_mutex)
+
+
+/* --- debugging and messages --- */
+#define ENG_DEBUG GSL_DEBUG_FUNCTION (GSL_MSG_ENGINE, NULL)
+#define MAS_DEBUG GSL_DEBUG_FUNCTION (GSL_MSG_MASTER, NULL)
+#define JOB_DEBUG GSL_DEBUG_FUNCTION (GSL_MSG_JOBS, NULL)
+#define SCHED_DEBUG GSL_DEBUG_FUNCTION (GSL_MSG_SCHED, NULL)
+
+
+/* --- transactions --- */
+typedef union _EngineFlowJob EngineFlowJob;
+typedef enum {
+ ENGINE_JOB_NOP,
+ ENGINE_JOB_INTEGRATE,
+ ENGINE_JOB_DISCARD,
+ ENGINE_JOB_ICONNECT,
+ ENGINE_JOB_JCONNECT,
+ ENGINE_JOB_IDISCONNECT,
+ ENGINE_JOB_JDISCONNECT,
+ ENGINE_JOB_SET_CONSUMER,
+ ENGINE_JOB_UNSET_CONSUMER,
+ ENGINE_JOB_ACCESS,
+ ENGINE_JOB_ADD_POLL,
+ ENGINE_JOB_REMOVE_POLL,
+ ENGINE_JOB_FLOW_JOB,
+ ENGINE_JOB_DEBUG,
+ ENGINE_JOB_LAST
+} EngineJobType;
+struct _GslJob
+{
+ EngineJobType job_id;
+ GslJob *next;
+ union {
+ EngineNode *node;
+ struct {
+ EngineNode *dest_node;
+ guint dest_ijstream;
+ EngineNode *src_node;
+ guint src_ostream;
+ } connection;
+ struct {
+ EngineNode *node;
+ GslAccessFunc access_func;
+ gpointer data;
+ GslFreeFunc free_func;
+ } access;
+ struct {
+ GslPollFunc poll_func;
+ gpointer data;
+ GslFreeFunc free_func;
+ guint n_fds;
+ GPollFD *fds;
+ } poll;
+ struct {
+ EngineNode *node;
+ EngineFlowJob *fjob;
+ } flow_job;
+ gchar *debug;
+ } data;
+};
+struct _GslTrans
+{
+ GslJob *jobs_head;
+ GslJob *jobs_tail;
+ guint comitted : 1;
+ GslTrans *cqt_next; /* com-thread-queue */
+};
+typedef enum {
+ ENGINE_FLOW_JOB_NOP,
+ ENGINE_FLOW_JOB_SUSPEND,
+ ENGINE_FLOW_JOB_RESUME,
+ ENGINE_FLOW_JOB_ACCESS,
+ ENGINE_FLOW_JOB_LAST
+} EngineFlowJobType;
+typedef struct
+{
+ EngineFlowJobType fjob_id;
+ EngineFlowJob *next;
+ guint64 tick_stamp;
+} EngineFlowJobAny;
+typedef struct
+{
+ EngineFlowJobType fjob_id;
+ EngineFlowJob *next;
+ guint64 tick_stamp;
+ GslAccessFunc access_func;
+ gpointer data;
+ GslFreeFunc free_func;
+} EngineFlowJobAccess;
+union _EngineFlowJob
+{
+ EngineFlowJobType fjob_id;
+ EngineFlowJobAny any;
+ EngineFlowJobAccess access;
+};
+
+
+/* --- module nodes --- */
+typedef struct
+{
+ EngineNode *src_node;
+ guint src_stream; /* ostream of src_node */
+} EngineInput;
+typedef struct
+{
+ EngineNode *src_node;
+ guint src_stream; /* ostream of src_node */
+} EngineJInput;
+typedef struct
+{
+ gfloat *buffer;
+ guint n_outputs;
+} EngineOutput;
+struct _EngineNode /* fields sorted by order of processing access */
+{
+ GslModule module;
+
+ GslRecMutex rec_mutex; /* processing lock */
+ guint64 counter; /* <= GSL_TICK_STAMP */
+ EngineInput *inputs; /* [ENGINE_NODE_N_ISTREAMS()] */
+ EngineJInput **jinputs; /* [ENGINE_NODE_N_JSTREAMS()] */
+ EngineOutput *outputs; /* [ENGINE_NODE_N_OSTREAMS()] */
+
+ /* flow jobs */
+ EngineFlowJob *flow_jobs; /* active jobs */
+ EngineFlowJob *fjob_first, *fjob_last; /* trash list */
+
+ /* master-node-list */
+ EngineNode *mnl_next;
+ EngineNode *mnl_prev;
+ guint integrated : 1;
+ guint reconnected : 1;
+
+ guint is_consumer : 1;
+
+ /* scheduler */
+ guint sched_tag : 1;
+ guint sched_router_tag : 1;
+ guint sched_leaf_level;
+ EngineNode *toplevel_next; /* master-consumer-list, FIXME: overkill, using a GslRing is good enough */
+ GslRing *output_nodes; /* EngineNode* ring of nodes in ->outputs[] */
+};
+
+static void
+_engine_node_insert_flow_job (EngineNode *node,
+ EngineFlowJob *fjob)
+{
+ EngineFlowJob *last = NULL, *tmp = node->flow_jobs;
+
+ /* find next position */
+ while (tmp && tmp->any.tick_stamp <= fjob->any.tick_stamp)
+ {
+ last = tmp;
+ tmp = last->any.next;
+ }
+ /* insert before */
+ fjob->any.next = tmp;
+ if (last)
+ last->any.next = fjob;
+ else
+ node->flow_jobs = fjob;
+}
+
+static inline EngineFlowJob*
+_engine_node_pop_flow_job (EngineNode *node,
+ guint64 tick_stamp)
+{
+ EngineFlowJob *fjob = node->flow_jobs;
+
+ if_reject (fjob)
+ {
+ if (fjob->any.tick_stamp <= tick_stamp)
+ {
+ node->flow_jobs = fjob->any.next;
+
+ fjob->any.next = node->fjob_first;
+ node->fjob_first = fjob;
+ if (!node->fjob_last)
+ node->fjob_last = node->fjob_first;
+ }
+ else
+ fjob = NULL;
+ }
+
+ return fjob;
+}
+
+static inline guint64
+_engine_node_peek_flow_job_stamp (EngineNode *node)
+{
+ EngineFlowJob *fjob = node->flow_jobs;
+
+ if_reject (fjob)
+ return fjob->any.tick_stamp;
+
+ return GSL_MAX_TICK_STAMP;
+}
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_ENGINE_NODE_H__ */
diff --git a/flow/gsl/gslopschedule.c b/flow/gsl/gslopschedule.c
new file mode 100644
index 0000000..9102a41
--- /dev/null
+++ b/flow/gsl/gslopschedule.c
@@ -0,0 +1,582 @@
+/* GSL Engine - Flow module operation engine
+ * Copyright (C) 2001 Tim Janik
+ *
+ * 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.
+ */
+#include "gslopschedule.h"
+
+
+#include "gslcommon.h"
+
+
+/* --- functions --- */
+EngineSchedule*
+_engine_schedule_new (void)
+{
+ EngineSchedule *sched = gsl_new_struct0 (EngineSchedule, 1);
+
+ sched->n_items = 0;
+ sched->leaf_levels = 0;
+ sched->nodes = NULL;
+ sched->cycles = NULL;
+ sched->secured = FALSE;
+ sched->in_pqueue = FALSE;
+ sched->cur_leaf_level = ~0;
+ sched->cur_node = NULL;
+ sched->cur_cycle = NULL;
+
+ return sched;
+}
+
+static inline void
+unschedule_node (EngineSchedule *sched,
+ EngineNode *node)
+{
+ guint leaf_level;
+
+ g_return_if_fail (ENGINE_NODE_IS_SCHEDULED (node) == TRUE);
+ leaf_level = node->sched_leaf_level;
+ g_return_if_fail (leaf_level <= sched->leaf_levels);
+ g_return_if_fail (sched->n_items > 0);
+
+ SCHED_DEBUG ("unschedule_node(%p,%u)", node, leaf_level);
+ sched->nodes[leaf_level] = gsl_ring_remove (sched->nodes[leaf_level], node);
+ node->sched_leaf_level = 0;
+ node->sched_tag = FALSE;
+ if (node->flow_jobs)
+ _engine_mnl_reorder (node);
+ sched->n_items--;
+}
+
+static inline void
+unschedule_cycle (EngineSchedule *sched,
+ GslRing *ring)
+{
+ guint leaf_level;
+ GslRing *walk;
+
+ g_return_if_fail (ENGINE_NODE_IS_SCHEDULED (ENGINE_NODE (ring->data)) == TRUE);
+ leaf_level = ENGINE_NODE (ring->data)->sched_leaf_level;
+ g_return_if_fail (leaf_level <= sched->leaf_levels);
+ g_return_if_fail (sched->n_items > 0);
+
+ SCHED_DEBUG ("unschedule_cycle(%p,%u,%p)", ring->data, leaf_level, ring);
+ sched->nodes[leaf_level] = gsl_ring_remove (sched->nodes[leaf_level], ring);
+ for (walk = ring; walk; walk = gsl_ring_walk (ring, walk))
+ {
+ EngineNode *node = walk->data;
+
+ if (!ENGINE_NODE_IS_SCHEDULED (node))
+ g_warning ("node(%p) in schedule ring(%p) is untagged", node, ring);
+ node->sched_leaf_level = 0;
+ node->sched_tag = FALSE;
+ if (node->flow_jobs)
+ _engine_mnl_reorder (node);
+ }
+ sched->n_items--;
+}
+
+static void
+_engine_schedule_debug_dump (EngineSchedule *sched)
+{
+ g_printerr ("sched(%p) = {\n", sched);
+ if (sched)
+ {
+ guint i;
+
+ g_printerr (" n_items=%u, leaf_levels=%u, secured=%u,\n",
+ sched->n_items, sched->leaf_levels, sched->secured);
+ g_printerr (" in_pqueue=%u, cur_leaf_level=%u,\n",
+ sched->in_pqueue, sched->cur_leaf_level);
+ g_printerr (" cur_node=%p, cur_cycle=%p,\n",
+ sched->cur_node, sched->cur_cycle);
+ for (i = 0; i < sched->leaf_levels; i++)
+ {
+ GslRing *ring, *head = sched->nodes[i];
+
+ if (!head)
+ continue;
+ g_printerr (" { leaf_level=%u:", i);
+ for (ring = head; ring; ring = gsl_ring_walk (head, ring))
+ g_printerr (" node(%p(tag:%u))", ring->data, ((EngineNode*) ring->data)->sched_tag);
+ g_printerr (" },\n");
+ }
+ }
+ g_printerr ("};\n");
+}
+
+
+void
+_engine_schedule_clear (EngineSchedule *sched)
+{
+ guint i;
+
+ g_return_if_fail (sched != NULL);
+ g_return_if_fail (sched->secured == FALSE);
+ g_return_if_fail (sched->in_pqueue == FALSE);
+
+ for (i = 0; i < sched->leaf_levels; i++)
+ {
+ /* FIXME: each unschedule operation is a list walk, while we
+ * could easily leave the rings alone and free them as a whole
+ */
+ while (sched->nodes[i])
+ unschedule_node (sched, sched->nodes[i]->data);
+ while (sched->cycles[i])
+ unschedule_cycle (sched, sched->cycles[i]->data);
+ }
+ g_return_if_fail (sched->n_items == 0);
+}
+
+void
+_engine_schedule_destroy (EngineSchedule *sched)
+{
+ g_return_if_fail (sched != NULL);
+ g_return_if_fail (sched->secured == FALSE);
+ g_return_if_fail (sched->in_pqueue == FALSE);
+
+ _engine_schedule_clear (sched);
+ g_free (sched->nodes);
+ g_free (sched->cycles);
+ gsl_delete_struct (EngineSchedule, sched);
+}
+
+static void
+_engine_schedule_grow (EngineSchedule *sched,
+ guint leaf_level)
+{
+ guint ll = 1 << g_bit_storage (leaf_level); /* power2 growth alignment, ll >= leaf_level+1 */
+
+ if (sched->leaf_levels < ll)
+ {
+ guint i = sched->leaf_levels;
+
+ sched->leaf_levels = ll;
+ sched->nodes = g_renew (GslRing*, sched->nodes, sched->leaf_levels);
+ sched->cycles = g_renew (GslRing*, sched->cycles, sched->leaf_levels);
+ for (; i < sched->leaf_levels; i++)
+ {
+ sched->nodes[i] = NULL;
+ sched->cycles[i] = NULL;
+ }
+ }
+}
+
+void
+_engine_schedule_node (EngineSchedule *sched,
+ EngineNode *node,
+ guint leaf_level)
+{
+ g_return_if_fail (sched != NULL);
+ g_return_if_fail (sched->secured == FALSE);
+ g_return_if_fail (node != NULL);
+ g_return_if_fail (!ENGINE_NODE_IS_SCHEDULED (node));
+
+ SCHED_DEBUG ("schedule_node(%p,%u)", node, leaf_level);
+ node->sched_leaf_level = leaf_level;
+ node->sched_tag = TRUE;
+ if (node->flow_jobs)
+ _engine_mnl_reorder (node);
+ _engine_schedule_grow (sched, leaf_level);
+ /* could do 3-stage scheduling by expensiveness */
+ sched->nodes[leaf_level] = (ENGINE_NODE_IS_EXPENSIVE (node) ? gsl_ring_prepend : gsl_ring_append) (sched->nodes[leaf_level], node);
+ sched->n_items++;
+}
+
+void
+_engine_schedule_cycle (EngineSchedule *sched,
+ GslRing *cycle_nodes,
+ guint leaf_level)
+{
+ GslRing *walk;
+
+ g_return_if_fail (sched != NULL);
+ g_return_if_fail (sched->secured == FALSE);
+ g_return_if_fail (cycle_nodes != NULL);
+
+ for (walk = cycle_nodes; walk; walk = gsl_ring_walk (cycle_nodes, walk))
+ {
+ EngineNode *node = walk->data;
+
+ g_return_if_fail (!ENGINE_NODE_IS_SCHEDULED (node));
+ node->sched_leaf_level = leaf_level;
+ node->sched_tag = TRUE;
+ if (node->flow_jobs)
+ _engine_mnl_reorder (node);
+ }
+ _engine_schedule_grow (sched, leaf_level);
+ sched->cycles[leaf_level] = gsl_ring_prepend (sched->cycles[leaf_level], cycle_nodes);
+ sched->n_items++;
+}
+
+void
+_engine_schedule_restart (EngineSchedule *sched)
+{
+ g_return_if_fail (sched != NULL);
+ g_return_if_fail (sched->secured == TRUE);
+ g_return_if_fail (sched->cur_leaf_level == sched->leaf_levels);
+ g_return_if_fail (sched->cur_node == NULL);
+ g_return_if_fail (sched->cur_cycle == NULL);
+
+ sched->cur_leaf_level = 0;
+ if (sched->leaf_levels > 0)
+ {
+ sched->cur_node = sched->nodes[0];
+ sched->cur_cycle = sched->cycles[0];
+ }
+}
+
+void
+_engine_schedule_secure (EngineSchedule *sched)
+{
+ g_return_if_fail (sched != NULL);
+ g_return_if_fail (sched->secured == FALSE);
+
+ sched->secured = TRUE;
+ sched->cur_leaf_level = sched->leaf_levels;
+
+ if (gsl_debug_check (GSL_MSG_SCHED))
+ _engine_schedule_debug_dump (sched);
+}
+
+static void
+schedule_advance (EngineSchedule *sched)
+{
+ while (!sched->cur_node && !sched->cur_cycle && sched->cur_leaf_level < sched->leaf_levels)
+ {
+ sched->cur_leaf_level += 1;
+ if (sched->cur_leaf_level < sched->leaf_levels)
+ {
+ sched->cur_node = sched->nodes[sched->cur_leaf_level];
+ sched->cur_cycle = sched->cycles[sched->cur_leaf_level];
+ }
+ }
+}
+
+EngineNode*
+_engine_schedule_pop_node (EngineSchedule *sched)
+{
+ g_return_val_if_fail (sched != NULL, NULL);
+ g_return_val_if_fail (sched->secured == TRUE, NULL);
+ g_return_val_if_fail (sched->cur_leaf_level <= sched->leaf_levels, NULL);
+
+ do
+ {
+ guint leaf_level = sched->cur_leaf_level;
+
+ if (sched->cur_node)
+ {
+ EngineNode *node = sched->cur_node->data;
+
+ sched->cur_node = gsl_ring_walk (sched->nodes[leaf_level], sched->cur_node);
+ return node;
+ }
+ schedule_advance (sched);
+ }
+ while (sched->cur_node);
+
+ /* nothing to hand out, either we're empty or still have cycles pending */
+ return NULL;
+}
+
+GslRing*
+_engine_schedule_pop_cycle (EngineSchedule *sched)
+{
+ g_return_val_if_fail (sched != NULL, NULL);
+ g_return_val_if_fail (sched->secured == TRUE, NULL);
+ g_return_val_if_fail (sched->cur_leaf_level <= sched->leaf_levels, NULL);
+
+ do
+ {
+ guint leaf_level = sched->cur_leaf_level;
+
+ if (sched->cur_cycle)
+ {
+ GslRing *cycle = sched->cur_cycle->data;
+
+ sched->cur_cycle = gsl_ring_walk (sched->cycles[leaf_level], sched->cur_cycle);
+ return cycle;
+ }
+ schedule_advance (sched);
+ }
+ while (sched->cur_cycle);
+
+ /* nothing to hand out, either we're empty or still have nodes pending */
+ return NULL;
+}
+
+void
+_engine_schedule_unsecure (EngineSchedule *sched)
+{
+ g_return_if_fail (sched != NULL);
+ g_return_if_fail (sched->secured == TRUE);
+ g_return_if_fail (sched->in_pqueue == FALSE);
+ g_return_if_fail (sched->cur_leaf_level == sched->leaf_levels);
+ g_return_if_fail (sched->cur_node == NULL);
+ g_return_if_fail (sched->cur_cycle == NULL);
+
+ sched->secured = FALSE;
+ sched->cur_leaf_level = ~0;
+}
+
+
+/* --- depth scheduling --- */
+static GslRing*
+merge_untagged_node_lists_uniq (GslRing *ring1,
+ GslRing *ring2)
+{
+ GslRing *walk;
+
+ /* paranoid, ensure all nodes are untagged */
+ for (walk = ring2; walk; walk = gsl_ring_walk (ring2, walk))
+ {
+ EngineNode *node = walk->data;
+
+ g_assert (node->sched_router_tag == FALSE);
+ }
+
+ /* tag all nodes in list first */
+ for (walk = ring1; walk; walk = gsl_ring_walk (ring1, walk))
+ {
+ EngineNode *node = walk->data;
+
+ g_assert (node->sched_router_tag == FALSE); /* paranoid check */
+ node->sched_router_tag = TRUE;
+ }
+
+ /* merge list with missing (untagged) nodes */
+ for (walk = ring2; walk; walk = gsl_ring_walk (ring2, walk))
+ {
+ EngineNode *node = walk->data;
+
+ if (node->sched_router_tag == FALSE)
+ ring1 = gsl_ring_append (ring1, node);
+ }
+
+ /* untag all nodes */
+ for (walk = ring1; walk; walk = gsl_ring_walk (ring1, walk))
+ {
+ EngineNode *node = walk->data;
+
+ node->sched_router_tag = FALSE;
+ }
+ for (walk = ring2; walk; walk = gsl_ring_walk (ring2, walk))
+ {
+ EngineNode *node = walk->data;
+
+ node->sched_router_tag = FALSE;
+ }
+ gsl_ring_free (ring2);
+ return ring1;
+}
+
+static gboolean
+resolve_cycle (EngineCycle *cycle,
+ EngineNode *node,
+ GslRing **cycle_nodes_p)
+{
+ if (node != cycle->last)
+ return FALSE;
+ if (!cycle->seen_deferred_node)
+ {
+ g_error ("cycle without delay module: (%p)", cycle);
+ }
+ *cycle_nodes_p = merge_untagged_node_lists_uniq (*cycle_nodes_p, cycle->nodes);
+ cycle->nodes = NULL;
+ cycle->last = NULL;
+ return TRUE;
+}
+
+static gboolean
+master_resolve_cycles (EngineQuery *query,
+ EngineNode *node)
+{
+ GslRing *walk;
+ gboolean all_resolved = TRUE;
+
+ g_assert (query->cycles != NULL); /* paranoid */
+
+ walk = query->cycles;
+ while (walk)
+ {
+ GslRing *next = gsl_ring_walk (query->cycles, walk);
+ EngineCycle *cycle = walk->data;
+
+ if (resolve_cycle (cycle, node, &query->cycle_nodes))
+ {
+ g_assert (cycle->last == NULL); /* paranoid */
+ g_assert (cycle->nodes == NULL); /* paranoid */
+
+ gsl_delete_struct (EngineCycle, cycle);
+ query->cycles = gsl_ring_remove_node (query->cycles, walk);
+ }
+ else
+ all_resolved = FALSE;
+ walk = next;
+ }
+ if (all_resolved)
+ g_assert (query->cycles == NULL); /* paranoid */
+ return all_resolved;
+}
+
+static void
+query_add_cycle (EngineQuery *query,
+ EngineNode *dep,
+ EngineNode *node)
+{
+ EngineCycle *cycle = gsl_new_struct0 (EngineCycle, 1);
+
+ cycle->last = dep;
+ cycle->nodes = gsl_ring_prepend (NULL, node);
+ cycle->seen_deferred_node = ENGINE_NODE_IS_DEFERRED (node); /* dep will be checked when added to nodes */
+ query->cycles = gsl_ring_append (query->cycles, cycle);
+}
+
+static void
+query_merge_cycles (EngineQuery *query,
+ EngineQuery *child_query,
+ EngineNode *node)
+{
+ GslRing *walk;
+
+ g_assert (child_query->cycles != NULL); /* paranoid */
+
+ /* add node to all child cycles */
+ for (walk = child_query->cycles; walk; walk = gsl_ring_walk (child_query->cycles, walk))
+ {
+ EngineCycle *cycle = walk->data;
+
+ cycle->nodes = gsl_ring_prepend (cycle->nodes, node);
+ cycle->seen_deferred_node |= ENGINE_NODE_IS_DEFERRED (node);
+ }
+
+ /* merge child cycles into ours */
+ query->cycles = gsl_ring_concat (query->cycles, child_query->cycles);
+ child_query->cycles = NULL;
+
+ /* merge childs cycle nodes from resolved cycles into ours */
+ query->cycle_nodes = merge_untagged_node_lists_uniq (query->cycle_nodes, child_query->cycle_nodes);
+ child_query->cycle_nodes = NULL;
+}
+
+static void
+subschedule_query_node (EngineSchedule *schedule,
+ EngineNode *node,
+ EngineQuery *query)
+{
+ guint i, j, leaf_level = 0;
+
+ g_return_if_fail (node->sched_router_tag == FALSE);
+
+ SCHED_DEBUG ("start_query(%p)", node);
+ node->sched_router_tag = TRUE;
+ for (i = 0; i < ENGINE_NODE_N_ISTREAMS (node); i++)
+ {
+ EngineNode *child = node->inputs[i].src_node;
+
+ if (!child)
+ continue;
+ else if (ENGINE_NODE_IS_SCHEDULED (child))
+ {
+ leaf_level = MAX (leaf_level, child->sched_leaf_level + 1);
+ continue;
+ }
+ else if (child->sched_router_tag) /* cycle */
+ {
+ query_add_cycle (query, child, node);
+ }
+ else /* nice boy ;) */
+ {
+ EngineQuery child_query = { 0, };
+
+ subschedule_query_node (schedule, child, &child_query);
+ leaf_level = MAX (leaf_level, child_query.leaf_level + 1);
+ if (!child_query.cycles)
+ {
+ g_assert (child_query.cycle_nodes == NULL); /* paranoid */
+ _engine_schedule_node (schedule, child, child_query.leaf_level);
+ }
+ else if (master_resolve_cycles (&child_query, child))
+ {
+ g_assert (child == child_query.cycle_nodes->data); /* paranoid */
+ _engine_schedule_cycle (schedule, child_query.cycle_nodes, child_query.leaf_level);
+ child_query.cycle_nodes = NULL;
+ }
+ else
+ query_merge_cycles (query, &child_query, node);
+ g_assert (child_query.cycles == NULL); /* paranoid */
+ g_assert (child_query.cycle_nodes == NULL); /* paranoid */
+ }
+ }
+ for (j = 0; j < ENGINE_NODE_N_JSTREAMS (node); j++)
+ for (i = 0; i < node->module.jstreams[j].n_connections; i++)
+ {
+ EngineNode *child = node->jinputs[j][i].src_node;
+
+ if (ENGINE_NODE_IS_SCHEDULED (child))
+ {
+ leaf_level = MAX (leaf_level, child->sched_leaf_level + 1);
+ continue;
+ }
+ else if (child->sched_router_tag) /* cycle */
+ {
+ query_add_cycle (query, child, node);
+ }
+ else /* nice boy ;) */
+ {
+ EngineQuery child_query = { 0, };
+
+ subschedule_query_node (schedule, child, &child_query);
+ leaf_level = MAX (leaf_level, child_query.leaf_level + 1);
+ if (!child_query.cycles)
+ {
+ g_assert (child_query.cycle_nodes == NULL); /* paranoid */
+ _engine_schedule_node (schedule, child, child_query.leaf_level);
+ }
+ else if (master_resolve_cycles (&child_query, child))
+ {
+ g_assert (child == child_query.cycle_nodes->data); /* paranoid */
+ _engine_schedule_cycle (schedule, child_query.cycle_nodes, child_query.leaf_level);
+ child_query.cycle_nodes = NULL;
+ }
+ else
+ query_merge_cycles (query, &child_query, node);
+ g_assert (child_query.cycles == NULL); /* paranoid */
+ g_assert (child_query.cycle_nodes == NULL); /* paranoid */
+ }
+ }
+ query->leaf_level = leaf_level;
+ node->counter = GSL_TICK_STAMP;
+ node->sched_router_tag = FALSE;
+ SCHED_DEBUG ("end_query(%p)", node);
+}
+
+void
+_engine_schedule_consumer_node (EngineSchedule *schedule,
+ EngineNode *node)
+{
+ EngineQuery query = { 0, };
+
+ g_return_if_fail (schedule != NULL);
+ g_return_if_fail (schedule->secured == FALSE);
+ g_return_if_fail (node != NULL);
+ g_return_if_fail (ENGINE_NODE_IS_CONSUMER (node));
+
+ subschedule_query_node (schedule, node, &query);
+ g_assert (query.cycles == NULL); /* paranoid */
+ g_assert (query.cycle_nodes == NULL); /* paranoid */
+ _engine_schedule_node (schedule, node, query.leaf_level);
+}
diff --git a/flow/gsl/gslopschedule.h b/flow/gsl/gslopschedule.h
new file mode 100644
index 0000000..a2b5281
--- /dev/null
+++ b/flow/gsl/gslopschedule.h
@@ -0,0 +1,79 @@
+/* GSL Engine - Flow module operation engine
+ * Copyright (C) 2001 Tim Janik
+ *
+ * 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.
+ */
+#ifndef __GSL_ENGINE_SCHEDULE_H__
+#define __GSL_ENGINE_SCHEDULE_H__
+
+#include <gsl/gslopnode.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+typedef struct
+{
+ EngineNode *last; /* resolve node */
+ GslRing *nodes; /* of type EngineNode* */
+ guint seen_deferred_node : 1;
+} EngineCycle;
+typedef struct
+{
+ guint leaf_level;
+ GslRing *cycles; /* of type Cycle* */
+ GslRing *cycle_nodes; /* of type EngineNode* */
+} EngineQuery;
+struct _EngineSchedule
+{
+ guint n_items;
+ guint leaf_levels;
+ GslRing **nodes; /* EngineNode* */
+ GslRing **cycles; /* GslRing* */
+ guint secured : 1;
+ guint in_pqueue : 1;
+ guint cur_leaf_level;
+ GslRing *cur_node;
+ GslRing *cur_cycle;
+};
+#define GSL_SCHEDULE_NONPOPABLE(schedule) ((schedule)->cur_leaf_level >= (schedule)->leaf_levels)
+
+
+/* --- MasterThread --- */
+EngineSchedule* _engine_schedule_new (void);
+void _engine_schedule_clear (EngineSchedule *schedule);
+void _engine_schedule_destroy (EngineSchedule *schedule);
+void _engine_schedule_consumer_node (EngineSchedule *schedule,
+ EngineNode *node);
+void _engine_schedule_node (EngineSchedule *schedule,
+ EngineNode *node,
+ guint leaf_level);
+void _engine_schedule_cycle (EngineSchedule *schedule,
+ GslRing *cycle_nodes,
+ guint leaf_level);
+void _engine_schedule_secure (EngineSchedule *schedule);
+EngineNode* _engine_schedule_pop_node (EngineSchedule *schedule);
+GslRing* _engine_schedule_pop_cycle (EngineSchedule *schedule);
+void _engine_schedule_restart (EngineSchedule *schedule);
+void _engine_schedule_unsecure (EngineSchedule *schedule);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_ENGINE_SCHEDULE_H__ */
diff --git a/flow/gsl/gsloputil.c b/flow/gsl/gsloputil.c
new file mode 100644
index 0000000..9adce89
--- /dev/null
+++ b/flow/gsl/gsloputil.c
@@ -0,0 +1,721 @@
+/* GSL Engine - Flow module operation engine
+ * Copyright (C) 2001 Tim Janik
+ *
+ * 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.
+ */
+#include "gsloputil.h"
+
+#include "gslcommon.h"
+#include "gslopnode.h"
+#include "gslopschedule.h"
+#include "gslsignal.h"
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+
+
+/* --- UserThread --- */
+GslOStream*
+_engine_alloc_ostreams (guint n)
+{
+ if (n)
+ {
+ guint i = sizeof (GslOStream) * n + sizeof (gfloat) * gsl_engine_block_size () * n;
+ GslOStream *streams = gsl_alloc_memblock0 (i);
+ gfloat *buffers = (gfloat*) (streams + n);
+
+ for (i = 0; i < n; i++)
+ {
+ streams[i].values = buffers;
+ buffers += gsl_engine_block_size ();
+ }
+ return streams;
+ }
+ else
+ return NULL;
+}
+
+static void
+free_node (EngineNode *node)
+{
+ guint j;
+
+ g_return_if_fail (node != NULL);
+ g_return_if_fail (node->output_nodes == NULL);
+ g_return_if_fail (node->integrated == FALSE);
+ g_return_if_fail (node->sched_tag == FALSE);
+ g_return_if_fail (node->sched_router_tag == FALSE);
+
+ if (node->module.klass->free)
+ node->module.klass->free (node->module.user_data, node->module.klass);
+ gsl_rec_mutex_destroy (&node->rec_mutex);
+ if (node->module.ostreams)
+ {
+ guint n = ENGINE_NODE_N_OSTREAMS (node);
+ guint i = sizeof (GslOStream) * n + sizeof (gfloat) * gsl_engine_block_size () * n;
+
+ gsl_free_memblock (i, node->module.ostreams);
+ gsl_delete_structs (EngineOutput, ENGINE_NODE_N_OSTREAMS (node), node->outputs);
+ }
+ if (node->module.istreams)
+ {
+ gsl_delete_structs (GslIStream, ENGINE_NODE_N_ISTREAMS (node), node->module.istreams);
+ gsl_delete_structs (EngineInput, ENGINE_NODE_N_ISTREAMS (node), node->inputs);
+ }
+ for (j = 0; j < ENGINE_NODE_N_JSTREAMS (node); j++)
+ {
+ g_free (node->jinputs[j]);
+ g_free (node->module.jstreams[j].values);
+ }
+ if (node->module.jstreams)
+ {
+ gsl_delete_structs (GslJStream, ENGINE_NODE_N_JSTREAMS (node), node->module.jstreams);
+ gsl_delete_structs (EngineJInput*, ENGINE_NODE_N_JSTREAMS (node), node->jinputs);
+ }
+ gsl_delete_struct (EngineNode, node);
+}
+
+static void
+free_job (GslJob *job)
+{
+ g_return_if_fail (job != NULL);
+
+ switch (job->job_id)
+ {
+ case ENGINE_JOB_ACCESS:
+ if (job->data.access.free_func)
+ job->data.access.free_func (job->data.access.data);
+ break;
+ case ENGINE_JOB_DEBUG:
+ g_free (job->data.debug);
+ break;
+ case ENGINE_JOB_ADD_POLL:
+ case ENGINE_JOB_REMOVE_POLL:
+ g_free (job->data.poll.fds);
+ if (job->data.poll.free_func)
+ job->data.poll.free_func (job->data.poll.data);
+ break;
+ case ENGINE_JOB_DISCARD:
+ free_node (job->data.node);
+ break;
+ default: ;
+ }
+ gsl_delete_struct (GslJob, job);
+}
+
+static void
+free_flow_job (EngineFlowJob *fjob)
+{
+ switch (fjob->fjob_id)
+ {
+ case ENGINE_FLOW_JOB_SUSPEND:
+ case ENGINE_FLOW_JOB_RESUME:
+ gsl_delete_struct (EngineFlowJobAny, &fjob->any);
+ break;
+ case ENGINE_FLOW_JOB_ACCESS:
+ if (fjob->access.free_func)
+ fjob->access.free_func (fjob->access.data);
+ gsl_delete_struct (EngineFlowJobAccess, &fjob->access);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+void
+_engine_free_trans (GslTrans *trans)
+{
+ GslJob *job;
+
+ g_return_if_fail (trans != NULL);
+ g_return_if_fail (trans->comitted == FALSE);
+ if (trans->jobs_tail)
+ g_return_if_fail (trans->jobs_tail->next == NULL); /* paranoid */
+
+ job = trans->jobs_head;
+ while (job)
+ {
+ GslJob *tmp = job->next;
+
+ free_job (job);
+ job = tmp;
+ }
+ gsl_delete_struct (GslTrans, trans);
+}
+
+
+/* -- master node list --- */
+static EngineNode *master_node_list_head = NULL;
+static EngineNode *master_node_list_tail = NULL;
+
+EngineNode*
+_engine_mnl_head (void)
+{
+ return master_node_list_head;
+}
+
+void
+_engine_mnl_remove (EngineNode *node)
+{
+ g_return_if_fail (node->integrated == TRUE);
+
+ node->integrated = FALSE;
+ /* remove */
+ if (node->mnl_prev)
+ node->mnl_prev->mnl_next = node->mnl_next;
+ else
+ master_node_list_head = node->mnl_next;
+ if (node->mnl_next)
+ node->mnl_next->mnl_prev = node->mnl_prev;
+ else
+ master_node_list_tail = node->mnl_prev;
+ node->mnl_prev = NULL;
+ node->mnl_next = NULL;
+}
+
+void
+_engine_mnl_integrate (EngineNode *node)
+{
+ g_return_if_fail (node->integrated == FALSE);
+ g_return_if_fail (node->flow_jobs == NULL);
+
+ node->integrated = TRUE;
+ /* append */
+ if (master_node_list_tail)
+ master_node_list_tail->mnl_next = node;
+ node->mnl_prev = master_node_list_tail;
+ master_node_list_tail = node;
+ if (!master_node_list_head)
+ master_node_list_head = master_node_list_tail;
+ g_assert (node->mnl_next == NULL);
+}
+
+void
+_engine_mnl_reorder (EngineNode *node)
+{
+ EngineNode *sibling;
+
+ g_return_if_fail (node->integrated == TRUE);
+
+ /* the master node list is partially sorted. that is, all
+ * nodes which are not scheduled and have pending flow_jobs
+ * are agglomerated at the head.
+ */
+ sibling = node->mnl_prev ? node->mnl_prev : node->mnl_next;
+ if (sibling && GSL_MNL_HEAD_NODE (node) != GSL_MNL_HEAD_NODE (sibling))
+ {
+ /* remove */
+ if (node->mnl_prev)
+ node->mnl_prev->mnl_next = node->mnl_next;
+ else
+ master_node_list_head = node->mnl_next;
+ if (node->mnl_next)
+ node->mnl_next->mnl_prev = node->mnl_prev;
+ else
+ master_node_list_tail = node->mnl_prev;
+ if (GSL_MNL_HEAD_NODE (node)) /* move towards head */
+ {
+ /* prepend to non-NULL list */
+ master_node_list_head->mnl_prev = node;
+ node->mnl_next = master_node_list_head;
+ master_node_list_head = node;
+ node->mnl_prev = NULL;
+ }
+ else /* move towards tail */
+ {
+ /* append to non-NULL list */
+ master_node_list_tail->mnl_next = node;
+ node->mnl_prev = master_node_list_tail;
+ master_node_list_tail = node;
+ node->mnl_next = NULL;
+ }
+ }
+}
+
+
+/* --- const value blocks --- */
+typedef struct
+{
+ guint n_nodes;
+ gfloat **nodes;
+ guint8 *nodes_used;
+} ConstValuesArray;
+
+static const guint8 CONST_VALUES_EXPIRE = 16; /* expire value after being unused for 16 times */
+
+static inline gfloat**
+const_values_lookup_nextmost (ConstValuesArray *array,
+ gfloat key_value)
+{
+ guint n_nodes = array->n_nodes;
+
+ if (n_nodes > 0)
+ {
+ gfloat **nodes = array->nodes;
+ gfloat **check;
+
+ nodes -= 1;
+ do
+ {
+ guint i;
+ register gfloat cmp;
+
+ i = (n_nodes + 1) >> 1;
+ check = nodes + i;
+ cmp = key_value - **check;
+ if (cmp > GSL_SIGNAL_EPSILON)
+ {
+ n_nodes -= i;
+ nodes = check;
+ }
+ else if (cmp < -GSL_SIGNAL_EPSILON)
+ n_nodes = i - 1;
+ else /* cmp ~==~ 0.0 */
+ return check; /* matched */
+ }
+ while (n_nodes);
+
+ return check; /* nextmost */
+ }
+
+ return NULL;
+}
+
+static inline guint
+upper_power2 (guint number)
+{
+ return gsl_alloc_upper_power2 (MAX (number, 8));
+}
+
+static inline void
+const_values_insert (ConstValuesArray *array,
+ guint index,
+ gfloat *value_block)
+{
+ if (array->n_nodes == 0)
+ {
+ guint new_size = upper_power2 (sizeof (gfloat*));
+
+ array->nodes = g_realloc (array->nodes, new_size);
+ array->nodes_used = g_realloc (array->nodes_used, new_size / sizeof (gfloat*));
+ array->n_nodes = 1;
+
+ g_assert (index == 0);
+ }
+ else
+ {
+ guint n_nodes = array->n_nodes++;
+
+ if (*array->nodes[index] < *value_block)
+ index++;
+
+ if (1)
+ {
+ guint new_size = upper_power2 (array->n_nodes * sizeof (gfloat*));
+ guint old_size = upper_power2 (n_nodes * sizeof (gfloat*));
+
+ if (new_size != old_size)
+ {
+ array->nodes = g_realloc (array->nodes, new_size);
+ array->nodes_used = g_realloc (array->nodes_used, new_size / sizeof(gfloat*));
+ }
+ }
+ g_memmove (array->nodes + index + 1, array->nodes + index, (n_nodes - index) * sizeof (array->nodes[0]));
+ g_memmove (array->nodes_used + index + 1, array->nodes_used + index, (n_nodes - index) * sizeof (array->nodes_used[0]));
+ }
+
+ array->nodes[index] = value_block;
+ array->nodes_used[index] = CONST_VALUES_EXPIRE;
+}
+
+static ConstValuesArray cvalue_array = { 0, NULL, NULL };
+
+gfloat*
+gsl_engine_const_values (gfloat value)
+{
+ extern const gfloat gsl_engine_master_zero_block[];
+ gfloat **block;
+
+ if (fabs (value) < GSL_SIGNAL_EPSILON)
+ return (gfloat*) gsl_engine_master_zero_block;
+
+ block = const_values_lookup_nextmost (&cvalue_array, value);
+
+ /* found correct match? */
+ if (block && fabs (**block - value) < GSL_SIGNAL_EPSILON)
+ {
+ cvalue_array.nodes_used[block - cvalue_array.nodes] = CONST_VALUES_EXPIRE;
+ return *block;
+ }
+ else
+ {
+ /* create new value block */
+ gfloat *values = g_new (gfloat, gsl_engine_block_size ());
+ guint i;
+
+ for (i = 0; i < gsl_engine_block_size (); i++)
+ values[i] = value;
+
+ if (block)
+ const_values_insert (&cvalue_array, block - cvalue_array.nodes, values);
+ else
+ const_values_insert (&cvalue_array, 0, values);
+
+ return values;
+ }
+}
+
+void
+_engine_recycle_const_values (void)
+{
+ gfloat **nodes = cvalue_array.nodes;
+ guint8 *used = cvalue_array.nodes_used;
+ guint count = cvalue_array.n_nodes, e = 0, i;
+
+ for (i = 0; i < count; i++)
+ {
+ used[i]--; /* invariant: use counts are never 0 */
+
+ if (used[i] == 0)
+ g_free (nodes[i]);
+ else /* preserve node */
+ {
+ if (e < i)
+ {
+ nodes[e] = nodes[i];
+ used[e] = used[i];
+ }
+ e++;
+ }
+ }
+ cvalue_array.n_nodes = e;
+}
+
+/* --- job transactions --- */
+static GslMutex cqueue_trans = { 0, };
+static GslTrans *cqueue_trans_pending_head = NULL;
+static GslTrans *cqueue_trans_pending_tail = NULL;
+static GslCond cqueue_trans_cond = { 0, };
+static GslTrans *cqueue_trans_trash = NULL;
+static GslTrans *cqueue_trans_active_head = NULL;
+static GslTrans *cqueue_trans_active_tail = NULL;
+static EngineFlowJob *cqueue_trash_fjobs = NULL;
+static GslJob *cqueue_trans_job = NULL;
+
+void
+_engine_enqueue_trans (GslTrans *trans)
+{
+ g_return_if_fail (trans != NULL);
+ g_return_if_fail (trans->comitted == TRUE);
+ g_return_if_fail (trans->jobs_head != NULL);
+ g_return_if_fail (trans->cqt_next == NULL);
+
+ GSL_SPIN_LOCK (&cqueue_trans);
+ if (cqueue_trans_pending_tail)
+ {
+ cqueue_trans_pending_tail->cqt_next = trans;
+ cqueue_trans_pending_tail->jobs_tail->next = trans->jobs_head;
+ }
+ else
+ cqueue_trans_pending_head = trans;
+ cqueue_trans_pending_tail = trans;
+ GSL_SPIN_UNLOCK (&cqueue_trans);
+ gsl_cond_signal (&cqueue_trans_cond);
+}
+
+void
+_engine_wait_on_trans (void)
+{
+ GSL_SPIN_LOCK (&cqueue_trans);
+ while (cqueue_trans_pending_head || cqueue_trans_active_head)
+ gsl_cond_wait (&cqueue_trans_cond, &cqueue_trans);
+ GSL_SPIN_UNLOCK (&cqueue_trans);
+}
+
+gboolean
+_engine_job_pending (void)
+{
+ gboolean pending = cqueue_trans_job != NULL;
+
+ if (!pending)
+ {
+ GSL_SPIN_LOCK (&cqueue_trans);
+ pending = cqueue_trans_pending_head != NULL;
+ GSL_SPIN_UNLOCK (&cqueue_trans);
+ }
+ return pending;
+}
+
+GslJob*
+_engine_pop_job (void) /* (glong max_useconds) */
+{
+ /* clean up if necessary and try fetching new jobs */
+ if (!cqueue_trans_job)
+ {
+ if (cqueue_trans_active_head)
+ {
+ GSL_SPIN_LOCK (&cqueue_trans);
+ /* get rid of processed transaction and
+ * signal UserThread which might be in
+ * op_com_wait_on_trans()
+ */
+ cqueue_trans_active_tail->cqt_next = cqueue_trans_trash;
+ cqueue_trans_trash = cqueue_trans_active_head;
+ /* fetch new transaction */
+ cqueue_trans_active_head = cqueue_trans_pending_head;
+ cqueue_trans_active_tail = cqueue_trans_pending_tail;
+ cqueue_trans_pending_head = NULL;
+ cqueue_trans_pending_tail = NULL;
+ GSL_SPIN_UNLOCK (&cqueue_trans);
+ gsl_cond_signal (&cqueue_trans_cond);
+ }
+ else
+ {
+ GSL_SPIN_LOCK (&cqueue_trans);
+ /* fetch new transaction */
+ cqueue_trans_active_head = cqueue_trans_pending_head;
+ cqueue_trans_active_tail = cqueue_trans_pending_tail;
+ cqueue_trans_pending_head = NULL;
+ cqueue_trans_pending_tail = NULL;
+ GSL_SPIN_UNLOCK (&cqueue_trans);
+ }
+ cqueue_trans_job = cqueue_trans_active_head ? cqueue_trans_active_head->jobs_head : NULL;
+ }
+
+ /* pick new job and out of here */
+ if (cqueue_trans_job)
+ {
+ GslJob *job = cqueue_trans_job;
+
+ cqueue_trans_job = job->next;
+ return job;
+ }
+
+#if 0
+ /* wait until jobs are present */
+ if (max_useconds != 0)
+ {
+ GSL_SPIN_LOCK (&cqueue_trans);
+ if (!cqueue_trans_pending_head)
+ gsl_cond_wait_timed (&cqueue_trans_cond,
+ &cqueue_trans,
+ max_useconds);
+ GSL_SPIN_UNLOCK (&cqueue_trans);
+
+ /* there may be jobs now, start from scratch */
+ return op_com_pop_job_timed (max_useconds < 0 ? -1 : 0);
+ }
+#endif
+
+ /* time expired, no jobs... */
+ return NULL;
+}
+
+
+/* --- user thread garbage collection --- */
+/**
+ * gsl_engine_garbage_collect
+ *
+ * GSL Engine user thread function. Collects processed jobs
+ * and transactions from the engine and frees them, this
+ * involves callback invocation of GslFreeFunc() functions,
+ * e.g. from gsl_job_access() or gsl_flow_job_access()
+ * jobs.
+ * This function may only be called from the user thread,
+ * as GslFreeFunc() functions are guranteed to be executed
+ * in the user thread.
+ */
+void
+gsl_engine_garbage_collect (void)
+{
+ GslTrans *trans;
+ EngineFlowJob *fjobs;
+
+ GSL_SPIN_LOCK (&cqueue_trans);
+ trans = cqueue_trans_trash;
+ cqueue_trans_trash = NULL;
+ fjobs = cqueue_trash_fjobs;
+ cqueue_trash_fjobs = NULL;
+ GSL_SPIN_UNLOCK (&cqueue_trans);
+
+ while (trans)
+ {
+ GslTrans *t = trans;
+
+ trans = t->cqt_next;
+ t->cqt_next = NULL;
+ t->jobs_tail->next = NULL;
+ t->comitted = FALSE;
+ _engine_free_trans (t);
+ }
+
+ while (fjobs)
+ {
+ EngineFlowJob *j = fjobs;
+
+ fjobs = j->any.next;
+ j->any.next = NULL;
+ free_flow_job (j);
+ }
+}
+
+
+/* --- node processing queue --- */
+static GslMutex pqueue_mutex = { 0, };
+static EngineSchedule *pqueue_schedule = NULL;
+static guint pqueue_n_nodes = 0;
+static guint pqueue_n_cycles = 0;
+static GslCond pqueue_done_cond = { 0, };
+static EngineFlowJob *pqueue_trash_fjobs_first = NULL;
+static EngineFlowJob *pqueue_trash_fjobs_last = NULL;
+
+void
+_engine_set_schedule (EngineSchedule *sched)
+{
+ g_return_if_fail (sched != NULL);
+ g_return_if_fail (sched->secured == TRUE);
+
+ GSL_SPIN_LOCK (&pqueue_mutex);
+ if_reject (pqueue_schedule)
+ {
+ GSL_SPIN_UNLOCK (&pqueue_mutex);
+ g_warning (G_STRLOC ": schedule already set");
+ return;
+ }
+ pqueue_schedule = sched;
+ sched->in_pqueue = TRUE;
+ GSL_SPIN_UNLOCK (&pqueue_mutex);
+}
+
+void
+_engine_unset_schedule (EngineSchedule *sched)
+{
+ EngineFlowJob *trash_fjobs_first, *trash_fjobs_last;
+
+ g_return_if_fail (sched != NULL);
+
+ GSL_SPIN_LOCK (&pqueue_mutex);
+ if_reject (pqueue_schedule != sched)
+ {
+ GSL_SPIN_UNLOCK (&pqueue_mutex);
+ g_warning (G_STRLOC ": schedule(%p) not currently set", sched);
+ return;
+ }
+ if_reject (pqueue_n_nodes || pqueue_n_cycles)
+ g_warning (G_STRLOC ": schedule(%p) still busy", sched);
+
+ sched->in_pqueue = FALSE;
+ pqueue_schedule = NULL;
+ trash_fjobs_first = pqueue_trash_fjobs_first;
+ trash_fjobs_last = pqueue_trash_fjobs_last;
+ pqueue_trash_fjobs_first = NULL;
+ pqueue_trash_fjobs_last = NULL;
+ GSL_SPIN_UNLOCK (&pqueue_mutex);
+
+ if (trash_fjobs_first) /* move trash flow jobs */
+ {
+ GSL_SPIN_LOCK (&cqueue_trans);
+ trash_fjobs_last->any.next = cqueue_trash_fjobs;
+ cqueue_trash_fjobs = trash_fjobs_first;
+ GSL_SPIN_UNLOCK (&cqueue_trans);
+ }
+}
+
+EngineNode*
+_engine_pop_unprocessed_node (void)
+{
+ EngineNode *node;
+
+ GSL_SPIN_LOCK (&pqueue_mutex);
+ node = pqueue_schedule ? _engine_schedule_pop_node (pqueue_schedule) : NULL;
+ if (node)
+ pqueue_n_nodes += 1;
+ GSL_SPIN_UNLOCK (&pqueue_mutex);
+
+ if (node)
+ ENGINE_NODE_LOCK (node);
+
+ return node;
+}
+
+void
+_engine_push_processed_node (EngineNode *node)
+{
+ g_return_if_fail (node != NULL);
+ g_return_if_fail (pqueue_n_nodes > 0);
+ g_return_if_fail (ENGINE_NODE_IS_SCHEDULED (node));
+
+ GSL_SPIN_LOCK (&pqueue_mutex);
+ g_assert (pqueue_n_nodes > 0); /* paranoid */
+ if (node->fjob_first) /* collect trash flow jobs */
+ {
+ node->fjob_last->any.next = pqueue_trash_fjobs_first;
+ pqueue_trash_fjobs_first = node->fjob_first;
+ if (!pqueue_trash_fjobs_last)
+ pqueue_trash_fjobs_last = node->fjob_last;
+ node->fjob_first = NULL;
+ node->fjob_last = NULL;
+ }
+ pqueue_n_nodes -= 1;
+ ENGINE_NODE_UNLOCK (node);
+ if (!pqueue_n_nodes && !pqueue_n_cycles && GSL_SCHEDULE_NONPOPABLE (pqueue_schedule))
+ gsl_cond_signal (&pqueue_done_cond);
+ GSL_SPIN_UNLOCK (&pqueue_mutex);
+}
+
+GslRing*
+_engine_pop_unprocessed_cycle (void)
+{
+ return NULL;
+}
+
+void
+_engine_push_processed_cycle (GslRing *cycle)
+{
+ g_return_if_fail (cycle != NULL);
+ g_return_if_fail (pqueue_n_cycles > 0);
+ g_return_if_fail (ENGINE_NODE_IS_SCHEDULED (cycle->data));
+}
+
+void
+_engine_wait_on_unprocessed (void)
+{
+ GSL_SPIN_LOCK (&pqueue_mutex);
+ while (pqueue_n_nodes || pqueue_n_cycles || !GSL_SCHEDULE_NONPOPABLE (pqueue_schedule))
+ gsl_cond_wait (&pqueue_done_cond, &pqueue_mutex);
+ GSL_SPIN_UNLOCK (&pqueue_mutex);
+}
+
+
+/* --- initialization --- */
+void
+_gsl_init_engine_utils (void)
+{
+ static gboolean initialized = FALSE;
+
+ g_assert (initialized == FALSE); /* single invocation */
+ initialized++;
+
+ gsl_mutex_init (&cqueue_trans);
+ gsl_cond_init (&cqueue_trans_cond);
+ gsl_mutex_init (&pqueue_mutex);
+ gsl_cond_init (&pqueue_done_cond);
+}
+
+
+/* vim:set ts=8 sts=2 sw=2: */
diff --git a/flow/gsl/gsloputil.h b/flow/gsl/gsloputil.h
new file mode 100644
index 0000000..9089770
--- /dev/null
+++ b/flow/gsl/gsloputil.h
@@ -0,0 +1,86 @@
+/* GSL Engine - Flow module operation engine
+ * Copyright (C) 2001 Tim Janik
+ *
+ * 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.
+ */
+#ifndef __GSL_ENGINE_UTIL_H__
+#define __GSL_ENGINE_UTIL_H__
+
+#include <gsl/gsldefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* --- typedefs --- */
+typedef struct _EngineNode EngineNode;
+typedef struct _EngineSchedule EngineSchedule;
+
+
+/* --- UserThread --- */
+void _engine_free_trans (GslTrans *trans);
+GslOStream* _engine_alloc_ostreams (guint n);
+#if 0 /* gslengine.h: */
+void gsl_engine_garbage_collect (void);
+gfloat* gsl_engine_const_values (gfloat value);
+#endif
+
+
+/* --- MasterThread --- */
+void _engine_recycle_const_values (void);
+/* master node list */
+void _engine_mnl_remove (EngineNode *node);
+void _engine_mnl_reorder (EngineNode *node);
+void _engine_mnl_integrate (EngineNode *node);
+#define GSL_MNL_HEAD_NODE(node) ((node)->flow_jobs && !(node)->sched_tag)
+EngineNode* _engine_mnl_head (void);
+
+/* communication routines for threads:
+ * UserThread - main application
+ * MasterThread - op engine control thread
+ * SlaveThread - op engine calculation threads
+ *
+ * these functions are for _internal_ use of gslop*.c implementations
+ */
+
+/* --- job transactions --- */
+/* UserThread */
+void _engine_enqueue_trans (GslTrans *trans);
+GslTrans* _engine_collect_trans (void);
+void _engine_wait_on_trans (void);
+/* MasterThread */
+/* GslJob* _engine_pop_job_timed (glong max_useconds); */
+GslJob* _engine_pop_job (void);
+gboolean _engine_job_pending (void);
+
+
+/* --- node processing queue --- */
+void _engine_set_schedule (EngineSchedule *schedule);
+void _engine_unset_schedule (EngineSchedule *schedule);
+EngineNode* _engine_pop_unprocessed_node (void);
+void _engine_push_processed_node (EngineNode *node);
+GslRing* _engine_pop_unprocessed_cycle (void);
+void _engine_push_processed_cycle (GslRing *cycle);
+void _engine_wait_on_unprocessed (void);
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_ENGINE_UTIL_H__ */
diff --git a/flow/gsl/gsloscillator-aux.c b/flow/gsl/gsloscillator-aux.c
new file mode 100644
index 0000000..d755bc5
--- /dev/null
+++ b/flow/gsl/gsloscillator-aux.c
@@ -0,0 +1,214 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 1999, 2000-2002 Tim Janik
+ *
+ * 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 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.
+ */
+
+
+#define OSC_FLAGS (GSL_INCLUDER_CASE | OSC_INCLUDER_FLAGS)
+#define ISYNC1_OSYNC0 ((OSC_FLAGS & OSC_FLAG_ISYNC) && !(OSC_FLAGS & OSC_FLAG_OSYNC))
+#define ISYNC1_OSYNC1 ((OSC_FLAGS & OSC_FLAG_ISYNC) && (OSC_FLAGS & OSC_FLAG_OSYNC))
+#define ISYNC0_OSYNC1 ((OSC_FLAGS & OSC_FLAG_OSYNC) && !(OSC_FLAGS & OSC_FLAG_ISYNC))
+#define WITH_OSYNC (OSC_FLAGS & OSC_FLAG_OSYNC)
+#define WITH_FREQ (OSC_FLAGS & OSC_FLAG_FREQ)
+#define WITH_SMOD (OSC_FLAGS & OSC_FLAG_SELF_MOD)
+#define WITH_LMOD (OSC_FLAGS & OSC_FLAG_LINEAR_MOD)
+#define WITH_EMOD (OSC_FLAGS & OSC_FLAG_EXP_MOD)
+#define WITH_PWM_MOD (OSC_FLAGS & OSC_FLAG_PWM_MOD)
+#define PULSE_OSC (OSC_FLAGS & OSC_FLAG_PULSE_OSC)
+
+
+static void
+GSL_INCLUDER_FUNC (GslOscData *osc,
+ guint n_values,
+ const gfloat *ifreq,
+ const gfloat *mod_in,
+ const gfloat *sync_in,
+ const gfloat *pwm_in,
+ gfloat *mono_out,
+ gfloat *sync_out)
+{
+ gfloat last_sync_level = osc->last_sync_level;
+ gfloat last_pwm_level = osc->last_pwm_level;
+ gdouble last_freq_level = osc->last_freq_level;
+ guint32 cur_pos = osc->cur_pos;
+ guint32 last_pos = osc->last_pos;
+ guint32 sync_pos, pos_inc;
+ gfloat posm_strength, self_posm_strength;
+ gfloat *boundary = mono_out + n_values;
+ GslOscWave *wave = &osc->wave;
+
+ /* FIXME: should we do gsl_fpu_setround() here? */
+
+ pos_inc = gsl_dtoi (osc->last_freq_level * gsl_cent_factor (osc->config.fine_tune) * wave->freq_to_step);
+ sync_pos = osc->config.phase * wave->phase_to_pos;
+ posm_strength = pos_inc * osc->config.fm_strength;
+ self_posm_strength = pos_inc * osc->config.self_fm_strength;
+
+ /* do the mixing */
+ do
+ {
+ gfloat v;
+
+ /* handle syncs
+ */
+#if (ISYNC1_OSYNC0) /* input sync only */
+ {
+ gfloat sync_level = *sync_in++;
+ if_reject (GSL_SIGNAL_RAISING_EDGE (last_sync_level, sync_level))
+ cur_pos = sync_pos;
+ last_sync_level = sync_level;
+ }
+#elif (ISYNC1_OSYNC1) /* input and output sync */
+ {
+ gfloat sync_level = *sync_in++;
+ if_reject (GSL_SIGNAL_RAISING_EDGE (last_sync_level, sync_level))
+ {
+ cur_pos = sync_pos;
+ *sync_out++ = 1.0;
+ }
+ else /* figure output sync position */
+ {
+ guint is_sync = (sync_pos <= cur_pos) + (last_pos < sync_pos) + (cur_pos < last_pos);
+ *sync_out++ = is_sync >= 2 ? 1.0 : 0.0;
+ }
+ last_sync_level = sync_level;
+ }
+#elif (ISYNC0_OSYNC1) /* output sync only */
+ {
+ /* figure output sync position */
+ guint is_sync = (sync_pos <= cur_pos) + (last_pos < sync_pos) + (cur_pos < last_pos);
+ *sync_out++ = is_sync >= 2 ? 1.0 : 0.0;
+ }
+#endif
+
+ /* track frequency changes
+ */
+#if (WITH_FREQ)
+ {
+ gdouble freq_level = *ifreq++;
+ freq_level = GSL_SIGNAL_TO_FREQ (freq_level);
+ if (GSL_SIGNAL_FREQ_CHANGED (last_freq_level, freq_level))
+ {
+ if_reject (freq_level <= wave->min_freq || freq_level > wave->max_freq)
+ {
+ gdouble fcpos, flpos;
+ const gfloat *orig_values = wave->values;
+
+ fcpos = cur_pos * wave->ifrac_to_float;
+ flpos = last_pos * wave->ifrac_to_float;
+ gsl_osc_table_lookup (osc->config.table, freq_level, wave);
+ if (orig_values != wave->values) /* catch non-changes */
+ {
+ last_pos = flpos / wave->ifrac_to_float;
+ cur_pos = fcpos / wave->ifrac_to_float;
+ sync_pos = osc->config.phase * wave->phase_to_pos;
+ pos_inc = gsl_dtoi (freq_level * gsl_cent_factor (osc->config.fine_tune) * wave->freq_to_step);
+#if (PULSE_OSC)
+ osc->last_pwm_level = 0;
+ osc_update_pwm_offset (osc, osc->last_pwm_level);
+ last_pwm_level = osc->last_pwm_level;
+#endif
+ }
+ }
+ else
+ pos_inc = gsl_dtoi (freq_level * gsl_cent_factor (osc->config.fine_tune) * wave->freq_to_step);
+ posm_strength = pos_inc * osc->config.fm_strength;
+ self_posm_strength = pos_inc * osc->config.self_fm_strength;
+ last_freq_level = freq_level;
+ }
+ }
+#endif
+
+ /* track pulse witdh modulation
+ */
+#if (WITH_PWM_MOD)
+ {
+ gfloat pwm_level = *pwm_in++;
+ if (fabs (last_pwm_level - pwm_level) > 1.0 / 65536.0)
+ {
+ last_pwm_level = pwm_level;
+ osc_update_pwm_offset (osc, pwm_level);
+ }
+ }
+#endif
+
+ /* output signal calculation
+ */
+#if (PULSE_OSC) /* pulse width modulation oscillator */
+ {
+ guint32 tpos, ipos;
+ tpos = cur_pos >> wave->n_frac_bits;
+ ipos = (cur_pos - osc->pwm_offset) >> wave->n_frac_bits;
+ v = wave->values[tpos] - wave->values[ipos];
+ v = (v + osc->pwm_center) * osc->pwm_max;
+ }
+#else /* table read out and linear ipol */
+ {
+ guint32 tpos, ifrac;
+ gfloat ffrac, w;
+ tpos = cur_pos >> wave->n_frac_bits;
+ ifrac = cur_pos & wave->frac_bitmask;
+ ffrac = ifrac * wave->ifrac_to_float;
+ v = wave->values[tpos];
+ w = wave->values[tpos + 1];
+ v *= 1.0 - ffrac;
+ w *= ffrac;
+ v += w;
+ }
+#endif /* v = value_out done */
+ *mono_out++ = v;
+
+ /* position increment
+ */
+#if (WITH_OSYNC)
+ last_pos = cur_pos;
+#endif
+#if (WITH_SMOD) /* self modulation */
+ cur_pos += self_posm_strength * v;
+#endif
+#if (WITH_LMOD) /* linear fm */
+ {
+ gfloat mod_level = *mod_in++;
+ cur_pos += pos_inc + posm_strength * mod_level;
+ }
+#elif (WITH_EMOD) /* exponential fm */
+ {
+ gfloat mod_level = *mod_in++;
+ cur_pos += pos_inc * gsl_signal_exp2 (osc->config.fm_strength * mod_level);
+ }
+#else /* no modulation */
+ cur_pos += pos_inc;
+#endif
+ }
+ while (mono_out < boundary);
+
+ osc->last_pos = WITH_OSYNC ? last_pos : cur_pos;
+ osc->cur_pos = cur_pos;
+ osc->last_sync_level = last_sync_level;
+ osc->last_freq_level = last_freq_level;
+ osc->last_pwm_level = last_pwm_level;
+}
+
+#undef ISYNC1_OSYNC0
+#undef ISYNC1_OSYNC1
+#undef ISYNC0_OSYNC1
+#undef WITH_OSYNC
+#undef WITH_FREQ
+#undef WITH_SMOD
+#undef WITH_LMOD
+#undef WITH_EMOD
+#undef OSC_FLAGS
diff --git a/flow/gsl/gsloscillator.c b/flow/gsl/gsloscillator.c
new file mode 100644
index 0000000..0747cff
--- /dev/null
+++ b/flow/gsl/gsloscillator.c
@@ -0,0 +1,219 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 1999, 2000-2002 Tim Janik
+ *
+ * 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 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.
+ */
+#include "gsloscillator.h"
+
+#include "gslsignal.h"
+
+#define SIGNAL_LEVEL_INVAL (-2.0) /* trigger level-changed checks */
+
+
+/* --- functions --- */
+static inline void
+osc_update_pwm_offset (GslOscData *osc,
+ gfloat pulse_mod) /* -1..+1 */
+{
+ guint32 maxp_offs, minp_offs, mpos, tpos;
+ gfloat min, max, foffset;
+
+ /* figure actual pulse width (0..1) */
+ foffset = osc->config.pulse_width; /* 0..1 */
+ foffset += pulse_mod * osc->config.pulse_mod_strength;
+ foffset = CLAMP (foffset, 0.0, 1.0);
+
+ /* calculate pulse scaling range for this offset */
+ osc->pwm_offset = foffset * osc->wave.n_values;
+ osc->pwm_offset <<= osc->wave.n_frac_bits;
+
+ maxp_offs = (osc->wave.min_pos + osc->wave.n_values + osc->wave.max_pos) << (osc->wave.n_frac_bits - 1);
+ minp_offs = (osc->wave.max_pos + osc->wave.min_pos) << (osc->wave.n_frac_bits - 1);
+
+ mpos = maxp_offs + (osc->pwm_offset >> 1);
+ tpos = mpos >> osc->wave.n_frac_bits;
+ max = osc->wave.values[tpos];
+ mpos -= osc->pwm_offset;
+ tpos = mpos >> osc->wave.n_frac_bits;
+ max -= osc->wave.values[tpos];
+ mpos = minp_offs + (osc->pwm_offset >> 1);
+ tpos = mpos >> osc->wave.n_frac_bits;
+ min = osc->wave.values[tpos];
+ mpos -= osc->pwm_offset;
+ tpos = mpos >> osc->wave.n_frac_bits;
+ min -= osc->wave.values[tpos];
+ osc->pwm_center = (min + max) / -2.0;
+ min = fabs (min + osc->pwm_center);
+ max = fabs (max + osc->pwm_center);
+ max = MAX (max, min);
+ if_reject (max < GSL_FLOAT_MIN_NORMAL)
+ {
+ osc->pwm_center = foffset < 0.5 ? -1.0 : +1.0;
+ osc->pwm_max = 1.0;
+ }
+ else
+ osc->pwm_max = 1.0 / max;
+}
+
+
+/* --- generate processing function variants --- */
+#define OSC_FLAG_INVAL (0xffffffff)
+#define OSC_FLAG_ISYNC (1)
+#define OSC_FLAG_OSYNC (2)
+#define OSC_FLAG_FREQ (4)
+#define OSC_FLAG_SELF_MOD (8)
+#define OSC_FLAG_LINEAR_MOD (16)
+#define OSC_FLAG_EXP_MOD (32)
+#define OSC_FLAG_PWM_MOD (64)
+#define OSC_FLAG_PULSE_OSC (128)
+
+/* normal oscillator variants */
+#define OSC_INCLUDER_FLAGS 0
+#define GSL_INCLUDER_FIRST_CASE 0
+#define GSL_INCLUDER_LAST_CASE 63
+#define GSL_INCLUDER_NAME oscillator_process_normal
+#define GSL_INCLUDER_TABLE static void (*osc_process_table[]) (GslOscData*,guint, \
+ const gfloat*,const gfloat*,const gfloat*, \
+ const gfloat*,gfloat*,gfloat*)
+#define GSL_INCLUDER_FILE "gsloscillator-aux.c"
+#include "gslincluder.c"
+#undef OSC_INCLUDER_FLAGS
+
+/* pulse width modulation oscillator variants */
+#define OSC_INCLUDER_FLAGS OSC_FLAG_PULSE_OSC
+#define GSL_INCLUDER_FIRST_CASE 0
+#define GSL_INCLUDER_LAST_CASE 127
+#define GSL_INCLUDER_NAME oscillator_process_pulse
+#define GSL_INCLUDER_TABLE static void (*osc_process_pulse_table[]) (GslOscData*,guint, \
+ const gfloat*,const gfloat*,const gfloat*, \
+ const gfloat*,gfloat*,gfloat*)
+#define GSL_INCLUDER_FILE "gsloscillator-aux.c"
+#include "gslincluder.c"
+#undef OSC_INCLUDER_FLAGS
+
+
+/* --- functions --- */
+static inline void
+osc_process (GslOscData *osc,
+ guint n_values,
+ guint mode,
+ const gfloat *ifreq,
+ const gfloat *imod,
+ const gfloat *isync,
+ const gfloat *ipwm,
+ gfloat *mono_out,
+ gfloat *sync_out)
+{
+ mode |= isync ? OSC_FLAG_ISYNC : 0;
+ mode |= sync_out ? OSC_FLAG_OSYNC : 0;
+ mode |= ifreq ? OSC_FLAG_FREQ : 0;
+ if (osc->config.pulse_mod_strength > GSL_FLOAT_MIN_NORMAL)
+ mode |= ipwm ? OSC_FLAG_PWM_MOD : 0;
+ if (osc->config.self_fm_strength > GSL_FLOAT_MIN_NORMAL)
+ mode |= OSC_FLAG_SELF_MOD;
+ if (imod && osc->config.exponential_fm)
+ mode |= OSC_FLAG_EXP_MOD;
+ else if (imod)
+ mode |= OSC_FLAG_LINEAR_MOD;
+
+ if_reject (mode != osc->last_mode)
+ {
+ guint change_mask = osc->last_mode >= OSC_FLAG_INVAL ? OSC_FLAG_INVAL : osc->last_mode ^ mode;
+
+ if (change_mask & OSC_FLAG_FREQ)
+ {
+ gdouble fcpos, flpos;
+
+ fcpos = osc->cur_pos * osc->wave.ifrac_to_float;
+ flpos = osc->last_pos * osc->wave.ifrac_to_float;
+ osc->last_freq_level = osc->config.cfreq;
+ gsl_osc_table_lookup (osc->config.table, osc->last_freq_level, &osc->wave);
+ osc->last_pos = flpos / osc->wave.ifrac_to_float;
+ osc->cur_pos = fcpos / osc->wave.ifrac_to_float;
+ }
+ if (!(mode & OSC_FLAG_ISYNC))
+ osc->last_sync_level = 0;
+ if (mode & OSC_FLAG_PULSE_OSC)
+ {
+ osc->last_pwm_level = 0;
+ osc_update_pwm_offset (osc, osc->last_pwm_level);
+ }
+ osc->last_mode = mode;
+ }
+
+ /* invoke generated function variant */
+ if (mode & OSC_FLAG_PULSE_OSC)
+ osc_process_pulse_table[mode & ~OSC_FLAG_PULSE_OSC] (osc, n_values,
+ ifreq, imod, isync, ipwm,
+ mono_out, sync_out);
+ else
+ osc_process_table[mode] (osc, n_values,
+ ifreq, imod, isync, NULL,
+ mono_out, sync_out);
+}
+
+void
+gsl_osc_process (GslOscData *osc,
+ guint n_values,
+ const gfloat *ifreq,
+ const gfloat *imod,
+ const gfloat *isync,
+ gfloat *mono_out,
+ gfloat *sync_out)
+{
+ g_return_if_fail (osc != NULL);
+ g_return_if_fail (n_values > 0);
+ g_return_if_fail (mono_out != NULL);
+
+ if (osc->last_mode & OSC_FLAG_PULSE_OSC)
+ osc->last_mode = OSC_FLAG_INVAL;
+ osc_process (osc, n_values, 0,
+ ifreq, imod, isync, NULL,
+ mono_out, sync_out);
+}
+
+void
+gsl_osc_process_pulse (GslOscData *osc,
+ guint n_values,
+ const gfloat *ifreq,
+ const gfloat *imod,
+ const gfloat *isync,
+ const gfloat *ipwm,
+ gfloat *mono_out,
+ gfloat *sync_out)
+{
+ g_return_if_fail (osc != NULL);
+ g_return_if_fail (n_values > 0);
+ g_return_if_fail (mono_out != NULL);
+
+ if (!(osc->last_mode & OSC_FLAG_PULSE_OSC))
+ osc->last_mode = OSC_FLAG_INVAL;
+ osc_process (osc, n_values, OSC_FLAG_PULSE_OSC,
+ ifreq, imod, isync, ipwm,
+ mono_out, sync_out);
+}
+
+void
+gsl_osc_config (GslOscData *osc,
+ GslOscConfig *config)
+{
+ g_return_if_fail (osc != NULL);
+ g_return_if_fail (config != NULL);
+ g_return_if_fail (config->table != NULL);
+
+ osc->config = *config;
+ osc->last_mode = OSC_FLAG_INVAL;
+}
diff --git a/flow/gsl/gsloscillator.h b/flow/gsl/gsloscillator.h
new file mode 100644
index 0000000..24223fc
--- /dev/null
+++ b/flow/gsl/gsloscillator.h
@@ -0,0 +1,84 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 1999, 2000-2002 Tim Janik
+ *
+ * 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 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.
+ */
+#ifndef __GSL_OSCILLATOR_H__
+#define __GSL_OSCILLATOR_H__
+
+#include <gsl/gsldefs.h>
+#include <gsl/gslosctable.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* --- structures --- */
+typedef struct
+{
+ GslOscTable *table;
+ guint exponential_fm : 1;
+ gfloat fm_strength; /* linear: 0..1, exponential: n_octaves */
+ gfloat self_fm_strength; /* 0..1 */
+ gfloat phase; /* -0.5..+0.5 */
+ gfloat cfreq; /* for ifreq == NULL */
+ gfloat pulse_width; /* 0..1 */
+ gfloat pulse_mod_strength; /* 0..0.5 */
+ gint fine_tune; /* -100..+100 */
+} GslOscConfig;
+typedef struct
+{
+ GslOscConfig config;
+ guint last_mode;
+ guint32 cur_pos, last_pos;
+ gfloat last_sync_level;
+ gdouble last_freq_level;
+ gfloat last_pwm_level;
+ GslOscWave wave;
+ /* pwm */
+ guint32 pwm_offset;
+ gfloat pwm_max, pwm_center;
+} GslOscData;
+
+
+/* --- Oscillator --- */
+void gsl_osc_config (GslOscData *osc,
+ GslOscConfig *config);
+void gsl_osc_process (GslOscData *osc,
+ guint n_values,
+ const gfloat *ifreq,
+ const gfloat *imod,
+ const gfloat *isync,
+ gfloat *mono_out,
+ gfloat *sync_out);
+void gsl_osc_process_pulse (GslOscData *osc,
+ guint n_values,
+ const gfloat *ifreq,
+ const gfloat *imod,
+ const gfloat *isync,
+ const gfloat *ipwm,
+ gfloat *mono_out,
+ gfloat *sync_out);
+
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_OSCILLATOR_H__ */
diff --git a/flow/gsl/gslosctable.c b/flow/gsl/gslosctable.c
new file mode 100644
index 0000000..f3e096d
--- /dev/null
+++ b/flow/gsl/gslosctable.c
@@ -0,0 +1,626 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001-2002 Tim Janik
+ *
+ * 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 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.
+ */
+#include "gslosctable.h"
+
+#include <string.h>
+#include "gbsearcharray.h"
+#include "gslcommon.h"
+#include "gslmath.h"
+#include "gslfft.h"
+
+
+#define OSC_DEBUG GSL_DEBUG_FUNCTION (GSL_MSG_OSC, G_STRLOC)
+
+#define OSC_FREQ_EPSILON (1e-3) /* range within which frequencies are "equal" */
+
+/* compare mfreqs against each other, use an arbitrary sample rate
+ * for which OSC_FREQ_EPSILON makes sense
+ */
+#define CACHE_MATCH_FREQ(usr_mfreq, cache_mfreq) \
+ (fabs ((cache_mfreq) * 44107 - (usr_mfreq) * 44107) < OSC_FREQ_EPSILON)
+
+
+/* --- structures --- */
+typedef struct
+{
+ /* main key (osc and cache tables) */
+ gfloat mfreq; /* [0..0.5], mix_freq relative */
+ /* secondary key (cache tables) */
+ GslOscWaveForm wave_form;
+ guint8 *filter_func; /* just here for key indexing */
+ /* data */
+ guint ref_count;
+ guint min_pos, max_pos; /* pulse extension */
+ guint n_values;
+ const gfloat values[1]; /* flexible array */
+} OscTableEntry;
+
+
+/* --- prototypes --- */
+static gint cache_table_entry_locs_cmp (gconstpointer bsearch_node1, /* key */
+ gconstpointer bsearch_node2);
+static gint osc_table_entry_locs_cmp (gconstpointer bsearch_node1, /* key */
+ gconstpointer bsearch_node2);
+static void osc_wave_extrema_pos (guint n_values,
+ const gfloat *values,
+ guint *minp_p,
+ guint *maxp_p);
+void gsl_osc_cache_debug_dump (void);
+
+
+/* --- variables --- */
+static GBSearchArray *cache_entries = NULL;
+static const GBSearchConfig cache_taconfig = {
+ sizeof (OscTableEntry*),
+ cache_table_entry_locs_cmp,
+ 0
+};
+static const GBSearchConfig osc_taconfig = {
+ sizeof (OscTableEntry*),
+ osc_table_entry_locs_cmp,
+ 0
+};
+
+
+/* --- functions --- */
+static gint
+cache_table_entry_locs_cmp (gconstpointer bsearch_node1, /* key */
+ gconstpointer bsearch_node2)
+{
+ const OscTableEntry * const *ep1 = bsearch_node1;
+ const OscTableEntry * const *ep2 = bsearch_node2;
+ const OscTableEntry *e1 = *ep1;
+ const OscTableEntry *e2 = *ep2;
+
+ if (e1->wave_form == e2->wave_form)
+ {
+ if (e1->filter_func == e2->filter_func)
+ return G_BSEARCH_ARRAY_CMP (e1->mfreq, e2->mfreq);
+ else
+ return e1->filter_func > e2->filter_func ? 1 : -1;
+ }
+ else
+ return e1->wave_form > e2->wave_form ? 1 : -1;
+}
+
+static gint
+osc_table_entry_locs_cmp (gconstpointer bsearch_node1, /* key */
+ gconstpointer bsearch_node2)
+{
+ const OscTableEntry * const *ep1 = bsearch_node1;
+ const OscTableEntry * const *ep2 = bsearch_node2;
+ const OscTableEntry *e1 = *ep1;
+ const OscTableEntry *e2 = *ep2;
+
+ return G_BSEARCH_ARRAY_CMP (e1->mfreq, e2->mfreq);
+}
+
+static OscTableEntry*
+cache_table_entry_lookup_best (GslOscWaveForm wave_form,
+ guint8* filter_func,
+ gfloat mfreq)
+{
+ OscTableEntry key, *k = &key, **ep1 = NULL, **ep2, **ep3 = NULL;
+
+ key.mfreq = mfreq;
+ key.wave_form = wave_form;
+ key.filter_func = filter_func;
+
+ /* get exact match or a match which is one off into either direction */
+ ep2 = g_bsearch_array_lookup_sibling (cache_entries, &cache_taconfig, &k);
+ if (ep2)
+ {
+ guint i = g_bsearch_array_get_index (cache_entries, &cache_taconfig, ep2);
+
+ /* get siblings */
+ if (i > 0)
+ ep1 = g_bsearch_array_get_nth (cache_entries, &cache_taconfig, i - 1);
+ if (i + 1 < g_bsearch_array_get_n_nodes (cache_entries))
+ ep3 = g_bsearch_array_get_nth (cache_entries, &cache_taconfig, i + 1);
+
+ /* get rid of invalid matches, i.e. ones with:
+ * - a different wave
+ * - a different filter
+ * - a filter wider than required
+ */
+ if (ep1 && ((*ep1)->wave_form != wave_form ||
+ (*ep1)->filter_func != filter_func ||
+ (*ep1)->mfreq < mfreq))
+ ep1 = NULL;
+ if (ep3 && ((*ep3)->wave_form != wave_form ||
+ (*ep3)->filter_func != filter_func ||
+ (*ep3)->mfreq < mfreq))
+ ep3 = NULL;
+ if ((*ep2)->wave_form != wave_form ||
+ (*ep2)->filter_func != filter_func ||
+ (*ep2)->mfreq < mfreq)
+ {
+ /* collapse siblings, so that, if we have valid matches, ep2 is amongst them */
+ if (ep1)
+ {
+ ep2 = ep1;
+ ep1 = NULL;
+ }
+ else if (ep3)
+ {
+ ep2 = ep3;
+ ep3 = NULL;
+ }
+ else
+ ep2 = NULL; /* no valid match at all */
+ }
+ }
+
+ /* now figure best out of valid siblings */
+ if (ep2)
+ {
+ if (ep1 && fabs ((*ep1)->mfreq - mfreq) < fabs ((*ep2)->mfreq - mfreq))
+ ep2 = ep1;
+ if (ep3 && fabs ((*ep3)->mfreq - mfreq) < fabs ((*ep2)->mfreq - mfreq))
+ ep2 = ep3;
+ }
+ return ep2 ? *ep2 : NULL;
+}
+
+static OscTableEntry*
+osc_table_entry_lookup_best (const GslOscTable *table,
+ gfloat mfreq,
+ gfloat *min_mfreq)
+{
+ OscTableEntry key, *k = &key, **ep;
+ guint i;
+
+ /* get exact match or a match which is one off into either direction */
+ key.mfreq = mfreq;
+ ep = g_bsearch_array_lookup_sibling (table->entry_array, &osc_taconfig, &k);
+ if_reject (!ep)
+ return NULL; /* ugh, bad */
+
+ if (mfreq > (*ep)->mfreq) /* need better filter */
+ {
+ i = g_bsearch_array_get_index (table->entry_array, &osc_taconfig, ep);
+ if (i + 1 < g_bsearch_array_get_n_nodes (table->entry_array))
+ ep = g_bsearch_array_get_nth (table->entry_array, &osc_taconfig, i + 1);
+ else /* bad, might cause aliasing */
+ OSC_DEBUG ("lookup mismatch, aliasing possible: want_freq=%f got_freq=%f",
+ mfreq * table->mix_freq, (*ep)->mfreq * table->mix_freq);
+ }
+
+ if (min_mfreq)
+ {
+ /* fetch mfreq from previous */
+ i = g_bsearch_array_get_index (table->entry_array, &osc_taconfig, ep);
+ if (i > 0)
+ {
+ OscTableEntry **tp = g_bsearch_array_get_nth (table->entry_array, &osc_taconfig, i - 1);
+
+ *min_mfreq = (*tp)->mfreq;
+ }
+ else
+ *min_mfreq = 0;
+ }
+
+ return *ep;
+}
+
+static guint
+wave_table_size (GslOscWaveForm wave_form,
+ gfloat mfreq)
+{
+ /* have to return power of 2, and honour 8 <= size */
+
+ /* FIXME: decide on other table sizes
+ 10000: 256
+ 5000: 512
+ 2500: 1024
+ 1250: 2048
+ GSL_OSC_WAVE_SAW_FALL always huge buffers to guarantee pulse width stepping granularity
+ */
+
+ if (wave_form == GSL_OSC_WAVE_SAW_FALL)
+ return 8192;
+
+ return 2048;
+}
+
+static void
+fft_filter (guint n_values,
+ gfloat *values, /* [0..n_values], n_values/2 complex values */
+ gdouble scale_window,
+ double (*window) (double))
+{
+ guint i;
+
+ n_values >>= 1;
+ scale_window /= (gdouble) n_values;
+ for (i = 0; i <= n_values; i++)
+ {
+ gdouble w = window (i * scale_window);
+ values[i * 2] *= w;
+ values[i * 2 + 1] *= w;
+ }
+}
+
+static OscTableEntry*
+cache_table_ref_entry (GslOscWaveForm wave_form,
+ double (*filter_func) (double),
+ gfloat mfreq)
+{
+ OscTableEntry *e = cache_table_entry_lookup_best (wave_form, (guint8*) filter_func, mfreq);
+
+ if (e && !CACHE_MATCH_FREQ (mfreq, e->mfreq))
+ e = NULL;
+ if (!e)
+ {
+ guint size = wave_table_size (wave_form, mfreq);
+ gfloat *values, *fft, step, min, max;
+
+ /* size:
+ * - OscTableEntry already contains the first float values
+ * - we need n_values+1 adressable floats to provide values[0] == values[n_values]
+ */
+ e = g_malloc (sizeof (OscTableEntry) + sizeof (gfloat) * size);
+ values = (gfloat*) &e->values[0];
+ e->wave_form = wave_form;
+ e->filter_func = (guint8*) filter_func;
+ e->mfreq = mfreq;
+ e->ref_count = 1;
+ e->n_values = size;
+ gsl_osc_wave_fill_buffer (e->wave_form, e->n_values, values);
+
+ /* filter wave accordingly */
+ gsl_osc_wave_extrema (e->n_values, values, &min, &max);
+ fft = g_new (gfloat, e->n_values + 2); /* [0..n_values] for n_values/2 complex freqs */
+ gsl_power2_fftar_simple (e->n_values, values, fft);
+ step = e->mfreq * (gdouble) e->n_values;
+ fft_filter (e->n_values, fft, step, filter_func);
+ gsl_power2_fftsr_simple (e->n_values, fft, values);
+ g_free (fft);
+ gsl_osc_wave_normalize (e->n_values, values, (min + max) / 2, max);
+
+ /* provide values[0]==values[n_values] */
+ values[e->n_values] = values[0];
+
+ /* pulse min/max pos extension */
+ osc_wave_extrema_pos (e->n_values, values, &e->min_pos, &e->max_pos);
+
+ /* insert into cache */
+ cache_entries = g_bsearch_array_insert (cache_entries, &cache_taconfig, &e);
+ }
+ else
+ e->ref_count++;
+ return e;
+}
+
+static void
+cache_table_unref_entry (OscTableEntry *e)
+{
+ g_return_if_fail (e->ref_count > 0);
+
+ e->ref_count -= 1;
+ if (e->ref_count == 0)
+ {
+ OscTableEntry **ep;
+ guint i;
+
+ ep = g_bsearch_array_lookup (cache_entries, &cache_taconfig, &e);
+ i = g_bsearch_array_get_index (cache_entries, &cache_taconfig, ep);
+ cache_entries = g_bsearch_array_remove (cache_entries, &cache_taconfig, i);
+ }
+}
+
+GslOscTable*
+gsl_osc_table_create (gfloat mix_freq,
+ GslOscWaveForm wave_form,
+ double (*filter_func) (double),
+ guint n_freqs,
+ const gfloat *freqs)
+{
+ GslOscTable *table;
+ gfloat nyquist;
+ guint i;
+
+ g_return_val_if_fail (mix_freq > 0, NULL);
+ g_return_val_if_fail (n_freqs > 0, NULL);
+ g_return_val_if_fail (freqs != NULL, NULL);
+
+ if (!cache_entries)
+ cache_entries = g_bsearch_array_create (&cache_taconfig);
+
+ table = gsl_new_struct (GslOscTable, 1);
+ table->mix_freq = mix_freq;
+ table->wave_form = wave_form;
+ table->entry_array = g_bsearch_array_create (&osc_taconfig);
+ nyquist = table->mix_freq * 0.5;
+ if (wave_form == GSL_OSC_WAVE_PULSE_SAW)
+ wave_form = GSL_OSC_WAVE_SAW_FALL;
+ for (i = 0; i < n_freqs; i++)
+ {
+ OscTableEntry *e;
+ gdouble mfreq = MIN (nyquist, freqs[i]);
+
+ mfreq /= table->mix_freq;
+ e = osc_table_entry_lookup_best (table, mfreq, NULL);
+ if (!e || fabs (e->mfreq * table->mix_freq - mfreq * table->mix_freq) > OSC_FREQ_EPSILON)
+ {
+ e = cache_table_ref_entry (wave_form, filter_func, mfreq);
+ table->entry_array = g_bsearch_array_insert (table->entry_array, &osc_taconfig, &e);
+ }
+ else if (e)
+ OSC_DEBUG ("not inserting existing entry (freq=%f) for freq %f (nyquist=%f)",
+ e->mfreq * table->mix_freq, mfreq * table->mix_freq, nyquist);
+ }
+
+ return table;
+}
+
+void
+gsl_osc_table_lookup (const GslOscTable *table,
+ gfloat freq,
+ GslOscWave *wave)
+{
+ OscTableEntry *e;
+ gfloat mfreq, min_mfreq;
+
+ g_return_if_fail (table != NULL);
+ g_return_if_fail (wave != NULL);
+
+ mfreq = freq / table->mix_freq;
+ e = osc_table_entry_lookup_best (table, mfreq, &min_mfreq);
+ if (e)
+ {
+ guint32 int_one;
+ gfloat float_one;
+
+ wave->min_freq = min_mfreq * table->mix_freq;
+ wave->max_freq = e->mfreq * table->mix_freq;
+ wave->n_values = e->n_values;
+ wave->values = e->values;
+ wave->n_frac_bits = g_bit_storage (wave->n_values - 1);
+ wave->n_frac_bits = 32 - wave->n_frac_bits;
+ int_one = 1 << wave->n_frac_bits;
+ wave->frac_bitmask = int_one - 1;
+ float_one = int_one;
+ wave->freq_to_step = float_one * wave->n_values / table->mix_freq;
+ wave->phase_to_pos = wave->n_values * float_one;
+ wave->ifrac_to_float = 1.0 / float_one;
+ /* pulse min/max pos extension */
+ wave->min_pos = e->min_pos;
+ wave->max_pos = e->max_pos;
+ }
+ else
+ {
+ /* shouldn't happen */
+ OSC_DEBUG ("table lookup revealed NULL, empty table?");
+ memset (wave, 0, sizeof (*wave));
+ }
+}
+
+void
+gsl_osc_table_free (GslOscTable *table)
+{
+ guint n;
+
+ g_return_if_fail (table != NULL);
+
+ n = g_bsearch_array_get_n_nodes (table->entry_array);
+ while (n--)
+ {
+ OscTableEntry **ep;
+
+ ep = g_bsearch_array_get_nth (table->entry_array, &osc_taconfig, n);
+ cache_table_unref_entry (*ep);
+ table->entry_array = g_bsearch_array_remove (table->entry_array, &osc_taconfig, n);
+ }
+ g_bsearch_array_free (table->entry_array, &osc_taconfig);
+ gsl_delete_struct (GslOscTable, table);
+}
+
+void
+gsl_osc_cache_debug_dump (void)
+{
+ OSC_DEBUG ("left in cache: %u", g_bsearch_array_get_n_nodes (cache_entries));
+}
+
+void
+gsl_osc_wave_fill_buffer (GslOscWaveForm type,
+ guint n_values,
+ gfloat *values)
+{
+ gdouble max = n_values, hmax = max * 0.5, qmax = n_values * 0.25;
+ gint i, half = n_values / 2, quarter = half / 2;
+
+ switch (type)
+ {
+ gdouble frac, pos;
+ case GSL_OSC_WAVE_SINE:
+ for (i = 0; i < n_values; i++)
+ {
+ frac = ((gdouble) i) / max; /* [0..1[ */
+ pos = frac * 2. * GSL_PI;
+ values[i] = sin (pos);
+ }
+ break;
+ case GSL_OSC_WAVE_SAW_RISE:
+ for (i = 0; i < n_values; i++)
+ {
+ frac = ((gdouble) i) / max; /* [0..1[ */
+ values[i] = 2.0 * frac - 1.0;
+ }
+ break;
+ case GSL_OSC_WAVE_SAW_FALL:
+ for (i = 0; i < n_values; i++)
+ {
+ frac = ((gdouble) i) / max; /* [0..1[ */
+ values[i] = 1.0 - 2.0 * frac;
+ }
+ break;
+ case GSL_OSC_WAVE_PEAK_RISE: /* spaced saw */
+ for (i = 0; i < half; i++)
+ {
+ frac = ((gdouble) i) / hmax;
+ values[i] = 2.0 * frac - 1.0;
+ }
+ for (; i < n_values; i++)
+ values[i] = -1.0;
+ break;
+ case GSL_OSC_WAVE_PEAK_FALL: /* spaced saw */
+ for (i = 0; i < half; i++)
+ {
+ frac = ((gdouble) i) / hmax;
+ values[i] = 1.0 - 2.0 * frac;
+ }
+ for (; i < n_values; i++)
+ values[i] = -1.0;
+ break;
+ case GSL_OSC_WAVE_TRIANGLE:
+ for (i = 0; i < quarter; i++)
+ {
+ frac = ((gdouble) i) / qmax;
+ values[i] = frac;
+ }
+ for (; i < half + quarter; i++)
+ {
+ frac = ((gdouble) i - quarter) / hmax;
+ values[i] = 1.0 - 2.0 * frac;
+ }
+ for (; i < n_values; i++)
+ {
+ frac = ((gdouble) i - half - quarter) / qmax;
+ values[i] = frac - 1.0;
+ }
+ break;
+ case GSL_OSC_WAVE_MOOG_SAW:
+ for (i = 0; i < half; i++)
+ {
+ frac = ((gdouble) i) / hmax;
+ values[i] = 2.0 * frac - 1.0;
+ }
+ for (; i < n_values; i++)
+ {
+ frac = ((gdouble) i) / max;
+ values[i] = 1.0 - 2.0 * frac;
+ }
+ break;
+ case GSL_OSC_WAVE_SQUARE:
+ for (i = 0; i < half; i++)
+ values[i] = 1.0;
+ for (; i < n_values; i++)
+ values[i] = -1.0;
+ break;
+ default:
+ g_critical ("%s: invalid wave form id (%u)", G_STRLOC, type);
+ case GSL_OSC_WAVE_NONE:
+ for (i = 0; i < n_values; i++)
+ values[i] = 0;
+ break;
+ }
+}
+
+static void
+osc_wave_extrema_pos (guint n_values,
+ const gfloat *values,
+ guint *minp_p,
+ guint *maxp_p)
+{
+ guint i, minp = 0, maxp = 0;
+ gfloat min = values[0], max = min;
+
+ for (i = 1; i < n_values; i++)
+ {
+ if (values[i] > max)
+ {
+ max = values[i];
+ maxp = i;
+ }
+ else if (values[i] < min)
+ {
+ min = values[i];
+ minp = i;
+ }
+ }
+ *minp_p = minp;
+ *maxp_p = maxp;
+}
+
+void
+gsl_osc_wave_extrema (guint n_values,
+ const gfloat *values,
+ gfloat *min_p,
+ gfloat *max_p)
+{
+ guint minp, maxp;
+
+ g_return_if_fail (n_values > 0 && values != NULL && min_p != NULL && max_p != NULL);
+
+ osc_wave_extrema_pos (n_values, values, &minp, &maxp);
+ *min_p = values[minp];
+ *max_p = values[maxp];
+}
+
+void
+gsl_osc_wave_adjust_range (guint n_values,
+ gfloat *values,
+ gfloat min,
+ gfloat max,
+ gfloat new_center,
+ gfloat new_max)
+{
+ gfloat center;
+ guint i;
+
+ g_return_if_fail (n_values > 0 && values != NULL);
+
+ center = (min + max) / 2;
+ center = new_center - center;
+ min = fabs (min + center);
+ max = fabs (max + center);
+ if (min > max)
+ max = min;
+ if (max > GSL_FLOAT_MIN_NORMAL)
+ max = new_max / max;
+ else
+ max = 0;
+ for (i = 0; i < n_values; i++)
+ values[i] = (values[i] + center) * max;
+}
+
+void
+gsl_osc_wave_normalize (guint n_values,
+ gfloat *values,
+ gfloat new_center,
+ gfloat new_max)
+{
+ gfloat min, max;
+ guint i;
+
+ g_return_if_fail (n_values > 0 && values != NULL);
+
+ min = values[0];
+ max = min;
+ for (i = 1; i < n_values; i++)
+ {
+ register gfloat v = values[i];
+
+ max = MAX (max, v);
+ min = MIN (min, v);
+ }
+
+ gsl_osc_wave_adjust_range (n_values, values, min, max, new_center, new_max);
+}
diff --git a/flow/gsl/gslosctable.h b/flow/gsl/gslosctable.h
new file mode 100644
index 0000000..021e5b9
--- /dev/null
+++ b/flow/gsl/gslosctable.h
@@ -0,0 +1,104 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001-2002 Tim Janik
+ *
+ * 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 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.
+ */
+#ifndef __GSL_OSC_TABLE_H__
+#define __GSL_OSC_TABLE_H__
+
+#include <gsl/gsldefs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* --- structures & enums --- */
+typedef enum /*< skip >*/
+{
+ GSL_OSC_WAVE_NONE,
+ GSL_OSC_WAVE_SINE,
+ GSL_OSC_WAVE_TRIANGLE,
+ GSL_OSC_WAVE_SAW_RISE,
+ GSL_OSC_WAVE_SAW_FALL,
+ GSL_OSC_WAVE_PEAK_RISE,
+ GSL_OSC_WAVE_PEAK_FALL,
+ GSL_OSC_WAVE_MOOG_SAW,
+ GSL_OSC_WAVE_SQUARE,
+ GSL_OSC_WAVE_PULSE_SAW
+} GslOscWaveForm;
+
+typedef struct
+{
+ gfloat mix_freq;
+ GslOscWaveForm wave_form;
+ gpointer entry_array;
+} GslOscTable;
+
+typedef struct
+{
+ gfloat min_freq;
+ gfloat max_freq;
+ guint n_values;
+ const gfloat *values; /* contains n_values+1 values with values[0]==values[n_values] */
+ /* integer stepping (block size dependant) */
+ guint32 n_frac_bits;
+ guint32 frac_bitmask;
+ gfloat freq_to_step; /* freq -> int.frac */
+ gfloat phase_to_pos; /* 0..1 -> int.frac */
+ gfloat ifrac_to_float; /* frac -> 0..1 float */
+ guint min_pos, max_pos; /* pulse extension */
+} GslOscWave;
+
+
+/* --- oscillator table --- */
+GslOscTable* gsl_osc_table_create (gfloat mix_freq,
+ GslOscWaveForm wave_form,
+ double (*filter_func) (double),
+ guint n_freqs,
+ const gfloat *freqs);
+void gsl_osc_table_lookup (const GslOscTable *table,
+ gfloat freq,
+ GslOscWave *wave);
+void gsl_osc_table_free (GslOscTable *table);
+
+
+/* --- oscillator wave utils --- */
+void gsl_osc_wave_fill_buffer (GslOscWaveForm type,
+ guint n_values,
+ gfloat *values);
+void gsl_osc_wave_extrema (guint n_values,
+ const gfloat *values,
+ gfloat *min,
+ gfloat *max);
+void gsl_osc_wave_normalize (guint n_values,
+ gfloat *values,
+ gfloat new_center,
+ gfloat new_max);
+void gsl_osc_wave_adjust_range (guint n_values,
+ gfloat *values,
+ gfloat min,
+ gfloat max,
+ gfloat new_center,
+ gfloat new_max);
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_OSC_TABLE_H__ */
diff --git a/flow/gsl/gslsignal.c b/flow/gsl/gslsignal.c
new file mode 100644
index 0000000..9afc5bb
--- /dev/null
+++ b/flow/gsl/gslsignal.c
@@ -0,0 +1,258 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001-2002 Tim Janik and Stefan Westerfeld
+ *
+ * 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 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.
+ */
+#include "gslsignal.h"
+
+#include "gslcommon.h"
+
+
+/* --- frequency modulation --- */
+void
+gsl_frequency_modulator (const GslFrequencyModulator *fm,
+ guint n_values,
+ const gfloat *ifreq,
+ const gfloat *ifmod,
+ gfloat *fm_buffer)
+{
+ gfloat *bound, fine_tune, fm_strength;
+ gboolean with_fine_tune;
+
+ fine_tune = gsl_cent_factor (fm->fine_tune);
+ with_fine_tune = fm->fine_tune != 0;
+ fm_strength = fm->fm_strength;
+
+ bound = fm_buffer + n_values;
+ if (ifreq && ifmod)
+ {
+ if (fm->exponential_fm)
+ {
+ if (with_fine_tune)
+ do {
+ *fm_buffer++ = *ifreq++ * gsl_approx_exp2 (fm_strength * *ifmod++) * fine_tune;
+ } while (fm_buffer < bound);
+ else
+ do {
+ *fm_buffer++ = *ifreq++ * gsl_approx_exp2 (fm_strength * *ifmod++);
+ } while (fm_buffer < bound);
+ }
+ else
+ {
+ if (with_fine_tune)
+ do {
+ *fm_buffer++ = *ifreq++ * (1 + fm_strength * *ifmod++) * fine_tune;
+ } while (fm_buffer < bound);
+ else
+ do {
+ *fm_buffer++ = *ifreq++ * (1 + fm_strength * *ifmod++);
+ } while (fm_buffer < bound);
+ }
+ }
+ else if (ifmod)
+ {
+ gfloat signal_freq = fm->signal_freq * fine_tune;
+
+ if (fm->exponential_fm)
+ do {
+ *fm_buffer++ = signal_freq * gsl_approx_exp2 (fm_strength * *ifmod++);
+ } while (fm_buffer < bound);
+ else
+ do {
+ *fm_buffer++ = signal_freq * (1 + fm_strength * *ifmod++);
+ } while (fm_buffer < bound);
+ }
+ else if (ifreq)
+ {
+ if (with_fine_tune)
+ do {
+ *fm_buffer++ = *ifreq++ * fine_tune;
+ } while (fm_buffer < bound);
+ else
+ do {
+ *fm_buffer++ = *ifreq++;
+ } while (fm_buffer < bound);
+ }
+ else
+ {
+ gfloat signal_freq = fm->signal_freq * fine_tune;
+
+ do {
+ *fm_buffer++ = signal_freq;
+ } while (fm_buffer < bound);
+ }
+}
+
+
+/* --- windows --- */
+double
+gsl_window_bartlett (double x) /* triangle */
+{
+ if (fabs (x) > 1)
+ return 0;
+
+ return 1.0 - fabs (x);
+}
+
+double
+gsl_window_blackman (double x)
+{
+ if (fabs (x) > 1)
+ return 0;
+
+ return 0.42 + 0.5 * cos (GSL_PI * x) + 0.08 * cos (2.0 * GSL_PI * x);
+}
+
+double
+gsl_window_cos (double x) /* von Hann window */
+{
+ if (fabs (x) > 1)
+ return 0;
+
+ return 0.5 * cos (x * GSL_PI) + 0.5;
+}
+
+double
+gsl_window_hamming (double x) /* sharp (rectangle) cutoffs at boundaries */
+{
+ if (fabs (x) > 1)
+ return 0;
+
+ return 0.54 + 0.46 * cos (GSL_PI * x);
+}
+
+double
+gsl_window_sinc (double x) /* noramlied C. Lanczos window */
+{
+ if (fabs (x) > 1)
+ return 0;
+ x = x * GSL_PI;
+ if (fabs (x) < 1e-12)
+ return 1.0;
+ else
+ return sin (x) / x;
+}
+
+double
+gsl_window_rect (double x) /* a square */
+{
+ if (fabs (x) > 1)
+ return 0;
+ return 1.0;
+}
+
+/*
+cos_roll_off(x)= x>fh?0:x<fl?1:cos(pi/2.*((fl-x)/(fh-fl)))
+*/
+
+
+/* --- cents & init --- */
+const gdouble *gsl_cent_table = NULL;
+#define GSL_2_RAISED_TO_1_OVER_1200_d ( /* 2^(1/1200) */ \
+ 1.0005777895065548488418016859213821589946746826171875)
+void
+_gsl_init_signal (void)
+{
+ static gdouble cent_table_space[201];
+ gint i;
+
+ /* cent table initialization,
+ * allow negative indexing within [-100..+100]
+ */
+ gsl_cent_table = cent_table_space + 100;
+ for (i = -100; i <= 100; i++)
+ cent_table_space[100 + i] = pow (GSL_2_RAISED_TO_1_OVER_1200_d, i);
+}
+
+
+/* --- gsl_approx_atan1() --- */
+double
+gsl_approx_atan1_prescale (double boost_amount)
+{
+ double max_boost_factor = 100; /* atan1(x*100) gets pretty close to 1 for x=1 */
+ double recip_tan_1_div_0_75 = 0.24202942695518667705824990442766; /* 1/tan(1/0.75) */
+ double scale;
+
+ g_return_val_if_fail (boost_amount >= 0 && boost_amount <= 1.0, 1.0);
+
+ /* scale boost_amount from [0..1] to -1..1 */
+ boost_amount = boost_amount * 2 - 1.0;
+
+ /* prescale factor for atan1(x*prescale), ranges from 1/max_boost_factor..max_boost_factor */
+ scale = pow (max_boost_factor, tan (boost_amount / 0.75) * recip_tan_1_div_0_75);
+
+ return scale;
+}
+
+
+/* --- exp2f() approximation taylor coefficients finder --- */
+#if 0
+#include <stdio.h>
+double
+exp2coeff (int n)
+{
+ double r = 1;
+ int i;
+
+ for (i = 1; i <= n; i++)
+ {
+ r *= GSL_LN2;
+ r /= i;
+ }
+ return r;
+}
+/* generate taylor coefficients */
+int
+main (int argc,
+ char *argv[])
+{
+ int i;
+
+ for (i = 0; i < 20; i++)
+ printf ("#define EXP2_TAYLOR_COEFF_%u\t(%.40f)\n", i, exp2coeff (i));
+
+ return 0;
+}
+/* test/bench program */
+#define _GNU_SOURCE
+#include <math.h>
+int
+main (int argc,
+ char *argv[])
+{
+ double x, dummy = 0, l = 4;
+
+ if (1) /* print errors */
+ for (x = -3; x < 3.01; x += 0.1)
+ {
+ g_print ("%+f %+1.20f \t (%.20f - %.20f)\n",
+ x, exp (x * GSL_LN2) - gsl_signal_exp2 (x),
+ exp (x * GSL_LN2), gsl_signal_exp2 (x));
+ }
+
+ if (0) /* bench test */
+ for (x = -l; x < l; x += 0.000001)
+ {
+ dummy += gsl_signal_exp2 (x);
+ // dummy += exp2f (x);
+ }
+
+ g_print ("%f\r \n", dummy);
+
+ return 0;
+}
+#endif /* coeff generation */
+
diff --git a/flow/gsl/gslsignal.h b/flow/gsl/gslsignal.h
new file mode 100644
index 0000000..aa92f32
--- /dev/null
+++ b/flow/gsl/gslsignal.h
@@ -0,0 +1,343 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001-2002 Tim Janik and Stefan Westerfeld
+ *
+ * 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 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.
+ */
+#ifndef __GSL_SIGNAL_H__
+#define __GSL_SIGNAL_H__
+
+#include <gsl/gsldefs.h>
+#include <gsl/gslieee754.h>
+#include <gsl/gslmath.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* smallest value of a signal sample, greater than zero
+ */
+#define GSL_SIGNAL_EPSILON (1.15e-14) /* 1.16415321826934814453125e-9 ~= 1/2^33 */
+
+/* maximum value of a signal sample
+ */
+#define GSL_SIGNAL_KAPPA (1.5)
+
+/* catch edges in sync signals.
+ * sync signals should be constant, do comparing against
+ * an epsilon just hurts speed in the common case
+ */
+#define GSL_SIGNAL_RAISING_EDGE(v1,v2) ((v1) < (v2))
+#define GSL_SIGNAL_FALLING_EDGE(v1,v2) ((v1) > (v2))
+
+/* value changes in signals which represent frequencies
+ */
+#define GSL_SIGNAL_FREQ_CHANGED(v1,v2) (fabs ((v1) - (v2)) > 1e-7)
+
+/* value changes in signals which represent modulation
+ */
+#define GSL_SIGNAL_MOD_CHANGED(v1,v2) (fabs ((v1) - (v2)) > 1e-8)
+
+/* value changes in signals which represent dB ranges
+ */
+#define GSL_SIGNAL_GAIN_CHANGED(v1,v2) (fabs ((v1) - (v2)) > 1e-8)
+
+/* convert between literal frequencies and signal values
+ */
+#if defined (BSE_COMPILATION) || defined (BSE_PLUGIN_FALLBACK)
+#include <bse/bseglobals.h>
+# define GSL_SIGNAL_TO_FREQ_FACTOR (BSE_MAX_FREQUENCY_f)
+# define GSL_SIGNAL_FROM_FREQ_FACTOR (1.0 / BSE_MAX_FREQUENCY_f)
+# define GSL_SIGNAL_TO_FREQ(value) (((gfloat) (value)) * GSL_SIGNAL_TO_FREQ_FACTOR)
+# define GSL_SIGNAL_FROM_FREQ(freq) (((gfloat) (freq)) * GSL_SIGNAL_FROM_FREQ_FACTOR)
+#elif defined (GSL_USE_ARTS_THREADS) /* must be aRts */
+# define GSL_SIGNAL_TO_FREQ(x) (x)
+# define GSL_SIGNAL_FROM_FREQ(x) (x)
+#endif
+
+
+/* --- frequency modulation --- */
+typedef struct {
+ gfloat fm_strength; /* linear: 0..1, exponential: n_octaves */
+ guint exponential_fm : 1;
+ gfloat signal_freq; /* for ifreq == NULL (as GSL_SIGNAL_FROM_FREQ) */
+ gint fine_tune; /* -100..+100 */
+} GslFrequencyModulator;
+
+void gsl_frequency_modulator (const GslFrequencyModulator *fm,
+ guint n_values,
+ const gfloat *ifreq,
+ const gfloat *ifmod,
+ gfloat *fm_buffer);
+
+
+/* --- function approximations --- */
+
+/**
+ * gsl_signal_exp2
+ * Deprecated in favour of gsl_approx_exp2().
+ */
+static inline float gsl_signal_exp2 (float x) G_GNUC_CONST;
+
+/**
+ * gsl_approx_exp2
+ * @ex: exponent within [-127..127]
+ * @RETURNS: y approximating 2^x
+ * Fast approximation of 2 raised to the power of x.
+ * Multiplicative error stays below 8e-6 and aproaches zero
+ * for integer values of x (i.e. x - floor (x) = 0).
+ */
+static inline double gsl_approx_exp2 (float ex) G_GNUC_CONST;
+
+
+/**
+ * gsl_approx_atan1
+ * Fast atan(x)/(PI/2) approximation, with maximum error < 0.01 and
+ * gsl_approx_atan1(0)==0, according to the formula:
+ * n1 = -0.41156875521951602506487246309908;
+ * n2 = -1.0091272542790025586079663559158;
+ * d1 = 0.81901156857081841441890603235599;
+ * d2 = 1.0091272542790025586079663559158;
+ * positive_atan1(x) = 1 + (n1 * x + n2) / ((1 + d1 * x) * x + d2);
+ */
+static inline double gsl_approx_atan1 (register double x) G_GNUC_CONST;
+
+/**
+ * gsl_approx_atan1_prescale
+ * @boost_amount: boost amount between [0..1]
+ * @RETURNS: prescale factor for gsl_approx_atan1()
+ * Calculate the prescale factor for gsl_approx_atan1(x*prescale) from
+ * a linear boost factor, where 0.5 amounts to prescale=1.0, 1.0 results
+ * in maximum boost and 0.0 results in maximum attenuation.
+ */
+double gsl_approx_atan1_prescale (double boost_amount);
+
+/**
+ * gsl_approx_qcircle1
+ * @x: x within [0..1]
+ * @RETURNS: y for circle approximation within [0..1]
+ * Fast approximation of the upper right quadrant of a circle.
+ * Errors at x=0 and x=1 are zero, for the rest of the curve, the error
+ * wasn't minimized, but distributed to best fit the curverture of a
+ * quarter circle. The maximum error is below 0.092.
+ */
+static inline double gsl_approx_qcircle1 (register double x) G_GNUC_CONST;
+
+/**
+ * gsl_approx_qcircle2
+ * @x: x within [0..1]
+ * @RETURNS: y for circle approximation within [0..1]
+ * Fast approximation of the upper left quadrant of a circle.
+ * Errors at x=0 and x=1 are zero, for the rest of the curve, the error
+ * wasn't minimized, but distributed to best fit the curverture of a
+ * quarter circle. The maximum error is below 0.092.
+ */
+static inline double gsl_approx_qcircle2 (register double x) G_GNUC_CONST;
+
+/**
+ * gsl_approx_qcircle3
+ * @x: x within [0..1]
+ * @RETURNS: y for circle approximation within [0..1]
+ * Fast approximation of the lower left quadrant of a circle.
+ * Errors at x=0 and x=1 are zero, for the rest of the curve, the error
+ * wasn't minimized, but distributed to best fit the curverture of a
+ * quarter circle. The maximum error is below 0.092.
+ */
+static inline double gsl_approx_qcircle3 (register double x) G_GNUC_CONST;
+
+/**
+ * gsl_approx_qcircle4
+ * @x: x within [0..1]
+ * @RETURNS: y for circle approximation within [0..1]
+ * Fast approximation of the lower right quadrant of a circle.
+ * Errors at x=0 and x=1 are zero, for the rest of the curve, the error
+ * wasn't minimized, but distributed to best fit the curverture of a
+ * quarter circle. The maximum error is below 0.092.
+ */
+static inline double gsl_approx_qcircle4 (register double x) G_GNUC_CONST;
+
+
+/* --- windows --- */
+double gsl_window_bartlett (double x); /* narrowest */
+double gsl_window_blackman (double x);
+double gsl_window_cos (double x);
+double gsl_window_hamming (double x);
+double gsl_window_sinc (double x);
+double gsl_window_rect (double x); /* widest */
+
+
+/* --- cents (1/100th of a semitone) --- */
+#define gsl_cent_factor(index /* -100..100 */) (gsl_cent_table[index])
+extern const gdouble *gsl_cent_table;
+
+
+/* --- implementation details --- */
+static inline double G_GNUC_CONST
+gsl_approx_atan1 (register double x)
+{
+ if (x < 0) /* make use of -atan(-x)==atan(x) */
+ {
+ register double numerator, denominator = -1.0;
+
+ denominator += x * 0.81901156857081841441890603235599; /* d1 */
+ numerator = x * 0.41156875521951602506487246309908; /* -n1 */
+ denominator *= x;
+ numerator += -1.0091272542790025586079663559158; /* n2 */
+ denominator += 1.0091272542790025586079663559158; /* d2 */
+
+ return -1.0 - numerator / denominator;
+ }
+ else
+ {
+ register double numerator, denominator = 1.0;
+
+ denominator += x * 0.81901156857081841441890603235599; /* d1 */
+ numerator = x * -0.41156875521951602506487246309908; /* n1 */
+ denominator *= x;
+ numerator += -1.0091272542790025586079663559158; /* n2 */
+ denominator += 1.0091272542790025586079663559158; /* d2 */
+
+ return 1.0 + numerator / denominator;
+ }
+}
+
+static inline double G_GNUC_CONST
+gsl_approx_qcircle1 (register double x)
+{
+ double numerator = 1.20460124790369468987715633298929 * x - 1.20460124790369468987715633298929;
+ double denominator = x - 1.20460124790369468987715633298929;
+ /* R1(x)=(1.2046012479036946898771563 * x - 1.2046012479036946898771563) / (x - 1.2046012479036946898771563) */
+ return numerator / denominator;
+}
+
+static inline double G_GNUC_CONST
+gsl_approx_qcircle2 (register double x)
+{
+ double numerator = 1.20460124790369468987715633298929*x;
+ double denominator = x + 0.20460124790369468987715633298929;
+ /* R2(x)=1.2046012479036946898771563*x/(x + 0.2046012479036946898771563) */
+ return numerator / denominator;
+}
+
+static inline double G_GNUC_CONST
+gsl_approx_qcircle3 (register double x)
+{
+ double numerator = 0.20460124790369468987715633298929 - 0.20460124790369468987715633298929 * x;
+ double denominator = x + 0.20460124790369468987715633298929;
+ /* R3(x)=(0.2046012479036946898771563 - 0.2046012479036946898771563 * x) / (x + 0.2046012479036946898771563) */
+ return numerator / denominator;
+}
+
+static inline double G_GNUC_CONST
+gsl_approx_qcircle4 (register double x)
+{
+ double numerator = -0.20460124790369468987715633298929 * x;
+ double denominator = x - 1.20460124790369468987715633298929;
+ /* R4(x)=-0.2046012479036946898771563 * x / (x - 1.2046012479036946898771563) */
+ return numerator / denominator;
+}
+
+static inline double G_GNUC_CONST
+gsl_approx_exp2 (float ex)
+{
+ register GslFloatIEEE754 fp = { 0, };
+ register double numer, denom, x;
+ gint i;
+
+ i = gsl_ftoi (ex);
+ fp.mpn.biased_exponent = GSL_FLOAT_BIAS + i;
+ x = ex - i;
+ numer = x * 1.022782938747283388104723674300322141276;
+ denom = x - 8.72117024533378044415954808601135282456;
+ numer += 8.786902350800703562041965087953613538091;
+ denom *= x;
+ numer *= x;
+ denom += 25.25880955504064143887016455761526606757;
+ numer += 25.2588095552441757401874424757283407864;
+
+ return numer / denom * fp.v_float;
+}
+
+static inline float G_GNUC_CONST
+_gsl_signal_exp2_fraction (float x) /* 2^x, -0.5 <= x <= 0.5 */
+{
+ static const float exp2taylorC0 = 1.0000000000000000000000000000000000000000;
+ static const float exp2taylorC1 = 0.6931471805599452862267639829951804131269;
+ static const float exp2taylorC2 = 0.2402265069591006940719069007172947749496;
+ static const float exp2taylorC3 = 0.0555041086648215761800706502526736585423;
+ static const float exp2taylorC4 = 0.0096181291076284768787330037298488605302;
+ static const float exp2taylorC5 = 0.0013333558146428443284131626356270317046;
+#if 0
+ static const float exp2taylorC6 = 0.0001540353039338160877607525334198612654;
+ static const float exp2taylorC7 = 0.0000152527338040598393887042200089965149;
+ static const float exp2taylorC8 = 0.0000013215486790144307390984122416166535;
+ static const float exp2taylorC9 = 0.0000001017808600923969859895309888857262;
+#endif
+ float r = 0.0;
+
+ /* order 5 taylor series aproximation */
+ r += exp2taylorC5;
+ r *= x;
+ r += exp2taylorC4;
+ r *= x;
+ r += exp2taylorC3;
+ r *= x;
+ r += exp2taylorC2;
+ r *= x;
+ r += exp2taylorC1;
+ r *= x;
+ r += exp2taylorC0;
+
+ return r;
+}
+static inline float G_GNUC_CONST
+gsl_signal_exp2 (float x) /* 2^x, -3.5 <= x <= 3.5, prec>16bit */
+{
+ if_reject (x < -0.5)
+ {
+ if_reject (x < -1.5)
+ {
+ if (x < -2.5)
+ return 0.125 * _gsl_signal_exp2_fraction (x + 3);
+ else /* -2.5 <= x < -1.5 */
+ return 0.25 * _gsl_signal_exp2_fraction (x + 2);
+ }
+ else /* -1.5 <= x < -0.5 */
+ return 0.5 * _gsl_signal_exp2_fraction (x + 1);
+ }
+ else if_reject (x > 0.5)
+ {
+ if_reject (x > 1.5)
+ {
+ if (x > 2.5)
+ return 8 * _gsl_signal_exp2_fraction (x - 3);
+ else /* 1.5 < x <= 2.5 */
+ return 4 * _gsl_signal_exp2_fraction (x - 2);
+ }
+ else /* 0.5 < x <= 1.5 */
+ return 2 * _gsl_signal_exp2_fraction (x - 1);
+ }
+ else
+ return _gsl_signal_exp2_fraction (x);
+}
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_SIGNAL_H__ */
diff --git a/flow/gsl/gsltests.c b/flow/gsl/gsltests.c
new file mode 100644
index 0000000..12a1664
--- /dev/null
+++ b/flow/gsl/gsltests.c
@@ -0,0 +1,650 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001-2002 Tim Janik and Stefan Westerfeld
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <gsl/gslmath.h>
+#include <gsl/gslcommon.h>
+#include <gsl/gslmath.h>
+#include <gsl/gslfilter.h>
+#include <gsl/gslloader.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define PREC "15"
+
+
+static void usage (void) G_GNUC_NORETURN;
+
+
+static guint shift_argc = 0;
+static const gchar **shift_argv = NULL;
+
+static const gchar*
+shift (void)
+{
+ const gchar *arg;
+
+ if (shift_argc > 1)
+ {
+ shift_argc--;
+ arg = shift_argv++[1];
+ if (!arg)
+ arg = "";
+ }
+ else
+ arg = NULL;
+ return arg;
+}
+static const gchar*
+pshift (void)
+{
+ const gchar *arg = shift ();
+
+ return arg ? arg : "";
+}
+
+int
+main (int argc,
+ char *argv[])
+{
+ const gchar *arg;
+
+ /* iir filter parameters */
+ enum { FILTER_GNUPLOT, FILTER_SCAN } filter_mode = FILTER_GNUPLOT;
+ const gchar *filter_label = 0;
+ gdouble *a, *b;
+ guint order = 0;
+
+ shift_argc = argc;
+ shift_argv = (gchar **)argv;
+
+ if (!g_thread_supported ())
+ g_thread_init (NULL);
+ gsl_init (NULL, NULL);
+
+ arg = shift ();
+ if (!arg)
+ usage ();
+
+ restart:
+ a = b = 0;
+
+ if (strcmp (arg, "wave-scan") == 0)
+ {
+ const gchar *file = pshift ();
+
+ while (file)
+ {
+ GslWaveFileInfo *fi;
+ GslErrorType error;
+
+ fi = gsl_wave_file_info_load (file, &error);
+ if (fi)
+ {
+ guint i;
+
+ g_print ("Loader \"%s\" found %u waves in \"%s\":\n", fi->loader->name, fi->n_waves, file);
+ for (i = 0; i < fi->n_waves; i++)
+ g_print ("%u) %s\n", i + 1, fi->waves[i].name);
+ gsl_wave_file_info_unref (fi);
+ }
+ else
+ g_print ("Failed to scan \"%s\": %s\n", file, gsl_strerror (error));
+ file = pshift ();
+ if (!file[0])
+ break;
+ }
+ }
+ else if (strcmp (arg, "file-test") == 0)
+ {
+ const gchar *file = pshift ();
+
+ g_print ("file test for \"%s\":\n", file);
+ g_print (" is readable : %s\n", gsl_strerror (gsl_check_file (file, "r")));
+ g_print (" is writable : %s\n", gsl_strerror (gsl_check_file (file, "w")));
+ g_print (" is executable : %s\n", gsl_strerror (gsl_check_file (file, "x")));
+ g_print (" is file : %s\n", gsl_strerror (gsl_check_file (file, "f")));
+ g_print (" is directory : %s\n", gsl_strerror (gsl_check_file (file, "d")));
+ g_print (" is link : %s\n", gsl_strerror (gsl_check_file (file, "l")));
+ }
+ else if (strcmp (arg, "rf") == 0)
+ {
+ double x, y, z;
+ x = atof (pshift ());
+ y = atof (pshift ());
+ z = atof (pshift ());
+
+ g_print ("rf(%f, %f, %f) = %."PREC"f\n", x, y, z, gsl_ellip_rf (x, y, z));
+ }
+ else if (strcmp (arg, "F") == 0)
+ {
+ double phi, ak;
+ phi = atof (pshift ());
+ ak = atof (pshift ());
+
+ g_print ("F(%f, %f) = %."PREC"f\n", phi, ak, gsl_ellip_F (phi, ak));
+ }
+ else if (strcmp (arg, "sn") == 0)
+ {
+ double u, emmc;
+ u = atof (pshift ());
+ emmc = atof (pshift ());
+
+ g_print ("sn(%f, %f) = %."PREC"f\n", u, emmc, gsl_ellip_sn (u, emmc));
+ }
+ else if (strcmp (arg, "snc") == 0)
+ {
+ GslComplex u, emmc;
+ u.re = atof (pshift ());
+ u.im = atof (pshift ());
+ emmc.re = atof (pshift ());
+ emmc.im = atof (pshift ());
+
+ g_print ("snc(%s, %s) = %s\n",
+ gsl_complex_str (u),
+ gsl_complex_str (emmc),
+ gsl_complex_str (gsl_complex_ellip_sn (u, emmc)));
+ }
+ else if (strcmp (arg, "sci_snc") == 0)
+ {
+ GslComplex u, k2;
+ u.re = atof (pshift ());
+ u.im = atof (pshift ());
+ k2.re = atof (pshift ());
+ k2.im = atof (pshift ());
+
+ g_print ("sci_snc(%s, %s) = %s\n",
+ gsl_complex_str (u),
+ gsl_complex_str (k2),
+ gsl_complex_str (gsl_complex_ellip_sn (u, gsl_complex_sub (gsl_complex (1.0, 0), k2))));
+ }
+ else if (strcmp (arg, "asn") == 0)
+ {
+ double y, emmc;
+ y = atof (pshift ());
+ emmc = atof (pshift ());
+
+ g_print ("asn(%f, %f) = %."PREC"f\n", y, emmc, gsl_ellip_asn (y, emmc));
+ }
+ else if (strcmp (arg, "asnc") == 0)
+ {
+ GslComplex y, emmc;
+ y.re = atof (pshift ());
+ y.im = atof (pshift ());
+ emmc.re = atof (pshift ());
+ emmc.im = atof (pshift ());
+
+ g_print ("asnc(%s, %s) = %s\n",
+ gsl_complex_str (y), gsl_complex_str (emmc),
+ gsl_complex_str (gsl_complex_ellip_asn (y, emmc)));
+ g_print ("asn(%f, %f = %."PREC"f\n",
+ y.re, emmc.re, gsl_ellip_asn (y.re, emmc.re));
+ }
+ else if (strcmp (arg, "sci_sn") == 0)
+ {
+ double u, k2;
+ u = atof (pshift ());
+ k2 = atof (pshift ());
+ g_print ("sci_sn(%f, %f) = %."PREC"f\n", u, k2, gsl_ellip_sn (u, 1.0 - k2));
+ }
+ else if (strcmp (arg, "sci_asn") == 0)
+ {
+ double y, k2;
+ y = atof (pshift ());
+ k2 = atof (pshift ());
+ g_print ("sci_asn(%f, %f) = %."PREC"f\n", y, k2, gsl_ellip_asn (y, 1.0 - k2));
+ }
+ else if (strcmp (arg, "sci_asnc") == 0)
+ {
+ GslComplex y, k2;
+ y.re = atof (pshift ());
+ y.im = atof (pshift ());
+ k2.re = atof (pshift ());
+ k2.im = atof (pshift ());
+ g_print ("sci_asnc(%s, %s) = %s\n",
+ gsl_complex_str (y), gsl_complex_str (k2),
+ gsl_complex_str (gsl_complex_ellip_asn (y, gsl_complex_sub (gsl_complex (1.0, 0), k2))));
+ g_print ("asn(%f, %f = %."PREC"f\n",
+ y.re, k2.re, gsl_ellip_asn (y.re, 1.0 - k2.re));
+ }
+ else if (strcmp (arg, "sin") == 0)
+ {
+ GslComplex phi;
+ phi.re = atof (pshift ());
+ phi.im = atof (pshift ());
+ g_print ("sin(%s) = %s\n",
+ gsl_complex_str (phi),
+ gsl_complex_str (gsl_complex_sin (phi)));
+ }
+ else if (strcmp (arg, "cos") == 0)
+ {
+ GslComplex phi;
+ phi.re = atof (pshift ());
+ phi.im = atof (pshift ());
+ g_print ("cos(%s) = %s\n",
+ gsl_complex_str (phi),
+ gsl_complex_str (gsl_complex_cos (phi)));
+ }
+ else if (strcmp (arg, "tan") == 0)
+ {
+ GslComplex phi;
+ phi.re = atof (pshift ());
+ phi.im = atof (pshift ());
+ g_print ("tan(%s) = %s\n",
+ gsl_complex_str (phi),
+ gsl_complex_str (gsl_complex_tan (phi)));
+ }
+ else if (strcmp (arg, "sinh") == 0)
+ {
+ GslComplex phi;
+ phi.re = atof (pshift ());
+ phi.im = atof (pshift ());
+ g_print ("sinh(%s) = %s\n",
+ gsl_complex_str (phi),
+ gsl_complex_str (gsl_complex_sinh (phi)));
+ }
+ else if (strcmp (arg, "cosh") == 0)
+ {
+ GslComplex phi;
+ phi.re = atof (pshift ());
+ phi.im = atof (pshift ());
+ g_print ("cosh(%s) = %s\n",
+ gsl_complex_str (phi),
+ gsl_complex_str (gsl_complex_cosh (phi)));
+ }
+ else if (strcmp (arg, "tanh") == 0)
+ {
+ GslComplex phi;
+ phi.re = atof (pshift ());
+ phi.im = atof (pshift ());
+ g_print ("tanh(%s) = %s\n",
+ gsl_complex_str (phi),
+ gsl_complex_str (gsl_complex_tanh (phi)));
+ }
+ else if (strcmp (arg, "midi2freq") == 0)
+ {
+ gint note;
+ note = atol (pshift ());
+ note = CLAMP (note, 0, 128);
+ g_print ("midi2freq(%u) = %f\n",
+ note,
+ gsl_temp_freq (gsl_get_config ()->kammer_freq,
+ note - gsl_get_config ()->midi_kammer_note));
+ }
+ else if (strcmp (arg, "blp") == 0)
+ {
+ double f, e;
+ order = atoi (pshift ()); order = MAX (order, 1);
+ f = atof (pshift ());
+ e = atof (pshift ());
+ f *= GSL_PI / 2.;
+ a = g_new (gdouble, order + 1);
+ b = g_new (gdouble, order + 1);
+ gsl_filter_butter_lp (order, f, e, a, b);
+ g_print ("# Lowpass Butterworth filter order=%u freq=%f epsilon(s^2)=%f norm0=%f:\n",
+ order, f, e,
+ gsl_poly_eval (order, a, 1) / gsl_poly_eval (order, b, 1));
+ filter_label = "BL";
+ }
+ else if (strcmp (arg, "bhp") == 0)
+ {
+ double f, e;
+ order = atoi (pshift ()); order = MAX (order, 1);
+ f = atof (pshift ());
+ e = atof (pshift ());
+ f *= GSL_PI / 2.;
+ a = g_new (gdouble, order + 1);
+ b = g_new (gdouble, order + 1);
+
+ gsl_filter_butter_hp (order, f, e, a, b);
+ g_print ("# Highpass Butterworth filter order=%u freq=%f epsilon(s^2)=%f norm0=%f:\n",
+ order, f, e,
+ gsl_poly_eval (order, a, 1) / gsl_poly_eval (order, b, 1));
+ filter_label = "BH";
+ }
+ else if (strcmp (arg, "bbp") == 0)
+ {
+ double f1, f2, e;
+ order = atoi (pshift ()); order = MAX (order, 1);
+ f1 = atof (pshift ());
+ f2 = atof (pshift ());
+ e = atof (pshift ());
+ f1 *= GSL_PI / 2.;
+ f2 *= GSL_PI / 2.;
+ a = g_new (gdouble, order + 1);
+ b = g_new (gdouble, order + 1);
+
+ gsl_filter_butter_bp (order, f1, f2, e, a, b);
+ g_print ("# Bandpass Butterworth filter order=%u freq1=%f freq2=%f epsilon(s^2)=%f norm0=%f:\n",
+ order, f1, f2, e,
+ gsl_poly_eval (order, a, 1) / gsl_poly_eval (order, b, 1));
+ filter_label = "BP";
+ }
+ else if (strcmp (arg, "bbs") == 0)
+ {
+ double f1, f2, e;
+ order = atoi (pshift ()); order = MAX (order, 1);
+ f1 = atof (pshift ());
+ f2 = atof (pshift ());
+ e = atof (pshift ());
+ f1 *= GSL_PI / 2.;
+ f2 *= GSL_PI / 2.;
+ a = g_new (gdouble, order + 1);
+ b = g_new (gdouble, order + 1);
+
+ gsl_filter_butter_bs (order, f1, f2, e, a, b);
+ g_print ("# Bandstop Butterworth filter order=%u freq1=%f freq2=%f epsilon(s^2)=%f norm0=%f:\n",
+ order, f1, f2, e,
+ gsl_poly_eval (order, a, 1) / gsl_poly_eval (order, b, 1));
+ filter_label = "BS";
+ }
+ else if (strcmp (arg, "t1l") == 0)
+ {
+ double f, e;
+ order = atoi (pshift ()); order = MAX (order, 1);
+ f = atof (pshift ());
+ e = atof (pshift ());
+ f *= GSL_PI / 2.;
+ a = g_new (gdouble, order + 1);
+ b = g_new (gdouble, order + 1);
+
+ gsl_filter_tscheb1_lp (order, f, e, a, b);
+ g_print ("# Lowpass Tschebyscheff Type1 order=%u freq=%f epsilon(s^2)=%f norm0=%f:\n",
+ order, f, e,
+ gsl_poly_eval (order, a, 1) / gsl_poly_eval (order, b, 1));
+ filter_label = "T1L";
+ }
+ else if (strcmp (arg, "t1h") == 0)
+ {
+ double f, e;
+ order = atoi (pshift ()); order = MAX (order, 1);
+ f = atof (pshift ());
+ e = atof (pshift ());
+ f *= GSL_PI / 2.;
+
+ a = g_new (gdouble, order + 1);
+ b = g_new (gdouble, order + 1);
+
+ gsl_filter_tscheb1_hp (order, f, e, a, b);
+ g_print ("# Highpass Tschebyscheff Type1 order=%u freq=%f epsilon(s^2)=%f norm0=%f:\n",
+ order, f, e,
+ gsl_poly_eval (order, a, 1) / gsl_poly_eval (order, b, 1));
+ filter_label = "T1H";
+ }
+ else if (strcmp (arg, "t1s") == 0)
+ {
+ double fc, fr, e;
+ order = atoi (pshift ()); order = MAX (order, 1);
+ fc = atof (pshift ());
+ fr = atof (pshift ());
+ e = atof (pshift ());
+ fc *= GSL_PI / 2.;
+ fr *= GSL_PI / 2.;
+
+ a = g_new (gdouble, order + 1);
+ b = g_new (gdouble, order + 1);
+
+ gsl_filter_tscheb1_bs (order, fc, fr, e, a, b);
+ g_print ("# Bandstop Tschebyscheff Type1 order=%u freq_c=%f freq_r=%f epsilon(s^2)=%f norm=%f:\n",
+ order, fc, fr, e,
+ gsl_poly_eval (order, a, 1) / gsl_poly_eval (order, b, 1));
+ filter_label = "T1S";
+ }
+ else if (strcmp (arg, "t1p") == 0)
+ {
+ double fc, fr, e;
+ order = atoi (pshift ()); order = MAX (order, 1);
+ fc = atof (pshift ());
+ fr = atof (pshift ());
+ e = atof (pshift ());
+ fc *= GSL_PI / 2.;
+ fr *= GSL_PI / 2.;
+
+ a = g_new (gdouble, order + 1);
+ b = g_new (gdouble, order + 1);
+
+ gsl_filter_tscheb1_bp (order, fc, fr, e, a, b);
+ g_print ("# Bandpass Tschebyscheff Type1 order=%u freq_c=%f freq_r=%f epsilon(s^2)=%f norm=%f:\n",
+ order, fc, fr, e,
+ gsl_poly_eval (order, a, 1) / gsl_poly_eval (order, b, 1));
+ filter_label = "T1P";
+ }
+ else if (strcmp (arg, "t2l") == 0)
+ {
+ double f, st, e;
+ order = atoi (pshift ()); order = MAX (order, 1);
+ f = atof (pshift ());
+ st = atof (pshift ());
+ e = atof (pshift ());
+ f *= GSL_PI / 2.;
+
+ a = g_new (gdouble, order + 1);
+ b = g_new (gdouble, order + 1);
+
+ gsl_filter_tscheb2_lp (order, f, st, e, a, b);
+ g_print ("# Lowpass Tschebyscheff Type2 order=%u freq=%f steepness=%f (%f) epsilon(s^2)=%f norm=%f:\n",
+ order, f, st, f * (1.+st), e,
+ gsl_poly_eval (order, a, 1) / gsl_poly_eval (order, b, 1));
+ filter_label = "T2L";
+ }
+ else if (strcmp (arg, "t2h") == 0)
+ {
+ double f, st, e;
+ order = atoi (pshift ()); order = MAX (order, 1);
+ f = atof (pshift ());
+ st = atof (pshift ());
+ e = atof (pshift ());
+ f *= GSL_PI / 2.;
+
+ a = g_new (gdouble, order + 1);
+ b = g_new (gdouble, order + 1);
+
+ gsl_filter_tscheb2_hp (order, f, st, e, a, b);
+ g_print ("# Highpass Tschebyscheff Type2 order=%u freq=%f steepness=%f (%f, %f) epsilon(s^2)=%f norm=%f:\n",
+ order, f, st, GSL_PI - f, (GSL_PI - f) * (1.+st), e,
+ gsl_poly_eval (order, a, 1) / gsl_poly_eval (order, b, 1));
+ filter_label = "T2H";
+ }
+ else if (strcmp (arg, "t2p") == 0)
+ {
+ double f1, f2, st, e;
+ order = atoi (pshift ()); order = MAX (order, 1);
+ f1 = atof (pshift ());
+ f2 = atof (pshift ());
+ st = atof (pshift ());
+ e = atof (pshift ());
+ f1 *= GSL_PI / 2.;
+ f2 *= GSL_PI / 2.;
+
+ a = g_new (gdouble, order + 1);
+ b = g_new (gdouble, order + 1);
+
+ gsl_filter_tscheb2_bp (order, f1, f2, st, e, a, b);
+ g_print ("# Bandpass Tschebyscheff Type2 order=%u freq1=%f freq2=%f steepness=%f epsilon(s^2)=%f norm=%f:\n",
+ order, f1, f2, st, e,
+ gsl_poly_eval (order, a, 1) / gsl_poly_eval (order, b, 1));
+ filter_label = "T2P";
+ }
+ else if (strcmp (arg, "t2s") == 0)
+ {
+ double f1, f2, st, e;
+ order = atoi (pshift ()); order = MAX (order, 1);
+ f1 = atof (pshift ());
+ f2 = atof (pshift ());
+ st = atof (pshift ());
+ e = atof (pshift ());
+ f1 *= GSL_PI / 2.;
+ f2 *= GSL_PI / 2.;
+
+ a = g_new (gdouble, order + 1);
+ b = g_new (gdouble, order + 1);
+
+ gsl_filter_tscheb2_bs (order, f1, f2, st, e, a, b);
+ g_print ("# Bandstop Tschebyscheff Type2 order=%u freq1=%f freq2=%f steepness=%f epsilon(s^2)=%f norm=%f:\n",
+ order, f1, f2, st, e,
+ gsl_poly_eval (order, a, 1) / gsl_poly_eval (order, b, 1));
+ filter_label = "T2S";
+ }
+ else if (strcmp (arg, "scan") == 0)
+ {
+ filter_mode = FILTER_SCAN;
+ }
+ else if (strcmp (arg, "fir") == 0)
+ {
+ unsigned int iorder = atoi (pshift ());
+ unsigned int n_points = 0;
+
+ double *freq = g_newa (double, argc / 2 + 1);
+ double *value = g_newa (double, argc / 2 + 1);
+ double *a = g_newa (double, iorder);
+ const char *f, *v;
+
+ do
+ {
+ f = pshift ();
+ v = pshift ();
+
+ if (f[0] && v[0])
+ {
+ freq[n_points] = atof (f) * GSL_PI;
+ value[n_points] = atof (v);
+ n_points++;
+ }
+ }
+ while (f[0] && v[0]);
+
+ gsl_filter_fir_approx (iorder, a, n_points, freq, value);
+ g_print ("FIR%u(z)=%s\n", iorder, gsl_poly_str (iorder, a, "z"));
+ }
+ else if (strncmp (arg, "poly", 4) == 0)
+ {
+ guint order;
+ arg = arg + 4;
+ order = 2;
+ {
+ double a[100] = { 1, 2, 1 }, b[100] = { 1, -3./2., 0.5 };
+ g_print ("# Test order=%u norm=%f:\n",
+ order,
+ gsl_poly_eval (order, a, 1) / gsl_poly_eval (order, b, 1));
+ g_print ("H%u(z)=%s/%s\n", order,
+ gsl_poly_str (order, a, "z"),
+ gsl_poly_str (order, b, "z"));
+ if (*arg)
+ {
+ GslComplex root, roots[100];
+ guint i;
+
+ if (*arg == 'r')
+ {
+ g_print ("#roots:\n");
+ gsl_poly_complex_roots (order, a, roots);
+ for (i = 0; i < order; i++)
+ {
+ root = gsl_complex_div (gsl_complex (1, 0), roots[i]);
+ g_print ("%+.14f %+.14f # %.14f\n", root.re, root.im, gsl_complex_abs (root));
+ }
+ }
+ if (*arg == 'p')
+ {
+ g_print ("#poles:\n");
+ gsl_poly_complex_roots (order, b, roots);
+ for (i = 0; i < order; i++)
+ {
+ root = gsl_complex_div (gsl_complex (1, 0), roots[i]);
+ g_print ("%+.14f %+.14f # %.14f\n", root.re, root.im, gsl_complex_abs (root));
+ }
+ }
+ }
+ }
+ }
+ else
+ usage ();
+
+ if (a && b)
+ {
+ gdouble freq;
+
+ if (filter_mode == FILTER_SCAN)
+ {
+ freq = 0.001;
+ while (freq < 3.14)
+ {
+ g_print ("%f %.20f\n", freq, gsl_filter_sine_scan (order, a, b, freq, MAX((int)(1000.0/freq),10000)));
+ freq = MIN (freq * 1.1, freq + 0.01);
+ }
+ }
+ else if (filter_mode == FILTER_GNUPLOT)
+ {
+ g_print ("%s%u(z)=%s/%s\n", filter_label, order,
+ gsl_poly_str (order, a, "z"),
+ gsl_poly_str (order, b, "z"));
+ }
+ else
+ g_error ("unknown filter_mode");
+ g_free (a);
+ g_free (b);
+ }
+
+ arg = shift ();
+ if (arg)
+ goto restart;
+
+ return 0;
+}
+
+static void
+usage (void)
+{
+ g_print ("usage: gsltests {test} [args...]\n");
+ g_print ("tests:\n");
+ g_print (" wave-scan <file> scan a wave file for waves\n");
+ g_print (" file-test <file> test file properties\n");
+ g_print (" rf <x> <y> <z> Carlson's elliptic integral of the first kind\n");
+ g_print (" F <phi> <ak> Legendre elliptic integral of the 1st kind\n");
+ g_print (" sn <u> <emmc> Jacobian elliptic function sn()\n");
+ g_print (" asn <y> <emmc> elliptic integral, inverse sn()\n");
+ g_print (" sin <phi.re> <phi.im> complex sine\n");
+ g_print (" cos <phi.re> <phi.im> complex cosine\n");
+ g_print (" tan <phi.re> <phi.im> complex tangent\n");
+ g_print (" sinh <phi.re> <phi.im> complex hyperbolic sine\n");
+ g_print (" cosh <phi.re> <phi.im> complex hyperbolic cosine\n");
+ g_print (" tanh <phi.re> <phi.im> complex hyperbolic tangent\n");
+ g_print (" midi2freq <midinote> convert midinote into oscilaltor frequency\n");
+ g_print (" snc <u.re> <u.im> <emmc.re> <emmc.im> sn() for complex numbers\n");
+ g_print (" asnc <y.re> <y.im> <emmc.re> <emmc.im> asn() for complex numbers\n");
+ g_print (" sci_sn <u> <k2> scilab version of sn()\n");
+ g_print (" sci_asn <y> <k2> scilab version of asn()\n");
+ g_print (" sci_snc <u.re> <u.im> <k2.re> <k2.im> scilab version of snc()\n");
+ g_print (" sci_asnc <y.re> <y.im> <k2.re> <k2.im> scilab version of asnc()\n");
+ g_print (" blp <order> <freq> <epsilon> butterworth lowpass filter\n");
+ g_print (" bhp <order> <freq> <epsilon> butterworth higpass filter\n");
+ g_print (" bbp <order> <freqc> <freqr> <epsilon> butterworth bandpass filter\n");
+ g_print (" t1l <order> <freq> <epsilon> type1 tschebyscheff lowpass filter\n");
+ g_print (" t1h <order> <freq> <epsilon> type1 tschebyscheff highpass filter\n");
+ g_print (" t1s <order> <freqc> <freqr> <epsilon> type1 tschebyscheff bandstop filter\n");
+ g_print (" t1p <order> <freqc> <freqr> <epsilon> type1 tschebyscheff bandpass filter\n");
+ g_print (" t2l <order> <freqc> <steepn> <epsilon> type2 tschebyscheff lowpass filter\n");
+ g_print (" t2h <order> <freqc> <steepn> <epsilon> type2 tschebyscheff highpass filter\n");
+ g_print (" fir <order> <freq1> <value1> ... fir approximation\n");
+ g_print (" scan blp <order> <freq> <epsilon> scan butterworth lowpass filter\n");
+ g_print (" poly | polyr | polyp polynom test (+roots or +poles)\n");
+ exit (1);
+}
+
+
+
+/* vim:set ts=8 sts=2 sw=2: */
diff --git a/flow/gsl/gslwave.header b/flow/gsl/gslwave.header
new file mode 100644
index 0000000..2b0bf5b
--- /dev/null
+++ b/flow/gsl/gslwave.header
Binary files differ
diff --git a/flow/gsl/gslwavechunk.c b/flow/gsl/gslwavechunk.c
new file mode 100644
index 0000000..06a105f
--- /dev/null
+++ b/flow/gsl/gslwavechunk.c
@@ -0,0 +1,812 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001 Tim Janik
+ *
+ * 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.
+ */
+#include "gslwavechunk.h"
+
+#include "gslcommon.h"
+#include "gsldatahandle.h"
+
+#include <string.h>
+
+
+/* --- macros --- */
+#define PRINT_DEBUG_INFO (0)
+#define STATIC_ZERO_SIZE (4096)
+#define PBLOCK_SIZE(pad, n_channels) (MAX (2 * (pad), (n_channels) * gsl_get_config ()->wave_chunk_big_pad))
+
+#define PHASE_NORM(wchunk) ((GslWaveChunkMem*) (0))
+#define PHASE_NORM_BACKWARD(wchunk) ((GslWaveChunkMem*) (+1))
+#define PHASE_UNDEF(wchunk) ((GslWaveChunkMem*) (+2))
+#define PHASE_HEAD(wchunk) (&(wchunk)->head)
+#define PHASE_ENTER(wchunk) (&(wchunk)->enter)
+#define PHASE_WRAP(wchunk) (&(wchunk)->wrap)
+#define PHASE_PPWRAP(wchunk) (&(wchunk)->ppwrap)
+#define PHASE_LEAVE(wchunk) (&(wchunk)->leave)
+#define PHASE_TAIL(wchunk) (&(wchunk)->tail)
+
+
+/* --- typedefs & structures --- */
+typedef struct {
+ GslLong pos; /* input */
+ GslLong rel_pos;
+ GslLong lbound, ubound; /* PHASE_NORM/_BACKWARD */
+} Iter;
+typedef struct {
+ GslLong dir;
+ GslLong pos;
+ GslLong loop_count;
+} WPos;
+
+
+/* --- variables --- */
+static gfloat static_zero_block[STATIC_ZERO_SIZE] = { 0, }; /* FIXME */
+
+
+/* --- functions --- */
+static inline void
+wpos_step (GslWaveChunk *wchunk,
+ WPos *wpos)
+{
+ wpos->pos += wpos->dir;
+ if (wpos->loop_count)
+ {
+ if (wchunk->loop_type == GSL_WAVE_LOOP_PINGPONG)
+ {
+ if (wpos->dir < 0 &&
+ wpos->pos == wchunk->loop_first + wpos->dir)
+ {
+ wpos->loop_count--;
+ wpos->dir = -wpos->dir;
+ wpos->pos = wchunk->loop_first + wpos->dir;
+ }
+ else if (wpos->pos == wchunk->loop_last + wpos->dir)
+ {
+ wpos->loop_count--;
+ wpos->dir = -wpos->dir;
+ wpos->pos = wchunk->loop_last + wpos->dir;
+ }
+ }
+ else
+ {
+ if (wpos->pos == wchunk->loop_last + wpos->dir && wpos->loop_count)
+ {
+ wpos->loop_count--;
+ wpos->pos = wchunk->loop_first;
+ }
+ }
+ }
+}
+
+static void
+fill_block (GslWaveChunk *wchunk,
+ gfloat *block,
+ GslLong offset,
+ guint length,
+ gboolean backward,
+ guint loop_count)
+{
+ GslLong dcache_length = gsl_data_handle_length (wchunk->dcache->dhandle);
+ guint i, dnode_length = wchunk->dcache->node_size;
+ GslDataCacheNode *dnode;
+ WPos wpos;
+
+ wpos.dir = wchunk->n_channels;
+ if (backward)
+ wpos.dir = -wpos.dir;
+ wpos.pos = offset;
+ wpos.loop_count = loop_count;
+ dnode = gsl_data_cache_ref_node (wchunk->dcache, 0, TRUE);
+ for (i = 0; i < length; i++)
+ {
+ GslLong offset = wpos.pos;
+
+ if (offset < 0 || offset >= dcache_length)
+ block[i] = 0;
+ else
+ {
+ if (offset < dnode->offset || offset >= dnode->offset + dnode_length)
+ {
+ gsl_data_cache_unref_node (wchunk->dcache, dnode);
+ dnode = gsl_data_cache_ref_node (wchunk->dcache, offset, TRUE);
+ }
+ block[i] = dnode->data[offset - dnode->offset];
+ }
+ wpos_step (wchunk, &wpos);
+ }
+ gsl_data_cache_unref_node (wchunk->dcache, dnode);
+}
+
+static gfloat*
+create_block_for_offset (GslWaveChunk *wchunk,
+ GslLong offset,
+ guint length)
+{
+ GslLong padding = wchunk->n_pad_values;
+ GslLong one = wchunk->n_channels;
+ GslLong wave_last = wchunk->length - one;
+ GslLong loop_width = wchunk->loop_last - wchunk->loop_first;
+ gfloat *mem;
+ GslLong l, j, k;
+
+ if (wchunk->loop_type != GSL_WAVE_LOOP_PINGPONG)
+ loop_width += one;
+
+ l = length + 2 * padding;
+ mem = gsl_new_struct (gfloat, l);
+ offset -= padding;
+ j = ((wchunk->wave_length - one - offset) -
+ (wchunk->pploop_ends_backwards ? wchunk->loop_first : wave_last - wchunk->loop_last));
+ if (j >= 0)
+ {
+ k = j / loop_width;
+ /* g_print ("endoffset-setup: j=%ld %%=%ld, k=%ld, k&1=%ld\n", j, j % loop_width, k, k & 1); */
+ j %= loop_width;
+ if (wchunk->loop_type == GSL_WAVE_LOOP_PINGPONG)
+ {
+ if (wchunk->pploop_ends_backwards && (k & 1))
+ fill_block (wchunk, mem, wchunk->loop_last - j, l, FALSE, k);
+ else if (wchunk->pploop_ends_backwards)
+ fill_block (wchunk, mem, wchunk->loop_first + j, l, TRUE, k);
+ else if (k & 1)
+ fill_block (wchunk, mem, wchunk->loop_first + j, l, TRUE, k);
+ else
+ fill_block (wchunk, mem, wchunk->loop_last - j, l, FALSE, k);
+ }
+ else
+ fill_block (wchunk, mem, wchunk->loop_last - j, l, FALSE, k);
+ }
+ else if (wchunk->pploop_ends_backwards)
+ fill_block (wchunk, mem, wchunk->loop_first + j, l, TRUE, 0);
+ else
+ fill_block (wchunk, mem, wchunk->loop_last - j, l, FALSE, 0);
+ return mem + padding;
+}
+
+static void
+setup_pblocks (GslWaveChunk *wchunk)
+{
+ GslLong padding = wchunk->n_pad_values;
+ GslLong big_pad = PBLOCK_SIZE (wchunk->n_pad_values, wchunk->n_channels);
+ GslLong loop_width = wchunk->loop_last - wchunk->loop_first;
+ GslLong one = wchunk->n_channels;
+ GslLong loop_duration, wave_last = wchunk->length - one;
+ gfloat *mem;
+ guint l;
+
+ if (wchunk->loop_type != GSL_WAVE_LOOP_PINGPONG)
+ loop_width += one;
+ loop_duration = loop_width * wchunk->loop_count;
+
+ wchunk->head.start = -padding;
+ wchunk->head.end = big_pad;
+ wchunk->head.length = wchunk->head.end - wchunk->head.start + one;
+ wchunk->tail_start_norm = wave_last - big_pad;
+ wchunk->tail.start = wchunk->tail_start_norm + loop_duration;
+ wchunk->tail.end = wchunk->tail.start + big_pad + padding;
+ wchunk->tail.length = wchunk->tail.end - wchunk->tail.start + one;
+ if (wchunk->loop_type)
+ {
+ wchunk->enter.start = wchunk->loop_last - padding;
+ wchunk->enter.end = wchunk->loop_last + one + big_pad;
+ wchunk->wrap.start = loop_width - padding;
+ wchunk->wrap.end = big_pad;
+ if (wchunk->loop_type == GSL_WAVE_LOOP_PINGPONG)
+ {
+ wchunk->enter.end -= one;
+ wchunk->wrap.end -= one;
+ wchunk->ppwrap.start = wchunk->wrap.start;
+ wchunk->ppwrap.end = wchunk->wrap.end + loop_width;
+ wchunk->ppwrap.length = wchunk->ppwrap.end - wchunk->ppwrap.start + one;
+ wchunk->wrap.length = loop_width - wchunk->wrap.start + wchunk->wrap.end + one;
+ wchunk->wrap.start += loop_width;
+ }
+ else
+ wchunk->wrap.length = loop_width - wchunk->wrap.start + wchunk->wrap.end + one;
+ wchunk->leave_end_norm = wchunk->loop_last + big_pad;
+ wchunk->leave.start = wchunk->loop_last + loop_duration - padding;
+ wchunk->leave.end = wchunk->leave_end_norm + loop_duration;
+ if (wchunk->mini_loop)
+ {
+ wchunk->leave.start -= wchunk->wrap.length + padding;
+ wchunk->enter.end += wchunk->wrap.length + padding;
+ }
+ wchunk->leave.length = wchunk->leave.end - wchunk->leave.start + one;
+ wchunk->enter.length = wchunk->enter.end - wchunk->enter.start + one;
+ if (wchunk->pploop_ends_backwards)
+ {
+ wchunk->tail.start += wchunk->loop_last - wave_last + wchunk->loop_first;
+ wchunk->tail.end += wchunk->loop_last - wave_last + wchunk->loop_first;
+ wchunk->tail_start_norm = 0 + big_pad;
+ wchunk->leave_end_norm = wchunk->loop_first - big_pad;
+ }
+ }
+ else
+ {
+ /*
+ wchunk->enter.start = wchunk->head.end;
+ wchunk->enter.end = wchunk->head.end;
+ wchunk->enter.length = 0;
+ */
+ wchunk->enter.start = wchunk->tail.start;
+ wchunk->enter.end = wchunk->head.end;
+ wchunk->enter.length = 0;
+ wchunk->wrap.start = wchunk->tail.end + 1;
+ wchunk->wrap.end = wchunk->head.start - 1;
+ wchunk->wrap.length = 0;
+ wchunk->ppwrap.start = wchunk->tail.end + 1;
+ wchunk->ppwrap.end = wchunk->head.start - 1;
+ wchunk->ppwrap.length = 0;
+ wchunk->leave.start = wchunk->tail.start;
+ wchunk->leave.end = wchunk->tail.end;
+ wchunk->leave_end_norm = 0;
+ wchunk->leave.length = 0;
+ }
+
+ l = wchunk->head.length + 2 * padding;
+ mem = gsl_new_struct (gfloat, l);
+ fill_block (wchunk, mem, wchunk->head.start - padding, l, FALSE, wchunk->loop_count);
+ wchunk->head.mem = mem + padding;
+ if (wchunk->loop_type)
+ {
+ l = wchunk->enter.length + 2 * padding;
+ mem = gsl_new_struct (gfloat, l);
+ fill_block (wchunk, mem, wchunk->enter.start - padding, l, FALSE, wchunk->loop_count);
+ wchunk->enter.mem = mem + padding;
+ if (wchunk->loop_type == GSL_WAVE_LOOP_PINGPONG)
+ {
+ wchunk->wrap.mem = create_block_for_offset (wchunk, wchunk->loop_last + one + wchunk->wrap.start, wchunk->wrap.length);
+ wchunk->ppwrap.mem = create_block_for_offset (wchunk, wchunk->loop_last + one + wchunk->ppwrap.start, wchunk->ppwrap.length);
+ }
+ else
+ {
+ l = wchunk->wrap.length + 2 * padding;
+ mem = gsl_new_struct (gfloat, l);
+ fill_block (wchunk, mem, wchunk->loop_first + wchunk->wrap.start - padding, l, FALSE, wchunk->loop_count - 1);
+ wchunk->wrap.mem = mem + padding;
+ }
+ wchunk->leave.mem = create_block_for_offset (wchunk, wchunk->leave.start, wchunk->leave.length);
+ }
+ wchunk->tail.mem = create_block_for_offset (wchunk, wchunk->tail.start, wchunk->tail.length);
+}
+
+static inline GslWaveChunkMem*
+wave_identify_offset (GslWaveChunk *wchunk,
+ Iter *iter)
+{
+ GslLong pos = iter->pos;
+ GslLong one = wchunk->n_channels;
+
+ if (pos < wchunk->head.start) /* outside wave boundaries */
+ {
+ iter->lbound = 0;
+ iter->rel_pos = wchunk->n_pad_values;
+ iter->ubound = iter->rel_pos + MIN (STATIC_ZERO_SIZE - 2 * wchunk->n_pad_values, wchunk->head.start - pos);
+ if (PRINT_DEBUG_INFO)
+ g_print ("PHASE_UNDEF, pre-head %ld %ld %ld\n", iter->lbound, iter->rel_pos, iter->ubound);
+ return PHASE_UNDEF (wchunk);
+ }
+ if (pos > wchunk->tail.end) /* outside wave boundaries */
+ {
+ iter->lbound = 0;
+ iter->rel_pos = wchunk->n_pad_values;
+ iter->ubound = iter->rel_pos + MIN (STATIC_ZERO_SIZE - 2 * wchunk->n_pad_values, pos - wchunk->tail.end);
+ if (PRINT_DEBUG_INFO)
+ g_print ("PHASE_UNDEF, post-tail %ld %ld %ld\n", iter->lbound, iter->rel_pos, iter->ubound);
+ return PHASE_UNDEF (wchunk);
+ }
+ if (pos <= wchunk->head.end)
+ {
+ iter->rel_pos = pos - wchunk->head.start;
+ if (PRINT_DEBUG_INFO)
+ g_print ("PHASE_HEAD %ld %ld %ld\n", wchunk->head.start, iter->rel_pos, wchunk->head.end);
+ return PHASE_HEAD (wchunk);
+ }
+ else if (pos <= wchunk->enter.end) /* before loop */
+ {
+ if (pos >= wchunk->enter.start)
+ {
+ iter->rel_pos = pos - wchunk->enter.start;
+ if (PRINT_DEBUG_INFO)
+ g_print ("PHASE_ENTER %ld %ld %ld\n", wchunk->enter.start, iter->rel_pos, wchunk->enter.end);
+ return PHASE_ENTER (wchunk);
+ }
+ iter->rel_pos = pos - wchunk->head.end;
+ iter->lbound = wchunk->head.end;
+ iter->ubound = wchunk->enter.start;
+ if (PRINT_DEBUG_INFO)
+ g_print ("PHASE_NORM, pre-enter %ld %ld %ld\n", iter->lbound, iter->rel_pos, iter->ubound);
+ return PHASE_NORM (wchunk);
+ }
+ else if (pos >= wchunk->tail.start)
+ {
+ iter->rel_pos = pos - wchunk->tail.start;
+ if (PRINT_DEBUG_INFO)
+ g_print ("PHASE_TAIL %ld %ld %ld\n", wchunk->tail.start, iter->rel_pos, wchunk->tail.end);
+ return PHASE_TAIL (wchunk);
+ }
+ else if (pos >= wchunk->leave.start) /* after loop */
+ {
+ if (pos <= wchunk->leave.end)
+ {
+ iter->rel_pos = pos - wchunk->leave.start;
+ if (PRINT_DEBUG_INFO)
+ g_print ("PHASE_LEAVE %ld %ld %ld\n", wchunk->leave.start, iter->rel_pos, wchunk->leave.end);
+ return PHASE_LEAVE (wchunk);
+ }
+ iter->rel_pos = pos - wchunk->leave.end;
+ if (wchunk->pploop_ends_backwards)
+ {
+ iter->lbound = wchunk->tail_start_norm;
+ iter->ubound = wchunk->leave_end_norm;
+ if (PRINT_DEBUG_INFO)
+ g_print ("PHASE_NORM_BACKWARD, post-leave %ld %ld %ld\n", iter->lbound, iter->rel_pos, iter->ubound);
+ return PHASE_NORM_BACKWARD (wchunk);
+ }
+ else
+ {
+ iter->lbound = wchunk->leave_end_norm;
+ iter->ubound = wchunk->tail_start_norm;
+ if (PRINT_DEBUG_INFO)
+ g_print ("PHASE_NORM, post-leave %ld %ld %ld\n", iter->lbound, iter->rel_pos, iter->ubound);
+ return PHASE_NORM (wchunk);
+ }
+ }
+ else if (wchunk->loop_type == GSL_WAVE_LOOP_PINGPONG) /* in ping-pong loop */
+ {
+ guint loop_width = wchunk->loop_last - wchunk->loop_first;
+
+ pos -= wchunk->loop_last + one;
+ pos %= 2 * loop_width;
+ if (pos <= wchunk->ppwrap.end)
+ {
+ if (pos <= wchunk->wrap.end)
+ {
+ iter->rel_pos = wchunk->wrap.length - one - wchunk->wrap.end + pos;
+ if (PRINT_DEBUG_INFO)
+ g_print ("PHASE_WRAP %ld %ld %ld\n", wchunk->wrap.start, iter->rel_pos, wchunk->wrap.end);
+ return PHASE_WRAP (wchunk);
+ }
+ if (pos >= wchunk->ppwrap.start)
+ {
+ iter->rel_pos = pos - wchunk->ppwrap.start;
+ if (PRINT_DEBUG_INFO)
+ g_print ("PHASE_PPWRAP %ld %ld %ld\n", wchunk->ppwrap.start, iter->rel_pos, wchunk->ppwrap.end);
+ return PHASE_PPWRAP (wchunk);
+ }
+ iter->ubound = wchunk->loop_last - one - wchunk->wrap.end;
+ iter->lbound = wchunk->loop_last - one - wchunk->ppwrap.start;
+ iter->rel_pos = pos - wchunk->wrap.end;
+ if (PRINT_DEBUG_INFO)
+ g_print ("PHASE_NORM_BACKWARD, pploop %ld %ld %ld\n", iter->lbound, iter->rel_pos, iter->ubound);
+ return PHASE_NORM_BACKWARD (wchunk);
+ }
+ if (pos >= wchunk->wrap.start)
+ {
+ iter->rel_pos = pos - wchunk->wrap.start;
+ if (PRINT_DEBUG_INFO)
+ g_print ("PHASE_WRAP %ld %ld %ld\n", wchunk->wrap.start, iter->rel_pos, wchunk->wrap.end);
+ return PHASE_WRAP (wchunk);
+ }
+ iter->rel_pos = pos - wchunk->ppwrap.end;
+ iter->ubound = wchunk->loop_first + one + wchunk->wrap.start - loop_width;
+ iter->lbound = wchunk->loop_first + one + wchunk->ppwrap.end - loop_width;
+ if (PRINT_DEBUG_INFO)
+ g_print ("PHASE_NORM, pploop %ld %ld %ld\n", iter->lbound, iter->rel_pos, iter->ubound);
+ return PHASE_NORM (wchunk);
+ }
+ else if (wchunk->loop_type == GSL_WAVE_LOOP_JUMP) /* in jump loop */
+ {
+ guint loop_width = wchunk->loop_last - wchunk->loop_first + one;
+
+ pos -= wchunk->loop_last + one;
+ pos %= loop_width;
+ if (pos >= wchunk->wrap.start)
+ {
+ iter->rel_pos = pos - wchunk->wrap.start;
+ if (PRINT_DEBUG_INFO)
+ g_print ("PHASE_WRAP %ld %ld %ld\n", wchunk->wrap.start, iter->rel_pos, wchunk->wrap.end);
+ return PHASE_WRAP (wchunk);
+ }
+ if (pos <= wchunk->wrap.end)
+ {
+ iter->rel_pos = wchunk->wrap.length - one - wchunk->wrap.end + pos;
+ if (PRINT_DEBUG_INFO)
+ g_print ("PHASE_WRAP %ld %ld %ld\n", wchunk->wrap.start, iter->rel_pos, wchunk->wrap.end);
+ return PHASE_WRAP (wchunk);
+ }
+ iter->rel_pos = pos - wchunk->wrap.end;
+ iter->lbound = wchunk->loop_first + wchunk->wrap.end;
+ iter->ubound = wchunk->loop_first + wchunk->wrap.start;
+ if (PRINT_DEBUG_INFO)
+ g_print ("PHASE_NORM, jloop %ld %ld %ld\n", iter->lbound, iter->rel_pos, iter->ubound);
+ return PHASE_NORM (wchunk);
+ }
+ iter->rel_pos = pos - wchunk->head.end;
+ iter->lbound = wchunk->head.end;
+ iter->ubound = wchunk->enter.start;
+ if (PRINT_DEBUG_INFO)
+ g_print ("PHASE_NORM, noloop %ld %ld %ld\n", iter->lbound, iter->rel_pos, iter->ubound);
+ return PHASE_NORM (wchunk);
+}
+
+void
+gsl_wave_chunk_use_block (GslWaveChunk *wchunk,
+ GslWaveChunkBlock *block)
+{
+ GslWaveChunkMem *phase;
+ GslLong one;
+ Iter iter;
+ gboolean reverse;
+
+ g_return_if_fail (wchunk != NULL);
+ g_return_if_fail (wchunk->open_count > 0);
+ g_return_if_fail (block != NULL);
+ g_return_if_fail (wchunk->dcache != NULL);
+ g_return_if_fail (block->node == NULL);
+ g_return_if_fail (block->play_dir == -1 || block->play_dir == +1);
+
+ block->offset /= wchunk->n_channels;
+ block->offset *= wchunk->n_channels;
+
+ one = wchunk->n_channels;
+ reverse = block->play_dir < 0;
+ iter.pos = block->offset;
+ phase = wave_identify_offset (wchunk, &iter);
+
+ block->is_silent = FALSE;
+ if (phase <= PHASE_UNDEF (wchunk))
+ {
+ GslDataCacheNode *dnode;
+ guint offset;
+
+ if (phase == PHASE_UNDEF (wchunk))
+ {
+ block->is_silent = TRUE;
+ reverse = FALSE;
+ block->length = (iter.ubound - iter.rel_pos) / wchunk->n_channels;
+ block->length *= wchunk->n_channels;
+ g_assert (block->length <= STATIC_ZERO_SIZE - 2 * wchunk->n_pad_values);
+ block->start = static_zero_block + iter.rel_pos;
+ }
+ else
+ {
+ GslLong max_length;
+
+ if (phase == PHASE_NORM_BACKWARD (wchunk))
+ {
+ offset = iter.ubound - iter.rel_pos;
+ reverse = !reverse;
+ }
+ else
+ offset = iter.lbound + iter.rel_pos;
+ max_length = reverse ? offset - iter.lbound : iter.ubound - offset;
+ dnode = gsl_data_cache_ref_node (wchunk->dcache, offset, TRUE); /* FIXME: demand_load */
+ offset -= dnode->offset;
+ block->start = dnode->data + offset;
+ if (reverse)
+ {
+ block->length = 1 + offset / wchunk->n_channels;
+ block->length *= wchunk->n_channels;
+ }
+ else
+ {
+ block->length = (wchunk->dcache->node_size - offset) / wchunk->n_channels;
+ block->length *= wchunk->n_channels;
+ }
+ block->length = MIN (block->length, max_length);
+ block->node = dnode;
+ }
+ }
+ else
+ {
+ block->start = phase->mem + iter.rel_pos;
+ if (reverse)
+ block->length = one + iter.rel_pos;
+ else
+ block->length = phase->length - iter.rel_pos;
+ }
+ if (reverse)
+ {
+ block->dirstride = -wchunk->n_channels;
+ block->end = block->start - block->length;
+ }
+ else
+ {
+ block->dirstride = +wchunk->n_channels;
+ block->end = block->start + block->length;
+ }
+ g_assert (block->length > 0);
+ /* we might want to partly reset this at some point to implement
+ * truly infinite loops
+ */
+ block->next_offset = block->offset + (block->play_dir > 0 ? block->length : -block->length);
+}
+
+void
+gsl_wave_chunk_unuse_block (GslWaveChunk *wchunk,
+ GslWaveChunkBlock *block)
+{
+ g_return_if_fail (wchunk != NULL);
+ g_return_if_fail (block != NULL);
+ g_return_if_fail (wchunk->dcache != NULL);
+
+ if (block->node)
+ {
+ gsl_data_cache_unref_node (wchunk->dcache, block->node);
+ block->node = NULL;
+ }
+}
+
+static void
+wave_chunk_setup_loop (GslWaveChunk *wchunk)
+{
+ GslWaveLoopType loop_type = wchunk->requested_loop_type;
+ GslLong loop_first = wchunk->requested_loop_first;
+ GslLong loop_last = wchunk->requested_loop_last;
+ guint loop_count = wchunk->requested_loop_count;
+ GslLong one, padding, big_pad;
+
+ g_return_if_fail (wchunk->open_count > 0);
+
+ one = wchunk->n_channels;
+ padding = wchunk->n_pad_values;
+ big_pad = PBLOCK_SIZE (wchunk->n_pad_values, wchunk->n_channels);
+
+ /* check validity */
+ if (loop_count < 1 || loop_first < 0 || loop_last < 0 || wchunk->length < 1)
+ loop_type = GSL_WAVE_LOOP_NONE;
+
+ /* setup loop types */
+ switch (loop_type)
+ {
+ case GSL_WAVE_LOOP_JUMP:
+ loop_first /= wchunk->n_channels;
+ loop_last /= wchunk->n_channels;
+ if (loop_last >= wchunk->length ||
+ loop_first >= loop_last)
+ goto CASE_DONT_LOOP;
+ wchunk->loop_type = loop_type;
+ wchunk->loop_first = loop_first * wchunk->n_channels;
+ wchunk->loop_last = loop_last * wchunk->n_channels;
+ wchunk->loop_count = (G_MAXINT - wchunk->length) / (wchunk->loop_last - wchunk->loop_first + one);
+ wchunk->loop_count = MIN (wchunk->loop_count, loop_count);
+ wchunk->wave_length = wchunk->length + (wchunk->loop_last - wchunk->loop_first + one) * wchunk->loop_count;
+ break;
+ case GSL_WAVE_LOOP_PINGPONG:
+ loop_first /= wchunk->n_channels;
+ loop_last /= wchunk->n_channels;
+ if (loop_last >= wchunk->length ||
+ loop_first >= loop_last)
+ goto CASE_DONT_LOOP;
+ wchunk->loop_type = loop_type;
+ wchunk->loop_first = loop_first * wchunk->n_channels;
+ wchunk->loop_last = loop_last * wchunk->n_channels;
+ wchunk->loop_count = (G_MAXINT - wchunk->loop_last - one) / (wchunk->loop_last - wchunk->loop_first);
+ wchunk->loop_count = MIN (wchunk->loop_count, loop_count);
+ wchunk->wave_length = wchunk->loop_last + one + (wchunk->loop_last - wchunk->loop_first) * wchunk->loop_count;
+ if (wchunk->loop_count & 1) /* FIXME */
+ wchunk->wave_length += wchunk->loop_first;
+ else
+ wchunk->wave_length += wchunk->length - one - wchunk->loop_last;
+ break;
+ CASE_DONT_LOOP:
+ loop_type = GSL_WAVE_LOOP_NONE;
+ case GSL_WAVE_LOOP_NONE:
+ wchunk->loop_type = loop_type;
+ wchunk->loop_first = wchunk->length + 1;
+ wchunk->loop_last = -1;
+ wchunk->loop_count = 0;
+ wchunk->wave_length = wchunk->length;
+ break;
+ }
+ wchunk->pploop_ends_backwards = wchunk->loop_type == GSL_WAVE_LOOP_PINGPONG && (wchunk->loop_count & 1);
+ wchunk->mini_loop = wchunk->loop_type && wchunk->loop_last - wchunk->loop_first < 2 * big_pad + padding;
+}
+
+GslWaveChunk*
+gsl_wave_chunk_new (GslDataCache *dcache,
+ gfloat osc_freq,
+ gfloat mix_freq,
+ GslWaveLoopType loop_type,
+ GslLong loop_first,
+ GslLong loop_last,
+ guint loop_count)
+{
+ GslWaveChunk *wchunk;
+
+ g_return_val_if_fail (dcache != NULL, NULL);
+ g_return_val_if_fail (osc_freq < mix_freq / 2, NULL);
+ g_return_val_if_fail (loop_type >= GSL_WAVE_LOOP_NONE && loop_type <= GSL_WAVE_LOOP_PINGPONG, NULL);
+
+ wchunk = gsl_new_struct0 (GslWaveChunk, 1);
+ wchunk->dcache = gsl_data_cache_ref (dcache);
+ wchunk->length = 0;
+ wchunk->n_channels = 0;
+ wchunk->n_pad_values = 0;
+ wchunk->wave_length = 0;
+ wchunk->loop_type = GSL_WAVE_LOOP_NONE;
+ wchunk->leave_end_norm = 0;
+ wchunk->tail_start_norm = 0;
+ wchunk->ref_count = 1;
+ wchunk->open_count = 0;
+ wchunk->mix_freq = mix_freq;
+ wchunk->osc_freq = osc_freq;
+ wchunk->requested_loop_type = loop_type;
+ wchunk->requested_loop_first = loop_first;
+ wchunk->requested_loop_last = loop_last;
+ wchunk->requested_loop_count = loop_count;
+
+ return wchunk;
+}
+
+GslWaveChunk*
+gsl_wave_chunk_ref (GslWaveChunk *wchunk)
+{
+ g_return_val_if_fail (wchunk != NULL, NULL);
+ g_return_val_if_fail (wchunk->ref_count > 0, NULL);
+
+ wchunk->ref_count++;
+ return wchunk;
+}
+
+void
+gsl_wave_chunk_unref (GslWaveChunk *wchunk)
+{
+ g_return_if_fail (wchunk != NULL);
+ g_return_if_fail (wchunk->ref_count > 0);
+
+ wchunk->ref_count--;
+ if (wchunk->ref_count == 0)
+ {
+ g_return_if_fail (wchunk->open_count == 0);
+ gsl_data_cache_unref (wchunk->dcache);
+ gsl_delete_struct (GslWaveChunk, wchunk);
+ }
+}
+
+GslErrorType
+gsl_wave_chunk_open (GslWaveChunk *wchunk)
+{
+ g_return_val_if_fail (wchunk != NULL, GSL_ERROR_INTERNAL);
+ g_return_val_if_fail (wchunk->ref_count > 0, GSL_ERROR_INTERNAL);
+
+ if (wchunk->open_count == 0)
+ {
+ GslErrorType error;
+
+ error = gsl_data_handle_open (wchunk->dcache->dhandle);
+ if (error != GSL_ERROR_NONE)
+ return error;
+ if (gsl_data_handle_n_values (wchunk->dcache->dhandle) < gsl_data_handle_n_channels (wchunk->dcache->dhandle))
+ {
+ gsl_data_handle_close (wchunk->dcache->dhandle);
+ return GSL_ERROR_FILE_EMPTY;
+ }
+ wchunk->n_channels = gsl_data_handle_n_channels (wchunk->dcache->dhandle);
+ wchunk->length = gsl_data_handle_n_values (wchunk->dcache->dhandle) / wchunk->n_channels;
+ wchunk->length *= wchunk->n_channels;
+ wchunk->n_pad_values = gsl_get_config ()->wave_chunk_padding * wchunk->n_channels;
+ gsl_data_cache_open (wchunk->dcache);
+ gsl_data_handle_close (wchunk->dcache->dhandle);
+ g_return_val_if_fail (wchunk->dcache->padding >= wchunk->n_pad_values, GSL_ERROR_INTERNAL);
+ wchunk->open_count++;
+ wchunk->ref_count++;
+ wave_chunk_setup_loop (wchunk);
+ setup_pblocks (wchunk);
+ }
+ else
+ wchunk->open_count++;
+ return GSL_ERROR_NONE;
+}
+
+void
+gsl_wave_chunk_close (GslWaveChunk *wchunk)
+{
+ GslLong padding;
+
+ g_return_if_fail (wchunk != NULL);
+ g_return_if_fail (wchunk->open_count > 0);
+ g_return_if_fail (wchunk->ref_count > 0);
+
+ wchunk->open_count--;
+ if (wchunk->open_count)
+ return;
+
+ padding = wchunk->n_pad_values;
+ gsl_data_cache_close (wchunk->dcache);
+ if (wchunk->head.mem)
+ gsl_delete_structs (gfloat, wchunk->head.length + 2 * padding, wchunk->head.mem - padding);
+ memset (&wchunk->head, 0, sizeof (GslWaveChunkMem));
+ if (wchunk->enter.mem)
+ gsl_delete_structs (gfloat, wchunk->enter.length + 2 * padding, wchunk->enter.mem - padding);
+ memset (&wchunk->enter, 0, sizeof (GslWaveChunkMem));
+ if (wchunk->wrap.mem)
+ gsl_delete_structs (gfloat, wchunk->wrap.length + 2 * padding, wchunk->wrap.mem - padding);
+ memset (&wchunk->wrap, 0, sizeof (GslWaveChunkMem));
+ if (wchunk->ppwrap.mem)
+ gsl_delete_structs (gfloat, wchunk->ppwrap.length + 2 * padding, wchunk->ppwrap.mem - padding);
+ memset (&wchunk->ppwrap, 0, sizeof (GslWaveChunkMem));
+ if (wchunk->leave.mem)
+ gsl_delete_structs (gfloat, wchunk->leave.length + 2 * padding, wchunk->leave.mem - padding);
+ memset (&wchunk->leave, 0, sizeof (GslWaveChunkMem));
+ if (wchunk->tail.mem)
+ gsl_delete_structs (gfloat, wchunk->tail.length + 2 * padding, wchunk->tail.mem - padding);
+ memset (&wchunk->tail, 0, sizeof (GslWaveChunkMem));
+ wchunk->length = 0;
+ wchunk->n_channels = 0;
+ wchunk->n_pad_values = 0;
+ wchunk->wave_length = 0;
+ wchunk->loop_type = GSL_WAVE_LOOP_NONE;
+ wchunk->leave_end_norm = 0;
+ wchunk->tail_start_norm = 0;
+ gsl_wave_chunk_unref (wchunk);
+}
+
+void
+gsl_wave_chunk_debug_block (GslWaveChunk *wchunk,
+ GslLong offset,
+ GslLong length,
+ gfloat *block)
+{
+ g_return_if_fail (wchunk != NULL);
+
+ fill_block (wchunk, block, offset, length, FALSE, wchunk->loop_count);
+}
+
+GslWaveChunk*
+_gsl_wave_chunk_copy (GslWaveChunk *wchunk)
+{
+ g_return_val_if_fail (wchunk != NULL, NULL);
+ g_return_val_if_fail (wchunk->ref_count > 0, NULL);
+
+ return gsl_wave_chunk_new (wchunk->dcache,
+ wchunk->osc_freq,
+ wchunk->mix_freq,
+ wchunk->loop_type,
+ wchunk->loop_first,
+ wchunk->loop_last,
+ wchunk->loop_count);
+}
+
+const gchar*
+gsl_wave_loop_type_to_string (GslWaveLoopType wave_loop)
+{
+ g_return_val_if_fail (wave_loop >= GSL_WAVE_LOOP_NONE && wave_loop <= GSL_WAVE_LOOP_PINGPONG, NULL);
+
+ switch (wave_loop)
+ {
+ case GSL_WAVE_LOOP_NONE: return "none";
+ case GSL_WAVE_LOOP_JUMP: return "jump";
+ case GSL_WAVE_LOOP_PINGPONG: return "pingpong";
+ default: return NULL;
+ }
+}
+
+GslWaveLoopType
+gsl_wave_loop_type_from_string (const gchar *string)
+{
+ g_return_val_if_fail (string != NULL, 0);
+
+ while (*string == ' ')
+ string++;
+ if (strncasecmp (string, "jump", 4) == 0)
+ return GSL_WAVE_LOOP_JUMP;
+ if (strncasecmp (string, "pingpong", 8) == 0)
+ return GSL_WAVE_LOOP_PINGPONG;
+ return GSL_WAVE_LOOP_NONE;
+}
diff --git a/flow/gsl/gslwavechunk.h b/flow/gsl/gslwavechunk.h
new file mode 100644
index 0000000..c4deaf5
--- /dev/null
+++ b/flow/gsl/gslwavechunk.h
@@ -0,0 +1,129 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001 Tim Janik
+ *
+ * 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.
+ */
+#ifndef __GSL_WAVE_CHUNK_H__
+#define __GSL_WAVE_CHUNK_H__
+
+#include <gsl/gsldefs.h>
+#include <gsl/gsldatacache.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* --- typedefs & structures --- */
+typedef enum /*< skip >*/
+{
+ GSL_WAVE_LOOP_NONE,
+ GSL_WAVE_LOOP_JUMP,
+ GSL_WAVE_LOOP_PINGPONG
+} GslWaveLoopType;
+typedef struct
+{
+ GslLong start, end, length;
+ gfloat *mem;
+} GslWaveChunkMem;
+struct _GslWaveChunk
+{
+ /* wave chunk data residency */
+ GslDataCache *dcache;
+ GslLong length; /* number of per-channel-values * n-channels */
+
+ /* chunk specific parameters */
+ gint n_channels;
+ GslLong n_pad_values; /* guaranteed pad values around blocks */
+ GslLong wave_length; /* start + loop duration + end (single channel) */
+
+ /* flags */
+ guint pploop_ends_backwards : 1;
+ guint mini_loop : 1;
+
+ /* loop spec */
+ GslWaveLoopType loop_type;
+ GslLong loop_first;
+ GslLong loop_last;
+ guint loop_count;
+
+ /* preformatted blocks */
+ GslWaveChunkMem head;
+ GslWaveChunkMem enter;
+ GslWaveChunkMem wrap;
+ GslWaveChunkMem ppwrap;
+ GslWaveChunkMem leave;
+ GslWaveChunkMem tail;
+ GslLong leave_end_norm;
+ GslLong tail_start_norm;
+
+ GslWaveLoopType requested_loop_type;
+ GslLong requested_loop_first;
+ GslLong requested_loop_last;
+ guint requested_loop_count;
+ guint ref_count;
+ guint open_count;
+ /* legacy */
+ gfloat mix_freq; /* recorded with mix_freq */
+ gfloat osc_freq; /* while oscillating at osc_freq */
+};
+struct _GslWaveChunkBlock
+{
+ /* requisition (in) */
+ gint play_dir; /* usually +1 */
+ GslLong offset; /* requested offset into wave */
+ /* result (out) */
+ GslLong length; /* resulting signed? length of block in # values */
+ gboolean is_silent; /* sample end reached, values are 0 */
+ gint dirstride; /* >0 => increment, <0 => decrement */
+ gfloat *start; /* first data value location */
+ gfloat *end; /* last data value location +1 */
+ GslLong next_offset; /* offset of next adjunct block */
+ /*< private >*/
+ gpointer node;
+};
+
+
+/* --- prototypes --- */
+void gsl_wave_chunk_use_block (GslWaveChunk *wave_chunk,
+ GslWaveChunkBlock *block);
+void gsl_wave_chunk_unuse_block (GslWaveChunk *wave_chunk,
+ GslWaveChunkBlock *block);
+GslWaveChunk* gsl_wave_chunk_new (GslDataCache *dcache,
+ gfloat osc_freq,
+ gfloat mix_freq,
+ GslWaveLoopType loop_type,
+ GslLong loop_first,
+ GslLong loop_end,
+ guint loop_count);
+GslWaveChunk* gsl_wave_chunk_ref (GslWaveChunk *wchunk);
+void gsl_wave_chunk_unref (GslWaveChunk *wchunk);
+GslErrorType gsl_wave_chunk_open (GslWaveChunk *wchunk);
+void gsl_wave_chunk_close (GslWaveChunk *wchunk);
+void gsl_wave_chunk_debug_block (GslWaveChunk *wchunk,
+ GslLong offset,
+ GslLong length,
+ gfloat *block);
+GslWaveChunk* _gsl_wave_chunk_copy (GslWaveChunk *wchunk);
+const gchar* gsl_wave_loop_type_to_string (GslWaveLoopType wave_loop);
+GslWaveLoopType gsl_wave_loop_type_from_string (const gchar *string);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_WAVE_CHUNK_H__ */
diff --git a/flow/gsl/gslwaveloader.c b/flow/gsl/gslwaveloader.c
new file mode 100644
index 0000000..cd097d9
--- /dev/null
+++ b/flow/gsl/gslwaveloader.c
@@ -0,0 +1,2 @@
+#include <gsl/gslwaveloader.h>
+
diff --git a/flow/gsl/gslwaveloader.h b/flow/gsl/gslwaveloader.h
new file mode 100644
index 0000000..7453359
--- /dev/null
+++ b/flow/gsl/gslwaveloader.h
@@ -0,0 +1,6 @@
+
+#ifndef GSLWAVELOADER_H
+#define GSLWAVELOADER_H
+
+#endif // GSLWAVELOADER_H
+
diff --git a/flow/gsl/gslwaveosc-aux.c b/flow/gsl/gslwaveosc-aux.c
new file mode 100644
index 0000000..4485242
--- /dev/null
+++ b/flow/gsl/gslwaveosc-aux.c
@@ -0,0 +1,249 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001-2002 Tim Janik and Stefan Westerfeld
+ *
+ * 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 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.
+ */
+
+
+#define CHECK_SYNC (WOSC_MIX_VARIANT & WOSC_MIX_WITH_SYNC)
+#define CHECK_FREQ (WOSC_MIX_VARIANT & WOSC_MIX_WITH_FREQ)
+#define CHECK_MOD (WOSC_MIX_VARIANT & WOSC_MIX_WITH_MOD)
+#define EXPONENTIAL_FM (WOSC_MIX_VARIANT & WOSC_MIX_WITH_EXP_FM)
+#define DIRSTRIDE(b) (b->dirstride) /* (1) change for n_channel stepping */
+
+
+static void
+WOSC_MIX_VARIANT_NAME (GslWaveOscData *wosc,
+ guint n_values,
+ const gfloat *freq_in,
+ const gfloat *mod_in,
+ const gfloat *sync_in,
+ gfloat *wave_out)
+{
+ gfloat *wave_boundary;
+ gfloat last_sync_level = wosc->last_sync_level;
+ gfloat last_freq_level = wosc->last_freq_level;
+ gfloat last_mod_level = wosc->last_mod_level;
+ GslWaveChunkBlock *block = &wosc->block;
+ gdouble *a = wosc->a, *b = wosc->b, *y = wosc->y;
+ gfloat *boundary = block->end;
+ guint wosc_j = wosc->j;
+
+ /* do the mixing */
+ wave_boundary = wave_out + n_values;
+ do
+ {
+ gfloat ffrac;
+
+ if (CHECK_SYNC)
+ {
+ gfloat sync_level = *sync_in++;
+ if_reject (GSL_SIGNAL_RAISING_EDGE (last_sync_level, sync_level))
+ {
+ wosc->j = wosc_j;
+ gsl_wave_osc_retrigger (wosc, CHECK_FREQ ? GSL_SIGNAL_TO_FREQ (*freq_in) : wosc->config.cfreq);
+ /* retrigger alters last_freq and last_mod */
+ last_freq_level = wosc->last_freq_level;
+ last_mod_level = wosc->last_mod_level;
+ wosc_j = wosc->j;
+ boundary = block->end;
+ /* FIXME: g_assert (ABS (block->dirstride) == 1); */
+ last_sync_level = sync_level;
+ }
+ }
+ if (CHECK_MOD && CHECK_FREQ)
+ {
+ gfloat mod_level = *mod_in++, freq_level = *freq_in++;
+ if_reject (GSL_SIGNAL_FREQ_CHANGED (last_freq_level, freq_level))
+ {
+ last_freq_level = freq_level;
+ if (GSL_SIGNAL_MOD_CHANGED (last_mod_level, mod_level))
+ last_mod_level = mod_level;
+ goto UPDATE_FREQ;
+ }
+ else if_reject (GSL_SIGNAL_MOD_CHANGED (last_mod_level, mod_level))
+ {
+ gfloat new_freq;
+ last_mod_level = mod_level;
+ UPDATE_FREQ:
+ new_freq = GSL_SIGNAL_TO_FREQ (freq_level);
+ if (EXPONENTIAL_FM)
+ new_freq *= gsl_signal_exp2 (wosc->config.fm_strength * mod_level);
+ else /* LINEAR_FM */
+ new_freq *= 1.0 + wosc->config.fm_strength * mod_level;
+ wave_osc_transform_filter (wosc, new_freq);
+ }
+ }
+ else if (CHECK_MOD)
+ {
+ gfloat mod_level = *mod_in++;
+ if (GSL_SIGNAL_MOD_CHANGED (last_mod_level, mod_level))
+ {
+ gfloat new_freq = wosc->config.cfreq;
+ if (EXPONENTIAL_FM)
+ new_freq *= gsl_signal_exp2 (wosc->config.fm_strength * mod_level);
+ else /* LINEAR_FM */
+ new_freq *= 1.0 + wosc->config.fm_strength * mod_level;
+ last_mod_level = mod_level;
+ wave_osc_transform_filter (wosc, new_freq);
+ }
+ }
+ else if (CHECK_FREQ)
+ {
+ gfloat freq_level = *freq_in++;
+ if (GSL_SIGNAL_FREQ_CHANGED (last_freq_level, freq_level))
+ {
+ last_freq_level = freq_level;
+ wave_osc_transform_filter (wosc, GSL_SIGNAL_TO_FREQ (freq_level));
+ }
+ }
+
+ /* process filter while necesary */
+ while (wosc->cur_pos >= (FRAC_MASK + 1) << 1)
+ {
+ gfloat c, c0, c1, c2, c3, c4, c5, c6, c7, c8;
+ gfloat d, d0, d1, d2, d3, d4, d5, d6, d7;
+ gfloat *x;
+
+ if_reject (wosc->x >= boundary) /* wchunk block boundary */
+ {
+ GslLong next_offset = block->next_offset;
+
+ gsl_wave_chunk_unuse_block (wosc->wchunk, block);
+ block->play_dir = wosc->config.play_dir;
+ block->offset = next_offset;
+ gsl_wave_chunk_use_block (wosc->wchunk, block);
+ wosc->x = block->start + wosc->config.channel;
+ boundary = block->end;
+ /* FIXME: g_assert (ABS (block->dirstride) == 1); */
+ }
+
+ if_expect (block->dirstride > 0)
+ {
+ x = wosc->x;
+ d0 = b[0] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d1 = b[1] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d2 = b[2] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d3 = b[3] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d4 = b[4] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d5 = b[5] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d6 = b[6] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d7 = b[7] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ c8 = a[8] * x[-4 * DIRSTRIDE (block)];
+ c6 = a[6] * x[-3 * DIRSTRIDE (block)];
+ c4 = a[4] * x[-2 * DIRSTRIDE (block)];
+ c2 = a[2] * x[-1 * DIRSTRIDE (block)];
+ c0 = a[0] * x[0 * DIRSTRIDE (block)];
+ d = d0 + d1 + d2 + d3 + d4 + d5 + d6 + d7;
+ c = c0 + c2 + c4 + c6 + c8;
+ y[wosc_j] = c - d; wosc_j++; wosc_j &= 0x7;
+ d0 = b[0] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d1 = b[1] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d2 = b[2] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d3 = b[3] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d4 = b[4] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d5 = b[5] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d6 = b[6] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d7 = b[7] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ c7 = a[7] * x[-3 * DIRSTRIDE (block)];
+ c5 = a[5] * x[-2 * DIRSTRIDE (block)];
+ c3 = a[3] * x[-1 * DIRSTRIDE (block)];
+ c1 = a[1] * x[0 * DIRSTRIDE (block)];
+ d = d0 + d1 + d2 + d3 + d4 + d5 + d6 + d7;
+ c = c1 + c3 + c5 + c7;
+ y[wosc_j] = c - d; wosc_j++; wosc_j &= 0x7;
+ wosc->x += DIRSTRIDE (block);
+ }
+ else /* dirstride < 0 */
+ {
+ x = wosc->x;
+ d0 = b[0] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d1 = b[1] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d2 = b[2] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d3 = b[3] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d4 = b[4] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d5 = b[5] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d6 = b[6] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d7 = b[7] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ c8 = a[8] * x[-4 * -DIRSTRIDE (block)];
+ c6 = a[6] * x[-3 * -DIRSTRIDE (block)];
+ c4 = a[4] * x[-2 * -DIRSTRIDE (block)];
+ c2 = a[2] * x[-1 * -DIRSTRIDE (block)];
+ c0 = a[0] * x[0 * -DIRSTRIDE (block)];
+ d = d0 + d1 + d2 + d3 + d4 + d5 + d6 + d7;
+ c = c0 + c2 + c4 + c6 + c8;
+ y[wosc_j] = c - d; wosc_j++; wosc_j &= 0x7;
+ d0 = b[0] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d1 = b[1] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d2 = b[2] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d3 = b[3] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d4 = b[4] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d5 = b[5] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d6 = b[6] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ d7 = b[7] * y[wosc_j]; wosc_j++; wosc_j &= 0x7;
+ c7 = a[7] * x[-3 * -DIRSTRIDE (block)];
+ c5 = a[5] * x[-2 * -DIRSTRIDE (block)];
+ c3 = a[3] * x[-1 * -DIRSTRIDE (block)];
+ c1 = a[1] * x[0 * -DIRSTRIDE (block)];
+ d = d0 + d1 + d2 + d3 + d4 + d5 + d6 + d7;
+ c = c1 + c3 + c5 + c7;
+ y[wosc_j] = c - d; wosc_j++; wosc_j &= 0x7;
+ wosc->x += -DIRSTRIDE (block);
+ }
+
+ wosc->cur_pos -= (FRAC_MASK + 1) << 1;
+ }
+
+ /* interpolate filter output from current pos
+ * wosc->cur_pos >> FRAC_SHIFT is 1 or 0;
+ */
+ if (wosc->cur_pos >> FRAC_SHIFT)
+ {
+ guint k = wosc_j - 2;
+
+ ffrac = wosc->cur_pos & FRAC_MASK; /* int -> float */
+ ffrac *= 1. / (FRAC_MASK + 1.);
+ *wave_out++ = y[k & 0x7] * (1.0 - ffrac) + y[(k + 1) & 0x7] * ffrac;
+ }
+ else
+ {
+ guint k = wosc_j - 3;
+
+ ffrac = wosc->cur_pos; /* int -> float */
+ ffrac *= 1. / (FRAC_MASK + 1.);
+ *wave_out++ = y[k & 0x7] * (1.0 - ffrac) + y[(k + 1) & 0x7] * ffrac;
+ }
+
+ /* increment */
+ wosc->cur_pos += wosc->istep;
+ }
+ while (wave_out < wave_boundary);
+ wosc->j = wosc_j;
+ wosc->last_sync_level = last_sync_level;
+ wosc->last_freq_level = last_freq_level;
+ wosc->last_mod_level = last_mod_level;
+}
+
+#undef CHECK_SYNC
+#undef CHECK_FREQ
+#undef CHECK_MOD
+#undef EXPONENTIAL_FM
+#undef DIRSTRIDE
+
+#undef WOSC_MIX_VARIANT
+#undef WOSC_MIX_VARIANT_NAME
+
+/* vim:set ts=8 sw=2 sts=2: */
diff --git a/flow/gsl/gslwaveosc.c b/flow/gsl/gslwaveosc.c
new file mode 100644
index 0000000..a17c836
--- /dev/null
+++ b/flow/gsl/gslwaveosc.c
@@ -0,0 +1,376 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001-2002 Tim Janik and Stefan Westerfeld
+ *
+ * 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 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.
+ */
+#include "gslwaveosc.h"
+
+#include "gslfilter.h"
+#include "gslsignal.h"
+#include "gslengine.h" /* for gsl_engine_sample_freq() */
+#include <string.h>
+
+
+#define FRAC_SHIFT (16)
+#define FRAC_MASK ((1 << FRAC_SHIFT) - 1)
+#define SIGNAL_LEVEL_INVAL (-2.0) /* trigger level-changed checks */
+
+
+/* --- prototype --- */
+static void wave_osc_transform_filter (GslWaveOscData *wosc,
+ gfloat play_freq);
+
+
+/* --- generated function variants --- */
+#define WOSC_MIX_VARIANT_INVAL (0xffffffff)
+#define WOSC_MIX_WITH_SYNC (1)
+#define WOSC_MIX_WITH_FREQ (2)
+#define WOSC_MIX_WITH_MOD (4)
+#define WOSC_MIX_WITH_EXP_FM (8)
+#define WOSC_MIX_VARIANT_NAME wosc_process_sfme
+#define WOSC_MIX_VARIANT (WOSC_MIX_WITH_SYNC | WOSC_MIX_WITH_FREQ | WOSC_MIX_WITH_MOD | WOSC_MIX_WITH_EXP_FM)
+#include "gslwaveosc-aux.c"
+#define WOSC_MIX_VARIANT_NAME wosc_process_sfm_
+#define WOSC_MIX_VARIANT (WOSC_MIX_WITH_SYNC | WOSC_MIX_WITH_FREQ | WOSC_MIX_WITH_MOD | 0 )
+#include "gslwaveosc-aux.c"
+#if 0
+#define WOSC_MIX_VARIANT_NAME wosc_process_sf_e
+#define WOSC_MIX_VARIANT (WOSC_MIX_WITH_SYNC | WOSC_MIX_WITH_FREQ | 0 | WOSC_MIX_WITH_EXP_FM)
+#include "gslwaveosc-aux.c"
+#endif
+#define WOSC_MIX_VARIANT_NAME wosc_process_sf__
+#define WOSC_MIX_VARIANT (WOSC_MIX_WITH_SYNC | WOSC_MIX_WITH_FREQ | 0 | 0 )
+#include "gslwaveosc-aux.c"
+#define WOSC_MIX_VARIANT_NAME wosc_process_s_me
+#define WOSC_MIX_VARIANT (WOSC_MIX_WITH_SYNC | 0 | WOSC_MIX_WITH_MOD | WOSC_MIX_WITH_EXP_FM)
+#include "gslwaveosc-aux.c"
+#define WOSC_MIX_VARIANT_NAME wosc_process_s_m_
+#define WOSC_MIX_VARIANT (WOSC_MIX_WITH_SYNC | 0 | WOSC_MIX_WITH_MOD | 0 )
+#include "gslwaveosc-aux.c"
+#if 0
+#define WOSC_MIX_VARIANT_NAME wosc_process_s__e
+#define WOSC_MIX_VARIANT (WOSC_MIX_WITH_SYNC | 0 | 0 | WOSC_MIX_WITH_EXP_FM)
+#include "gslwaveosc-aux.c"
+#endif
+#define WOSC_MIX_VARIANT_NAME wosc_process_s___
+#define WOSC_MIX_VARIANT (WOSC_MIX_WITH_SYNC | 0 | 0 | 0 )
+#include "gslwaveosc-aux.c"
+#define WOSC_MIX_VARIANT_NAME wosc_process__fme
+#define WOSC_MIX_VARIANT (0 | WOSC_MIX_WITH_FREQ | WOSC_MIX_WITH_MOD | WOSC_MIX_WITH_EXP_FM)
+#include "gslwaveosc-aux.c"
+#define WOSC_MIX_VARIANT_NAME wosc_process__fm_
+#define WOSC_MIX_VARIANT (0 | WOSC_MIX_WITH_FREQ | WOSC_MIX_WITH_MOD | 0 )
+#include "gslwaveosc-aux.c"
+#if 0
+#define WOSC_MIX_VARIANT_NAME wosc_process__f_e
+#define WOSC_MIX_VARIANT (0 | WOSC_MIX_WITH_FREQ | 0 | WOSC_MIX_WITH_EXP_FM)
+#include "gslwaveosc-aux.c"
+#endif
+#define WOSC_MIX_VARIANT_NAME wosc_process__f__
+#define WOSC_MIX_VARIANT (0 | WOSC_MIX_WITH_FREQ | 0 | 0 )
+#include "gslwaveosc-aux.c"
+#define WOSC_MIX_VARIANT_NAME wosc_process___me
+#define WOSC_MIX_VARIANT (0 | 0 | WOSC_MIX_WITH_MOD | WOSC_MIX_WITH_EXP_FM)
+#include "gslwaveosc-aux.c"
+#define WOSC_MIX_VARIANT_NAME wosc_process___m_
+#define WOSC_MIX_VARIANT (0 | 0 | WOSC_MIX_WITH_MOD | 0 )
+#include "gslwaveosc-aux.c"
+#if 0
+#define WOSC_MIX_VARIANT_NAME wosc_process____e
+#define WOSC_MIX_VARIANT (0 | 0 | 0 | WOSC_MIX_WITH_EXP_FM)
+#include "gslwaveosc-aux.c"
+#endif
+#define WOSC_MIX_VARIANT_NAME wosc_process_____
+#define WOSC_MIX_VARIANT (0 | 0 | 0 | 0 )
+#include "gslwaveosc-aux.c"
+
+
+/* --- functions --- */
+gboolean
+gsl_wave_osc_process (GslWaveOscData *wosc,
+ guint n_values,
+ const gfloat *freq_in,
+ const gfloat *mod_in,
+ const gfloat *sync_in,
+ gfloat *mono_out)
+{
+ guint mode = 0;
+
+ g_return_val_if_fail (wosc != NULL, FALSE);
+ g_return_val_if_fail (n_values > 0, FALSE);
+ g_return_val_if_fail (mono_out != NULL, FALSE);
+
+ if_reject (!wosc->config.wchunk_from_freq)
+ return FALSE;
+
+ /* mode changes:
+ * freq_in: if (freq_in) last_freq=inval else set_filter()
+ * sync_in: last_sync=0
+ * mod_in: if (mod_in) last_mod=0 else if (freq_in) last_freq=inval else transform_filter()
+ * exp_mod: n/a
+ */
+
+ if (sync_in)
+ mode |= WOSC_MIX_WITH_SYNC;
+ if (freq_in)
+ mode |= WOSC_MIX_WITH_FREQ;
+ if (mod_in)
+ mode |= WOSC_MIX_WITH_MOD;
+ if (wosc->config.exponential_fm)
+ mode |= WOSC_MIX_WITH_EXP_FM;
+
+ if_reject (mode != wosc->last_mode)
+ {
+ guint mask = wosc->last_mode ^ mode;
+
+ if (mask & WOSC_MIX_WITH_SYNC)
+ wosc->last_sync_level = 0;
+ if (mask & WOSC_MIX_WITH_FREQ)
+ {
+ if (freq_in)
+ wosc->last_freq_level = SIGNAL_LEVEL_INVAL;
+ else
+ gsl_wave_osc_set_filter (wosc, wosc->config.cfreq, FALSE);
+ }
+ if (mask & WOSC_MIX_WITH_MOD)
+ {
+ if (mod_in)
+ wosc->last_mod_level = 0;
+ else if (freq_in)
+ wosc->last_freq_level = SIGNAL_LEVEL_INVAL;
+ else /* !mod_in && !freq_in */
+ wave_osc_transform_filter (wosc, wosc->config.cfreq);
+ }
+ wosc->last_mode = mode;
+ }
+
+ switch (mode)
+ {
+ case 0 | 0 | 0 | 0:
+ case 0 | 0 | 0 | WOSC_MIX_WITH_EXP_FM:
+ wosc_process_____ (wosc, n_values, freq_in, mod_in, sync_in, mono_out);
+ break;
+ case 0 | 0 | WOSC_MIX_WITH_MOD | 0:
+ wosc_process___m_ (wosc, n_values, freq_in, mod_in, sync_in, mono_out);
+ break;
+ case 0 | 0 | WOSC_MIX_WITH_MOD | WOSC_MIX_WITH_EXP_FM:
+ wosc_process___me (wosc, n_values, freq_in, mod_in, sync_in, mono_out);
+ break;
+ case 0 | WOSC_MIX_WITH_FREQ | 0 | 0:
+ case 0 | WOSC_MIX_WITH_FREQ | 0 | WOSC_MIX_WITH_EXP_FM:
+ wosc_process__f__ (wosc, n_values, freq_in, mod_in, sync_in, mono_out);
+ break;
+ case 0 | WOSC_MIX_WITH_FREQ | WOSC_MIX_WITH_MOD | 0:
+ wosc_process__fm_ (wosc, n_values, freq_in, mod_in, sync_in, mono_out);
+ break;
+ case 0 | WOSC_MIX_WITH_FREQ | WOSC_MIX_WITH_MOD | WOSC_MIX_WITH_EXP_FM:
+ wosc_process__fme (wosc, n_values, freq_in, mod_in, sync_in, mono_out);
+ break;
+ case WOSC_MIX_WITH_SYNC | 0 | 0 | 0:
+ case WOSC_MIX_WITH_SYNC | 0 | 0 | WOSC_MIX_WITH_EXP_FM:
+ wosc_process_s___ (wosc, n_values, freq_in, mod_in, sync_in, mono_out);
+ break;
+ case WOSC_MIX_WITH_SYNC | 0 | WOSC_MIX_WITH_MOD | 0:
+ wosc_process_s_m_ (wosc, n_values, freq_in, mod_in, sync_in, mono_out);
+ break;
+ case WOSC_MIX_WITH_SYNC | 0 | WOSC_MIX_WITH_MOD | WOSC_MIX_WITH_EXP_FM:
+ wosc_process_s_me (wosc, n_values, freq_in, mod_in, sync_in, mono_out);
+ break;
+ case WOSC_MIX_WITH_SYNC | WOSC_MIX_WITH_FREQ | 0 | 0:
+ case WOSC_MIX_WITH_SYNC | WOSC_MIX_WITH_FREQ | 0 | WOSC_MIX_WITH_EXP_FM:
+ wosc_process_sf__ (wosc, n_values, freq_in, mod_in, sync_in, mono_out);
+ break;
+ case WOSC_MIX_WITH_SYNC | WOSC_MIX_WITH_FREQ | WOSC_MIX_WITH_MOD | 0:
+ wosc_process_sfm_ (wosc, n_values, freq_in, mod_in, sync_in, mono_out);
+ break;
+ case WOSC_MIX_WITH_SYNC | WOSC_MIX_WITH_FREQ | WOSC_MIX_WITH_MOD | WOSC_MIX_WITH_EXP_FM:
+ wosc_process_sfme (wosc, n_values, freq_in, mod_in, sync_in, mono_out);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ if (wosc->y[0] != 0.0 &&
+ !(fabs (wosc->y[0]) > GSL_SIGNAL_EPSILON && fabs (wosc->y[0]) < GSL_SIGNAL_KAPPA))
+ {
+ guint i;
+
+ /*g_printerr ("clearing filter state at:\n");*/
+ for (i = 0; i < GSL_WAVE_OSC_FILTER_ORDER; i++)
+ {
+ /*g_printerr ("%u) %+.38f\n", i, wosc->y[i]);*/
+ if (GSL_DOUBLE_IS_INF (wosc->y[0]) || fabs (wosc->y[0]) > GSL_SIGNAL_KAPPA)
+ wosc->y[i] = GSL_DOUBLE_SIGN (wosc->y[0]) ? -1.0 : 1.0;
+ else
+ wosc->y[i] = 0.0;
+ }
+ }
+ g_assert (!GSL_DOUBLE_IS_NANINF (wosc->y[0]));
+ g_assert (!GSL_DOUBLE_IS_SUBNORMAL (wosc->y[0]));
+
+ wosc->done = (wosc->block.is_silent && /* FIXME, let filter state run out? */
+ ((wosc->block.play_dir < 0 && wosc->block.offset < 0) ||
+ (wosc->block.play_dir > 0 && wosc->block.offset > wosc->wchunk->wave_length)));
+
+ return TRUE;
+}
+
+void
+gsl_wave_osc_set_filter (GslWaveOscData *wosc,
+ gfloat play_freq,
+ gboolean clear_state)
+{
+ gfloat zero_padding = 2;
+ gfloat step;
+ guint i, istep;
+
+ g_return_if_fail (play_freq > 0);
+
+ if_reject (!wosc->config.wchunk_from_freq)
+ return;
+
+ wosc->step_factor = zero_padding * wosc->wchunk->mix_freq;
+ wosc->step_factor /= wosc->wchunk->osc_freq * wosc->mix_freq;
+ step = wosc->step_factor * play_freq;
+ istep = step * (FRAC_MASK + 1.) + 0.5;
+
+ if (istep != wosc->istep)
+ {
+ gfloat nyquist_fact = GSL_PI * 2.0 / wosc->mix_freq, cutoff_freq = 18000, stop_freq = 24000;
+ gfloat empiric_filter_stability_limit = 6.;
+ gfloat filt_fact = CLAMP (1. / step,
+ 1. / (empiric_filter_stability_limit * zero_padding),
+ 1. / zero_padding /* spectrum half */);
+ gfloat freq_c = cutoff_freq * nyquist_fact * filt_fact;
+ gfloat freq_r = stop_freq * nyquist_fact * filt_fact;
+
+ /* FIXME: this should store filter roots and poles, so modulation does lp->lp transform */
+
+ wosc->istep = istep;
+ gsl_filter_tscheb2_lp (GSL_WAVE_OSC_FILTER_ORDER, freq_c, freq_r / freq_c, 0.18, wosc->a, wosc->b);
+ for (i = 0; i < GSL_WAVE_OSC_FILTER_ORDER + 1; i++)
+ wosc->a[i] *= zero_padding; /* scale to compensate for zero-padding */
+ for (i = 0; i < (GSL_WAVE_OSC_FILTER_ORDER + 1) / 2; i++) /* reverse bs */
+ {
+ gfloat t = wosc->b[GSL_WAVE_OSC_FILTER_ORDER - i];
+
+ wosc->b[GSL_WAVE_OSC_FILTER_ORDER - i] = wosc->b[i];
+ wosc->b[i] = t;
+ }
+ /*g_printerr ("filter: fc=%f fr=%f st=%f is=%u\n", freq_c/GSL_PI*2, freq_r/GSL_PI*2, step, wosc->istep);*/
+ }
+
+ if (clear_state)
+ {
+ /* clear filter state */
+ memset (wosc->y, 0, sizeof (wosc->y));
+ wosc->j = 0;
+ wosc->cur_pos = 0; /* might want to initialize with istep? */
+ }
+}
+
+static void
+wave_osc_transform_filter (GslWaveOscData *wosc,
+ gfloat play_freq)
+{
+ gfloat step;
+ guint istep;
+
+ step = wosc->step_factor * play_freq;
+ istep = step * (FRAC_MASK + 1.) + 0.5;
+ if (istep != wosc->istep)
+ {
+ wosc->istep = istep;
+ /* transform filter poles and roots, normalize filter, update a[] and b[] */
+ }
+}
+
+void
+gsl_wave_osc_retrigger (GslWaveOscData *wosc,
+ gfloat base_freq)
+{
+ g_return_if_fail (wosc != NULL);
+
+ if_reject (!wosc->config.wchunk_from_freq)
+ return;
+
+ if (wosc->wchunk)
+ gsl_wave_chunk_unuse_block (wosc->wchunk, &wosc->block);
+ wosc->wchunk = wosc->config.wchunk_from_freq (wosc->config.wchunk_data, base_freq);
+ wosc->block.play_dir = wosc->config.play_dir;
+ wosc->block.offset = wosc->config.start_offset;
+ gsl_wave_chunk_use_block (wosc->wchunk, &wosc->block);
+ wosc->x = wosc->block.start + wosc->config.channel;
+
+ /*g_printerr ("wave lookup: want=%f got=%f length=%lu\n",
+ base_freq, wosc->wchunk->osc_freq, wosc->wchunk->wave_length);*/
+
+ wosc->last_freq_level = GSL_SIGNAL_FROM_FREQ (base_freq);
+ wosc->last_mod_level = 0;
+ gsl_wave_osc_set_filter (wosc, base_freq, TRUE);
+}
+
+void
+gsl_wave_osc_config (GslWaveOscData *wosc,
+ GslWaveOscConfig *config)
+{
+ g_return_if_fail (wosc != NULL);
+ g_return_if_fail (config != NULL);
+
+ if (wosc->config.wchunk_data != config->wchunk_data ||
+ wosc->config.wchunk_from_freq != config->wchunk_from_freq ||
+ wosc->config.channel != config->channel)
+ {
+ if (wosc->wchunk)
+ gsl_wave_chunk_unuse_block (wosc->wchunk, &wosc->block);
+ wosc->wchunk = NULL;
+ wosc->config = *config;
+ gsl_wave_osc_retrigger (wosc, wosc->config.cfreq);
+ }
+ else
+ {
+ wosc->config.play_dir = config->play_dir;
+ wosc->config.fm_strength = config->fm_strength;
+ if (wosc->config.cfreq != config->cfreq ||
+ wosc->config.start_offset != config->start_offset)
+ {
+ wosc->config.start_offset = config->start_offset;
+ wosc->config.cfreq = config->cfreq;
+ gsl_wave_osc_retrigger (wosc, wosc->config.cfreq);
+ }
+ }
+}
+
+void
+gsl_wave_osc_init (GslWaveOscData *wosc)
+{
+ g_return_if_fail (wosc != NULL);
+
+ g_assert (GSL_WAVE_OSC_FILTER_ORDER <= gsl_get_config ()->wave_chunk_padding);
+
+ memset (wosc, 0, sizeof (GslWaveOscData));
+ wosc->mix_freq = gsl_engine_sample_freq ();
+}
+
+void
+gsl_wave_osc_shutdown (GslWaveOscData *wosc)
+{
+ g_return_if_fail (wosc != NULL);
+
+ if (wosc->wchunk)
+ gsl_wave_chunk_unuse_block (wosc->wchunk, &wosc->block);
+ memset (wosc, 0xaa, sizeof (GslWaveOscData));
+}
diff --git a/flow/gsl/gslwaveosc.h b/flow/gsl/gslwaveosc.h
new file mode 100644
index 0000000..c41b207
--- /dev/null
+++ b/flow/gsl/gslwaveosc.h
@@ -0,0 +1,96 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001-2002 Tim Janik and Stefan Westerfeld
+ *
+ * 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 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.
+ */
+#ifndef __GSL_WAVE_OSC_H__
+#define __GSL_WAVE_OSC_H__
+
+#include <gsl/gsldefs.h>
+#include <gsl/gslwavechunk.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GSL_WAVE_OSC_FILTER_ORDER (8) /* <= GslConfig.wave_chunk_padding ! */
+
+typedef struct
+{
+ GslLong start_offset;
+ gint play_dir, channel;
+
+ gpointer wchunk_data;
+ GslWaveChunk* (*wchunk_from_freq) (gpointer wchunk_data,
+ gfloat freq);
+
+ gfloat fm_strength; /* linear: 0..1, exponential: n_octaves */
+ guint exponential_fm : 1;
+ gfloat cfreq; /* for ifreq == NULL */
+} GslWaveOscConfig;
+
+typedef struct
+{
+ GslWaveOscConfig config;
+ guint last_mode;
+ gfloat last_sync_level, last_freq_level, last_mod_level;
+ GslWaveChunkBlock block;
+ gfloat *x; /* pointer into block */
+ guint cur_pos, istep; /* FIXME */
+ gdouble a[GSL_WAVE_OSC_FILTER_ORDER + 1]; /* order */
+ gdouble b[GSL_WAVE_OSC_FILTER_ORDER + 1]; /* reversed order */
+ gdouble y[GSL_WAVE_OSC_FILTER_ORDER + 1];
+ guint j; /* y[] index */
+ GslWaveChunk *wchunk;
+ gfloat mix_freq; /* gsl_engine_sample_freq() */
+ gfloat step_factor;
+ gboolean done; /* FIXME. caution, this is TRUE only if
+ * (play_dir < 0 && cur_pos < 0) ||
+ * (play_dir > 0 && cur_pos > wchunk.length)
+ */
+} GslWaveOscData;
+
+
+void gsl_wave_osc_config (GslWaveOscData *wosc,
+ GslWaveOscConfig *config);
+gboolean gsl_wave_osc_process (GslWaveOscData *wosc,
+ guint n_values,
+ const gfloat *ifreq,
+ const gfloat *mod,
+ const gfloat *sync,
+ gfloat *mono_out);
+void gsl_wave_osc_retrigger (GslWaveOscData *wosc,
+ gfloat freq);
+void gsl_wave_osc_set_filter (GslWaveOscData *wosc,
+ gfloat freq,
+ gboolean clear_state);
+
+void gsl_wave_osc_init (GslWaveOscData *wosc);
+void gsl_wave_osc_shutdown (GslWaveOscData *wosc);
+
+/* setup:
+ * wosc = g_new0 (GslWaveOscData, 1);
+ * wosc->mix_freq = gsl_engine_sample_freq ();
+ */
+
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GSL_WAVE_OSC_H__ */
diff --git a/flow/gsl/gslwchunk.c b/flow/gsl/gslwchunk.c
new file mode 100644
index 0000000..1fa4d74
--- /dev/null
+++ b/flow/gsl/gslwchunk.c
@@ -0,0 +1,279 @@
+/* GSL - Generic Sound Layer
+ * Copyright (C) 2001-2002 Tim Janik
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "gslwavechunk.h"
+#include "gsldatahandle.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <math.h>
+
+enum {
+ VERBOSITY_NONE,
+ VERBOSITY_SETUP,
+ VERBOSITY_BLOCKS,
+ VERBOSITY_DATA,
+ VERBOSITY_PADDING,
+ VERBOSITY_CHECKS,
+};
+static guint verbosity = VERBOSITY_SETUP;
+
+static gfloat my_data[] = {
+ 0.555555555,1,2,3,4,5,6,7,8,9,
+ 10,11,12,13,14,15,16,17,18,19,
+ 20,21,22,23,24,25,26,27,28,29,
+ 30,31,32,33,34,35,36,
+};
+static guint my_data_length = sizeof (my_data) / sizeof (my_data[0]);
+
+static void print_block (GslWaveChunk *wchunk,
+ GslWaveChunkBlock *block);
+
+#define DEBUG_SIZE (1024 * 256)
+#define MINI_DEBUG_SIZE (16)
+
+static void
+run_tests (GslWaveLoopType loop_type,
+ gint play_dir,
+ gint loop_first,
+ gint loop_last,
+ gint loop_count)
+{
+ gfloat tmpstorage[DEBUG_SIZE], *cmpblock = tmpstorage + DEBUG_SIZE / 2;
+ GslDataHandle *myhandle;
+ GslDataCache *dcache;
+ GslWaveChunkBlock block = { 0, 0 };
+ GslWaveChunk *wchunk;
+ GslErrorType error;
+
+ myhandle = gsl_data_handle_new_mem (1, 32, my_data_length, my_data, NULL);
+ dcache = gsl_data_cache_new (myhandle, 1);
+ gsl_data_handle_unref (myhandle);
+ wchunk = gsl_wave_chunk_new (dcache,
+ 44.0, 44100.0,
+ loop_type, loop_first, loop_last, loop_count);
+ error = gsl_wave_chunk_open (wchunk);
+ if (error)
+ g_error ("failed to open wave chunk: %s", gsl_strerror (error));
+ gsl_wave_chunk_unref (wchunk);
+ if (verbosity >= VERBOSITY_SETUP)
+ g_print ("SETUP: loop_type=%u loop_first=%ld loop_last=%ld loop_count=%d playdir=%+d\n",
+ wchunk->loop_type, wchunk->loop_first, wchunk->loop_last, wchunk->loop_count, play_dir);
+ gsl_wave_chunk_debug_block (wchunk, - DEBUG_SIZE / 2, DEBUG_SIZE, cmpblock - DEBUG_SIZE / 2);
+
+ block.play_dir = play_dir;
+
+ block.offset = block.play_dir < 0 ? wchunk->wave_length + MINI_DEBUG_SIZE/2 : -MINI_DEBUG_SIZE/2;
+ while (block.offset < wchunk->wave_length + MINI_DEBUG_SIZE &&
+ block.offset > -MINI_DEBUG_SIZE)
+ {
+ gint i, start, end, abort;
+
+ gsl_wave_chunk_use_block (wchunk, &block);
+
+ print_block (wchunk, &block);
+ if (block.play_dir > 0)
+ {
+ start = block.offset - wchunk->n_pad_values;
+ end = block.offset + block.length + wchunk->n_pad_values;
+ }
+ else
+ {
+ start = block.offset + wchunk->n_pad_values;
+ end = block.offset - block.length - wchunk->n_pad_values;
+ }
+ abort = FALSE;
+ for (i = start; i != end; i += block.play_dir)
+ {
+ gfloat v = (block.play_dir < 0) ^ (block.dirstride > 0) ? block.start[i - block.offset] : block.start[block.offset - i];
+
+ if (fabs (cmpblock[i] - v) > 1e-15)
+ {
+ abort = TRUE;
+ verbosity = 99;
+ }
+ if (verbosity >= VERBOSITY_CHECKS)
+ g_print ("%s: offset=%d (block.offset=%ld) value=%.16f found=%.16f\n",
+ fabs (cmpblock[i] - v) > 1e-15 ? "MISMATCH" : "match",
+ i, (i - block.offset), cmpblock[i], v);
+ }
+ if (abort)
+ {
+ g_error ("mismatches occoured, setup: loop_type=%u loop_first=%ld loop_last=%ld loop_count=%d (length=%ld)",
+ wchunk->loop_type, wchunk->loop_first, wchunk->loop_last, wchunk->loop_count,
+ gsl_data_handle_length (wchunk->dcache->dhandle));
+ }
+
+ gsl_wave_chunk_unuse_block (wchunk, &block);
+
+ block.offset = block.next_offset;
+ /* block.offset += block.play_dir; */
+ }
+ gsl_wave_chunk_close (wchunk);
+ gsl_data_cache_unref (dcache);
+}
+
+static void
+print_block (GslWaveChunk *wchunk,
+ GslWaveChunkBlock *block)
+{
+ gfloat *p = NULL;
+ guint i;
+
+ if (verbosity >= VERBOSITY_BLOCKS)
+ {
+ g_print ("BLOCK:");
+ g_print (" offset=%ld", block->offset);
+ g_print (" length=%ld", block->length);
+ g_print (" dirstride=%d", block->dirstride);
+ }
+
+ if (verbosity >= VERBOSITY_PADDING)
+ {
+ g_print (" {prepad:");
+ i = wchunk->n_pad_values;
+ p = block->start - (block->dirstride > 0 ? i : -i);
+ while (i--)
+ {
+ g_print (" %.1f", *p);
+ p += block->dirstride;
+ }
+ g_print ("}");
+ }
+
+ if (verbosity >= VERBOSITY_DATA)
+ {
+ g_print (" {data:");
+ p = block->start;
+ while (p != block->end)
+ {
+ g_print (" %.1f", *p);
+ p += block->dirstride;
+ }
+ g_print ("}");
+ }
+
+ if (verbosity >= VERBOSITY_PADDING)
+ {
+ i = wchunk->n_pad_values;
+ g_print (" {postpad:");
+ while (i--)
+ {
+ g_print (" %.1f", *p);
+ p += block->dirstride;
+ }
+ g_print ("}");
+ }
+
+ if (verbosity >= VERBOSITY_BLOCKS)
+ g_print ("\n");
+}
+
+int
+main (gint argc,
+ gchar *argv[])
+{
+ GslConfigValue gslconfig[] = {
+ { "wave_chunk_padding", 1, },
+ { "wave_chunk_big_pad", 2, },
+ { "dcache_block_size", 16, },
+ { NULL, },
+ };
+ gint i, j, k;
+
+ if (!g_thread_supported ())
+ g_thread_init (NULL);
+ gsl_init (gslconfig, NULL);
+
+ if (1)
+ {
+ GslDataHandle *myhandle;
+ GslDataHandle *rhandle1, *rhandle2;
+ GslLong o, l, i, e;
+ GslErrorType error;
+
+ g_print ("reversed datahandle test:...\n");
+
+ myhandle = gsl_data_handle_new_mem (1, 32, my_data_length, my_data, NULL);
+ rhandle1 = gsl_data_handle_new_reverse (myhandle);
+ gsl_data_handle_unref (myhandle);
+ rhandle2 = gsl_data_handle_new_reverse (rhandle1);
+ gsl_data_handle_unref (rhandle1);
+ error = gsl_data_handle_open (rhandle2);
+ if (error)
+ g_error ("failed to open rhandle2: %s", gsl_strerror (error));
+ gsl_data_handle_unref (rhandle2);
+
+ g_assert (gsl_data_handle_length (rhandle2) == gsl_data_handle_length (myhandle));
+
+ for (i = 1; i < 8; i++)
+ {
+ o = 0;
+ l = gsl_data_handle_length (rhandle2);
+ while (l)
+ {
+ gfloat d1[8], d2[8];
+
+ e = gsl_data_handle_read (myhandle, o, MIN (i, l), d1);
+ g_assert (e == MIN (i, l));
+ e = gsl_data_handle_read (rhandle2, o, MIN (i, l), d2);
+ g_assert (e == MIN (i, l));
+ g_assert (memcmp (d1, d2, sizeof (d1[0]) * e) == 0);
+ l -= e;
+ o += e;
+ }
+ }
+ gsl_data_handle_close (rhandle2);
+ g_print ("passed.\n");
+ }
+
+ if (1)
+ {
+ g_print ("primitive loop tests:...\n");
+
+ run_tests (GSL_WAVE_LOOP_NONE, -1, 0, 0, 0);
+
+ run_tests (GSL_WAVE_LOOP_NONE, 1, 0, 0, 0);
+ run_tests (GSL_WAVE_LOOP_NONE, -1, 0, 0, 0);
+ run_tests (GSL_WAVE_LOOP_JUMP, 1, 0, 0, 0);
+ run_tests (GSL_WAVE_LOOP_PINGPONG, 1, 0, 0, 0);
+ run_tests (GSL_WAVE_LOOP_JUMP, -1, 0, 0, 0);
+ run_tests (GSL_WAVE_LOOP_PINGPONG, -1, 0, 0, 0);
+ g_print ("passed.\n");
+ }
+
+ if (1)
+ {
+ g_print ("brute loop tests:...\n");
+ for (i = 1; i < 7; i++)
+ for (j = 0; j < my_data_length - 1; j++)
+ for (k = j + 1; k < my_data_length; k++)
+ {
+ run_tests (GSL_WAVE_LOOP_JUMP, 1, j, k, i);
+ run_tests (GSL_WAVE_LOOP_PINGPONG, 1, j, k, i);
+ run_tests (GSL_WAVE_LOOP_JUMP, -1, j, k, i);
+ run_tests (GSL_WAVE_LOOP_PINGPONG, -1, j, k, i);
+ }
+ g_print ("passed.\n");
+ }
+
+ return 0;
+}
diff --git a/flow/gslpp/Makefile.am b/flow/gslpp/Makefile.am
new file mode 100644
index 0000000..11f7407
--- /dev/null
+++ b/flow/gslpp/Makefile.am
@@ -0,0 +1,7 @@
+INCLUDES = -I$(top_srcdir)/flow -I$(top_srcdir)/flow/gsl -I$(top_builddir)/flow -I$(top_srcdir)/mcop -I$(top_builddir)/mcop -I$(top_builddir) $(all_includes)
+
+noinst_LTLIBRARIES = libgslpp.la
+
+libgslpp_la_SOURCES = datahandle.cpp
+#libgslpp_la_LIBADD = $(top_builddir)/mcop/libmcop.la $(top_builddir)/flow/gsl/libgsl.la -lm $(LIBPOSIX4)
+#libgslpp_la_LDFLAGS = -no-undefined
diff --git a/flow/gslpp/datahandle.cpp b/flow/gslpp/datahandle.cpp
new file mode 100644
index 0000000..963e57e
--- /dev/null
+++ b/flow/gslpp/datahandle.cpp
@@ -0,0 +1,412 @@
+ /*
+
+ Copyright (C) 2002 Hans Meine
+ hans_meine@gmx.net
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include "datahandle.h"
+#include "../../mcop/debug.h"
+
+namespace GSL {
+
+void DataHandle::copyFrom(const DataHandle &other)
+{
+ handle_ = other.handle_;
+ if(handle_)
+ gsl_data_handle_ref(handle_);
+}
+
+DataHandle::DataHandle(GslDataHandle *handle)
+ : handle_(handle)
+{
+}
+
+DataHandle::DataHandle(const DataHandle &other) { copyFrom(other); }
+
+DataHandle &DataHandle::operator =(const DataHandle &other)
+{
+ if(!( other == *this )) {
+ if(handle_)
+ gsl_data_handle_unref(handle_);
+ copyFrom(other);
+ }
+ return *this;
+}
+
+bool DataHandle::operator ==(const DataHandle &other) const
+{
+ return handle_ == other.handle_;
+}
+
+bool DataHandle::isNull() const
+{
+ return handle_ == 0;
+}
+
+DataHandle::~DataHandle()
+{
+ if(handle_)
+ gsl_data_handle_unref(handle_);
+}
+
+gint DataHandle::open()
+{
+ arts_return_val_if_fail(handle_ != 0, -1);
+
+ arts_debug("open()ing datahandle (open_count before: %d)..",
+ handle_->open_count);
+
+ return gsl_data_handle_open(handle_);
+}
+
+void DataHandle::close()
+{
+ arts_return_if_fail(handle_ != 0);
+
+ arts_debug("close()ing datahandle (open_count before: %d)..",
+ handle_->open_count);
+
+ gsl_data_handle_close(handle_);
+}
+
+bool DataHandle::isOpen() const
+{
+ if(!handle_)
+ return false;
+
+ return handle_->open_count != 0;
+}
+
+GslLong DataHandle::read(GslLong valueOffset, GslLong valueCount, gfloat *values)
+{
+ arts_return_val_if_fail(handle_ != 0, 0);
+
+ return gsl_data_handle_read(handle_, valueOffset, valueCount, values);
+}
+
+DataHandle DataHandle::createCropped(GslLong headCutValueCount,
+ GslLong tailCutValueCount)
+{
+ arts_return_val_if_fail(handle_ != 0, null());
+
+ return DataHandle(gsl_data_handle_new_crop(handle_,
+ headCutValueCount, tailCutValueCount));
+}
+
+DataHandle DataHandle::createCut(GslLong cutOffset,
+ GslLong cutValueCount)
+{
+ arts_return_val_if_fail(handle_ != 0, null());
+
+ return DataHandle(gsl_data_handle_new_cut(handle_, cutOffset,
+ cutValueCount));
+}
+
+DataHandle DataHandle::createReversed()
+{
+ arts_return_val_if_fail(handle_ != 0, null());
+
+ return DataHandle(gsl_data_handle_new_reverse(handle_));
+}
+
+GslDataCache *DataHandle::createGslDataCache()
+{
+ arts_debug("wanna have cache with padding %d for each of %d channels..",
+ gsl_get_config()->wave_chunk_padding,
+ channelCount());
+ return gsl_data_cache_from_dhandle(handle_,
+ gsl_get_config()->wave_chunk_padding *
+ channelCount());
+}
+
+GslLong DataHandle::valueCount() const
+{
+ arts_return_val_if_fail(handle_ != 0, 0);
+ arts_return_val_if_fail(isOpen(), 0);
+
+ return handle_->setup.n_values;
+}
+
+guint DataHandle::channelCount() const
+{
+ arts_return_val_if_fail(handle_ != 0, 0);
+ arts_return_val_if_fail(isOpen(), 0);
+
+ return handle_->setup.n_channels;
+}
+
+guint DataHandle::bitDepth() const
+{
+ arts_return_val_if_fail(handle_ != 0, 0);
+ arts_return_val_if_fail(isOpen(), 0);
+
+ return handle_->setup.bit_depth;
+}
+
+// ----------------------------------------------------------------------------
+
+WaveChunkDescription::WaveChunkDescription(const GslWaveDsc *parent, guint index)
+ : parent_(parent), parentIndex_(index)
+{
+ if(index>parent->n_chunks)
+ {
+ arts_debug("wrong index given to WaveChunkDescription constructor, "
+ "using 0 instead..");
+ parentIndex_ = 0;
+ }
+}
+
+float WaveChunkDescription::oscillatorFrequency()
+{
+ return parent_->chunks[parentIndex_].osc_freq;
+}
+
+float WaveChunkDescription::mixerFrequency()
+{
+ return parent_->chunks[parentIndex_].mix_freq;
+}
+
+GslWaveLoopType WaveChunkDescription::loopType()
+{
+ return parent_->chunks[parentIndex_].loop_type;
+}
+
+GslLong WaveChunkDescription::loopStart()
+{
+ return parent_->chunks[parentIndex_].loop_start;
+}
+
+GslLong WaveChunkDescription::loopEnd()
+{
+ return parent_->chunks[parentIndex_].loop_end;
+}
+
+guint WaveChunkDescription::loopCount()
+{
+ return parent_->chunks[parentIndex_].loop_count;
+}
+
+WaveDataHandle WaveChunkDescription::createDataHandle()
+{
+ return WaveDataHandle(parent_, parentIndex_);
+}
+
+// ----------------------------------------------------------------------------
+
+/**
+ * We use GslWaveFileInfos' refcounting - probably this lazy
+ * construction happens only once, where the object is used. After
+ * copying it would have to be constructed again, but that's not
+ * likely to happen. (?)
+ */
+void WaveDescription::ensurePointer() const
+{
+ if(!desc_)
+ desc_ = gsl_wave_dsc_load(parentInfo_, parentIndex_, &error_);
+}
+
+void WaveDescription::copyFrom(const WaveDescription &other)
+{
+ parentInfo_ = other.parentInfo_;
+ parentIndex_ = other.parentIndex_;
+ gsl_wave_file_info_ref(other.parentInfo_);
+}
+
+// internal, private
+WaveDescription::WaveDescription(GslWaveFileInfo *parent, guint index,
+ const std::string &name)
+ : parentInfo_(parent), name_(name), parentIndex_(index),
+ desc_(0), error_(GSL_ERROR_NONE)
+{
+ gsl_wave_file_info_ref(parentInfo_);
+}
+
+WaveDescription::~WaveDescription()
+{
+ if(desc_)
+ gsl_wave_dsc_free(desc_);
+ gsl_wave_file_info_unref(parentInfo_);
+}
+
+WaveDescription::WaveDescription(const WaveDescription &other)
+ : desc_(0), error_(GSL_ERROR_NONE)
+{
+ copyFrom(other);
+}
+
+WaveDescription &WaveDescription::operator =(const WaveDescription &other)
+{
+ if(desc_)
+ gsl_wave_dsc_free(desc_);
+ gsl_wave_file_info_unref(parentInfo_);
+ copyFrom(other);
+ return *this;
+}
+
+const std::string &WaveDescription::name() const
+{
+ return name_;
+}
+
+GslErrorType WaveDescription::error() const
+{
+ ensurePointer();
+ return error_;
+}
+
+guint WaveDescription::chunkCount() const
+{
+ ensurePointer();
+ return desc_ ? desc_->n_chunks : 0;
+}
+
+WaveChunkDescription WaveDescription::chunkDescription(guint index) const
+{
+ ensurePointer();
+ return WaveChunkDescription(desc_, index);
+}
+
+guint WaveDescription::channelCount() const
+{
+ ensurePointer();
+ return desc_ ? desc_->n_channels : 0;
+}
+
+// ----------------------------------------------------------------------------
+
+void WaveFileInfo::copyFrom(const WaveFileInfo &other)
+{
+ info_ = other.info_;
+ filename_ = other.filename_;
+ if(info_)
+ gsl_wave_file_info_ref(info_);
+
+ error_ = other.error_;
+}
+
+WaveFileInfo::WaveFileInfo(const std::string &filename)
+ : info_(0), error_(GSL_ERROR_NONE), filename_(filename)
+{
+ info_ = gsl_wave_file_info_load(filename.c_str(), &error_);
+}
+
+WaveFileInfo::~WaveFileInfo()
+{
+ if(info_)
+ gsl_wave_file_info_unref(info_);
+}
+
+WaveFileInfo::WaveFileInfo(const WaveFileInfo &other)
+{
+ copyFrom(other);
+}
+
+WaveFileInfo &WaveFileInfo::operator =(const WaveFileInfo &other)
+{
+ if(info_)
+ gsl_wave_file_info_unref(info_);
+ copyFrom(other);
+ return *this;
+}
+
+guint WaveFileInfo::waveCount() const
+{
+ return info_ ? info_->n_waves : 0;
+}
+
+std::string WaveFileInfo::waveName(guint index) const
+{
+ if(index >= waveCount())
+ return "";
+ return info_->waves[index].name;
+}
+
+WaveDescription WaveFileInfo::waveDescription(guint index)
+{
+ return WaveDescription(info_, index, waveName(index));
+}
+
+GslErrorType WaveFileInfo::error() const
+{
+ return error_;
+}
+
+// ----------------------------------------------------------------------------
+
+WaveDataHandle::WaveDataHandle()
+ : DataHandle(NULL),
+ oscillatorFrequency_(0),
+ mixerFrequency_(0)
+{
+}
+
+WaveDataHandle::WaveDataHandle(const GslWaveDsc *waveDesc, guint chunkIndex)
+ : DataHandle(NULL),
+ oscillatorFrequency_(0),
+ mixerFrequency_(0)
+{
+ handle_ = gsl_wave_handle_create(const_cast<GslWaveDsc *>(waveDesc),
+ chunkIndex, &error_);
+ if(error() == GSL_ERROR_NONE)
+ {
+ oscillatorFrequency_ = waveDesc->chunks[chunkIndex].osc_freq;
+ mixerFrequency_ = waveDesc->chunks[chunkIndex].mix_freq;
+ }
+}
+
+WaveDataHandle::WaveDataHandle(const std::string& filename,
+ guint waveIndex,
+ guint chunkIndex)
+ : DataHandle(NULL),
+ oscillatorFrequency_(0),
+ mixerFrequency_(0)
+{
+ GSL::WaveFileInfo info(filename);
+ error_ = info.error();
+
+ if(!info.error())
+ {
+ GSL::WaveDescription desc= info.waveDescription(waveIndex);
+ error_ = desc.error();
+
+ if(!desc.error() && (desc.chunkCount() > chunkIndex))
+ {
+ GSL::WaveChunkDescription chunkDesc= desc.chunkDescription(chunkIndex);
+
+ (*this) = chunkDesc.createDataHandle();
+ }
+ }
+}
+
+GslErrorType WaveDataHandle::error() const
+{
+ return error_;
+}
+
+float WaveDataHandle::oscillatorFrequency() const
+{
+ return oscillatorFrequency_;
+}
+
+float WaveDataHandle::mixerFrequency() const
+{
+ return mixerFrequency_;
+}
+
+}
diff --git a/flow/gslpp/datahandle.h b/flow/gslpp/datahandle.h
new file mode 100644
index 0000000..7cab930
--- /dev/null
+++ b/flow/gslpp/datahandle.h
@@ -0,0 +1,220 @@
+ /*
+
+ Copyright (C) 2002 Hans Meine
+ hans_meine@gmx.net
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef GSLPP_DATAHANDLE_H
+#define GSLPP_DATAHANDLE_H
+
+#include <gsl/gsldatahandle.h>
+#include <gsl/gslloader.h>
+#include <string>
+
+namespace GSL
+{
+ class WaveFileInfo;
+ class WaveDataHandle;
+ class WaveDescription;
+
+ class DataHandle
+ {
+ protected:
+ GslDataHandle *handle_;
+
+ void clearHandle();
+ void copyFrom(const DataHandle &other);
+
+ DataHandle(GslDataHandle *handle);
+
+ public:
+ static DataHandle null() { return DataHandle(); }
+
+ DataHandle(): handle_(0) {}
+
+ DataHandle(const DataHandle &other);
+
+ DataHandle &operator =(const DataHandle &other);
+
+ bool operator ==(const DataHandle &other) const;
+
+ bool isNull() const;
+
+ virtual ~DataHandle();
+
+ /**
+ * returns error code with errno meaning
+ */
+ virtual gint open();
+
+ virtual void close();
+
+ bool isOpen() const;
+
+ /**
+ * read from this datahandle and fill buffer pointed to by
+ * values with sample data from the range
+ * [valueOffset..valueOffset+valueCount-1]
+ *
+ * returns number of sample values actually read, -1 on error
+ * (errno _may_ be useful then)
+ */
+ virtual GslLong read(GslLong valueOffset, GslLong valueCount, gfloat *values);
+
+ /**
+ * Create a new data handle by chopping off headCutValueCount
+ * values at the start, and tailCutValueCount values at the
+ * end of this data handle.
+ */
+ DataHandle createCropped(GslLong headCutValueCount,
+ GslLong tailCutValueCount);
+
+ /**
+ * Create a new data handle by removing the values
+ * [cutOffset..cutOffset+cutValueCount-1].
+ */
+ DataHandle createCut(GslLong cutOffset,
+ GslLong cutValueCount);
+
+ /**
+ * Create a new data handle which contains the same values as
+ * this one but in reversed order.
+ */
+ DataHandle createReversed();
+
+ // this will maybe be made private in the future, having a
+ // better interface instead
+ GslDataCache *createGslDataCache();
+
+ GslLong valueCount() const;
+
+ guint bitDepth() const;
+
+ guint channelCount() const;
+ };
+
+ class WaveChunkDescription
+ {
+ friend class WaveDescription;
+
+ const GslWaveDsc *parent_;
+ guint parentIndex_;
+
+ WaveChunkDescription(const GslWaveDsc *parent, guint index);
+
+ public:
+ float oscillatorFrequency();
+ float mixerFrequency();
+
+ GslWaveLoopType loopType();
+ GslLong loopStart(); /* sample offset */
+ GslLong loopEnd(); /* sample offset */
+ guint loopCount();
+
+ WaveDataHandle createDataHandle();
+ };
+
+ class WaveDescription
+ {
+ friend class WaveFileInfo; // for construction of WaveDescriptions
+
+ mutable GslWaveFileInfo *parentInfo_; // mutable for ensurePointer()
+ std::string name_;
+ guint parentIndex_;
+ mutable GslWaveDsc *desc_;
+ mutable GslErrorType error_;
+
+ void ensurePointer() const; // lazy construction
+
+ void copyFrom(const WaveDescription &other);
+
+ WaveDescription(GslWaveFileInfo *parent, guint index, const std::string &name);
+
+ public:
+ ~WaveDescription();
+
+ WaveDescription(const WaveDescription &other);
+
+ WaveDescription &operator =(const WaveDescription &other);
+
+ const std::string &name() const;
+
+ GslErrorType error() const;
+
+ guint chunkCount() const;
+
+ WaveChunkDescription chunkDescription(guint index) const;
+
+ guint channelCount() const;
+ };
+
+ class WaveFileInfo
+ {
+ GslWaveFileInfo *info_;
+ GslErrorType error_;
+ std::string filename_;
+
+ void copyFrom(const WaveFileInfo &other);
+
+ public:
+ WaveFileInfo(const std::string &filename);
+
+ ~WaveFileInfo();
+
+ WaveFileInfo(const WaveFileInfo &other);
+
+ WaveFileInfo &operator =(const WaveFileInfo &other);
+
+ guint waveCount() const;
+
+ std::string waveName(guint index) const;
+
+ WaveDescription waveDescription(guint index);
+
+ GslErrorType error() const;
+ };
+
+ class WaveDataHandle: public DataHandle
+ {
+ friend class WaveChunkDescription;
+
+ GslErrorType error_;
+
+ float oscillatorFrequency_;
+ float mixerFrequency_;
+
+ WaveDataHandle();
+ WaveDataHandle(const GslWaveDsc *waveDesc, guint chunkIndex = 0);
+
+ public:
+ WaveDataHandle(const std::string& filename,
+ guint waveIndex = 0,
+ guint chunkIndex = 0);
+
+ static WaveDataHandle null() { return WaveDataHandle(); }
+
+ GslErrorType error() const;
+
+ float oscillatorFrequency() const;
+
+ float mixerFrequency() const;
+ };
+}
+
+#endif // GSLPP_DATAHANDLE_H
diff --git a/flow/gslschedule.cc b/flow/gslschedule.cc
new file mode 100644
index 0000000..370bac1
--- /dev/null
+++ b/flow/gslschedule.cc
@@ -0,0 +1,1195 @@
+ /*
+
+ Copyright (C) 2000-2002 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include "config.h"
+
+#include "virtualports.h"
+#include "startupmanager.h"
+#include "gslschedule.h"
+#include "debug.h"
+#include "asyncschedule.h"
+#include "audiosubsys.h"
+#include <gsl/gslcommon.h>
+#include <gsl/gslengine.h>
+#include <algorithm>
+#include <stdio.h>
+#include <iostream>
+#include <stack>
+
+/* HACK */
+class GslMainLoop {
+protected:
+ std::list<GslClass *> freeClassList;
+
+public:
+ GslEngineLoop loop;
+
+ static bool waitOnTransNeedData;
+ static bool gslDataCalculated;
+
+ /* static check function */
+ static gboolean gslCheck(gpointer /* data */, guint /* n_values */,
+ glong* /* timeout_p */,
+ guint /* n_fds */, const GPollFD* /* fds */,
+ gboolean /* revents_filled */)
+ {
+ return waitOnTransNeedData;
+ }
+ /* mainloop integration: initialize (called to get initial loop setup) */
+ void initialize()
+ {
+ gsl_transact(gsl_job_add_poll (gslCheck, 0, 0, 0, 0), 0);
+ gsl_engine_prepare(&loop);
+
+ for(unsigned int i = 0; i != loop.n_fds; i++)
+ {
+ printf("TODO: engine fd %d\n",i);
+ }
+ }
+ /* mainloop integration: process (TODO - should be called by IOManager) */
+ void process()
+ {
+ printf("TODO: mainloop wrapper for fd watches\n");
+ if(gsl_engine_check(&loop))
+ gsl_engine_dispatch();
+ }
+ /* wait for a transaction */
+ void waitOnTrans()
+ {
+ arts_return_if_fail(waitOnTransNeedData == false);
+ gsl_engine_wait_on_trans();
+ }
+ /* make the engine calculate something */
+ void run()
+ {
+ waitOnTransNeedData = true;
+ gslDataCalculated = false;
+
+ while(!gslDataCalculated && gsl_engine_check(&loop))
+ gsl_engine_dispatch();
+
+ gslDataCalculated = false;
+ waitOnTransNeedData = false;
+
+ if(!freeClassList.empty())
+ {
+ /*
+ * make sure that all transactions that are still pending
+ * get finished (especially important in threaded case,
+ * since an entry in the free list doesn't necessarily
+ * mean that the module has entierly been freed)
+ */
+ waitOnTrans();
+
+ std::list<GslClass *>::iterator fi;
+ for(fi = freeClassList.begin(); fi != freeClassList.end(); fi++)
+ free(*fi);
+
+ freeClassList.clear();
+ }
+ }
+ void freeGslClass(GslClass *klass)
+ {
+ freeClassList.push_back(klass);
+ }
+} gslMainLoop;
+
+bool GslMainLoop::waitOnTransNeedData = false;
+bool GslMainLoop::gslDataCalculated = false;
+namespace Arts { extern void *gslGlobalMutexTable; }
+
+
+using namespace std;
+using namespace Arts;
+
+// ----------- Port -----------
+
+Port::Port(const string& name, void *ptr, long flags, StdScheduleNode* parent)
+ : _name(name), _ptr(ptr), _flags((AttributeType)flags),
+ parent(parent), _dynamicPort(false)
+{
+ _vport = new VPort(this);
+}
+
+Port::~Port()
+{
+ if(_vport)
+ delete _vport;
+}
+
+AttributeType Port::flags()
+{
+ return _flags;
+}
+
+string Port::name()
+{
+ return _name;
+}
+
+ASyncPort *Port::asyncPort()
+{
+ return 0;
+}
+
+AudioPort *Port::audioPort()
+{
+ return 0;
+}
+
+void Port::addAutoDisconnect(Port *source)
+{
+ autoDisconnect.push_back(source);
+ source->autoDisconnect.push_back(this);
+}
+
+void Port::removeAutoDisconnect(Port *source)
+{
+ std::list<Port *>::iterator adi;
+
+ // remove our autodisconnection entry for source port
+ adi = find(autoDisconnect.begin(),autoDisconnect.end(),source);
+ assert(adi != autoDisconnect.end());
+ autoDisconnect.erase(adi);
+
+ // remove the source port autodisconnection entry to us
+ adi=find(source->autoDisconnect.begin(),source->autoDisconnect.end(),this);
+ assert(adi != source->autoDisconnect.end());
+ source->autoDisconnect.erase(adi);
+}
+
+void Port::disconnectAll()
+{
+ if(_vport)
+ delete _vport;
+ _vport = 0;
+ assert(autoDisconnect.empty());
+ while(!autoDisconnect.empty())
+ {
+ Port *other = *autoDisconnect.begin();
+
+ // syntax is disconnect(source)
+ if(_flags & streamIn)
+ // if we're incoming, other port is source
+ vport()->disconnect(other->vport());
+ else
+ // if we're outgoing, we're the source
+ other->vport()->disconnect(this->vport());
+ }
+}
+
+void Port::setPtr(void *ptr)
+{
+ _ptr = ptr;
+}
+
+// ------- AudioPort ---------
+
+AudioPort::AudioPort(const string& name,
+ void *ptr, long flags,StdScheduleNode *parent)
+ : Port(name,ptr,flags,parent)
+{
+ destcount = 0;
+ sourcemodule = 0;
+ source = 0;
+ gslIsConstant = false;
+}
+
+AudioPort::~AudioPort()
+{
+ //
+}
+
+AudioPort *AudioPort::audioPort()
+{
+ return this;
+}
+
+void AudioPort::setFloatValue(float f)
+{
+ gslIsConstant = true;
+ gslConstantValue = f;
+
+ parent->_connectionCountChanged = true;
+}
+
+void AudioPort::connect(Port *psource)
+{
+ if (source) return; // Error, should not happen (See BR70028)
+ source = psource->audioPort();
+ assert(source);
+ addAutoDisconnect(psource);
+
+ source->parent->_connectionCountChanged = parent->_connectionCountChanged = true;
+ source->destcount++;
+ sourcemodule = source->parent;
+
+ // GSL connect
+ GslTrans *trans = gsl_trans_open();
+ gsl_trans_add(trans, gsl_job_connect(source->parent->gslModule,
+ source->gslEngineChannel,
+ parent->gslModule,
+ gslEngineChannel));
+ gsl_trans_commit(trans);
+}
+
+void AudioPort::disconnect(Port *psource)
+{
+ if (!source || source != psource->audioPort()) return; // Error, should not happen (See BR70028)
+ assert(source);
+ assert(source == psource->audioPort());
+ removeAutoDisconnect(psource);
+
+ assert(sourcemodule == source->parent);
+ sourcemodule = 0;
+
+ source->parent->_connectionCountChanged = parent->_connectionCountChanged = true;
+ source->destcount--;
+ source = 0;
+
+ // GSL disconnect
+ GslTrans *trans = gsl_trans_open();
+ gsl_trans_add(trans, gsl_job_disconnect(parent->gslModule,
+ gslEngineChannel));
+ gsl_trans_commit(trans);
+}
+
+// --------- MultiPort ----------
+
+MultiPort::MultiPort(const string& name,
+ void *ptr, long flags,StdScheduleNode *parent)
+ : Port(name,ptr,flags,parent)
+{
+ conns = 0;
+ nextID = 0;
+ initConns();
+}
+
+MultiPort::~MultiPort()
+{
+ if(conns)
+ {
+ delete[] conns;
+ conns = 0;
+ }
+}
+
+void MultiPort::initConns()
+{
+ if(conns != 0) delete[] conns;
+ conns = new float_ptr[parts.size() + 1];
+ conns[parts.size()] = (float *)0;
+
+ *(float ***)_ptr = conns;
+
+ long n = 0;
+ std::list<Part>::iterator i;
+ for(i = parts.begin();i != parts.end(); i++)
+ {
+ AudioPort *p = i->dest;
+ p->setPtr((void *)&conns[n++]);
+ }
+}
+
+void MultiPort::connect(Port *port)
+{
+ AudioPort *dport;
+ char sid[20];
+ sprintf(sid,"%ld",nextID++);
+
+ addAutoDisconnect(port);
+
+ dport = new AudioPort("_"+_name+string(sid),0,streamIn,parent);
+
+ Part part;
+ part.src = (AudioPort *)port;
+ part.dest = dport;
+
+ parts.push_back(part);
+ initConns();
+
+ parent->addDynamicPort(dport);
+ dport->vport()->connect(port->vport());
+}
+
+void MultiPort::disconnect(Port *sport)
+{
+ AudioPort *port = (AudioPort *)sport;
+ removeAutoDisconnect(sport);
+
+ std::list<Part>::iterator i;
+ for(i = parts.begin(); i != parts.end(); i++)
+ {
+ if(i->src == port)
+ {
+ AudioPort *dport = i->dest;
+ parts.erase(i);
+ initConns();
+
+ dport->vport()->disconnect(port->vport());
+ parent->removeDynamicPort(dport);
+
+ delete dport;
+ return;
+ }
+ }
+}
+
+// -------- StdScheduleNode ---------
+
+void StdScheduleNode::freeConn()
+{
+ if(inConn)
+ {
+ delete[] inConn;
+ inConn = 0;
+ }
+ if(outConn)
+ {
+ delete[] outConn;
+ outConn = 0;
+ }
+ inConnCount = outConnCount = 0;
+
+ if(gslModule)
+ {
+ gsl_transact(gsl_job_discard(gslModule),0);
+
+ gslModule = 0;
+ gslRunning = false;
+ }
+}
+
+void StdScheduleNode::gslProcess(GslModule *module, guint n_values)
+{
+ StdScheduleNode *node = (StdScheduleNode *)module->user_data;
+ if(!node->running) /* FIXME: need reasonable suspend in the engine */
+ return;
+
+ arts_return_if_fail(node->module != 0);
+
+ GslMainLoop::gslDataCalculated = true;
+
+ unsigned long j;
+ for(j=0;j<node->inConnCount;j++)
+ {
+ if(node->inConn[j]->gslIsConstant)
+ *((float **)node->inConn[j]->_ptr) =
+ gsl_engine_const_values(node->inConn[j]->gslConstantValue);
+ else
+ *((float **)node->inConn[j]->_ptr) = const_cast<float *>(module->istreams[j].values);
+ }
+
+ for(j=0;j<node->outConnCount;j++)
+ *((float **)node->outConn[j]->_ptr) = module->ostreams[j].values;
+
+ node->module->calculateBlock(n_values);
+}
+
+static void gslModuleFree(gpointer /* data */, const GslClass *klass)
+{
+ gslMainLoop.freeGslClass(const_cast<GslClass *>(klass));
+}
+
+void StdScheduleNode::rebuildConn()
+{
+ std::list<Port *>::iterator i;
+
+ freeConn();
+
+ inConnCount = outConnCount = 0;
+ inConn = new AudioPort_ptr[ports.size()];
+ outConn = new AudioPort_ptr[ports.size()];
+
+ for(i=ports.begin();i != ports.end();i++)
+ {
+ AudioPort *p = (*i)->audioPort();
+ if(p)
+ {
+ if(p->flags() & streamIn)
+ {
+ p->gslEngineChannel = inConnCount;
+ inConn[inConnCount++] = p;
+ }
+ if(p->flags() & streamOut)
+ {
+ p->gslEngineChannel = outConnCount;
+ outConn[outConnCount++] = p;
+ }
+ }
+ }
+
+ /* create GSL node */
+ GslClass *gslClass = (GslClass *)calloc(sizeof(GslClass),1);
+ gslClass->n_istreams = inConnCount;
+ gslClass->n_ostreams = outConnCount;
+ gslClass->process = gslProcess;
+ gslClass->free = gslModuleFree;
+
+ gslModule = gsl_module_new (gslClass, (StdScheduleNode *)this);
+
+ GslTrans *trans = gsl_trans_open();
+ gsl_trans_add(trans,gsl_job_integrate(gslModule));
+ gsl_trans_add(trans,gsl_job_set_consumer(gslModule, running));
+ gslRunning = running;
+
+ /* since destroying the old module and creating a new one will destroy
+ * all the connections, we need to restore them here
+ */
+ unsigned int c;
+ for(c = 0; c < inConnCount; c++)
+ {
+ if(inConn[c]->source)
+ {
+ gsl_trans_add(trans,
+ gsl_job_connect(inConn[c]->source->parent->gslModule,
+ inConn[c]->source->gslEngineChannel,
+ inConn[c]->parent->gslModule,
+ inConn[c]->gslEngineChannel));
+ }
+ }
+ for(c = 0; c < outConnCount; c++)
+ {
+ std::list<Port *>::iterator ci;
+
+ for(ci = outConn[c]->autoDisconnect.begin();
+ ci != outConn[c]->autoDisconnect.end(); ci++)
+ {
+ AudioPort *dest = (*ci)->audioPort();
+ if( dest )
+ {
+ gsl_trans_add(trans,
+ gsl_job_connect(outConn[c]->parent->gslModule,
+ outConn[c]->gslEngineChannel,
+ dest->parent->gslModule,
+ dest->gslEngineChannel));
+ }
+ else
+ {
+ arts_debug( "no audio port: %s for %s", ( *ci )->name().c_str(), _object->_interfaceName().c_str() );
+ }
+ }
+ }
+ gsl_trans_commit(trans);
+}
+
+Object_skel *StdScheduleNode::object()
+{
+ return _object;
+}
+
+void *StdScheduleNode::cast(const string &target)
+{
+ if(target == "StdScheduleNode") return (StdScheduleNode *)this;
+ return 0;
+}
+
+
+void StdScheduleNode::accessModule()
+{
+ if(module) return;
+
+ module = (SynthModule_base *)_object->_cast(Arts::SynthModule_base::_IID);
+ if(!module)
+ arts_warning("Error using interface %s in the flowsystem: only objects"
+ " implementing Arts::SynthModule should carry streams.",
+ _object->_interfaceName().c_str());
+}
+
+StdScheduleNode::StdScheduleNode(Object_skel *object, StdFlowSystem *flowSystem) : ScheduleNode(object)
+{
+ _object = object;
+ this->flowSystem = flowSystem;
+ running = false;
+ suspended = false;
+ module = 0;
+ gslModule = 0;
+ gslRunning = false;
+ queryInitStreamFunc = 0;
+ inConn = outConn = 0;
+ inConnCount = outConnCount = 0;
+}
+
+StdScheduleNode::~StdScheduleNode()
+{
+ /* stop module if still running */
+ if(running) stop();
+ /* disconnect all ports */
+ stack<Port *> disconnect_stack;
+
+ /*
+ * we must be a bit careful here, as dynamic ports (which are created
+ * for connections by MultiPorts) will suddenly start disappearing, so
+ * we better make a copy of those ports that will stay, and disconnect
+ * them then
+ */
+ std::list<Port *>::iterator i;
+ for(i=ports.begin();i != ports.end();i++)
+ {
+ if(!(*i)->dynamicPort()) disconnect_stack.push(*i);
+ }
+
+ while(!disconnect_stack.empty())
+ {
+ disconnect_stack.top()->disconnectAll();
+ disconnect_stack.pop();
+ }
+ /* free them */
+ for(i=ports.begin();i != ports.end();i++)
+ delete (*i);
+ ports.clear();
+
+ freeConn();
+}
+
+void StdScheduleNode::initStream(const string& name, void *ptr, long flags)
+{
+ if(flags == -1)
+ {
+ queryInitStreamFunc = (QueryInitStreamFunc)ptr;
+ }
+ else if(flags & streamAsync)
+ {
+ ports.push_back(new ASyncPort(name,ptr,flags,this));
+ }
+ else if(flags & streamMulti)
+ {
+ ports.push_back(new MultiPort(name,ptr,flags,this));
+ }
+ else
+ {
+ ports.push_back(new AudioPort(name,ptr,flags,this));
+ }
+
+ // TODO: maybe initialize a bit later
+ rebuildConn();
+}
+
+void StdScheduleNode::addDynamicPort(Port *port)
+{
+ port->setDynamicPort();
+ ports.push_back(port);
+ rebuildConn();
+}
+
+void StdScheduleNode::removeDynamicPort(Port *port)
+{
+ std::list<Port *>::iterator i;
+ for(i=ports.begin();i!=ports.end();i++)
+ {
+ Port *p = *i;
+ if(p->name() == port->name())
+ {
+ ports.erase(i);
+ rebuildConn();
+ return;
+ }
+ }
+}
+
+void StdScheduleNode::start()
+{
+ assert(!running);
+ running = true;
+
+ //cout << "start" << endl;
+ accessModule();
+ module->streamInit();
+ module->streamStart();
+ flowSystem->startedChanged();
+}
+
+void StdScheduleNode::stop()
+{
+ assert(running);
+ running = false;
+
+ accessModule();
+ module->streamEnd();
+ flowSystem->startedChanged();
+}
+
+void StdScheduleNode::requireFlow()
+{
+ // cout << "rf" << module->_interfaceName() << endl;
+ flowSystem->updateStarted();
+ gslMainLoop.run();
+}
+
+AutoSuspendState StdScheduleNode::suspendable()
+{
+ if(running) {
+ accessModule();
+ return module->autoSuspend();
+ }
+ // if its not running, who cares?
+ return asSuspend;
+}
+
+void StdScheduleNode::suspend()
+{
+ if(running) {
+ accessModule();
+ suspended = true;
+ if((module->autoSuspend() & asSuspendMask) == asSuspendStop) stop();
+ }
+}
+
+void StdScheduleNode::restart()
+{
+ if(suspended) {
+ accessModule();
+ suspended = false;
+ if(!running && (module->autoSuspend() & asSuspendMask) == asSuspendStop) start();
+ }
+}
+
+Port *StdScheduleNode::findPort(const string& name)
+{
+ std::list<Port *>::iterator i;
+ for(i=ports.begin();i!=ports.end();i++)
+ {
+ Port *p = *i;
+ if(p->name() == name) return p;
+ }
+ if(queryInitStreamFunc)
+ {
+ if(queryInitStreamFunc(_object,name))
+ {
+ for(i=ports.begin();i!=ports.end();i++)
+ {
+ Port *p = *i;
+ if(p->name() == name) return p;
+ }
+ }
+ }
+ return 0;
+}
+
+void StdScheduleNode::virtualize(const std::string& port,
+ ScheduleNode *implNode,
+ const std::string& implPort)
+{
+ StdScheduleNode *impl=(StdScheduleNode *)implNode->cast("StdScheduleNode");
+ if(impl)
+ {
+ Port *p1 = findPort(port);
+ Port *p2 = impl->findPort(implPort);
+
+ assert(p1);
+ assert(p2);
+ p1->vport()->virtualize(p2->vport());
+ }
+}
+
+void StdScheduleNode::devirtualize(const std::string& port,
+ ScheduleNode *implNode,
+ const std::string& implPort)
+{
+ StdScheduleNode *impl=(StdScheduleNode *)implNode->cast("StdScheduleNode");
+ if(impl)
+ {
+ Port *p1 = findPort(port);
+ Port *p2 = impl->findPort(implPort);
+
+ p1->vport()->devirtualize(p2->vport());
+ }
+}
+
+void StdScheduleNode::connect(const string& port, ScheduleNode *dest,
+ const string& destport)
+{
+ RemoteScheduleNode *rsn = dest->remoteScheduleNode();
+ if(rsn)
+ {
+ // RemoteScheduleNodes know better how to connect remotely
+ rsn->connect(destport,this,port);
+ return;
+ }
+
+ flowSystem->restart();
+
+ Port *p1 = findPort(port);
+ Port *p2 = ((StdScheduleNode *)dest)->findPort(destport);
+
+ if(p1 && p2)
+ {
+ if((p1->flags() & streamIn) && (p2->flags() & streamOut))
+ {
+ p1->vport()->connect(p2->vport());
+ }
+ else if((p2->flags() & streamIn) && (p1->flags() & streamOut))
+ {
+ p2->vport()->connect(p1->vport());
+ }
+ }
+}
+
+void StdScheduleNode::disconnect(const string& port, ScheduleNode *dest,
+ const string& destport)
+{
+ RemoteScheduleNode *rsn = dest->remoteScheduleNode();
+ if(rsn)
+ {
+ // RemoteScheduleNodes know better how to disconnect remotely
+ rsn->disconnect(destport,this,port);
+ return;
+ }
+
+ flowSystem->restart();
+
+ Port *p1 = findPort(port);
+ Port *p2 = ((StdScheduleNode *)dest)->findPort(destport);
+
+ if(p1 && p2)
+ {
+ if((p1->flags() & streamIn) && (p2->flags() & streamOut))
+ {
+ p1->vport()->disconnect(p2->vport());
+ }
+ else if((p2->flags() & streamIn) && (p1->flags() & streamOut))
+ {
+ p2->vport()->disconnect(p1->vport());
+ }
+ }
+}
+
+AttributeType StdScheduleNode::queryFlags(const std::string& port)
+{
+ arts_debug("findPort(%s)", port.c_str());
+ arts_debug("have %ld ports", ports.size());
+ Port *p1 = findPort(port);
+ arts_debug("done");
+
+ if(p1)
+ {
+ arts_debug("result %d",(long)p1->flags());
+ return p1->flags();
+ }
+ arts_debug("failed");
+ return (AttributeType)0;
+}
+
+void StdScheduleNode::setFloatValue(const string& port, float value)
+{
+ AudioPort *p = findPort(port)->audioPort();
+
+ if(p) {
+ p->vport()->setFloatValue(value);
+ } else {
+ assert(false);
+ }
+}
+
+unsigned long StdScheduleNode::inputConnectionCount(const string& port)
+{
+ unsigned long result = 0;
+
+ unsigned int c;
+ for(c = 0; c < inConnCount; c++)
+ {
+ if(inConn[c]->name() == port)
+ {
+ if(inConn[c]->source || inConn[c]->gslIsConstant)
+ result++;
+ }
+ }
+
+ return result;
+}
+
+unsigned long StdScheduleNode::outputConnectionCount(const string& port)
+{
+ unsigned long result = 0;
+
+ unsigned int c;
+ for(c = 0; c < outConnCount; c++)
+ {
+ if(outConn[c]->name() == port)
+ result += outConn[c]->destcount;
+ }
+
+ return result;
+}
+
+StdFlowSystem::StdFlowSystem()
+{
+ _suspended = false;
+ needUpdateStarted = false;
+
+ /* TODO: correct parameters */
+ static bool gsl_is_initialized = false;
+ if(!gsl_is_initialized)
+ {
+ GslConfigValue values[3] = {
+ { "wave_chunk_padding", 8 },
+ { "dcache_block_size", 4000, },
+ { 0, 0 }
+ };
+ gsl_is_initialized = true;
+
+ if (!g_thread_supported ())
+ g_thread_init(0);
+ gsl_init(values, (GslMutexTable *)gslGlobalMutexTable);
+
+ /*
+ * FIXME: both of these are really supposed to be tunable
+ * - the 512 because of low-latency apps, where calculating smaller
+ * block sizes might be necessary
+ * - the 44100 because of the obvious reason, that not every artsd
+ * is running at that rate
+ */
+ gsl_engine_init(false, 512, 44100, /* subsamplemask */ 63);
+ if(gslGlobalMutexTable)
+ arts_debug("gsl: using Unix98 pthreads directly for mutexes and conditions");
+ /*gsl_engine_debug_enable(GslEngineDebugLevel(GSL_ENGINE_DEBUG_JOBS | GSL_ENGINE_DEBUG_SCHED));*/
+ }
+ gslMainLoop.initialize();
+}
+
+ScheduleNode *StdFlowSystem::addObject(Object_skel *object)
+{
+ // do not add new modules when being in suspended state
+ restart();
+
+ StdScheduleNode *node = new StdScheduleNode(object,this);
+ nodes.push_back(node);
+ return node;
+}
+
+void StdFlowSystem::removeObject(ScheduleNode *node)
+{
+ StdScheduleNode *xnode = (StdScheduleNode *)node->cast("StdScheduleNode");
+ assert(xnode);
+ nodes.remove(xnode);
+ delete xnode;
+}
+
+bool StdFlowSystem::suspended()
+{
+ return _suspended;
+}
+
+bool StdFlowSystem::suspendable()
+{
+ /*
+ * What it does:
+ * -------------
+ *
+ * The suspension algorithm will first divide the graph of modules into
+ * subgraphs of interconnected modules. A subgraph is suspendable if
+ * all of its modules are suspendable and the subgraph does not contain
+ * producer(s) and consumer(s) at the same time.
+ *
+ * Finally, our module graph is suspendable if all its subgraphs are.
+ *
+ * How it is implemented:
+ * ----------------------
+ *
+ * For efficiency reasons, both steps are merged together. First all
+ * modules will be marked as unseen. Then a module is picked and
+ * all modules that it connects to are recursively added to the
+ * subgraph.
+ */
+
+ /*
+ * initialization: no nodes are seen
+ */
+ std::list<StdScheduleNode *>::iterator i;
+ for (i = nodes.begin(); i != nodes.end(); i++)
+ {
+ StdScheduleNode *node = *i;
+ node->suspendTag = false;
+ }
+
+ stack<StdScheduleNode*> todo;
+ for(i = nodes.begin(); i != nodes.end(); i++)
+ {
+ bool haveConsumer = false;
+ bool haveProducer = false;
+
+ /*
+ * examine the subgraph consisting of all nodes connected to (*i)
+ * (only will do anything if suspendTag is not already set)
+ */
+
+ todo.push(*i);
+ do
+ {
+ StdScheduleNode *node = todo.top();
+ todo.pop();
+
+ if(!node->suspendTag)
+ {
+ node->suspendTag = true; // never examine this node again
+
+ switch (node->suspendable())
+ {
+ case asNoSuspend|asProducer:
+ case asNoSuspend|asConsumer:
+ case asNoSuspend:
+ return false;
+ break;
+ case asSuspend:
+ case asSuspendStop:
+ /* nothing */
+ break;
+ case asSuspend|asProducer:
+ case asSuspendStop|asProducer:
+ if(haveConsumer)
+ return false;
+ else
+ haveProducer = true;
+ break;
+ case asSuspend|asConsumer:
+ case asSuspendStop|asConsumer:
+ if(haveProducer)
+ return false;
+ else
+ haveConsumer = true;
+ break;
+ default:
+ arts_fatal("bad suspend value %d", node->suspendable());
+ }
+
+ unsigned int c;
+ for(c = 0; c < node->inConnCount; c++)
+ {
+ if(node->inConn[c]->source)
+ todo.push(node->inConn[c]->source->parent);
+ }
+
+ for(c = 0; c < node->outConnCount; c++)
+ {
+ std::list<Port *>::iterator ci;
+
+ for(ci = node->outConn[c]->autoDisconnect.begin();
+ ci != node->outConn[c]->autoDisconnect.end(); ci++)
+ {
+ AudioPort *dest = (*ci)->audioPort();
+ if(dest)
+ todo.push(dest->parent);
+ }
+ }
+ }
+ } while(!todo.empty());
+ }
+ return true;
+}
+
+void StdFlowSystem::suspend()
+{
+ if(!_suspended)
+ {
+ std::list<StdScheduleNode *>::iterator i;
+ for(i = nodes.begin();i != nodes.end();i++)
+ {
+ StdScheduleNode *node = *i;
+ node->suspend();
+ }
+ _suspended = true;
+ }
+}
+
+void StdFlowSystem::restart()
+{
+ if(_suspended)
+ {
+ std::list<StdScheduleNode *>::iterator i;
+ for(i = nodes.begin();i != nodes.end();i++)
+ {
+ StdScheduleNode *node = *i;
+ node->restart();
+ }
+ _suspended = false;
+ }
+}
+
+/* remote accessibility */
+
+void StdFlowSystem::startObject(Object node)
+{
+ StdScheduleNode *sn =
+ (StdScheduleNode *)node._node()->cast("StdScheduleNode");
+ sn->start();
+}
+
+void StdFlowSystem::stopObject(Object node)
+{
+ StdScheduleNode *sn =
+ (StdScheduleNode *)node._node()->cast("StdScheduleNode");
+ sn->stop();
+}
+
+void StdFlowSystem::connectObject(Object sourceObject,const string& sourcePort,
+ Object destObject, const std::string& destPort)
+{
+ arts_debug("connect port %s to %s", sourcePort.c_str(), destPort.c_str());
+ StdScheduleNode *sn =
+ (StdScheduleNode *)sourceObject._node()->cast("StdScheduleNode");
+ assert(sn);
+
+ Port *port = sn->findPort(sourcePort);
+ assert(port);
+
+ StdScheduleNode *destsn =
+ (StdScheduleNode *)destObject._node()->cast("StdScheduleNode");
+ if(destsn)
+ {
+ sn->connect(sourcePort,destsn,destPort);
+ return;
+ }
+
+ ASyncPort *ap = port->asyncPort();
+
+ if(ap)
+ {
+ FlowSystemSender sender;
+ FlowSystemReceiver receiver;
+ FlowSystem remoteFs;
+
+ string dest = destObject.toString() + ":" + destPort;
+ ASyncNetSend *netsend = new ASyncNetSend(ap, dest);
+
+ sender = FlowSystemSender::_from_base(netsend); // don't release netsend
+ remoteFs = destObject._flowSystem();
+ receiver = remoteFs.createReceiver(destObject, destPort, sender);
+ netsend->setReceiver(receiver);
+ arts_debug("connected an asyncnetsend");
+ }
+}
+
+void StdFlowSystem::disconnectObject(Object sourceObject,
+ const string& sourcePort, Object destObject, const std::string& destPort)
+{
+ arts_debug("disconnect port %s and %s",sourcePort.c_str(),destPort.c_str());
+ StdScheduleNode *sn =
+ (StdScheduleNode *)sourceObject._node()->cast("StdScheduleNode");
+ assert(sn);
+
+ Port *port = sn->findPort(sourcePort);
+ assert(port);
+
+ StdScheduleNode *destsn =
+ (StdScheduleNode *)destObject._node()->cast("StdScheduleNode");
+ if(destsn)
+ {
+ sn->disconnect(sourcePort,destsn,destPort);
+ return;
+ }
+
+ ASyncPort *ap = port->asyncPort();
+ if(ap)
+ {
+ string dest = destObject.toString() + ":" + destPort;
+ ap->disconnectRemote(dest);
+ arts_debug("disconnected an asyncnetsend");
+ }
+}
+
+AttributeType StdFlowSystem::queryFlags(Object node, const std::string& port)
+{
+ StdScheduleNode *sn =
+ (StdScheduleNode *)node._node()->cast("StdScheduleNode");
+ assert(sn);
+ return sn->queryFlags(port);
+}
+
+void StdFlowSystem::setFloatValue(Object node, const std::string& port,
+ float value)
+{
+ StdScheduleNode *sn =
+ (StdScheduleNode *)node._node()->cast("StdScheduleNode");
+ assert(sn);
+ sn->setFloatValue(port,value);
+}
+
+FlowSystemReceiver StdFlowSystem::createReceiver(Object object,
+ const string &port, FlowSystemSender sender)
+{
+ StdScheduleNode *sn =
+ (StdScheduleNode *)object._node()->cast("StdScheduleNode");
+
+ Port *p = sn->findPort(port);
+ assert(p);
+
+ ASyncPort *ap = p->asyncPort();
+
+ if(ap)
+ {
+ arts_debug("creating packet receiver");
+ return FlowSystemReceiver::_from_base(new ASyncNetReceive(ap, sender));
+ }
+ return FlowSystemReceiver::null();
+}
+
+void StdFlowSystem::updateStarted()
+{
+ if(!needUpdateStarted)
+ return;
+
+ needUpdateStarted = false;
+
+ std::list<StdScheduleNode*>::iterator ni;
+ GslTrans *trans = 0;
+
+ for(ni = nodes.begin(); ni != nodes.end(); ni++)
+ {
+ StdScheduleNode *node = *ni;
+
+ if(node->running != node->gslRunning)
+ {
+ if(!trans)
+ trans = gsl_trans_open();
+ gsl_trans_add(trans, gsl_job_set_consumer(node->gslModule, node->running));
+ node->gslRunning = node->running;
+ }
+ }
+ if(trans)
+ gsl_trans_commit(trans);
+}
+
+void StdFlowSystem::startedChanged()
+{
+ needUpdateStarted = true;
+}
+
+// hacked initialization of Dispatcher::the()->flowSystem ;)
+
+namespace Arts {
+
+static class SetFlowSystem : public StartupClass {
+ FlowSystem_impl *fs;
+public:
+ void startup()
+ {
+ fs = new StdFlowSystem;
+ Dispatcher::the()->setFlowSystem(fs);
+ }
+ void shutdown()
+ {
+ fs->_release();
+ }
+} sfs;
+
+}
+
diff --git a/flow/gslschedule.h b/flow/gslschedule.h
new file mode 100644
index 0000000..4564dfc
--- /dev/null
+++ b/flow/gslschedule.h
@@ -0,0 +1,262 @@
+ /*
+
+ Copyright (C) 2000-2002 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef ARTS_GSLSCHEDULE_H
+#define ARTS_GSLSCHEDULE_H
+
+#include "artsflow.h"
+#include "flowsystem.h"
+#include <gsl/gsldefs.h>
+#include <string>
+#include <list>
+
+/*
+ * BC - Status (2002-03-08): Port, AudioPort, MultiPort, StdFlowSystem,
+ * StdScheduleNode
+ *
+ * None of these classes is considered part of the public API. Do NOT use it
+ * in your apps. These are part of the implementation of libartsflow's
+ * StdFlowSystem, and subject to change with the needs of it.
+ *
+ * If you want to access flowsystem functionality, do so over the core.idl
+ * specified flowsystem interface, (object)->_node() or stuff in mcop/connect.h.
+ */
+
+namespace Arts {
+
+class StdScheduleNode;
+
+class Port {
+ friend class VPort; // TODO: debugging, remove me when it works?
+ friend class VPortConnection; // TODO: debugging, remove me when it works?
+protected:
+ std::string _name;
+public:
+ void *_ptr;
+public: // FIXME: GSL
+ AttributeType _flags;
+ StdScheduleNode *parent;
+
+ // each port has a virtual port, which allows port redirection
+ class VPort *_vport;
+
+ // dynamic ports are created to implement multiports
+ bool _dynamicPort;
+
+ // functionality to remove all connections automatically as soon as
+ // the module gets destroyed
+ std::list<Port *> autoDisconnect;
+
+ /**
+ * call these from your (dis)connect implementation as soon as a the
+ * port gets (dis)connected to some other port (only one call per
+ * connection: destinationport->addAutoDisconnect(sourceport), not
+ * for the other direction)
+ */
+ void addAutoDisconnect(Port *source);
+ void removeAutoDisconnect(Port *source);
+
+public:
+ Port(const std::string& name, void *ptr, long flags,
+ StdScheduleNode* parent);
+ virtual ~Port();
+
+ inline VPort* vport() { assert(_vport); return _vport; }
+ AttributeType flags();
+ std::string name();
+ void setPtr(void *ptr);
+
+ inline bool dynamicPort() { return _dynamicPort; }
+ inline void setDynamicPort() { _dynamicPort = true; }
+
+ virtual class AudioPort *audioPort();
+ virtual class ASyncPort *asyncPort();
+
+ virtual void disconnectAll();
+ virtual void connect(Port *) = 0;
+ virtual void disconnect(Port *) = 0;
+};
+
+class AudioPort : public Port {
+public: // FIXME: GSL
+ AudioPort *source;
+
+public:
+ StdScheduleNode *sourcemodule;
+ unsigned long destcount;
+ unsigned long gslEngineChannel;
+
+ /* GSL */
+ bool gslIsConstant;
+ float gslConstantValue;
+
+ AudioPort(const std::string& name,
+ void *ptr, long flags,StdScheduleNode *parent);
+ ~AudioPort();
+
+ virtual class AudioPort *audioPort();
+
+ void setFloatValue(float f);
+ void connect(Port *psource);
+ void disconnect(Port *psource);
+};
+
+class MultiPort : public Port {
+protected:
+ struct Part {
+ AudioPort *src, *dest;
+ };
+
+ std::list<Part> parts;
+ typedef float *float_ptr;
+ float **conns;
+ long nextID;
+ void initConns();
+
+public:
+ MultiPort(const std::string& name,
+ void *ptr, long flags,StdScheduleNode *parent);
+ ~MultiPort();
+
+ void connect(Port *port);
+ void disconnect(Port *port);
+};
+
+class StdFlowSystem;
+
+class StdScheduleNode :public ScheduleNode
+{
+ friend class StdFlowSystem;
+ bool running;
+ bool suspended;
+
+ Object_skel *_object;
+ SynthModule_base *module;
+ StdFlowSystem *flowSystem;
+ std::list<Port *> ports;
+ AudioPort **inConn;
+ AudioPort **outConn;
+ unsigned long inConnCount, outConnCount;
+ typedef AudioPort *AudioPort_ptr;
+ QueryInitStreamFunc queryInitStreamFunc;
+
+ void freeConn();
+ void rebuildConn();
+ void accessModule();
+
+ static void gslProcess(GslModule *module, guint n_values);
+ public: /* TODO? */
+ Port *findPort(const std::string& name);
+
+public:
+
+ GslModule *gslModule;
+ bool gslRunning;
+
+ /**
+ * this is used by StdFlowSystem::suspend() to mark nodes which
+ * have already been seen by the algorithm
+ */
+ bool suspendTag;
+
+ StdScheduleNode(Object_skel *object, StdFlowSystem *flowSystem);
+ virtual ~StdScheduleNode();
+ void initStream(const std::string& name, void *ptr, long flags);
+ void addDynamicPort(Port *port);
+ void removeDynamicPort(Port *port);
+
+ void start();
+ void stop();
+ void requireFlow();
+ void virtualize(const std::string& port, ScheduleNode *implNode,
+ const std::string& implPort);
+ void devirtualize(const std::string& port, ScheduleNode *implNode,
+ const std::string& implPort);
+
+ // AutoSuspend stuff
+ AutoSuspendState suspendable();
+ void suspend();
+ void restart();
+
+ void connect(const std::string& port, ScheduleNode *dest,
+ const std::string& destport);
+ void disconnect(const std::string& port, ScheduleNode *dest,
+ const std::string& destport);
+
+ AttributeType queryFlags(const std::string& port);
+ void setFloatValue(const std::string& port, float value);
+
+ Object_skel *object();
+ void *cast(const std::string &target);
+
+ // used by StdSynthModule
+ unsigned long inputConnectionCount(const std::string& port);
+ unsigned long outputConnectionCount(const std::string& port);
+
+ bool _connectionCountChanged;
+ inline bool connectionCountChanged() {
+ bool c = _connectionCountChanged;
+ _connectionCountChanged = false;
+ return c;
+ }
+};
+
+class StdFlowSystem :public FlowSystem_impl
+{
+protected:
+ std::list<StdScheduleNode *> nodes;
+ bool _suspended;
+ bool needUpdateStarted;
+public:
+ StdFlowSystem();
+
+ ScheduleNode *addObject(Object_skel *object);
+ void removeObject(ScheduleNode *node);
+
+ /* AutoSuspend */
+ bool suspendable();
+ bool suspended();
+ void suspend();
+ void restart();
+
+ /* remote accessibility */
+ void startObject(Object node);
+ void stopObject(Object node);
+ void connectObject(Object sourceObject, const std::string& sourcePort,
+ Object destObject, const std::string& destPort);
+ void disconnectObject(Object sourceObject, const std::string& sourcePort,
+ Object destObject, const std::string& destPort);
+ AttributeType queryFlags(Object node, const std::string& port);
+ void setFloatValue(Object node, const std::string& port, float value);
+
+ FlowSystemReceiver createReceiver(Object object, const std::string &port,
+ FlowSystemSender sender);
+
+ /* interface to StdScheduleNode */
+ void schedule(unsigned long samples);
+ void updateStarted();
+ void startedChanged();
+};
+
+}
+
+#endif
diff --git a/flow/mcopclass/DataHandlePlay.mcopclass b/flow/mcopclass/DataHandlePlay.mcopclass
new file mode 100644
index 0000000..cd84c48
--- /dev/null
+++ b/flow/mcopclass/DataHandlePlay.mcopclass
@@ -0,0 +1,2 @@
+Interface=Arts::DataHandlePlay,Arts::SynthModule,Arts::Object
+Language=C++
diff --git a/flow/mcopclass/Makefile.am b/flow/mcopclass/Makefile.am
new file mode 100644
index 0000000..faf2683
--- /dev/null
+++ b/flow/mcopclass/Makefile.am
@@ -0,0 +1,15 @@
+mcopclassdir = $(libdir)/mcop/Arts
+mcopclass_DATA = Synth_ADD.mcopclass \
+ Synth_FREQUENCY.mcopclass \
+ Synth_MUL.mcopclass \
+ Synth_MULTI_ADD.mcopclass \
+ Synth_PLAY.mcopclass \
+ Synth_RECORD.mcopclass \
+ Synth_PLAY_WAV.mcopclass \
+ Synth_WAVE_SIN.mcopclass \
+ Synth_BUS_DOWNLINK.mcopclass \
+ Synth_BUS_UPLINK.mcopclass \
+ Synth_AMAN_PLAY.mcopclass \
+ Synth_AMAN_RECORD.mcopclass \
+ DataHandlePlay.mcopclass \
+ WaveDataHandle.mcopclass
diff --git a/flow/mcopclass/Synth_ADD.mcopclass b/flow/mcopclass/Synth_ADD.mcopclass
new file mode 100644
index 0000000..0429b3f
--- /dev/null
+++ b/flow/mcopclass/Synth_ADD.mcopclass
@@ -0,0 +1,3 @@
+Buildable=true
+Interface=Arts::Synth_ADD,Arts::SynthModule,Arts::Object
+Language=C++
diff --git a/flow/mcopclass/Synth_AMAN_PLAY.mcopclass b/flow/mcopclass/Synth_AMAN_PLAY.mcopclass
new file mode 100644
index 0000000..02f8e99
--- /dev/null
+++ b/flow/mcopclass/Synth_AMAN_PLAY.mcopclass
@@ -0,0 +1,3 @@
+Buildable=true
+Interface=Arts::Synth_AMAN_PLAY,Arts::SynthModule,Arts::Object
+Language=C++
diff --git a/flow/mcopclass/Synth_AMAN_RECORD.mcopclass b/flow/mcopclass/Synth_AMAN_RECORD.mcopclass
new file mode 100644
index 0000000..c92cb76
--- /dev/null
+++ b/flow/mcopclass/Synth_AMAN_RECORD.mcopclass
@@ -0,0 +1,3 @@
+Buildable=true
+Interface=Arts::Synth_AMAN_RECORD,Arts::SynthModule,Arts::Object
+Language=C++
diff --git a/flow/mcopclass/Synth_BUS_DOWNLINK.mcopclass b/flow/mcopclass/Synth_BUS_DOWNLINK.mcopclass
new file mode 100644
index 0000000..bcc0c2a
--- /dev/null
+++ b/flow/mcopclass/Synth_BUS_DOWNLINK.mcopclass
@@ -0,0 +1,3 @@
+Buildable=true
+Interface=Arts::Synth_BUS_DOWNLINK,Arts::SynthModule,Arts::Object
+Language=C++
diff --git a/flow/mcopclass/Synth_BUS_UPLINK.mcopclass b/flow/mcopclass/Synth_BUS_UPLINK.mcopclass
new file mode 100644
index 0000000..d262b1e
--- /dev/null
+++ b/flow/mcopclass/Synth_BUS_UPLINK.mcopclass
@@ -0,0 +1,3 @@
+Buildable=true
+Interface=Arts::Synth_BUS_UPLINK,Arts::SynthModule,Arts::Object
+Language=C++
diff --git a/flow/mcopclass/Synth_FREQUENCY.mcopclass b/flow/mcopclass/Synth_FREQUENCY.mcopclass
new file mode 100644
index 0000000..91c5016
--- /dev/null
+++ b/flow/mcopclass/Synth_FREQUENCY.mcopclass
@@ -0,0 +1,3 @@
+Buildable=true
+Interface=Arts::Synth_FREQUENCY,Arts::SynthModule,Arts::Object
+Language=C++
diff --git a/flow/mcopclass/Synth_MUL.mcopclass b/flow/mcopclass/Synth_MUL.mcopclass
new file mode 100644
index 0000000..c1087c2
--- /dev/null
+++ b/flow/mcopclass/Synth_MUL.mcopclass
@@ -0,0 +1,3 @@
+Buildable=true
+Interface=Arts::Synth_MUL,Arts::SynthModule,Arts::Object
+Language=C++
diff --git a/flow/mcopclass/Synth_MULTI_ADD.mcopclass b/flow/mcopclass/Synth_MULTI_ADD.mcopclass
new file mode 100644
index 0000000..f883f9e
--- /dev/null
+++ b/flow/mcopclass/Synth_MULTI_ADD.mcopclass
@@ -0,0 +1,3 @@
+Buildable=true
+Interface=Arts::Synth_MULTI_ADD,Arts::SynthModule,Arts::Object
+Language=C++
diff --git a/flow/mcopclass/Synth_PLAY.mcopclass b/flow/mcopclass/Synth_PLAY.mcopclass
new file mode 100644
index 0000000..35c3ac4
--- /dev/null
+++ b/flow/mcopclass/Synth_PLAY.mcopclass
@@ -0,0 +1,3 @@
+Buildable=true
+Interface=Arts::Synth_PLAY,Arts::SynthModule,Arts::Object
+Language=C++
diff --git a/flow/mcopclass/Synth_PLAY_WAV.mcopclass b/flow/mcopclass/Synth_PLAY_WAV.mcopclass
new file mode 100644
index 0000000..8ca8d5c
--- /dev/null
+++ b/flow/mcopclass/Synth_PLAY_WAV.mcopclass
@@ -0,0 +1,3 @@
+Buildable=true
+Interface=Arts::Synth_PLAY_WAV,Arts::SynthModule,Arts::Object
+Language=C++
diff --git a/flow/mcopclass/Synth_RECORD.mcopclass b/flow/mcopclass/Synth_RECORD.mcopclass
new file mode 100644
index 0000000..8b69cf7
--- /dev/null
+++ b/flow/mcopclass/Synth_RECORD.mcopclass
@@ -0,0 +1,3 @@
+Buildable=true
+Interface=Arts::Synth_RECORD,Arts::SynthModule,Arts::Object
+Language=C++
diff --git a/flow/mcopclass/Synth_WAVE_SIN.mcopclass b/flow/mcopclass/Synth_WAVE_SIN.mcopclass
new file mode 100644
index 0000000..422d68f
--- /dev/null
+++ b/flow/mcopclass/Synth_WAVE_SIN.mcopclass
@@ -0,0 +1,3 @@
+Buildable=true
+Interface=Arts::Synth_WAVE_SIN,Arts::SynthModule,Arts::Object
+Language=C++
diff --git a/flow/mcopclass/WaveDataHandle.mcopclass b/flow/mcopclass/WaveDataHandle.mcopclass
new file mode 100644
index 0000000..d25effd
--- /dev/null
+++ b/flow/mcopclass/WaveDataHandle.mcopclass
@@ -0,0 +1,2 @@
+Interface=Arts::WaveDataHandle,Arts::Object
+Language=C++
diff --git a/flow/pipebuffer.cc b/flow/pipebuffer.cc
new file mode 100644
index 0000000..bb6073a
--- /dev/null
+++ b/flow/pipebuffer.cc
@@ -0,0 +1,166 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include "pipebuffer.h"
+#include <assert.h>
+#include <cstring>
+
+using namespace std;
+using namespace Arts;
+
+PipeSegment::PipeSegment(long size, void *buffer)
+{
+ this->buffer = new char[size];
+ this->currentpos = this->buffer;
+ memcpy(this->buffer,buffer,size);
+
+ _remaining = size;
+}
+
+PipeSegment::~PipeSegment()
+{
+ delete[] buffer;
+}
+
+void *PipeSegment::data()
+{
+ return currentpos;
+}
+
+long PipeSegment::remaining()
+{
+ return _remaining;
+}
+
+void PipeSegment::skip(long count)
+{
+ _remaining -= count;
+ currentpos += count;
+ assert(_remaining >= 0);
+}
+
+PipeBuffer::PipeBuffer()
+{
+ _size = 0;
+}
+
+PipeBuffer::~PipeBuffer()
+{
+ clear();
+}
+
+void PipeBuffer::clear()
+{
+ while(segments.size() != 0)
+ {
+ PipeSegment *first = *segments.begin();
+ delete first;
+
+ segments.pop_front();
+ }
+ _size = 0;
+}
+
+void *PipeBuffer::peek(long size)
+{
+ while(!segments.empty())
+ {
+ PipeSegment *first = *segments.begin();
+ if(size <= first->remaining())
+ return first->data();
+ }
+ return 0;
+}
+
+void PipeBuffer::skip(long size)
+{
+ while(!segments.empty() && size > 0)
+ {
+ PipeSegment *first = *segments.begin();
+
+ // if we have less data to skip than the first segment contains
+ if(size < first->remaining())
+ {
+ // skip the data inside the segment
+
+ _size -= size;
+ first->skip(size);
+ return;
+ }
+ else
+ {
+ // otherwise erase the first segment
+
+ _size -= first->remaining();
+ size -= first->remaining();
+
+ delete first;
+ segments.pop_front();
+ }
+ }
+}
+
+long PipeBuffer::read(long size, void *buffer)
+{
+ long readbytes = 0;
+ char *bptr = (char *)buffer;
+
+ while(!segments.empty() && size > 0)
+ {
+ PipeSegment *first = *segments.begin();
+ long readCnt = size;
+ if(readCnt > first->remaining()) readCnt = first->remaining();
+
+ memcpy(bptr,first->data(),readCnt);
+
+ first->skip(readCnt);
+ size -= readCnt;
+ bptr += readCnt;
+ readbytes += readCnt;
+
+ if(first->remaining() == 0)
+ {
+ delete first;
+ segments.pop_front();
+ }
+ }
+
+ _size -= readbytes;
+ return readbytes;
+}
+
+long PipeBuffer::size()
+{
+ return _size;
+}
+
+void PipeBuffer::write(long size, void *buffer)
+{
+ segments.push_back(new PipeSegment(size,buffer));
+ _size += size;
+}
+
+void PipeBuffer::unRead(long size, void *buffer)
+{
+ segments.push_front(new PipeSegment(size,buffer));
+ _size += size;
+}
diff --git a/flow/pipebuffer.h b/flow/pipebuffer.h
new file mode 100644
index 0000000..c44e16b
--- /dev/null
+++ b/flow/pipebuffer.h
@@ -0,0 +1,75 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef __PIPEBUFFER_H__
+#define __PIPEBUFFER_H__
+
+/*
+ * BC - Status (2002-03-08): PipeSegment, PipeBuffer
+ *
+ * None of these classes is considered part of the public API. Do NOT use it
+ * in your apps. These are part of the implementation of libartsflow's
+ * AudioSubSystem, and subject to change/disappearing due to optimization
+ * work.
+ */
+
+
+#include <list>
+namespace Arts {
+
+class PipeSegment {
+ long _remaining;
+ char *currentpos, *buffer;
+public:
+ PipeSegment(long size, void *buffer);
+ ~PipeSegment();
+
+ void *data();
+ long remaining();
+ void skip(long count);
+};
+
+class PipeBuffer {
+protected:
+ std::list<PipeSegment *> segments;
+ long _size;
+
+public:
+ PipeBuffer();
+ ~PipeBuffer();
+
+ // reading
+ void *peek(long size);
+ void skip(long size);
+ long read(long size, void *buffer);
+ void unRead(long size, void *buffer);
+
+ // writing
+ void write(long size, void *buffer);
+ void clear();
+
+ // status
+ long size();
+};
+}
+
+#endif
diff --git a/flow/resample.cc b/flow/resample.cc
new file mode 100644
index 0000000..45cd099
--- /dev/null
+++ b/flow/resample.cc
@@ -0,0 +1,305 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include "resample.h"
+#include "debug.h"
+#include <math.h>
+#include <assert.h>
+#include <stdio.h>
+
+#define compose_16le(first,second) \
+ (((((second)+128)&0xff) << 8)+(first))
+
+#define compose_16be(first,second) \
+ (((((first)+128)&0xff) << 8)+(second))
+
+#define conv_16_float(x) \
+ ((float)((x)-32768)/32768.0)
+
+#define conv_8_float(x) \
+ ((float)((x)-128)/128.0)
+
+using namespace Arts;
+
+class Arts::ResamplerPrivate {
+public:
+ bool underrun;
+ Resampler::Endianness endianness;
+};
+
+const unsigned int Resampler::bufferSize;
+const unsigned int Resampler::bufferWrap;
+
+Resampler::Resampler(Refiller *refiller) :
+ dropBytes(0), refiller(refiller), pos(0.0), step(1.0), channels(2),
+ bits(16),
+ block(0), haveBlock(-1)
+{
+ d = new ResamplerPrivate();
+ d->underrun = false;
+ d->endianness = littleEndian;
+ updateSampleSize();
+}
+
+Resampler::~Resampler()
+{
+ delete d;
+}
+
+void Resampler::updateSampleSize()
+{
+ sampleSize = channels * bits / 8;
+ bufferSamples = bufferSize / sampleSize;
+}
+
+void Resampler::setStep(double newStep)
+{
+ arts_return_if_fail(newStep > 0);
+
+ step = newStep;
+}
+
+void Resampler::setChannels(int newChannels)
+{
+ arts_return_if_fail(newChannels == 1 || newChannels == 2);
+
+ channels = newChannels;
+ updateSampleSize();
+}
+
+void Resampler::setBits(int newBits)
+{
+ arts_return_if_fail(newBits == 8 || newBits == 16);
+
+ bits = newBits;
+ updateSampleSize();
+}
+
+void Resampler::setEndianness(Endianness newEndianness)
+{
+ arts_return_if_fail(newEndianness == bigEndian || newEndianness == littleEndian);
+
+ d->endianness = newEndianness;
+}
+
+bool Resampler::underrun()
+{
+ return d->underrun;
+}
+
+void Resampler::ensureRefill()
+{
+ if(haveBlock == block) return;
+
+ unsigned long missing;
+ if(block == 0)
+ {
+ missing = bufferSize+sampleSize
+ - refiller->read(buffer,bufferSize+sampleSize);
+
+ d->underrun = (missing == bufferSize+sampleSize);
+ }
+ else
+ {
+ /*
+ * try to drop away "half-sample" reads from the last refill
+ */
+ if(dropBytes > 0)
+ dropBytes -= refiller->read(buffer,dropBytes);
+
+ /*
+ * only if this worked there is hope that we can read sane data
+ */
+ if(dropBytes == 0)
+ {
+ missing = bufferSize
+ - refiller->read(&buffer[sampleSize], bufferSize);
+
+ d->underrun = (missing == bufferSize);
+ }
+ else
+ {
+ missing = bufferSize;
+ d->underrun = true;
+ }
+ }
+ haveBlock++;
+ assert(haveBlock == block);
+
+ /*
+ * If we don't have enough input to fill the block fully, it might be
+ * that the input stall occurred in the middle of a sample. For instance,
+ * if samples are 4 bytes long, it might be that we would have needed
+ * 13 more bytes to do a full refill.
+ *
+ * In this situation, there are four samples and one byte missing to
+ * refill the buffer - the one byte is what we need to care about here:
+ * on the next read, we'll have one byte too much (if we simply ignore
+ * the fact, we end up with misaligned reading, causing noise, or
+ * swapped stereo channels or similar).
+ *
+ * So we set dropBytes here, which is a variable which indicates how
+ * many bytes to drop away upon next refill.
+ */
+ if(missing & (sampleSize - 1))
+ dropBytes = missing & (sampleSize - 1);
+
+ unsigned int i = 0, wrap = (block == 0)?0:sampleSize;
+ if(bits == 16)
+ {
+ // wrap the last part of the buffer back to the beginning (history)
+ while(i<wrap)
+ {
+ fbuffer[i/2] = fbuffer[(bufferSize+i)/2];
+ i += 2;
+ }
+
+ // convert data from incoming
+ if(d->endianness == littleEndian)
+ {
+ while(i<bufferSize+sampleSize-missing)
+ {
+ fbuffer[i/2] = conv_16_float(compose_16le(buffer[i],buffer[i+1]));
+ i += 2;
+ }
+ }
+ else
+ {
+ while(i<bufferSize+sampleSize-missing)
+ {
+ fbuffer[i/2] = conv_16_float(compose_16be(buffer[i],buffer[i+1]));
+ i += 2;
+ }
+ }
+
+ // fill up missing bytes with zero samples
+ while(i<bufferSize+sampleSize)
+ {
+ fbuffer[i/2] = 0.0;
+ i += 2;
+ }
+ }
+ else if(bits == 8)
+ {
+ // wrap the last part of the buffer back to the beginning (history)
+ while(i<wrap)
+ {
+ fbuffer[i] = fbuffer[bufferSize+i];
+ i++;
+ }
+
+ // convert data from incoming
+ while(i<bufferSize+sampleSize-missing)
+ {
+ fbuffer[i] = conv_8_float(buffer[i]);
+ i++;
+ }
+
+ // fill up missing bytes with zero samples
+ while(i<bufferSize+sampleSize)
+ {
+ fbuffer[i++] = 0.0;
+ }
+ }
+ else
+ {
+ assert(false);
+ }
+}
+
+#define RESAMPLER_STEP() \
+ pos += step; \
+ i++; \
+ while(pos >= bufferSamples) \
+ { \
+ pos -= bufferSamples; \
+ block++; \
+ ensureRefill(); \
+ }
+
+void Resampler::run(float *left, float *right, unsigned long samples)
+{
+ ensureRefill();
+ unsigned long i = 0;
+ double delta = step - floor(step);
+ bool interpolate = fabs(delta) > 0.001;
+
+ if(channels == 2 && interpolate)
+ {
+ while(i < samples)
+ {
+ double error = pos - floor(pos);
+ unsigned long offset = 2*(unsigned long)pos;
+
+ left[i] = fbuffer[offset+0]*(1.0-error)+fbuffer[offset+2]*error;
+ right[i] = fbuffer[offset+1]*(1.0-error)+fbuffer[offset+3]*error;
+ RESAMPLER_STEP();
+ }
+ }
+ else if(channels == 1 && interpolate)
+ {
+ while(i < samples)
+ {
+ double error = pos - floor(pos);
+ unsigned long offset = (unsigned long)pos;
+
+ left[i] = right[i] = fbuffer[offset]*(1.0-error)
+ + fbuffer[offset+1]*error;
+ RESAMPLER_STEP();
+ }
+ }
+ else if(channels == 2)
+ {
+ while(i < samples)
+ {
+ unsigned long offset = 2*(unsigned long)pos;
+
+ left[i] = fbuffer[offset+0];
+ right[i] = fbuffer[offset+1];
+ RESAMPLER_STEP();
+ }
+ }
+ else if(channels == 1)
+ {
+ while(i < samples)
+ {
+ unsigned long offset = (unsigned long)pos;
+
+ left[i] = right[i] = fbuffer[offset];
+ RESAMPLER_STEP();
+ }
+ }
+ else
+ {
+ assert(false);
+ }
+}
+
+Refiller::~Refiller()
+{
+}
+
+#undef RESAMPLER_STEP
+#undef compose_16le
+#undef compose_16be
+#undef conv_16_float
+#undef conv_8_float
diff --git a/flow/resample.h b/flow/resample.h
new file mode 100644
index 0000000..3cb99e3
--- /dev/null
+++ b/flow/resample.h
@@ -0,0 +1,167 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+
+#ifndef ARTS_FLOW_RESAMPLE_H
+#define ARTS_FLOW_RESAMPLE_H
+
+#include "arts_export.h"
+
+/*
+ * BC - Status (2002-03-08): Resampler / Refiller.
+ *
+ * These classes will be kept binary compatible. Resampler has a private
+ * data pointer for this purpose.
+ */
+
+namespace Arts {
+
+/**
+ * Refiller interface
+ *
+ * this is used by the resampler class
+ */
+class ARTS_EXPORT Refiller {
+public:
+ /**
+ * callback method to supply data to the Resampler
+ *
+ * here you supply data in the encoding specified in the Resampler class
+ * (bits, channels, endianness) to the Resampler
+ *
+ * @param buffer a pointer to a buffer where the data can be filled to
+ * @param len the size of the buffer in bytes
+ *
+ * @returns the number of bytes really available
+ */
+ virtual unsigned long read(unsigned char *buffer, unsigned long len) = 0;
+ virtual ~Refiller();
+};
+
+class ResamplerPrivate;
+
+/**
+ * The Resampler class resamples data from an input stream, which is read
+ * through the Refiller interface, and renders it into the float format which
+ * aRts usually uses, converting the sampling rate and format as needed.
+ */
+class ARTS_EXPORT Resampler {
+protected:
+ static const unsigned int bufferSize = 256; // 64 samples in buffer
+ static const unsigned int bufferWrap = 64; // + "wrap around"
+ /*
+ * BC: bufferWrap just needs channels * (filtersize - 1) * bytes per sample
+ * bytes wrap around - this used to be 4: 2 channels, linear interpolation,
+ * 16bit. However, for supporting float resampling and/or better filters,
+ * we'll make this 64 to be safe.
+ */
+
+ int bufferSamples;
+ int sampleSize;
+ int dropBytes;
+
+ Refiller *refiller;
+ double pos, step;
+ int channels,bits;
+
+ unsigned char buffer[bufferSize+bufferWrap];
+ float fbuffer[bufferSize+bufferWrap];
+ long block, haveBlock;
+
+ class ResamplerPrivate *d;
+
+ void updateSampleSize();
+ void ensureRefill();
+public:
+ /**
+ * constructor
+ *
+ */
+ Resampler(Refiller *refiller);
+ ~Resampler();
+
+ /**
+ * sets the resampling step in the input stream
+ *
+ * for instance, settings step to 2.0, the file would be played twice as
+ * fast - you can calculate the resampling step from the sampling rate
+ * the stream you resample was recorded at, and the sampling rate you want
+ * it to be resampled to, using
+ *
+ * step = originalSamplingRate / desiredSamplingRate
+ *
+ * for instance, if a stream recorded at 22050 Hz is to be played at 48000
+ * Hz, step would be
+ *
+ * step = 22050 / 48000 = 0.46
+ */
+ void setStep(double step);
+
+ /**
+ * sets the number of channels in the input stream
+ *
+ * the channels are expected to be interleaved, thus if you have two
+ * channels, you will have one sample for the left stream, one for the
+ * right, one for the left, ... and so on
+ *
+ * currently only either mono (channels = 1) or stereo (channels = 2)
+ * streams are supported
+ */
+ void setChannels(int channels);
+
+ /**
+ * sets the number of bits in the input stream
+ *
+ * currently, only 16 bit and 8 bit streams are supported
+ */
+ void setBits(int bits);
+
+ enum Endianness { bigEndian, littleEndian };
+
+ /**
+ * sets the endianess of the input stream
+ *
+ * supported are bigEndian and littleEndian
+ */
+ void setEndianness(Endianness endianness);
+
+ /**
+ * renders a buffer of float samples from the input stream
+ *
+ * the data is obtained by querying the refiller for data from the
+ * input stream and filling them into the float array pointed to by
+ * left and right - if reading data fails, the underrun flag is set
+ */
+ void run(float *left, float *right, unsigned long samples);
+
+ /**
+ * query the underrun flag
+ *
+ * underruns occur if run is called, but no data is available from the
+ * Refiller object
+ */
+ bool underrun();
+};
+
+}
+
+#endif /* ARTS_FLOW_RESAMPLE_H */
diff --git a/flow/stdsynthmodule.cc b/flow/stdsynthmodule.cc
new file mode 100644
index 0000000..6d1c122
--- /dev/null
+++ b/flow/stdsynthmodule.cc
@@ -0,0 +1,92 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include "stdsynthmodule.h"
+#include "gslschedule.h"
+#include "audiosubsys.h"
+#include "flowsystem.h"
+#include "debug.h"
+
+using namespace Arts;
+using namespace std;
+
+StdSynthModule::StdSynthModule()
+{
+ // TODO: maybe this should be handled over some other mechanism
+
+ samplingRate = AudioSubSystem::the()->samplingRate();
+ samplingRateFloat = (float)samplingRate;
+}
+
+void StdSynthModule::streamInit()
+{
+}
+
+void StdSynthModule::streamStart()
+{
+}
+
+void StdSynthModule::streamEnd()
+{
+}
+
+void StdSynthModule::start()
+{
+ _node()->start();
+}
+
+void StdSynthModule::stop()
+{
+ _node()->stop();
+}
+
+AutoSuspendState StdSynthModule::autoSuspend()
+{
+ return asNoSuspend;
+}
+
+unsigned long StdSynthModule::inputConnectionCount(const std::string& port)
+{
+ StdScheduleNode *xnode = (StdScheduleNode *)
+ _node()->cast("StdScheduleNode");
+ arts_return_val_if_fail(xnode, 0);
+
+ return xnode->inputConnectionCount(port);
+}
+
+unsigned long StdSynthModule::outputConnectionCount(const std::string& port)
+{
+ StdScheduleNode *xnode = (StdScheduleNode *)
+ _node()->cast("StdScheduleNode");
+ arts_return_val_if_fail(xnode, 0);
+
+ return xnode->outputConnectionCount(port);
+}
+
+bool StdSynthModule::connectionCountChanged()
+{
+ StdScheduleNode *xnode = (StdScheduleNode *)
+ _node()->cast("StdScheduleNode");
+ arts_return_val_if_fail(xnode, 0);
+
+ return xnode->connectionCountChanged();
+}
diff --git a/flow/stdsynthmodule.h b/flow/stdsynthmodule.h
new file mode 100644
index 0000000..fb1830a
--- /dev/null
+++ b/flow/stdsynthmodule.h
@@ -0,0 +1,65 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef STDSYNTHMODULE_H
+#define STDSYNTHMODULE_H
+
+#include "arts_export.h"
+#include "artsflow.h"
+
+/*
+ * BC - Status (2002-03-08): StdSynthModule
+ *
+ * This class is intended for public use (inheritance) as it supplies a base
+ * for all objects using streams. It will be kept binary compatible.
+ */
+
+namespace Arts {
+
+class StdSynthModulePrivate;
+
+class ARTS_EXPORT StdSynthModule : virtual public SynthModule_base {
+private:
+ StdSynthModulePrivate *d;
+
+protected:
+ long samplingRate;
+ float samplingRateFloat;
+
+public:
+ StdSynthModule();
+
+ void start();
+ void stop();
+
+ void streamInit();
+ void streamStart();
+ void streamEnd();
+
+ AutoSuspendState autoSuspend();
+
+ unsigned long inputConnectionCount(const std::string& portname);
+ unsigned long outputConnectionCount(const std::string& portname);
+ bool connectionCountChanged();
+};
+}
+#endif /* STDSYNTHMODULE_H */
diff --git a/flow/stereoeffectstack_impl.cc b/flow/stereoeffectstack_impl.cc
new file mode 100644
index 0000000..3e82cfb
--- /dev/null
+++ b/flow/stereoeffectstack_impl.cc
@@ -0,0 +1,179 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include "artsflow.h"
+#include "flowsystem.h"
+#include "stdsynthmodule.h"
+#include "debug.h"
+#include <iostream>
+
+using namespace std;
+using namespace Arts;
+
+namespace Arts {
+
+class StereoEffectStack_impl : public StereoEffectStack_skel,
+ public StdSynthModule
+{
+ long nextID;
+
+ struct EffectEntry {
+ StereoEffect effect;
+ string name;
+ long id;
+ };
+ list<EffectEntry *> fx;
+
+ void xconnect(bool connect, Object from, string fromP, Object to, string toP)
+ {
+ if(connect)
+ from._node()->connect(fromP,to._node(),toP);
+ else
+ from._node()->disconnect(fromP,to._node(),toP);
+ }
+ void xvirtualize(bool connect, string myPort, Object impl, string implPort)
+ {
+ if(connect)
+ _node()->virtualize(myPort,impl._node(),implPort);
+ else
+ _node()->devirtualize(myPort,impl._node(),implPort);
+ }
+ void internalconnect(bool c)
+ {
+ if(fx.empty())
+ {
+ /* no effects - forward input through to output */
+ xvirtualize(c,"outleft",Object::_from_base(this->_copy()),"inleft");
+ xvirtualize(c,"outright",Object::_from_base(this->_copy()),"inright");
+ }
+ else
+ {
+ list<EffectEntry *>::iterator ei;
+ EffectEntry *laste = 0;
+
+ long count = 0;
+ for(ei = fx.begin(); ei != fx.end(); ei++, count++)
+ {
+ EffectEntry *e = *ei;
+ if(count == 0) /* top of chain? virtualize to effect */
+ {
+ xvirtualize(c,"inleft",e->effect,"inleft");
+ xvirtualize(c,"inright",e->effect,"inright");
+ }
+ else /* not top? connect last effect to current effect */
+ {
+ xconnect(c,laste->effect,"outleft",e->effect,"inleft");
+ xconnect(c,laste->effect,"outright",e->effect,"inright");
+ }
+ laste = e;
+ }
+ /* end: virtualize effect output to our output */
+ xvirtualize(c,"outleft",laste->effect,"outleft");
+ xvirtualize(c,"outright",laste->effect,"outright");
+ }
+ }
+ void disconnect() { internalconnect(false); }
+ void reconnect() { internalconnect(true); }
+public:
+ StereoEffectStack_impl() : nextID(1)
+ {
+ reconnect();
+ }
+ ~StereoEffectStack_impl()
+ {
+ // disconnect remaining effects
+ EffectEntry *laste = 0;
+ list<EffectEntry *>::iterator ei;
+
+ for(ei = fx.begin(); ei != fx.end(); ei++)
+ {
+ EffectEntry *e = *ei;
+ if(laste)
+ {
+ xconnect(false,laste->effect,"outleft",e->effect,"inleft");
+ xconnect(false,laste->effect,"outright",e->effect,"inright");
+ }
+ laste = e;
+ }
+ // delete remaining effect entries
+ for(ei = fx.begin(); ei != fx.end(); ei++)
+ delete *ei;
+ fx.clear();
+ }
+ long insertTop(StereoEffect effect, const string& name)
+ {
+ arts_return_val_if_fail(!effect.isNull(),0);
+
+ disconnect();
+ EffectEntry *e = new EffectEntry();
+ e->effect = effect;
+ e->name = name;
+ e->id = nextID++;
+ fx.push_front(e);
+ reconnect();
+ return e->id;
+ }
+ long insertBottom(StereoEffect effect, const string& name)
+ {
+ arts_return_val_if_fail(!effect.isNull(),0);
+
+ disconnect();
+ EffectEntry *e = new EffectEntry();
+ e->effect = effect;
+ e->name = name;
+ e->id = nextID++;
+ fx.push_back(e);
+ reconnect();
+ return e->id;
+ }
+
+ void remove(long ID)
+ {
+ arts_return_if_fail(ID != 0);
+
+ bool found = false;
+ disconnect();
+ list<EffectEntry *>::iterator ei = fx.begin();
+
+ while(ei != fx.end())
+ {
+ if((*ei)->id == ID) {
+ found = true;
+ delete (*ei);
+ fx.erase(ei);
+ ei = fx.begin();
+ }
+ else ei++;
+ }
+ if(!found) {
+ arts_warning("StereoEffectStack::remove failed. id %d not found?",
+ ID);
+ }
+ reconnect();
+ }
+
+ AutoSuspendState autoSuspend() { return asSuspend; }
+};
+
+REGISTER_IMPLEMENTATION(StereoEffectStack_impl);
+
+}
diff --git a/flow/stereofftscope_impl.cc b/flow/stereofftscope_impl.cc
new file mode 100644
index 0000000..59ec05a
--- /dev/null
+++ b/flow/stereofftscope_impl.cc
@@ -0,0 +1,131 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include "artsflow.h"
+#include "fft.h"
+#include "stdsynthmodule.h"
+#include <math.h>
+#include <iostream>
+
+using namespace std;
+using namespace Arts;
+
+namespace Arts {
+
+class StereoFFTScope_impl : public StereoFFTScope_skel, public StdSynthModule {
+protected:
+ static const unsigned long SAMPLES = 4096;
+ vector<float> _scope;
+ /*
+ * some gcc versions expose ugly behaviour with virtual inheritance:
+ * putting window[4096] & inbuffer[4096] here bloats the vtable then,
+ * and tells you to recompile with -fhuge-objects ... so allocate them
+ * dynamically
+ */
+ float *window;
+ float *inbuffer;
+ unsigned long inbufferpos;
+public:
+ void do_fft()
+ {
+ float out_real[SAMPLES],out_img[SAMPLES];
+ arts_fft_float(SAMPLES,0,inbuffer,0,out_real,out_img);
+
+ _scope.clear();
+ unsigned int i = 3;
+ unsigned int j = 0;
+ for(;;) {
+ float xrange = 0.0;
+ while(j != i)
+ {
+ xrange += (fabs(out_img[j]) + fabs(out_real[j]))/(float)SAMPLES;
+ j++;
+ }
+ _scope.push_back(xrange);
+
+ if(i == SAMPLES/2) return;
+
+ i += i/2;
+ if(i > SAMPLES/2) i = SAMPLES/2;
+ }
+ }
+ void streamInit()
+ {
+ unsigned long i;
+ for(i=0;i<SAMPLES;i++)
+ {
+ float x = (float)i/(float)SAMPLES;
+ window[i] = sin(x*M_PI)*sin(x*M_PI);
+ inbuffer[i] = 0;
+ }
+ do_fft(); // initialize so that we never return an empty scope
+ }
+ void streamStart()
+ {
+ inbufferpos = 0;
+ }
+ vector<float> *scope()
+ {
+ return new vector<float>(_scope);
+ }
+ /*
+ in audio stream inleft, inright;
+ out audio stream outleft, outright;
+ */
+ void calculateBlock(unsigned long samples)
+ {
+ unsigned long i;
+ for(i=0;i<samples;i++)
+ {
+ inbuffer[inbufferpos] =
+ (inleft[i] + inright[i])*window[inbufferpos];
+ if(++inbufferpos == SAMPLES)
+ {
+ do_fft();
+ inbufferpos = 0;
+ }
+ /*
+ monitoring only tasks can't be done with that StereoEffect
+ interface nicely - copy input to output until there is
+ something better
+ */
+ outleft[i] = inleft[i];
+ outright[i] = inright[i];
+ }
+ }
+
+ /* prevent vtable overflows (see above) */
+ StereoFFTScope_impl() {
+ window = new float[SAMPLES];
+ inbuffer = new float[SAMPLES];
+ }
+ ~StereoFFTScope_impl() {
+ delete [] window;
+ delete [] inbuffer;
+ }
+};
+
+const unsigned long StereoFFTScope_impl::SAMPLES;
+
+REGISTER_IMPLEMENTATION(StereoFFTScope_impl);
+
+}
diff --git a/flow/stereovolumecontrol_impl.cc b/flow/stereovolumecontrol_impl.cc
new file mode 100644
index 0000000..ae90ae6
--- /dev/null
+++ b/flow/stereovolumecontrol_impl.cc
@@ -0,0 +1,197 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include <math.h>
+#include "artsflow.h"
+#include "stdsynthmodule.h"
+#include "flowsystem.h"
+#include <debug.h>
+
+#include <cstring>
+
+using namespace Arts;
+
+namespace Arts {
+
+class StereoVolumeControl_impl : virtual public StereoVolumeControl_skel,
+ virtual public StdSynthModule
+{
+ float _scaleFactor;
+ float _currentVolumeLeft;
+ float _currentVolumeRight;
+ bool _virtualized;
+ bool _calcVolume;
+public:
+ StereoVolumeControl_impl() :_scaleFactor(1.0), _currentVolumeLeft(0.0),
+ _currentVolumeRight(0.0), _virtualized( false ),
+ _calcVolume( false )
+ {
+ virtualize();
+ }
+
+ /*attribute float scaleFactor;*/
+ void scaleFactor(float newFactor) {
+ if(_scaleFactor != newFactor)
+ {
+ _scaleFactor = newFactor;
+ scaleFactor_changed(newFactor);
+ if( _scaleFactor == 1.0 )
+ {
+ if( !_calcVolume && !_virtualized )
+ virtualize();
+ }
+ else if( _virtualized )
+ devirtualize();
+ }
+ }
+ float scaleFactor() { return _scaleFactor; }
+
+ /*
+ readonly attribute float currentVolumeLeft;
+ readonly attribute float currentVolumeRight;
+ */
+ float currentVolumeLeft()
+ {
+ if( _virtualized && !_calcVolume )
+ needVolumeCalculation();
+
+ return _currentVolumeLeft;
+ }
+
+ float currentVolumeRight()
+ {
+ if( _virtualized && !_calcVolume )
+ needVolumeCalculation();
+
+ return _currentVolumeRight;
+ }
+
+ void needVolumeCalculation()
+ {
+ arts_debug( "calculate Volume in StereoVolumeControl" );
+ _calcVolume = true;
+ devirtualize();
+ }
+
+ void virtualize()
+ {
+ arts_debug( "virtualize StereoVolumeControl" );
+ _virtualized = true;
+ _node()->virtualize( "inleft", _node(), "outleft" );
+ _node()->virtualize( "inright", _node(), "outright" );
+ _currentVolumeRight = _currentVolumeLeft = 0.0;
+ }
+ void devirtualize()
+ {
+ arts_debug( "devirtualize StereoVolumeControl" );
+ _virtualized = false;
+ _node()->devirtualize( "inleft", _node(), "outleft" );
+ _node()->devirtualize( "inright", _node(), "outright" );
+ }
+ /*
+ in audio stream inleft, inright;
+ out audio stream outleft, outright;
+ */
+ void calculateBlock(unsigned long samples)
+ {
+ if( _scaleFactor == 1.0 )
+ {
+ if( _calcVolume )
+ {
+ /*
+ * make sure that we reach zero sometimes - otherwise there are
+ * performance issues with calculations close to zero
+ */
+ if(fabs(_currentVolumeLeft) < 0.001) _currentVolumeLeft = 0.0;
+ if(fabs(_currentVolumeRight) < 0.001) _currentVolumeRight = 0.0;
+
+ for( unsigned long i = 0; i < samples; i += 10 )
+ {
+ /* measure volume */
+ float delta;
+
+ // left
+ delta = fabs( outleft[ i ] ) - _currentVolumeLeft;
+ if( delta > 0.0 )
+ _currentVolumeLeft += 0.1 * delta;
+ else
+ _currentVolumeLeft += 0.003 * delta;
+
+ // right
+ delta = fabs( outright[ i ] ) - _currentVolumeRight;
+ if( delta > 0.0 )
+ _currentVolumeRight += 0.1 * delta;
+ else
+ _currentVolumeRight += 0.003 * delta;
+ }
+ memcpy( outleft, inleft, samples * sizeof( float ) );
+ memcpy( outright, inright, samples * sizeof( float ) );
+ }
+ return;
+ }
+
+ unsigned long i;
+
+ /*
+ * make sure that we reach zero sometimes - otherwise there are
+ * performance issues with calculations close to zero
+ */
+ if(fabs(_currentVolumeLeft) < 0.001) _currentVolumeLeft = 0.0;
+ if(fabs(_currentVolumeRight) < 0.001) _currentVolumeRight = 0.0;
+
+ for(i=0;i<samples;i++)
+ {
+ /* scale */
+ outleft[i] = inleft[i] * _scaleFactor;
+ outright[i] = inright[i] * _scaleFactor;
+
+ /* measure volume */
+ float delta;
+
+ // left
+ delta = fabs(outleft[i])-_currentVolumeLeft;
+ if(delta > 0.0)
+ _currentVolumeLeft += 0.01 * delta;
+ else
+ _currentVolumeLeft += 0.0003 * delta;
+
+ // right
+ delta = fabs(outright[i])-_currentVolumeRight;
+ if(delta > 0.0)
+ _currentVolumeRight += 0.01 * delta;
+ else
+ _currentVolumeRight += 0.0003 * delta;
+ }
+ }
+
+ AutoSuspendState autoSuspend() {
+ return (_currentVolumeLeft+_currentVolumeRight<0.001)?
+ asSuspend : asNoSuspend;
+ }
+
+};
+
+REGISTER_IMPLEMENTATION(StereoVolumeControl_impl);
+
+}
+
+// vim: sw=4 ts=4 noet
diff --git a/flow/synth_add_impl.cc b/flow/synth_add_impl.cc
new file mode 100644
index 0000000..1f52a21
--- /dev/null
+++ b/flow/synth_add_impl.cc
@@ -0,0 +1,44 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include "artsflow.h"
+#include "stdsynthmodule.h"
+
+using namespace Arts;
+
+namespace Arts {
+
+class Synth_ADD_impl :public Synth_ADD_skel, public StdSynthModule
+{
+public:
+ void calculateBlock(unsigned long samples)
+ {
+ unsigned long i;
+
+ for(i = 0;i < samples; i++)
+ outvalue[i] = invalue1[i] + invalue2[i];
+ }
+};
+
+REGISTER_IMPLEMENTATION(Synth_ADD_impl);
+
+}
diff --git a/flow/synth_frequency_impl.cc b/flow/synth_frequency_impl.cc
new file mode 100644
index 0000000..1c0bbbe
--- /dev/null
+++ b/flow/synth_frequency_impl.cc
@@ -0,0 +1,70 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include "artsflow.h"
+#include "stdsynthmodule.h"
+#include <math.h>
+#include <stdio.h>
+
+using namespace Arts;
+
+namespace Arts {
+
+class Synth_FREQUENCY_impl :public Synth_FREQUENCY_skel, public StdSynthModule
+{
+ float fpos;
+public:
+ void streamInit() {
+ fpos = 0;
+ }
+ void calculateBlock(unsigned long cycles) {
+ float fsample = samplingRateFloat;
+ float finc = *frequency/fsample;
+
+ while(cycles)
+ {
+ if(cycles >= 8 && ((finc*8+fpos) < 0.9))
+ {
+ fpos += finc; *pos++ = fpos;
+ fpos += finc; *pos++ = fpos;
+ fpos += finc; *pos++ = fpos;
+ fpos += finc; *pos++ = fpos;
+ fpos += finc; *pos++ = fpos;
+ fpos += finc; *pos++ = fpos;
+ fpos += finc; *pos++ = fpos;
+ fpos += finc; *pos++ = fpos;
+ cycles -= 8;
+ }
+ else
+ {
+ fpos += finc;
+ fpos -= floor(fpos);
+ *pos++ = fpos;
+ cycles--;
+ }
+ }
+ }
+};
+
+REGISTER_IMPLEMENTATION(Synth_FREQUENCY_impl);
+
+}
diff --git a/flow/synth_mul_impl.cc b/flow/synth_mul_impl.cc
new file mode 100644
index 0000000..11d97c8
--- /dev/null
+++ b/flow/synth_mul_impl.cc
@@ -0,0 +1,44 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include "artsflow.h"
+#include "stdsynthmodule.h"
+
+using namespace Arts;
+
+namespace Arts {
+
+class Synth_MUL_impl :public Synth_MUL_skel, public StdSynthModule
+{
+public:
+ void calculateBlock(unsigned long samples)
+ {
+ unsigned long i;
+
+ for(i = 0;i < samples; i++)
+ outvalue[i] = invalue1[i] * invalue2[i];
+ }
+};
+
+REGISTER_IMPLEMENTATION(Synth_MUL_impl);
+
+}
diff --git a/flow/synth_multi_add_impl.cc b/flow/synth_multi_add_impl.cc
new file mode 100644
index 0000000..2bd14dc
--- /dev/null
+++ b/flow/synth_multi_add_impl.cc
@@ -0,0 +1,64 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include "artsflow.h"
+#include "stdsynthmodule.h"
+
+using namespace Arts;
+
+namespace Arts {
+
+class Synth_MULTI_ADD_impl :public Synth_MULTI_ADD_skel, public StdSynthModule
+{
+public:
+ void calculateBlock(unsigned long cycles);
+ AutoSuspendState autoSuspend() { return asSuspend; }
+};
+
+REGISTER_IMPLEMENTATION(Synth_MULTI_ADD_impl);
+
+}
+
+void Synth_MULTI_ADD_impl::calculateBlock(unsigned long cycles)
+{
+ float *outend = outvalue + cycles;
+ float *outp, *inp;
+
+ if(!invalue[0])
+ {
+ // no invalue? zero out the outvalue
+ for(outp = outvalue; outp != outend; outp++) *outp = 0.0;
+ }
+ else
+ {
+ // copy first signal
+ for(outp = outvalue, inp = invalue[0]; outp != outend; outp++, inp++)
+ *outp = *inp;
+
+ // add the others
+ for(int sig=1;(inp = invalue[sig]) != 0;sig++)
+ {
+ for(outp = outvalue; outp != outend;outp++,inp++)
+ *outp += *inp;
+ }
+ }
+}
diff --git a/flow/synth_play_impl.cc b/flow/synth_play_impl.cc
new file mode 100644
index 0000000..c1be750
--- /dev/null
+++ b/flow/synth_play_impl.cc
@@ -0,0 +1,285 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include "artsflow.h"
+#include "debug.h"
+#include "convert.h"
+#include "objectmanager.h"
+#include "audiosubsys.h"
+#include "dispatcher.h"
+#include "iomanager.h"
+#include "flowsystem.h"
+#include "stdsynthmodule.h"
+#include <stdio.h>
+#include <iostream>
+
+using namespace std;
+using namespace Arts;
+
+namespace Arts {
+
+class Synth_PLAY_impl : virtual public Synth_PLAY_skel,
+ virtual public ASProducer,
+ virtual public StdSynthModule,
+ virtual public IONotify,
+ virtual public TimeNotify
+{
+protected:
+ AudioSubSystem *as;
+ bool haveSubSys;
+ /*
+ * these are to prevent the following situation
+ * 1) audio subsystem needs more data
+ * 2) calculation is started
+ * 3) somehow, some module makes a synchronous invocation to the outside
+ * world and waits for the result
+ * 4) since the audio subsystem still needs data, and since we are in an
+ * idle state now, another calculation will be started, which will of
+ * course fail due to reentrancy
+ * 5) repeat 4) until result is there => lots of wasted CPU cycles (when
+ * running with realtime priority: system freeze)
+ */
+ bool inProgress; // we are just doing some calculations
+ bool restartIOHandling; // I/O handlers removed upon reaching 4: restart
+
+ int audioReadFD;
+ int audioWriteFD;
+ bool audioOpen;
+
+ typedef unsigned char uchar;
+
+ unsigned char *outblock;
+ unsigned long maxsamples;
+ unsigned long channels;
+ int format;
+ int bits;
+
+ bool retryOpen;
+public:
+ /*
+ * functions from the SynthModule interface (which is inherited by
+ * SynthPlay)
+ */
+ void streamInit() {
+ as = AudioSubSystem::the();
+
+ maxsamples = 0;
+ outblock = 0;
+ retryOpen = false;
+ audioOpen = false;
+ inProgress = false;
+
+ haveSubSys = as->attachProducer(this);
+ if(!haveSubSys)
+ {
+ arts_info("Synth_PLAY: audio subsystem is already used");
+ return;
+ }
+
+ audioOpen = as->open();
+ if(!audioOpen)
+ {
+ if(Dispatcher::the()->flowSystem()->suspended())
+ {
+ arts_info("/dev/dsp currently unavailable (retrying)");
+ Dispatcher::the()->ioManager()->addTimer(1000, this);
+ retryOpen = true;
+ }
+ else
+ {
+ arts_info("Synth_PLAY: audio subsystem init failed");
+ arts_info("ASError = %s",as->error());
+ }
+ audioReadFD = audioWriteFD = -1;
+ }
+ else
+ {
+ audioReadFD = as->selectReadFD();
+ audioWriteFD = as->selectWriteFD();
+ }
+
+ channels = as->channels();
+ format = as->format();
+ bits = as->bits();
+ arts_debug("audio format is %d Hz, %d bits, %d channels",
+ as->samplingRate(), bits, channels);
+ }
+
+ void notifyTime() {
+ assert(retryOpen);
+
+ audioOpen = as->open();
+
+ if(audioOpen)
+ {
+ audioReadFD = as->selectReadFD();
+ audioWriteFD = as->selectWriteFD();
+
+ streamStart();
+ arts_info("/dev/dsp ok");
+ Dispatcher::the()->ioManager()->removeTimer(this);
+ retryOpen = false;
+ }
+ }
+
+ void streamStart() {
+ IOManager *iom = Dispatcher::the()->ioManager();
+
+ if(audioReadFD >= 0)
+ iom->watchFD(audioReadFD, IOType::read|IOType::except, this);
+
+ if(audioWriteFD >= 0)
+ iom->watchFD(audioWriteFD, IOType::write|IOType::except, this);
+ }
+
+ void streamEnd() {
+ if(retryOpen)
+ Dispatcher::the()->ioManager()->removeTimer(this);
+
+ arts_debug("Synth_PLAY: closing audio fd");
+ if(audioReadFD >= 0 || audioWriteFD >= 0)
+ {
+ IOManager *iom = Dispatcher::the()->ioManager();
+ iom->remove(this,IOType::all);
+ audioReadFD = audioWriteFD = -1;
+ }
+ AudioSubSystem::the()->detachProducer();
+
+ if(outblock)
+ {
+ delete[] outblock;
+ outblock = 0;
+ }
+ }
+
+ AutoSuspendState autoSuspend()
+ {
+ return static_cast<AutoSuspendState>(asSuspendStop|asConsumer);
+ }
+
+ void calculateBlock(unsigned long samples)
+ {
+ // no audio subsystem, no play
+ if(!as->running() || !haveSubSys) return;
+
+ if(samples > maxsamples)
+ {
+ maxsamples = samples;
+
+ if(outblock) delete[] outblock;
+ outblock = new uchar[maxsamples * channels * ( format & ( 8 | 16 | 32 ) ) / 8];
+ }
+
+ assert(channels);
+
+ arts_assert(format == 8 || format == 16 || format == 17 || format == 32 );
+ if(channels == 1)
+ {
+ if(format == 8)
+ convert_mono_float_8(samples,invalue_left,outblock);
+ else if(format == 16)
+ convert_mono_float_16le(samples,invalue_left,outblock);
+ else if(format == 17)
+ convert_mono_float_16be(samples,invalue_left,outblock);
+ else if(format == 32)
+ {
+ as->write( invalue_left, samples );
+ return;
+ }
+ }
+ else if(channels == 2)
+ {
+ if(format == 8)
+ convert_stereo_2float_i8(samples,invalue_left,invalue_right,
+ outblock);
+ else if(format == 16)
+ convert_stereo_2float_i16le(samples,invalue_left,invalue_right,
+ outblock);
+ else if(format == 17)
+ convert_stereo_2float_i16be(samples,invalue_left,invalue_right,
+ outblock);
+ else if(format == 32)
+ {
+ float * buffer = ( float* )outblock;
+ float * end = invalue_left + samples;
+ while( invalue_left < end )
+ {
+ *buffer++ = *invalue_left++;
+ *buffer++ = *invalue_right++;
+ }
+ as->write( outblock, 2 * samples * sizeof( float ) );
+ return;
+ }
+ }
+ else arts_warning("channels != 1 && channels != 2?");
+
+ as->write(outblock,channels * (bits / 8) * samples);
+ }
+
+ /**
+ * notifyIO from the IONotify interface (IOManager)
+ */
+ void notifyIO(int fd, int type)
+ {
+ arts_return_if_fail(as->running());
+ assert(fd == audioReadFD || fd == audioWriteFD);
+
+ if(inProgress)
+ {
+ if(!restartIOHandling)
+ {
+ // prevent lots of retries - we just can't do calculations
+ // now, so we need to wait until the situation has resolved
+ Dispatcher::the()->ioManager()->remove(this,IOType::all);
+ restartIOHandling = true;
+ }
+ return;
+ }
+
+ // convert iomanager notification types to audiosubsys notification
+ int asType = 0;
+
+ if(type & IOType::read) asType |= AudioSubSystem::ioRead;
+ if(type & IOType::write) asType |= AudioSubSystem::ioWrite;
+ assert(asType != 0);
+
+ restartIOHandling = false;
+ inProgress = true;
+ as->handleIO(asType);
+ inProgress = false;
+ if(restartIOHandling) streamStart();
+ }
+
+ /**
+ * needmore from the ASProducer interface (AudioSubSystem)
+ */
+ void needMore()
+ {
+ _node()->requireFlow();
+ }
+
+};
+
+REGISTER_IMPLEMENTATION(Synth_PLAY_impl);
+
+}
+// vim: sw=4 ts=4 noet
diff --git a/flow/synth_play_wav_impl.cc b/flow/synth_play_wav_impl.cc
new file mode 100644
index 0000000..d94703c
--- /dev/null
+++ b/flow/synth_play_wav_impl.cc
@@ -0,0 +1,579 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include "config.h"
+#ifdef HAVE_LIBAUDIOFILE
+#include "artsflow.h"
+#include "stdsynthmodule.h"
+#include "debug.h"
+#include "cachedwav.h"
+#include "convert.h"
+#include <stdio.h>
+#include <iostream>
+#include <climits>
+#include <cstdlib>
+#include <cstring>
+
+extern "C" {
+/* Some versions of libaudiofile seem to lack the extern "C" declaration,
+ * so you you may need that extra one.
+ *
+ * Other versions of libaudiofile seem to have two closing "}" in aupvlist.h,
+ * so if you can't compile, this, check that /usr/include/aupvlist.h contains
+ * something like that
+ *
+ * #ifdef __cplusplus
+ * }
+ * #endif
+ *
+ * only once not twice.
+ */
+#include "audiofile.h"
+}
+
+#include <sys/stat.h>
+#include <unistd.h>
+
+using namespace std;
+using namespace Arts;
+
+
+CachedWav *CachedWav::load(Cache *cache, string filename)
+{
+ CachedWav *wav;
+
+ wav = (CachedWav *)cache->get(string("CachedWav:")+filename);
+ if(!wav) {
+ wav = new CachedWav(cache,filename);
+
+ if(!wav->initOk) // loading failed
+ {
+ wav->decRef();
+ return 0;
+ }
+ }
+
+ return(wav);
+}
+
+bool CachedWav::isValid()
+{
+ if(!initOk)
+ return false;
+
+ struct stat newstat;
+
+ lstat(filename.c_str(),&newstat);
+ return(newstat.st_mtime == oldstat.st_mtime);
+}
+
+int CachedWav::memoryUsage()
+{
+ return(bufferSize);
+}
+
+CachedWav::CachedWav(Cache *cache, string filename) : CachedObject(cache),
+ filename(filename),initOk(false), buffer(0)
+{
+ int sampleFormat;
+ AFframecount frameCount;
+ AFfilehandle file;
+
+ setKey(string("CachedWav:")+filename);
+
+ if(lstat(filename.c_str(),&oldstat) == -1)
+ {
+ arts_info("CachedWav: Can't stat file '%s'", filename.c_str());
+ return;
+ }
+
+ file = afOpenFile(filename.c_str(), "r", NULL);
+ if(!file)
+ {
+ arts_info("CachedWav: Can't read file '%s'", filename.c_str());
+ return;
+ }
+
+ frameCount = afGetFrameCount(file, AF_DEFAULT_TRACK);
+ if(frameCount <= 0 || frameCount >= INT_MAX)
+ {
+ arts_info("CachedWav: Invalid length for '%s'", filename.c_str());
+ afCloseFile(file);
+ return;
+ }
+
+ channelCount = afGetChannels(file, AF_DEFAULT_TRACK);
+ afGetSampleFormat(file, AF_DEFAULT_TRACK, &sampleFormat, &sampleWidth);
+
+ // we want everything converted to little endian unconditionally
+ afSetVirtualByteOrder(file,AF_DEFAULT_TRACK, AF_BYTEORDER_LITTLEENDIAN);
+
+ arts_debug("loaded wav %s",filename.c_str());
+ arts_debug(" sample format: %d, sample width: %d",
+ sampleFormat,sampleWidth);
+ arts_debug(" channelCount: %d",channelCount);
+ arts_debug(" frameCount: %d",frameCount);
+
+ // different handling required for other sample widths
+ assert(sampleWidth == 16 || sampleWidth == 8);
+
+ long frameSize = (sampleWidth/8)*channelCount;
+ samplingRate = afGetRate(file, AF_DEFAULT_TRACK);
+
+ /*
+ * if we don't know the track bytes, we'll have to figure out ourselves
+ * how many frames are stored here - it would be nicer if libaudiofile
+ * let us know somehow whether the value returned for getFrameCount
+ * means "don't know" or is really the correct length
+ */
+ int trackBytes = afGetTrackBytes(file, AF_DEFAULT_TRACK);
+ if(trackBytes == -1)
+ {
+ arts_debug("unknown length");
+ long fcount = 0, f = 0;
+
+ list<void *> blocks;
+ do
+ {
+ void *block = malloc(1024 * frameSize);
+
+ f = afReadFrames(file, AF_DEFAULT_TRACK,block,1024);
+ if(f > 0)
+ {
+ fcount += f;
+ blocks.push_back(block);
+ }
+ else
+ {
+ free(block);
+ }
+ } while(f > 0);
+
+ frameCount = fcount;
+ arts_debug("figured out frameCount = %ld", fcount);
+
+ bufferSize = frameCount * frameSize;
+ buffer = new uchar[bufferSize];
+ assert(buffer);
+
+ // reassemble and free the blocks
+ while(!blocks.empty())
+ {
+ void *block = blocks.front();
+ blocks.pop_front();
+
+ f = (fcount>1024)?1024:fcount;
+ memcpy(&buffer[(frameCount-fcount)*frameSize],block,f*frameSize);
+ fcount -= f;
+ }
+ assert(fcount == 0);
+ }
+ else
+ {
+ bufferSize = frameCount * frameSize;
+ buffer = new uchar[bufferSize];
+ assert(buffer);
+
+ afReadFrames(file, AF_DEFAULT_TRACK,buffer,frameCount);
+ }
+
+ afCloseFile(file);
+ initOk = true;
+}
+
+CachedWav::~CachedWav()
+{
+ if(buffer)
+ delete[] buffer;
+}
+
+namespace Arts {
+
+class Synth_PLAY_WAV_impl : public Synth_PLAY_WAV_skel, public StdSynthModule {
+protected:
+ double flpos;
+
+ float _speed;
+ string _filename;
+ bool _finished;
+ CachedWav *cachedwav;
+
+ void unload()
+ {
+ if(cachedwav)
+ {
+ cachedwav->decRef();
+ cachedwav = 0;
+ }
+ }
+
+ void load()
+ {
+ // unload the old file if necessary
+ unload();
+
+ // load the new (which will reset the position)
+ cachedwav = CachedWav::load(Cache::the(), _filename);
+ flpos = 0.0;
+ }
+
+public:
+ float speed() { return _speed; }
+ void speed(float newSpeed) { _speed = newSpeed; }
+
+ string filename() { return _filename; }
+ void filename(const string& filename) { _filename = filename; load(); }
+
+ void finished(bool f)
+ {
+ if(_finished != f)
+ {
+ _finished = f;
+ finished_changed(f);
+ }
+ }
+ bool finished() { return _finished; }
+
+ Synth_PLAY_WAV_impl();
+ ~Synth_PLAY_WAV_impl();
+
+ void streamInit();
+ void calculateBlock(unsigned long samples);
+};
+
+REGISTER_IMPLEMENTATION(Synth_PLAY_WAV_impl);
+
+}
+
+Synth_PLAY_WAV_impl::Synth_PLAY_WAV_impl()
+{
+ cachedwav = 0;
+ _speed = 1.0;
+ _filename = "";
+ _finished = false;
+}
+
+Synth_PLAY_WAV_impl::~Synth_PLAY_WAV_impl()
+{
+ unload();
+}
+
+void Synth_PLAY_WAV_impl::streamInit()
+{
+ finished(false);
+}
+
+void Synth_PLAY_WAV_impl::calculateBlock(unsigned long samples)
+{
+ unsigned long haveSamples = 0;
+
+ if(cachedwav)
+ {
+ double speed = cachedwav->samplingRate / samplingRateFloat * _speed;
+
+ haveSamples = uni_convert_stereo_2float(samples, cachedwav->buffer,
+ cachedwav->bufferSize,cachedwav->channelCount,cachedwav->sampleWidth,
+ left,right,speed,flpos);
+
+ flpos += (double)haveSamples * speed;
+ }
+
+ if(haveSamples != samples)
+ {
+ unsigned long i;
+
+ for(i=haveSamples;i<samples;i++)
+ left[i] = right[i] = 0.0;
+
+ finished(true);
+ }
+
+/*
+ float speed = 0.0;
+ unsigned long haveSamples = 0;
+
+ if(cachedwav)
+ {
+ float allSamples = cachedwav->bufferSize*8 /
+ cachedwav->sampleWidth/cachedwav->channelCount;
+ float fHaveSamples = allSamples - flpos;
+
+ speed = cachedwav->samplingRate / (float)samplingRate * _speed;
+
+ fHaveSamples /= speed;
+ fHaveSamples -= 2.0; // one due to interpolation and another against
+ // rounding errors
+ if(fHaveSamples > 0)
+ {
+ haveSamples = (int)fHaveSamples;
+ if(haveSamples > samples) haveSamples = samples;
+ }
+ }
+
+ if(haveSamples) // something left to play?
+ {
+ if(cachedwav->channelCount == 1)
+ {
+ if(cachedwav->sampleWidth == 16) {
+ interpolate_mono_16le_float(haveSamples,
+ flpos,speed,cachedwav->buffer,left);
+ }
+ else {
+ interpolate_mono_8_float(haveSamples,
+ flpos,speed,cachedwav->buffer,left);
+ }
+ memcpy(right,left,sizeof(float)*haveSamples);
+ }
+ else if(cachedwav->channelCount == 2)
+ {
+ if(cachedwav->sampleWidth == 16) {
+ interpolate_stereo_i16le_2float(haveSamples,
+ flpos,speed,cachedwav->buffer,left,right);
+ }
+ else {
+ interpolate_stereo_i8_2float(haveSamples,
+ flpos,speed,cachedwav->buffer,left,right);
+ }
+ } else {
+ assert(false);
+ }
+
+ flpos += (float)haveSamples * speed;
+ }
+
+ if(haveSamples != samples)
+ {
+ unsigned long i;
+
+ for(i=haveSamples;i<samples;i++)
+ left[i] = right[i] = 0.0;
+
+ _finished = true;
+ }
+*/
+}
+
+
+#if 0
+class Synth_PLAY_WAV :public SynthModule {
+protected:
+ CachedWav *cachedwav;
+
+ unsigned char *buffer;
+ int channelCount;
+ unsigned long bufferSize, position, bytesPerSample;
+
+ // inputs:
+ enum { PROP_FILENAME };
+
+ // outputs:
+ enum { LEFT, RIGHT, DONE };
+
+public:
+ void Initialize();
+ void DeInitialize();
+ void Calculate() { assert(false); }
+ void CalculateBlock(unsigned long samples);
+ string getParams() { return("_filename;left,right,done"); }
+ static void *Creator() { return new Synth_PLAY_WAV; }
+};
+
+ModuleClient MC_Synth_PLAY_WAV(SynthModule::get_MS,"Synth_PLAY_WAV",Synth_PLAY_WAV::Creator);
+
+void Synth_PLAY_WAV::CalculateBlock(unsigned long samples)
+{
+ unsigned long haveSamples = samples;
+ unsigned long remainingSamples;
+
+ remainingSamples = (bufferSize-position)/bytesPerSample;
+ if(haveSamples > remainingSamples) haveSamples = remainingSamples;
+
+ float *left = out[LEFT], *right = out[RIGHT], *done = out[DONE];
+ unsigned long i;
+
+ if(haveSamples)
+ {
+ if(channelCount == 1)
+ {
+ if(bytesPerSample == 2) {
+ convert_mono_16le_float(haveSamples,&buffer[position],left);
+ }
+ else {
+ convert_mono_8_float(haveSamples,&buffer[position],left);
+ }
+ memcpy(right,left,sizeof(float)*haveSamples);
+ }
+ else if(channelCount == 2)
+ {
+ if(bytesPerSample == 2) {
+ convert_stereo_i16le_2float(haveSamples,&buffer[position],
+ left,right);
+ }
+ else {
+ convert_stereo_i8_2float(haveSamples,&buffer[position],
+ left,right);
+ }
+ } else {
+ assert(false);
+ }
+
+ for(i=0;i<haveSamples;i++) done[i] = 0.0;
+
+ position += bytesPerSample*channelCount*haveSamples;
+ }
+
+ for(i=haveSamples;i<samples;i++)
+ {
+ left[i] = right[i] = 0.0; done[i] = 1.0; // ready, kill me ;)
+ }
+}
+
+void Synth_PLAY_WAV::DeInitialize()
+{
+ cachedwav->decRef();
+}
+
+void Synth_PLAY_WAV::Initialize()
+{
+ cachedwav = CachedWav::load(Synthesizer->getCache(),
+ getStringProperty(PROP_FILENAME));
+
+ // may take some speed to access cachedwav every time
+ bufferSize = cachedwav->bufferSize;
+ channelCount = cachedwav->channelCount;
+ buffer = cachedwav->buffer;
+ bytesPerSample = cachedwav->sampleWidth/8;
+
+ haveCalculateBlock = true;
+ position = 0;
+}
+
+class Synth_PLAY_PITCHED_WAV :public SynthModule {
+protected:
+ CachedWav *cachedwav;
+ float flpos;
+
+ // inputs:
+ enum { FREQUENCY,RECFREQUENCY, PROP_FILENAME };
+
+ // outputs:
+ enum { LEFT, RIGHT, DONE };
+
+public:
+ void Initialize();
+ void DeInitialize();
+ void Calculate() { assert(false); }
+ void CalculateBlock(unsigned long samples);
+ string getParams() { return("frequency,recfrequency,_filename;left,right,done"); }
+ static void *Creator() { return new Synth_PLAY_PITCHED_WAV; }
+};
+
+ModuleClient MC_Synth_PLAY_PITCHED_WAV(SynthModule::get_MS,"Synth_PLAY_PITCHED_WAV",Synth_PLAY_PITCHED_WAV::Creator);
+
+void Synth_PLAY_PITCHED_WAV::CalculateBlock(unsigned long samples)
+{
+ float frequency = in[FREQUENCY][0], recfrequency = in[RECFREQUENCY][0];
+ float allSamples = cachedwav->bufferSize*8 /
+ cachedwav->sampleWidth/cachedwav->channelCount;
+ float fHaveSamples = allSamples - flpos;
+ float speed = cachedwav->samplingRate / (float)samplingRate *
+ frequency / recfrequency;
+
+ fHaveSamples /= speed;
+ fHaveSamples -= 2.0; // one due to interpolation and another against
+ // rounding errors
+
+ unsigned long haveSamples;
+
+ if(fHaveSamples < 0)
+ {
+ haveSamples = 0;
+ }
+ else
+ {
+ haveSamples = fHaveSamples;
+ if(haveSamples > samples) haveSamples = samples;
+ }
+
+ float *left = out[LEFT], *right = out[RIGHT], *done = out[DONE];
+ unsigned long i;
+
+ if(haveSamples)
+ {
+ if(cachedwav->channelCount == 1)
+ {
+ if(cachedwav->sampleWidth == 16) {
+ interpolate_mono_16le_float(haveSamples,
+ flpos,speed,cachedwav->buffer,left);
+ }
+ else {
+ interpolate_mono_8_float(haveSamples,
+ flpos,speed,cachedwav->buffer,left);
+ }
+ memcpy(right,left,sizeof(float)*haveSamples);
+ }
+ else if(cachedwav->channelCount == 2)
+ {
+ if(cachedwav->sampleWidth == 16) {
+ interpolate_stereo_i16le_2float(haveSamples,
+ flpos,speed,cachedwav->buffer,left,right);
+ }
+ else {
+ interpolate_stereo_i8_2float(haveSamples,
+ flpos,speed,cachedwav->buffer,left,right);
+ }
+ } else {
+ assert(false);
+ }
+
+ for(i=0;i<haveSamples;i++) done[i] = 0.0;
+
+ flpos += (float)haveSamples * speed;
+ }
+
+ for(i=haveSamples;i<samples;i++)
+ {
+ left[i] = right[i] = 0.0; done[i] = 1.0; // ready, kill me ;)
+ }
+}
+
+void Synth_PLAY_PITCHED_WAV::DeInitialize()
+{
+ cachedwav->decRef();
+}
+
+void Synth_PLAY_PITCHED_WAV::Initialize()
+{
+ cachedwav = CachedWav::load(Synthesizer->getCache(),
+ getStringProperty(PROP_FILENAME));
+
+ haveCalculateBlock = true;
+ flpos = 0.0;
+}
+#endif
+
+#else
+#ifdef __GNUC__
+#warning "No libaudiofile available, that means, you won't be able to play wavs"
+#endif
+#endif
+
diff --git a/flow/synth_record_impl.cc b/flow/synth_record_impl.cc
new file mode 100644
index 0000000..a159bee
--- /dev/null
+++ b/flow/synth_record_impl.cc
@@ -0,0 +1,184 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include "artsflow.h"
+#include "debug.h"
+#include "convert.h"
+#include "objectmanager.h"
+#include "audiosubsys.h"
+#include "dispatcher.h"
+#include "iomanager.h"
+#include "flowsystem.h"
+#include "stdsynthmodule.h"
+#include <stdio.h>
+#include <iostream>
+#include <cstring>
+
+#undef DEBUG_WAVEFORM
+#ifdef DEBUG_WAVEFORM
+#include <fstream>
+#endif
+
+using namespace std;
+using namespace Arts;
+
+namespace Arts {
+
+class Synth_RECORD_impl : virtual public Synth_RECORD_skel,
+ virtual public ASConsumer,
+ virtual public StdSynthModule
+{
+#ifdef DEBUG_WAVEFORM
+ ofstream plotfile;
+#endif
+protected:
+ AudioSubSystem *as;
+ bool haveSubSys;
+
+ typedef unsigned char uchar;
+
+ unsigned char *inblock;
+ unsigned long maxsamples;
+ unsigned long channels;
+ int format;
+ int bits;
+
+public:
+#ifdef DEBUG_WAVEFORM
+ Synth_RECORD_impl()
+ : plotfile( "/dev/shm/synth_record.plot" )
+ {
+ }
+#endif
+ /*
+ * functions from the SynthModule interface (which is inherited by
+ * SynthPlay)
+ */
+ void streamInit() {
+ as = AudioSubSystem::the();
+
+ channels = as->channels();
+ format = as->format();
+ bits = as->bits();
+ maxsamples = 0;
+ inblock = 0;
+
+ haveSubSys = as->attachConsumer(this);
+ if(!haveSubSys)
+ {
+ arts_info("Synth_RECORD: audio subsystem is already used");
+ return;
+ }
+ }
+
+ void streamEnd() {
+ arts_debug("Synth_RECORD: detaching");
+ if(haveSubSys) as->detachConsumer();
+
+ if(inblock)
+ {
+ delete[] inblock;
+ inblock = 0;
+ }
+ }
+
+ AutoSuspendState autoSuspend()
+ {
+ return static_cast<AutoSuspendState>(asSuspend|asProducer);
+ }
+
+ void calculateBlock(unsigned long samples)
+ {
+ // no audio subsystem, no play
+ if(!as->running() || !haveSubSys) return;
+
+ if(samples > maxsamples)
+ {
+ maxsamples = samples;
+
+ if(inblock) delete[] inblock;
+ inblock = new uchar[maxsamples * channels * bits / 8];
+ }
+
+ assert(channels);
+
+ as->read(inblock,channels * (bits/8) * samples);
+
+ arts_assert(format == 8 || format == 16 || format == 17 || format == 32);
+ if(format == 8)
+ {
+ if(channels == 1)
+ convert_mono_8_float(samples,inblock,left);
+
+ if(channels == 2)
+ convert_stereo_i8_2float(samples,inblock,left,right);
+ }
+ else if(format == 16)
+ {
+ if(channels == 1)
+ convert_mono_16le_float(samples,inblock,left);
+
+ if(channels == 2)
+ convert_stereo_i16le_2float(samples,inblock,left,right);
+ }
+ else if(format == 17)
+ {
+ if(channels == 1)
+ convert_mono_16be_float(samples,inblock,left);
+
+ if(channels == 2)
+ convert_stereo_i16be_2float(samples,inblock,left,right);
+ }
+ else if(format == 32)
+ {
+ if(channels == 2)
+ {
+ float * end = (float *)(inblock + 8 * samples);
+ float * floatbuffer = (float *)inblock;
+ while(floatbuffer < end)
+ {
+#ifdef DEBUG_WAVEFORM
+ plotfile << *floatbuffer << "\n";
+#endif
+ *left++ = *floatbuffer++;
+ *right++ = *floatbuffer++;
+ }
+ }
+ else if(channels == 1)
+ memcpy(left, inblock, samples);
+ }
+ }
+
+ /**
+ * havemore from the ASConsumer interface (AudioSubSystem)
+ */
+ void haveMore()
+ {
+ _node()->requireFlow();
+ }
+};
+
+REGISTER_IMPLEMENTATION(Synth_RECORD_impl);
+
+}
+
+// vim: sw=4 ts=4
diff --git a/flow/synth_wave_sin_impl.cc b/flow/synth_wave_sin_impl.cc
new file mode 100644
index 0000000..62e2f03
--- /dev/null
+++ b/flow/synth_wave_sin_impl.cc
@@ -0,0 +1,44 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include "artsflow.h"
+#include "stdsynthmodule.h"
+#include <math.h>
+
+using namespace Arts;
+
+namespace Arts {
+
+class Synth_WAVE_SIN_impl : virtual public Synth_WAVE_SIN_skel,
+ virtual public StdSynthModule
+{
+public:
+ void calculateBlock(unsigned long cycles)
+ {
+ for(unsigned long i=0; i<cycles; i++)
+ outvalue[i] = sin(pos[i]*2*M_PI);
+ }
+};
+
+REGISTER_IMPLEMENTATION(Synth_WAVE_SIN_impl);
+
+}
diff --git a/flow/synthschedule.h b/flow/synthschedule.h
new file mode 100644
index 0000000..f44667a
--- /dev/null
+++ b/flow/synthschedule.h
@@ -0,0 +1,36 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#ifndef SYNTHSCHEDULE_H
+#define SYNTHSCHEDULE_H
+
+#include "config.h"
+
+#ifdef __GNUC__
+#warning " * <synthschedule.h> included! *"
+#warning " * include <gslschedule.h> instead *"
+#endif
+
+#include "gslschedule.h"
+
+#endif // SYNTHSCHEDULE_H
+
diff --git a/flow/virtualports.cc b/flow/virtualports.cc
new file mode 100644
index 0000000..76b5087
--- /dev/null
+++ b/flow/virtualports.cc
@@ -0,0 +1,491 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+#include "virtualports.h"
+#include <algorithm>
+#include <stdio.h>
+
+using namespace Arts;
+using namespace std;
+
+#undef VPORT_DEBUG
+
+/* virtual port connections */
+
+/*
+
+Port virtualization is used in the following case: suppose you have a module
+M which has an input port and an output port like that:
+
+input
+ V
+-----
+ M
+-----
+ V
+output
+
+But suppose the module M is implement as combination of other modules, for
+instance the effect of M is achieved by passing the signal first through an
+A and then through an B module. Clients connecting M should "really" connect
+A,B. For this virtualization is used.
+
+There are two kinds:
+
+- masquerading: which means (like in our case), the input of a module is really
+ implemented with the input of another module. So M's input could be really
+ implemented by A's input
+
+ there is also output masquerading, which would be for instance that M's
+ output is really implemented by B's output
+
+- forwarding: if M in our example would choose to do nothing at all, it could
+ simply forward its input to its output
+
+
+The interface for the user:
+
+MCOP will show the virtualize function to the user, which the user can use
+to delegate the services of a port to another module onto another port.
+
+- masquerading: in our case, for instance the user could call
+
+ m._node()->virtualize("inputport",a._node(),"inputport");
+
+ which would forward all input m gets on "inputport" to a's "inputport"
+
+- forwarding: in the same way, the user could call
+
+ m._node()->virtualize("inputport",m._node(),"outputport");
+
+ which would make m forward its input directly to its output
+
+The implementation:
+
+Virtualization is implemented here, inside the flow system, using a fairly
+complex forwarding strategy, which will have a graph which contains
+
+- "user-made" connections (made with connect())
+- "virtualize-made" connections, which can be either forwarding
+ (input to output port) or masquerading (input to input or output to output)
+
+Out of all these, the algorithm builds "real" connections, which are
+then really performed inside the flow system. If you change the "user-made"
+or "virtualize-made" connections, the "real" connections are recalculated.
+
+The "real" connections are created by the expandHelper function. They are
+called vcTransport here.
+
+The strategy expandHelper uses is to go back to a port which is only output
+port (non forwarded, non masqueraded), and then follow the graph recursively
+over vcMasquerade and vcForward edges until it reaches a port which is only
+input. Then it creates a real connection.
+
+Some tweaks are there which allow that not on any change at the graph, all
+real connections will be removed, but only these that could possibly be
+affected by this change, and then not all real connections are created new,
+but only those that could possibly be created by this virtual connection.
+
+Every VPort contains a pointer to the "real" port, to let the flow system
+know where the "real" connections where real data will flow must be made.
+
+*/
+
+VPortConnection::VPortConnection(VPort *source, VPort *dest, Style style)
+ :source(source),dest(dest),style(style)
+{
+ if(style != vcTransport)
+ {
+ list<VPortConnection *>::iterator i;
+
+ // remove transport connections ending at "source" (they will
+ // probably be forwarded/masqueraded elsewhere by this VPortConnection)
+ i = source->incoming.begin();
+ while(i != source->incoming.end())
+ {
+ if((*i)->style == vcTransport)
+ {
+ delete *i;
+ i = source->incoming.begin();
+ }
+ else i++;
+ }
+
+ // remove transport connections starting at "dest" (they will
+ // probably be forwarded/masqueraded elsewhere by this VPortConnection)
+ i = dest->outgoing.begin();
+ while(i != dest->outgoing.end())
+ {
+ if((*i)->style == vcTransport)
+ {
+ delete *i;
+ i = dest->outgoing.begin();
+ }
+ else i++;
+ }
+ }
+
+ // add to the connection lists
+ source->outgoing.push_back(this);
+ dest->incoming.push_back(this);
+
+ if(style == vcTransport)
+ {
+#ifdef VPORT_DEBUG
+ arts_debug("emit a connection consumer = %s, producer = %s",
+ dest->name(), source->name());
+#endif
+ dest->port->connect(source->port);
+ }
+ else
+ {
+ source->makeTransport(this);
+ }
+}
+
+VPortConnection::~VPortConnection()
+{
+#ifdef VPORT_DEBUG
+ cout << "~VPortConnection" << endl;
+#endif
+
+ if(style != vcTransport)
+ {
+ // remove transport connection which go through this connection
+ source->removeTransport(this);
+ }
+
+ // remove this connection from the lists
+ list<VPortConnection *>::iterator ci;
+
+ ci = find(source->outgoing.begin(),source->outgoing.end(),this);
+ assert(ci != source->outgoing.end());
+ source->outgoing.erase(ci);
+
+ ci = find(dest->incoming.begin(),dest->incoming.end(),this);
+ assert(ci != dest->incoming.end());
+ dest->incoming.erase(ci);
+
+ if(style == vcTransport)
+ {
+#ifdef VPORT_DEBUG
+ arts_debug("delete connection %s -> %s",dest->name(), source->name());
+#endif
+ dest->port->disconnect(source->port);
+ }
+
+ // reestablish all connections which started/ended here before
+ if(style != vcTransport)
+ {
+ list<VPortConnection *>::iterator i;
+ stack<VPortConnection *> todo;
+
+ // reestablish transport connections which were ending at source...
+ for(i = source->incoming.begin(); i != source->incoming.end(); i++)
+ if((*i)->style != vcTransport) todo.push(*i);
+
+ // ... and starting at dest
+ for(i = dest->outgoing.begin(); i != dest->outgoing.end(); i++)
+ if((*i)->style != vcTransport) todo.push(*i);
+
+ // we need to do this with the stack as makeTransport can affect the
+ // incoming/outgoing lists by adding new vcTransport connections
+ while(!todo.empty())
+ {
+ todo.top()->source->makeTransport(todo.top());
+ todo.pop();
+ }
+ }
+
+#ifdef VPORT_DEBUG
+ cout << "~VPortConnection done" << endl;
+#endif
+}
+
+/*---------------------- virtual port implementation ----------------------*/
+
+VPort::VPort(Port *port) :port(port)
+{
+#ifdef VPORT_DEBUG
+ cout << "VPort: " << name() << endl;
+#endif
+}
+
+VPort::~VPort()
+{
+#ifdef VPORT_DEBUG
+ cout << "~VPort: " << name() << endl;
+#endif
+ while(!incoming.empty()) delete *incoming.begin();
+ while(!outgoing.empty()) delete *outgoing.begin();
+#ifdef VPORT_DEBUG
+ cout << "~VPort done" << endl;
+#endif
+}
+
+bool VPort::makeVirtualizeParams(VPort *forward, VPort*& source, VPort*& dest,
+ VPortConnection::Style& style)
+{
+ source = dest = 0;
+ // masquerading
+ if((port->flags() & streamIn) && (forward->port->flags() & streamIn))
+ {
+ // input: data flow direction is from us to the "forward" port
+ // XXX?
+ source = this;
+ dest = forward;
+ style = VPortConnection::vcMasquerade;
+ }
+ else if((port->flags() & streamOut) && (forward->port->flags() & streamOut))
+ {
+ // output: data flow direction is from the "forward" port to us
+ // XXX?
+ source = forward;
+ dest = this;
+ style = VPortConnection::vcMasquerade;
+ }
+ // forwarding
+ else if((port->flags() & streamIn) && (forward->port->flags() & streamOut))
+ {
+ source = this;
+ dest = forward;
+ style = VPortConnection::vcForward;
+ }
+ else if((port->flags() & streamOut) && (forward->port->flags() & streamIn))
+ {
+ source = forward;
+ dest = this;
+ style = VPortConnection::vcForward;
+ }
+ return source != 0;
+}
+
+/**
+ * a->virtualize(b) means, that the functionality that port a should provide
+ * (e.g. produce or consume data) is really provided by port b
+ */
+void VPort::virtualize(VPort *forward)
+{
+ VPort *source, *dest;
+ VPortConnection::Style style;
+
+ if(makeVirtualizeParams(forward,source,dest,style))
+ {
+#ifdef VPORT_DEBUG
+ cout << "virtualize ... source (producer) is " << source->name() <<
+ " dest (consumer) is " << dest->name() << endl;
+#endif
+ new VPortConnection(source,dest,style);
+ }
+}
+
+void VPort::devirtualize(VPort *forward)
+{
+ VPort *source, *dest;
+ VPortConnection::Style style;
+
+ // XXX?
+ if(makeVirtualizeParams(forward,source,dest,style))
+ {
+ list<VPortConnection *>::iterator i;
+ for(i = source->outgoing.begin(); i != source->outgoing.end(); i++)
+ {
+ if((*i)->source == source && (*i)->dest == dest
+ && (*i)->style == style)
+ {
+ delete (*i);
+ return;
+ }
+ }
+ }
+}
+
+void VPort::setFloatValue(float value)
+{
+ if(outgoing.empty())
+ {
+ AudioPort *aport = port->audioPort();
+ assert(aport);
+ aport->setFloatValue(value);
+ }
+ else
+ {
+ list<VPortConnection *>::iterator i;
+ for(i=outgoing.begin();i != outgoing.end(); i++)
+ {
+ VPortConnection *conn = *i;
+ assert(conn->style == VPortConnection::vcMasquerade);
+
+ conn->dest->setFloatValue(value);
+ }
+ }
+}
+
+void VPort::connect(VPort *dest)
+{
+ VPortConnection *conn;
+ if(port->flags() & streamOut)
+ {
+ conn = new VPortConnection(this,dest,VPortConnection::vcConnect);
+ }
+ else
+ {
+ conn = new VPortConnection(dest,this,VPortConnection::vcConnect);
+ }
+}
+
+void VPort::disconnect(VPort *dest)
+{
+ if(port->flags() & streamOut)
+ {
+ list<VPortConnection *>::iterator ci = outgoing.begin();
+ while(ci != outgoing.end())
+ {
+ assert((*ci)->source == this);
+ if((*ci)->dest == dest && (*ci)->style==VPortConnection::vcConnect)
+ {
+ delete (*ci); // will remove itself from the outgoing list
+ return;
+ }
+ ci++;
+ }
+ }
+ else
+ {
+ if(dest->port->flags() & streamOut)
+ {
+ dest->disconnect(this);
+ return;
+ }
+ }
+}
+
+void VPort::expandHelper(VPortConnection *conn, int state, VPort *current,
+ VPort *source, VPort *dest, bool remove)
+{
+ list<VPortConnection *>::iterator ci;
+
+#ifdef VPORT_DEBUG
+ cout << "expandhelper state " << state << " name " << current->name() << endl;
+#endif
+
+ if(state == 1) /* state 1: scan backward for output ports */
+ {
+ if(current->incoming.empty())
+ {
+ if(current->port->flags() & streamOut)
+ expandHelper(conn,2,current,current,dest,remove);
+ }
+ for(ci = current->incoming.begin(); ci != current->incoming.end();ci++)
+ {
+ assert((*ci)->style != VPortConnection::vcTransport);
+ expandHelper(conn,1,(*ci)->source,source,dest,remove);
+ }
+ }
+ else if(state == 2) /* state 2: output port expansion */
+ {
+ assert(current->port->flags() & streamOut);
+
+ for(ci = current->outgoing.begin(); ci != current->outgoing.end();ci++)
+ {
+ /* xconn=0 ensures that only paths are counted which contain conn */
+ VPortConnection *xconn = conn;
+ if(*ci == conn) xconn = 0;
+
+ if((*ci)->style == VPortConnection::vcMasquerade)
+ {
+ expandHelper(xconn,2,(*ci)->dest,source,dest,remove);
+ }
+ else if((*ci)->style == VPortConnection::vcConnect)
+ {
+ expandHelper(xconn,3,(*ci)->dest,source,(*ci)->dest,remove);
+ }
+ }
+ }
+ else if(state == 3) /* state 3: input port expansion */
+ {
+ assert(current->port->flags() & streamIn);
+
+ for(ci = current->outgoing.begin(); ci != current->outgoing.end();ci++)
+ {
+ /* xconn=0 ensures that only paths are counted which contain conn */
+ VPortConnection *xconn = conn;
+ if(*ci == conn) xconn = 0;
+
+ if((*ci)->style == VPortConnection::vcMasquerade)
+ {
+ // XXX ?
+ expandHelper(xconn,3,(*ci)->dest,source,(*ci)->dest,remove);
+ }
+ else if((*ci)->style == VPortConnection::vcForward)
+ {
+ expandHelper(xconn,2,(*ci)->dest,source,dest,remove);
+ }
+ }
+
+ if(current->outgoing.empty() && conn == 0)
+ {
+ if(remove)
+ {
+ // delete exactly one transport connection
+
+ bool removeOk = false;
+ ci = current->incoming.begin();
+ while(ci != current->incoming.end() && !removeOk)
+ {
+ if((*ci)->source == source && (*ci)->dest == dest
+ && (*ci)->style == VPortConnection::vcTransport)
+ {
+ delete (*ci);
+ removeOk = true;
+ }
+ else ci++;
+ }
+ assert(removeOk);
+ }
+ else
+ {
+ new VPortConnection(source,dest,VPortConnection::vcTransport);
+ }
+ }
+ }
+}
+
+void VPort::makeTransport(VPortConnection *conn)
+{
+ expandHelper(conn,1,this,0,0,false);
+}
+
+void VPort::removeTransport(VPortConnection *conn)
+{
+ expandHelper(conn,1,this,0,0,true);
+}
+
+const char *VPort::name()
+{
+ if(_name.empty())
+ {
+ _name = port->parent->object()->_interfaceName() + "." +
+ port->name();
+ }
+ return _name.c_str();
+}
diff --git a/flow/virtualports.h b/flow/virtualports.h
new file mode 100644
index 0000000..5e70fbf
--- /dev/null
+++ b/flow/virtualports.h
@@ -0,0 +1,87 @@
+ /*
+
+ Copyright (C) 2000 Stefan Westerfeld
+ stefan@space.twc.de
+
+ 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; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ */
+
+
+#ifndef VIRTUALPORTS_H
+#define VIRTUALPORTS_H
+
+#include "gslschedule.h"
+#include <list>
+
+/*
+ * BC - Status (2002-03-08): VPortConnection, VPort.
+ *
+ * None of these classes is considered part of the public API. Do NOT use it
+ * in your apps. These are part of the implementation of libartsflow's
+ * StdFlowSystem, and subject to change with the needs of it.
+ */
+
+namespace Arts {
+
+class VPortConnection {
+private:
+ friend class VPort;
+ VPort *source;
+ VPort *dest;
+
+public:
+ enum Style { vcForward, vcMasquerade, vcConnect, vcTransport } style;
+ VPortConnection(VPort *source, VPort *dest, Style style);
+ ~VPortConnection();
+};
+
+class VPort {
+private:
+ friend class VPortConnection;
+protected:
+ Port *port;
+ std::string _name;
+ std::list<VPortConnection *> incoming, outgoing;
+
+ void makeTransport(VPortConnection *conn);
+ void removeTransport(VPortConnection *conn);
+ void expandHelper(VPortConnection *conn, int state, VPort *current,
+ VPort *source, VPort *dest, bool remove);
+
+ bool makeVirtualizeParams(VPort *forward, VPort *& source, VPort *& dest,
+ VPortConnection::Style &style);
+
+ const char *name();
+public:
+ VPort(Port *p);
+ ~VPort();
+
+ void setFloatValue(float value);
+
+ void connect(VPort *vport);
+ void disconnect(VPort *port);
+
+ /**
+ * a->virtualize(b) means that the functionality that port a should provide
+ * (produce or consume data) is really provided by port b
+ */
+ void virtualize(VPort *port);
+ void devirtualize(VPort *port);
+};
+}
+
+#endif /* VIRTUALPORTS_H */